1 /* The source file was composed by module mixer */
\r
3 #include "include_c.h"
\r
7 /*=================================================================*/
\r
8 /* <<< [Global0/Global0.c] >>> */
\r
9 /*=================================================================*/
\r
11 /***********************************************************************
\r
12 <<< [Globals_initConst] >>>
\r
13 ************************************************************************/
\r
15 void Globals_initConst()
\r
17 AppKey_initGlobal_const();
\r
22 /***********************************************************************
\r
23 <<< [Globals_init] >>>
\r
24 ************************************************************************/
\r
29 e= Locale_init(); IF(e)goto fin;
\r
32 goto fin; // for avoid warning of no goto fin
\r
39 /***********************************************************************
\r
40 <<< [Globals_finish] >>>
\r
41 ************************************************************************/
\r
42 int Globals_finish( int e )
\r
44 e= AppKey_finishGlobal( e );
\r
51 /*=================================================================*/
\r
52 /* <<< [PlatformSDK_plus/PlatformSDK_plus.c] >>> */
\r
53 /*=================================================================*/
\r
55 /***********************************************************************
\r
56 <<< [GetCommandLineUnnamed] >>>
\r
57 ************************************************************************/
\r
58 int GetCommandLineUnnamed( int Index1, TCHAR* out_AParam, size_t AParamSize )
\r
60 TCHAR* line = GetCommandLine();
\r
69 IF( Index1 < 0 ) goto err_nf;
\r
75 while ( *p == _T(' ') ) p++;
\r
79 if ( c == _T('\0') ) goto err_nf; // Here is not decided to error or not
\r
82 //=== Skip named option
\r
83 else if ( c == _T('/') ) {
\r
87 if ( c == _T('"') || c == _T(' ') || c == _T('\0') ) break;
\r
91 if ( c == _T('"') ) {
\r
93 while ( *p != _T('"') && *p != _T('\0') ) p++;
\r
94 if ( *p == _T('"') ) p++;
\r
98 //=== Skip or Get unnamed parameter
\r
100 while ( *p == _T(' ') ) p++;
\r
105 if ( c == _T('"') ) {
\r
107 while ( *p2 != _T('"') && *p2 != _T('\0') ) p2++;
\r
110 while ( *p2 != _T(' ') && *p2 != _T('\0') ) p2++;
\r
113 if ( index == 0 ) {
\r
116 e= stcpy_part_r( out_AParam, AParamSize, out_AParam, NULL, p, p2 );
\r
117 ASSERT_D( !e, __noop() );
\r
121 p = ( *p2 == _T('"') ) ? p2+1 : p2;
\r
128 if ( AParamSize >= sizeof(TCHAR) ) *out_AParam = _T('\0');
\r
129 IF ( Index1 >= 2 ) return E_NOT_FOUND_SYMBOL;
\r
135 /***********************************************************************
\r
136 <<< [GetCommandLineNamed] >>>
\r
137 ************************************************************************/
\r
138 int GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize );
\r
140 int GetCommandLineNamed( const TCHAR* Name, bool bCase, TCHAR* out_Value, size_t ValueSize )
\r
143 return GetCommandLineNamed_sub( Name, bCase, &is_exist, out_Value, ValueSize );
\r
147 int GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize )
\r
149 TCHAR* line = GetCommandLine();
\r
153 const size_t name_len = _tcslen( Name );
\r
156 *out_IsExist = true;
\r
162 //=== Compare option name
\r
163 if ( c == _T('/') ) {
\r
168 if ( c == _T(':') || c == _T(' ') || c == _T('\0') ) break;
\r
172 bMatch = ( p2-p == (int)name_len && _tcsncmp( p, Name, p2-p ) == 0 );
\r
174 bMatch = ( p2-p == (int)name_len && _tcsnicmp( p, Name, p2-p ) == 0 );
\r
177 //=== Get the value
\r
178 if ( c == _T(':') ) {
\r
180 if ( *p == _T('"') ) {
\r
183 while ( *p2 != _T('"') && *p2 != _T('\0') ) p2++;
\r
185 return stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );
\r
191 while ( *p2 != _T(' ') && *p2 != _T('\0') ) p2++;
\r
193 return stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );
\r
199 IF( bMatch ) return E_NOT_FOUND_SYMBOL; // no value error
\r
203 else if ( c == _T('\0') ) break;
\r
206 else if ( c == _T('"') ) {
\r
208 while ( *p != _T('"') && *p != _T('\0') ) p++;
\r
209 while ( *p != _T(' ') && *p != _T('\0') ) p++;
\r
212 while ( *p != _T(' ') && *p != _T('\0') ) p++;
\r
214 while ( *p == _T(' ') ) p++;
\r
217 *out_IsExist = false;
\r
218 return E_NOT_FOUND_SYMBOL;
\r
223 /***********************************************************************
\r
224 <<< [GetCommandLineNamedI] >>>
\r
225 ************************************************************************/
\r
226 int GetCommandLineNamedI( const TCHAR* Name, bool bCase, int* out_Value )
\r
232 e= GetCommandLineNamed_sub( Name, bCase, &is_exist, s, sizeof(s) ); IF(e)goto fin; //[out] s
\r
233 if ( s[0] == _T('0') && s[1] == _T('x') )
\r
234 *out_Value = _tcstoul( s, NULL, 16 );
\r
236 *out_Value = _ttoi( s );
\r
244 /***********************************************************************
\r
245 <<< [GetCommandLineNamedC8] >>>
\r
246 ************************************************************************/
\r
248 int GetCommandLineNamedC8( const TCHAR* Name, bool bCase, char* out_Value, size_t ValueSize )
\r
254 s = (TCHAR*) malloc( ValueSize * sizeof(TCHAR) );
\r
255 e= GetCommandLineNamed_sub( Name, bCase, &is_exist, (TCHAR*) s, ValueSize * sizeof(TCHAR) ); IF(e)goto fin;
\r
257 sprintf_s( out_Value, ValueSize, "%S", s );
\r
259 if ( s != NULL ) free( s );
\r
266 /***********************************************************************
\r
267 <<< [GetCommandLineExist] >>>
\r
268 ************************************************************************/
\r
269 bool GetCommandLineExist( const TCHAR* Name, bool bCase )
\r
275 e = GetCommandLineNamed_sub( Name, bCase, &is_exist, v, sizeof(v) );
\r
276 if ( e == E_NOT_FOUND_SYMBOL ) ClearError();
\r
282 /***********************************************************************
\r
283 <<< [env_part] >>>
\r
284 ************************************************************************/
\r
285 int env_part( TCHAR* Str, unsigned StrSize, TCHAR* StrStart, TCHAR** out_StrLast,
\r
286 const TCHAR* Input )
\r
298 p = Input; o = StrStart; o_last = (TCHAR*)( (char*)Str + StrSize - sizeof(TCHAR) );
\r
299 IF_D( StrStart < Str || StrStart >= o_last ) goto err;
\r
302 IF_D( StrSize <= 2 ) return E_FEW_ARRAY;
\r
304 while ( c != _T('\0') ) {
\r
305 if ( c == _T('%') ) {
\r
307 if ( *p == _T('%') ) {
\r
309 //=== %
\95¶
\8e\9a\82ð
\83R
\83s
\81[
\82·
\82é
\r
310 IF( o == o_last )goto err_fa;
\r
316 //===
\8aÂ
\8b«
\95Ï
\90\94\96¼
\82ð name
\82É
\8eæ
\93¾
\82·
\82é
\r
317 p2 = _tcschr( p, _T('%') ); IF( p2 == NULL )goto err_ns;
\r
318 e= StrT_cpy( name, sizeof(name), _T("abc") ); IF(e)goto fin;
\r
319 e= stcpy_part_r( name, sizeof(name), name, NULL, p, p2 ); IF(e)goto fin;
\r
321 //===
\8aÂ
\8b«
\95Ï
\90\94\82Ì
\92l
\82ð o
\82É
\8eæ
\93¾
\82·
\82é
\r
322 count = ( o_last + sizeof(TCHAR) - o ) / sizeof(TCHAR);
\r
323 r= GetEnvironmentVariable( name, o, count );
\r
324 IF( r==0 ) goto err_ns; //
\8aÂ
\8b«
\95Ï
\90\94\82ª
\8c©
\82Â
\82©
\82ç
\82È
\82¢
\r
325 IF( r > count ) goto err_fa;
\r
327 //=== p, o
\82ð
\8dX
\90V
\82·
\82é
\r
329 o = _tcschr( o, _T('\0') );
\r
334 //===
\8aÂ
\8b«
\95Ï
\90\94\82Å
\82Í
\82È
\82¢
\95\94\95ª
\82ð
\83R
\83s
\81[
\82·
\82é
\r
335 IF( o == o_last )goto err_fa;
\r
345 if ( out_StrLast != NULL ) *out_StrLast = o;
\r
348 err_fa: e = E_FEW_ARRAY; goto fin;
\r
349 err_ns: e = E_NOT_FOUND_SYMBOL; goto fin;
\r
350 err: e = E_OTHERS; goto fin;
\r
355 /***********************************************************************
\r
356 <<< [env_malloc] >>>
\r
357 ************************************************************************/
\r
358 int env_malloc( TCHAR** out_Value, size_t* out_ValueLen, const TCHAR* Name )
\r
362 TCHAR* value = NULL;
\r
364 r= GetEnvironmentVariable( Name, NULL, 0 );
\r
367 return 0; //
\8aÂ
\8b«
\95Ï
\90\94\82ª
\92è
\8b`
\82³
\82ê
\82Ä
\82¢
\82È
\82¢
\82Æ
\82«
\82Å
\82à
\81A
\83G
\83\89\81[
\82É
\82µ
\82È
\82¢
\r
370 value = (TCHAR*) malloc( r * sizeof(TCHAR) );
\r
371 IF( value == NULL ) goto err_fm;
\r
372 GetEnvironmentVariable( Name, value, r );
\r
374 *out_Value = value;
\r
375 if ( out_ValueLen != NULL ) *out_ValueLen = r - 1;
\r
381 err_fm: e = E_FEW_MEMORY; goto fin;
\r
386 /*=================================================================*/
\r
387 /* <<< [Locale/Locale.c] >>> */
\r
388 /*=================================================================*/
\r
390 /***********************************************************************
\r
391 <<< [g_LocaleSymbol] >>>
\r
392 ************************************************************************/
\r
393 char* g_LocaleSymbol = "";
\r
397 /***********************************************************************
\r
398 <<< [Locale_init] >>>
\r
399 ************************************************************************/
\r
402 g_LocaleSymbol = ".OCP";
\r
403 setlocale( LC_ALL, ".OCP" );
\r
408 /***********************************************************************
\r
409 <<< [Locale_isInited] >>>
\r
410 ************************************************************************/
\r
411 int Locale_isInited()
\r
413 return ( g_LocaleSymbol[0] != '\0' );
\r
414 //
\82±
\82±
\82ª false
\82ð
\95Ô
\82·
\82Æ
\82«
\82Ì
\91Î
\8f\88\96@
\82Í
\81ALocale_isInited
\82Ì
\83w
\83\8b\83v
\82ð
\8eQ
\8fÆ
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B
\r
418 /*=================================================================*/
\r
419 /* <<< [FileT/FileT.c] >>> */
\r
420 /*=================================================================*/
\r
422 /***********************************************************************
\r
423 <<< [FileT_isExist] >>>
\r
424 ************************************************************************/
\r
425 bool FileT_isExist( const TCHAR* path )
\r
427 #if ! FileT_isExistWildcard
\r
431 if ( path[0] == _T('\0') ) return false;
\r
432 r = GetFileAttributes( path );
\r
433 return r != (DWORD)-1;
\r
438 WIN32_FIND_DATA data;
\r
440 find = FindFirstFileEx( path, FindExInfoStandard, &data,
\r
441 FindExSearchNameMatch, NULL, 0 );
\r
443 if ( find == INVALID_HANDLE_VALUE ) {
\r
456 /***********************************************************************
\r
457 <<< [FileT_isFile] >>>
\r
458 ************************************************************************/
\r
459 bool FileT_isFile( const TCHAR* path )
\r
461 DWORD r = GetFileAttributes( path );
\r
462 return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == 0;
\r
463 // 0x80000000
\82Í
\81A
\83t
\83@
\83C
\83\8b\82â
\83t
\83H
\83\8b\83_
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\82±
\82Æ
\82ð
\94»
\92è
\82·
\82é
\82½
\82ß
\r
468 /***********************************************************************
\r
469 <<< [FileT_isDir] >>>
\r
470 ************************************************************************/
\r
471 bool FileT_isDir( const TCHAR* path )
\r
473 DWORD r = GetFileAttributes( path );
\r
474 return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == FILE_ATTRIBUTE_DIRECTORY;
\r
475 // 0x80000000
\82Í
\81A
\83t
\83@
\83C
\83\8b\82â
\83t
\83H
\83\8b\83_
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\82±
\82Æ
\82ð
\94»
\92è
\82·
\82é
\82½
\82ß
\r
480 /***********************************************************************
\r
481 <<< [FileT_callByNestFind]
\83T
\83u
\83t
\83H
\83\8b\83_
\82à
\8aÜ
\82ß
\82Ä
\8ae
\83t
\83@
\83C
\83\8b\82Ì
\83p
\83X
\82ð
\93n
\82· >>>
\r
482 ************************************************************************/
\r
484 /*--- inherit from FileT_CallByNestFindData */
\r
485 void* CallerArgument;
\r
486 TCHAR* AbsPath; // abstruct path
\r
489 DWORD FileAttributes;
\r
493 FuncType CallbackFromNestFind;
\r
494 TCHAR AbsPathMem[4096];
\r
495 } FileT_CallByNestFindDataIn;
\r
497 int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m );
\r
500 int FileT_callByNestFind( const TCHAR* Path, BitField Flags, void* Argument, FuncType Callback )
\r
503 FileT_CallByNestFindDataIn data;
\r
508 e= StrT_cpy( data.AbsPathMem, sizeof(data.AbsPathMem), Path ); IF(e)goto fin;
\r
511 /* AbsPathMem
\82Ì
\8dÅ
\8cã
\82É \
\82ª
\96³
\82¢
\82È
\82ç
\92Ç
\89Á
\82·
\82é */
\r
512 p = _tcschr( data.AbsPathMem, _T('\0') );
\r
514 if ( *p != _T('\\') ) {
\r
516 IF( p >= data.AbsPathMem + (sizeof(data.AbsPathMem) / sizeof(TCHAR)) - 1 )goto err_fa;
\r
521 /* data
\82ð
\8f\89\8aú
\89»
\82·
\82é */
\r
522 data.CallerArgument = Argument;
\r
523 data.AbsPath = data.AbsPathMem;
\r
524 data.StepPath = p + 1;
\r
525 data.FileName = p + 1;
\r
526 data.Flags = Flags;
\r
527 data.CallbackFromNestFind = Callback;
\r
530 /*
\8dÄ
\8bN
\8cÄ
\82Ñ
\8fo
\82µ
\8aÖ
\90\94\82Ö */
\r
531 e= FileT_callByNestFind_sub( &data ); IF(e)goto fin;
\r
536 err_fa: e= E_FEW_ARRAY; goto fin;
\r
540 int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m )
\r
544 WIN32_FIND_DATA data;
\r
549 /* Path
\82É
\8ew
\92è
\82µ
\82½
\83t
\83H
\83\8b\83_
\82É
\91Î
\82µ
\82Ä
\83R
\81[
\83\8b\83o
\83b
\83N
\82·
\82é */
\r
550 if ( m->Flags & FileT_FolderBeforeFiles ) {
\r
551 *( m->FileName - 1 ) = _T('\0'); // m->AbsPath
\82Ì
\8dÅ
\8cã
\82Ì \
\82ð
\88ê
\8e\9e\93I
\82É
\83J
\83b
\83g
\r
552 *( m->FileName ) = _T('\0'); // m->FileName, m->StepPath
\82ð ""
\82É
\82·
\82é
\r
553 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
\r
555 if ( m->StepPath[0] == _T('\0') ) {
\r
556 TCHAR* step_path = m->StepPath;
\r
557 TCHAR* fname = m->FileName;
\r
559 m->StepPath = _T(".");
\r
560 m->FileName = StrT_refFName( m->AbsPath );
\r
561 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
562 m->StepPath = step_path;
\r
563 m->FileName = fname;
\r
565 else if ( m->FileName[0] == _T('\0') ) {
\r
566 TCHAR* fname = m->FileName;
\r
568 m->FileName = StrT_refFName( m->AbsPath );
\r
569 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
570 m->FileName = fname;
\r
573 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
575 *( m->FileName - 1 ) = _T('\\');
\r
579 /* *
\82ð
\92Ç
\89Á */
\r
581 IF( p >= m->AbsPathMem + (sizeof(m->AbsPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;
\r
582 *p = _T('*'); *(p+1) = _T('\0');
\r
585 /*
\83t
\83@
\83C
\83\8b\82©
\83t
\83H
\83\8b\83_
\82ð
\97ñ
\8b\93\82µ
\82Ü
\82· */
\r
586 find = FindFirstFileEx( m->AbsPathMem, FindExInfoStandard, &data,
\r
587 FindExSearchNameMatch, NULL, 0 );
\r
588 done = ( find == INVALID_HANDLE_VALUE );
\r
592 if ( _tcscmp( data.cFileName, _T(".") ) == 0 ||
\r
593 _tcscmp( data.cFileName, _T("..") ) == 0 ) {
\r
594 done = ! FindNextFile( find, &data );
\r
598 StrT_cpy( m->FileName,
\r
599 sizeof(m->AbsPathMem) - ( (char*)m->FileName - (char*)m->AbsPathMem ),
\r
601 m->FileAttributes = data.dwFileAttributes;
\r
603 if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
\r
604 TCHAR* prev_fname = m->FileName;
\r
606 p = _tcschr( m->FileName, _T('\0') );
\r
608 IF( p >= m->AbsPathMem + (sizeof(m->AbsPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;
\r
609 *p = _T('\\'); *(p+1) = _T('\0');
\r
610 m->FileName = p + 1;
\r
612 e= FileT_callByNestFind_sub( m ); IF(e)goto fin; /*
\8dÄ
\8bN
\8cÄ
\82Ñ
\8fo
\82µ */
\r
614 m->FileName = prev_fname;
\r
617 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
620 done = ! FindNextFile( find, &data );
\r
625 /* Path
\82É
\8ew
\92è
\82µ
\82½
\83t
\83H
\83\8b\83_
\82É
\91Î
\82µ
\82Ä
\83R
\81[
\83\8b\83o
\83b
\83N
\82·
\82é */
\r
626 if ( m->Flags & FileT_FolderAfterFiles ) {
\r
627 TCHAR* step_path = m->StepPath;
\r
628 TCHAR* fname = m->FileName;
\r
630 *( m->FileName - 1 ) = _T('\0');
\r
631 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
\r
632 if ( ( *( m->StepPath - 1 ) == _T('\0') ) && ( m->StepPath > m->AbsPath ) ) {
\r
633 m->StepPath = _T(".");
\r
635 m->FileName = StrT_refFName( m->AbsPath );
\r
637 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
639 m->StepPath = step_path;
\r
640 m->FileName = fname;
\r
646 err_fa: e= E_FEW_ARRAY; goto fin;
\r
651 /***********************************************************************
\r
652 <<< [FileT_openForRead] >>>
\r
653 ************************************************************************/
\r
654 int FileT_openForRead( FILE** out_pFile, const TCHAR* Path )
\r
658 assert( Locale_isInited() );
\r
660 #if DEBUGTOOLS_USES
\r
661 { int e= Debug_onOpen( Path ); if(e) return e; }
\r
664 en = _tfopen_s( out_pFile, Path, _T("r")_T(fopen_ccs) );
\r
665 if ( en == ENOENT ) {
\r
666 _tprintf( _T("not found \"%s\"\n"), Path );
\r
672 if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )
\r
673 _tprintf( _T("current = \"%s\"\n"), cwd );
\r
677 return E_NOT_FOUND_SYMBOL;
\r
679 if ( en == EACCES ) {
\r
680 _tprintf( _T("access denied \"%s\"\n"), Path );
\r
681 return E_ACCESS_DENIED;
\r
683 IF(en)return E_OTHERS;
\r
690 /***********************************************************************
\r
691 <<< [FileT_openForWrite] >>>
\r
692 ************************************************************************/
\r
693 int FileT_openForWrite( FILE** out_pFile, const TCHAR* Path, int Flags )
\r
701 IF_D( ! Locale_isInited() ) return E_NOT_INIT_GLOBAL;
\r
704 e= AppKey_addNewWritableFolder( Path ); IF(e)goto fin;
\r
707 if ( Flags & F_Append )
\r
708 open_type = ( Flags & F_Unicode ? _T("a")_T(fopen_ccs) : _T("at") );
\r
710 open_type = ( Flags & F_Unicode ? _T("w")_T(fopen_ccs) : _T("wt") );
\r
712 #if DEBUGTOOLS_USES
\r
713 { int e= Debug_onOpen( Path ); if(e) return e; }
\r
716 for ( retry_count = 0; ; retry_count ++ ) {
\r
717 en = _tfopen_s( out_pFile, Path, open_type );
\r
718 if ( en != EACCES ) break;
\r
721 if ( retry_count == 15 ) break;
\r
724 if ( en == 2 ) { // ENOENT
\r
725 e= FileT_mkdir( Path ); IF(e)goto fin;
\r
726 b= RemoveDirectory( Path ); IF(!b)goto err_gt;
\r
727 en = _tfopen_s( out_pFile, Path, open_type );
\r
730 _tprintf( _T("cannot open \"%s\"\n"), Path );
\r
736 if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )
\r
737 _tprintf( _T("current = \"%s\"\n"), cwd );
\r
741 e = E_NOT_FOUND_SYMBOL;
\r
751 err: e = E_OTHERS; goto fin;
\r
752 err_gt: e = SaveWindowsLastError(); goto fin;
\r
757 /***********************************************************************
\r
758 <<< [FileT_close] >>>
\r
759 ************************************************************************/
\r
760 int FileT_close( FILE* File, int e )
\r
762 if ( File != NULL ) {
\r
763 int r = fclose( File );
\r
764 IF(r&&!e)e=E_ERRNO;
\r
772 /***********************************************************************
\r
773 <<< [FileT_writePart] >>>
\r
774 ************************************************************************/
\r
775 errnum_t FileT_writePart( FILE* File, TCHAR* Start, TCHAR* Over )
\r
784 r= _ftprintf_s( File, _T("%s"), Start ); IF(r<0){ e=E_ERRNO; goto fin; }
\r
794 /***********************************************************************
\r
795 <<< [FileT_mkdir] >>>
\r
796 ************************************************************************/
\r
797 int FileT_mkdir( const TCHAR* Path )
\r
801 TCHAR* p = (TCHAR*) DUMMY_INITIAL_VALUE;
\r
804 TCHAR path2[MAX_PATH];
\r
807 e= StrT_getAbsPath( path2, sizeof(path2), Path, NULL ); IF(e)goto fin;
\r
809 e= AppKey_addNewWritableFolder( path2 ); IF(e)goto fin;
\r
813 //===
\91¶
\8dÝ
\82·
\82é
\83t
\83H
\83\8b\83_
\82ð
\92T
\82·
\r
815 r = GetFileAttributes( path2 );
\r
816 if ( r != (DWORD)-1 ) break; // "C:"
\82à
\83t
\83H
\83\8b\83_
\82Æ
\94»
\92è
\82³
\82ê
\82é
\r
818 p = StrT_refFName( path2 ) - 1; //
\90â
\91Î
\83p
\83X
\82È
\82Ì
\82Å
\95K
\82¸ *p=='\\'
\r
822 IF ( ! (r & FILE_ATTRIBUTE_DIRECTORY) ) goto err; //
\83t
\83@
\83C
\83\8b\82È
\82ç
\83G
\83\89\81[
\r
825 //===
\83t
\83H
\83\8b\83_
\82ð
\8dì
\90¬
\82·
\82é
\r
826 for ( ; n_folder > 0; n_folder -- ) {
\r
828 b= CreateDirectory( path2, NULL ); IF(!b)goto err;
\r
829 p = _tcschr( p, _T('\0') );
\r
836 err: e = E_OTHERS; goto fin;
\r
842 /***********************************************************************
\r
843 <<< [FileT_copy] >>>
\r
844 ************************************************************************/
\r
845 int FileT_copy_sub( FileT_CallByNestFindData* m );
\r
847 int FileT_copy( const TCHAR* SrcPath, const TCHAR* DstPath )
\r
849 const TCHAR* p_last;
\r
852 TCHAR path[MAX_PATH*4];
\r
856 e= AppKey_addNewWritableFolder( DstPath ); IF(e)goto fin;
\r
859 p_last = _tcschr( SrcPath, _T('\0') );
\r
860 IF_D( p_last <= SrcPath + 1 )goto err_ni;
\r
863 //===
\83t
\83H
\83\8b\83_
\82ð
\83R
\83s
\81[
\82·
\82é
\r
864 if ( *(p_last - 1) == _T('*') ) {
\r
865 IF_D( *(p_last - 2) != _T('\\') ) goto err_ni;
\r
867 e= StrT_getParentAbsPath( path, sizeof(path), SrcPath, NULL ); IF(e)goto fin;
\r
868 IF_D( ! FileT_isDir( path ) )goto err_nf;
\r
870 e= FileT_callByNestFind( path, FileT_FolderBeforeFiles, (void*) DstPath, (FuncType) FileT_copy_sub );
\r
875 //===
\83t
\83@
\83C
\83\8b\82ð
\83R
\83s
\81[
\82·
\82é
\r
877 IF_D( _tcschr( SrcPath, _T('*') ) != NULL )goto err_ni;
\r
878 IF_D( ! FileT_isFile( SrcPath ) ) goto err_nf;
\r
880 b= CopyFile( SrcPath, DstPath, FALSE );
\r
882 if ( FileT_isDir( DstPath ) ) {
\r
883 e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;
\r
884 b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;
\r
889 p_last = _tcschr( DstPath, _T('\0') ) - 1;
\r
890 IF_D( p_last < DstPath )goto err;
\r
891 if ( *p_last == _T('\\') ) {
\r
892 ee= FileT_mkdir( DstPath ); IF(ee)goto fin;
\r
893 e= stprintf_r( path, sizeof(path), _T("%s%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;
\r
894 b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;
\r
897 e = E_ACCESS_DENIED;
\r
898 ee= StrT_getParentAbsPath( path, sizeof(path), DstPath, NULL ); IF(ee)goto fin;
\r
899 ee= FileT_mkdir( path ); IF(ee)goto fin;
\r
900 b= CopyFile( SrcPath, DstPath, FALSE ); IF(!b)goto err_gt;
\r
910 err_ni: e = E_NOT_IMPLEMENT_YET; goto fin;
\r
911 err_nf: e = E_PATH_NOT_FOUND; goto fin;
\r
912 err_gt: e = SaveWindowsLastError(); goto fin;
\r
913 err: e = E_OTHERS; goto fin;
\r
917 int FileT_copy_sub( FileT_CallByNestFindData* m )
\r
919 const TCHAR* DstPath = (const TCHAR*) m->CallerArgument;
\r
922 TCHAR path[MAX_PATH*4];
\r
924 e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, m->StepPath ); IF(e)goto fin;
\r
926 if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
\r
927 if ( ! FileT_isDir( path ) )
\r
928 { b= CreateDirectory( path, NULL ); IF(!b)goto err_gt; }
\r
931 b= CopyFile( m->AbsPath, path, FALSE ); IF(!b)goto err_gt;
\r
938 err_gt: e = SaveWindowsLastError(); goto fin;
\r
944 /***********************************************************************
\r
945 <<< [FileT_del] >>>
\r
946 ************************************************************************/
\r
947 int FileT_del_sub( FileT_CallByNestFindData* m );
\r
949 int FileT_del( const TCHAR* Path )
\r
953 TCHAR abs_path[MAX_PATH];
\r
955 e= StrT_getAbsPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto fin;
\r
957 e= AppKey_addNewWritableFolder( abs_path ); IF(e)goto fin;
\r
960 r= GetFileAttributes( Path );
\r
961 if ( r != (DWORD)-1 ) {
\r
962 if ( r & FILE_ATTRIBUTE_DIRECTORY ) {
\r
963 e= FileT_callByNestFind( Path, FileT_FolderAfterFiles, NULL, (FuncType) FileT_del_sub );
\r
966 BOOL b= DeleteFile( Path ); IF(!b)goto err_gt;
\r
969 IF_D( FileT_isExist( Path ) )goto err_ad;
\r
975 err_gt: e = SaveWindowsLastError(); goto fin;
\r
976 err_ad: e = E_ACCESS_DENIED; goto fin;
\r
980 int FileT_del_sub( FileT_CallByNestFindData* m )
\r
985 if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
\r
986 b= RemoveDirectory( m->AbsPath ); IF(!b)goto err_gt;
\r
989 b= DeleteFile( m->AbsPath ); IF(!b)goto err_gt;
\r
996 err_gt: e = SaveWindowsLastError(); goto fin;
\r
999 /***********************************************************************
\r
1001 ************************************************************************/
\r
1002 static errnum_t AppKey_create( AppKey** out_m );
\r
1003 static bool AppKey_isSame( AppKey* m );
\r
1004 static void Writables_initConst( Writables* m );
\r
1005 static errnum_t Writables_init( Writables* m, AppKey* Key );
\r
1006 static errnum_t Writables_finish( Writables* m, int e );
\r
1007 static bool Writables_isInited( Writables* m );
\r
1008 static errnum_t Writables_clearPaths( Writables* m );
\r
1009 static errnum_t Writables_create( Writables** out_m, AppKey* Key );
\r
1010 static errnum_t Writables_copyToConst( Writables* To, Writables* From );
\r
1013 typedef struct _CurrentWritables CurrentWritables;
\r
1014 struct _CurrentWritables {
\r
1015 Writables m_CurrentWritables;
\r
1016 TCHAR* m_ProgramFiles; size_t m_ProgramFiles_Len;
\r
1017 TCHAR* m_windir; size_t m_windir_Len;
\r
1018 TCHAR* m_APPDATA; size_t m_APPDATA_Len;
\r
1019 TCHAR* m_LOCALAPPDATA; size_t m_LOCALAPPDATA_Len;
\r
1021 static void CurrentWritables_initConst( CurrentWritables* m );
\r
1022 static errnum_t CurrentWritables_init( CurrentWritables* m );
\r
1023 static errnum_t CurrentWritables_finish( CurrentWritables* m, int e );
\r
1024 static errnum_t CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* AbsPath );
\r
1027 //////////////////////////////
\r
1029 static AppKey g_AppKey;
\r
1030 static AppKey* g_AppKeyPrivate;
\r
1033 Writables g_DefaultWritables;
\r
1034 Writables g_CurrentWritables; // public
\r
1035 static CurrentWritables g_CurrentWritablesPrivate;
\r
1038 static errnum_t AppKey_create( AppKey** out_m )
\r
1042 IF( g_AppKeyPrivate != NULL ) { e=1; goto fin; }
\r
1043 // AppKey_newWritable
\82Ì in_out_m = NULL
\82Ì
\82Æ
\82«
\82Í
\81A2
\89ñ
\8cÄ
\82Ñ
\8fo
\82·
\82±
\82Æ
\82Í
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B
\r
1045 Writables_initConst( &g_DefaultWritables );
\r
1046 CurrentWritables_initConst( &g_CurrentWritablesPrivate );
\r
1048 e= CurrentWritables_init( &g_CurrentWritablesPrivate ); IF(e)goto fin;
\r
1049 e= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(e)goto fin;
\r
1051 *out_m = &g_AppKey;
\r
1052 g_AppKeyPrivate = &g_AppKey;
\r
1060 static bool AppKey_isSame( AppKey* m )
\r
1062 return ( m == g_AppKeyPrivate );
\r
1066 void AppKey_initGlobal_const()
\r
1068 Writables_initConst( &g_DefaultWritables );
\r
1072 errnum_t AppKey_finishGlobal( errnum_t e )
\r
1076 e= Writables_finish( &g_DefaultWritables, e );
\r
1077 e= CurrentWritables_finish( &g_CurrentWritablesPrivate, e );
\r
1078 ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)e=ee;
\r
1085 /***********************************************************************
\r
1086 <<< [AppKey_newWritable] >>>
\r
1087 ************************************************************************/
\r
1088 errnum_t AppKey_newWritable( AppKey** in_out_m, Writables** out_Writable, ... )
\r
1092 Writables* wr = NULL;
\r
1093 #if Uses_OutMallocIDTool
\r
1094 bool is_prev_out_malloc;
\r
1096 is_prev_out_malloc = OutMallocID_setEnable( false );
\r
1100 //=== AppKey* m
\82ð
\97L
\8cø
\82É
\82·
\82é
\r
1101 if ( in_out_m == NULL ) { //
\8d¡
\89ñ
\82Ì
\8aÖ
\90\94\82Ì
\92\86\82¾
\82¯
\82Å
\8eQ
\8fÆ
\82·
\82é
\r
1102 e= AppKey_create( &m ); IF(e)goto resume;
\r
1104 else if ( *in_out_m == NULL ) { //
\82P
\89ñ
\96Ú
\82É
\96{
\8aÖ
\90\94\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82½
\83\82\83W
\83\85\81[
\83\8b\82É
\93n
\82·
\r
1105 e= AppKey_create( &m ); IF(e)goto resume;
\r
1108 else { //
\96{
\8aÖ
\90\94\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82½
\83\82\83W
\83\85\81[
\83\8b\82©
\82ç
\93n
\82Á
\82½
\82à
\82Ì
\82ð
\8eg
\82¤
\r
1113 //===
\90³
\8bK
\82Ì AppKey
\82©
\83`
\83F
\83b
\83N
\82·
\82é
\r
1114 IF( ! AppKey_isSame( m ) )goto err;
\r
1117 //=== Writable
\82ð
\90¶
\90¬
\82·
\82é
\r
1118 if ( out_Writable == NULL ) {
\r
1119 wr = &g_DefaultWritables;
\r
1120 e= Writables_finish( wr, 0 ); IF(e)goto resume;
\r
1121 e= Writables_init( wr, m ); IF(e)goto resume;
\r
1124 e= Writables_create( &wr, m ); IF(e)goto resume;
\r
1125 *out_Writable = wr;
\r
1129 //=== Writable
\82É
\83p
\83X
\82ð
\93o
\98^
\82·
\82é
\r
1135 va_start( va, out_Writable );
\r
1136 for ( i=0; ; i++ ) {
\r
1137 path = va_arg( va, TCHAR* );
\r
1138 if ( path == NULL ) break;
\r
1139 IF( i == 5 ) goto err; //
\8dÅ
\8cã
\82Ì NULL
\96Y
\82ê
\91Î
\8dô
\r
1141 e= Writables_add( wr, m, path ); IF(e)goto resume;
\r
1145 #if defined(TempFile_get)
\r
1149 e= TempFile_get( &temp ); IF(e)goto resume;
\r
1150 e= Writables_add( wr, m, temp->TempPath ); IF(e)goto resume;
\r
1155 //===
\82·
\82®
\82É Writable
\82ð
\97L
\8cø
\82É
\82·
\82é
\r
1156 if ( out_Writable == NULL ) {
\r
1157 e= Writables_enable( wr ); IF(e)goto resume;
\r
1162 #if Uses_OutMallocIDTool
\r
1163 OutMallocID_setEnable( is_prev_out_malloc );
\r
1167 err: e = E_OTHERS; goto resume;
\r
1169 if ( wr != NULL ) {
\r
1170 if ( out_Writable == NULL )
\r
1171 e= Writables_finish( wr, e ); // g_DefaultWritables
\r
1173 e= Writables_delete( wr, e );
\r
1180 /***********************************************************************
\r
1181 <<< [AppKey_addNewWritableFolder]
\83`
\83F
\83b
\83N
\82·
\82é
\81A
\82Ü
\82½
\82Í
\92Ç
\89Á
\82·
\82é >>>
\r
1182 \81i
\92Ç
\89Á
\82Í
\96¢
\91Î
\89\9e\81j
\r
1183 ************************************************************************/
\r
1184 errnum_t AppKey_addNewWritableFolder( const TCHAR* Path )
\r
1189 Writables* wr = &g_CurrentWritablesPrivate.m_CurrentWritables;
\r
1191 TCHAR abs_path[MAX_PATH];
\r
1193 if ( g_AppKeyPrivate == NULL ) {
\r
1194 e= AppKey_newWritable( NULL, NULL, ".", NULL ); IF(e){goto fin;}
\r
1197 e= StrT_getAbsPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e){goto fin;}
\r
1199 pp_over = wr->m_Paths + wr->m_nPath;
\r
1200 for ( pp = wr->m_Paths; ; pp++ ) {
\r
1201 IF ( pp >= pp_over ) { e=E_OUT_OF_WRITABLE; goto fin; }
\r
1202 // Path (abs_path)
\82Í
\81AAppKey_newWritable
\82Å
\8b\96\89Â
\82³
\82ê
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B
\r
1203 //
\83E
\83H
\83b
\83`
\81E
\83E
\83B
\83\93\83h
\83E
\82É g_CurrentWritables.m_Paths,3
\82È
\82Ç
\82ð
\93ü
\97Í
\82µ
\82Ä
\r
1204 //
\8b\96\89Â
\82³
\82ê
\82Ä
\82¢
\82é
\83p
\83X
\82ð
\8am
\94F
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B
\r
1206 path_len = _tcslen( *pp );
\r
1207 if ( _tcsnicmp( *pp, abs_path, path_len ) == 0 &&
\r
1208 ( abs_path[ path_len ] == _T('\\') || abs_path[ path_len ] == _T('\0') ) ) break;
\r
1218 /***********************************************************************
\r
1219 <<< [AppKey_checkWritable] >>>
\r
1220 ************************************************************************/
\r
1221 errnum_t AppKey_checkWritable( const TCHAR* Path )
\r
1223 return AppKey_addNewWritableFolder( Path );
\r
1228 /***********************************************************************
\r
1229 <<< [Writables_init] >>>
\r
1230 ************************************************************************/
\r
1231 static void Writables_initConst( Writables* m )
\r
1233 m->m_Paths = NULL;
\r
1238 static errnum_t Writables_init( Writables* m, AppKey* Key )
\r
1240 IF( ! AppKey_isSame( Key ) ) return E_OTHERS;
\r
1242 m->m_Paths = NULL;
\r
1248 static errnum_t Writables_finish( Writables* m, int e )
\r
1252 ee= Writables_clearPaths( m ); IF(ee&&!e) e=ee;
\r
1258 static bool Writables_isInited( Writables* m )
\r
1260 return ( m->m_nPath != -1 );
\r
1264 static errnum_t Writables_clearPaths( Writables* m )
\r
1269 if ( m->m_Paths != NULL ) {
\r
1270 p_over = m->m_Paths + m->m_nPath;
\r
1271 for ( p = m->m_Paths; p < p_over; p++ ) {
\r
1274 free( m->m_Paths ); m->m_Paths = NULL;
\r
1281 static errnum_t Writables_create( Writables** out_m, AppKey* Key )
\r
1286 m = (Writables*) malloc( sizeof(*m) ); IF(m==NULL)return E_FEW_MEMORY;
\r
1287 Writables_initConst( m );
\r
1288 e= Writables_init( m, Key ); IF(e)goto resume;
\r
1291 resume: Writables_delete( m, 0 ); free(m); return e;
\r
1295 errnum_t Writables_delete( Writables* m, errnum_t e )
\r
1297 if ( m == NULL ) goto fin;
\r
1298 e= Writables_finish( m, e );
\r
1306 /***********************************************************************
\r
1307 <<< [Writables_add] >>>
\r
1308 ************************************************************************/
\r
1309 int Writables_add( Writables* m, AppKey* Key, TCHAR* Path )
\r
1315 TCHAR abs_path[MAX_PATH];
\r
1317 IF( ! AppKey_isSame( Key ) )goto err;
\r
1318 if ( Path[0] == _T('\0') ) return 0;
\r
1320 e= StrT_getAbsPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto resume;
\r
1322 e= CurrentWritables_askFileAccess( &g_CurrentWritablesPrivate, abs_path ); IF(e)goto resume;
\r
1324 pp = (TCHAR**) realloc( m->m_Paths, (m->m_nPath + 1) * sizeof(TCHAR*) );
\r
1325 IF( pp == NULL ) goto err;
\r
1328 path_size = (_tcslen( abs_path ) + 1) * sizeof(TCHAR);
\r
1329 p = (TCHAR*) malloc( path_size );
\r
1330 m->m_Paths[ m->m_nPath ] = p;
\r
1331 IF( p == NULL )goto err;
\r
1333 memcpy( p, abs_path, path_size );
\r
1334 if ( p[ path_size/sizeof(TCHAR) - 2 ] == _T('\\') )
\r
1335 p[ path_size/sizeof(TCHAR) - 2 ] = _T('\0');
\r
1342 err: e = E_OTHERS; goto resume;
\r
1344 if ( p != NULL ) free( p );
\r
1349 int Writables_remove( Writables* m, TCHAR* Path )
\r
1354 pp_over = m->m_Paths + m->m_nPath;
\r
1355 for ( pp = m->m_Paths; ; pp++ ) {
\r
1356 if ( pp >= pp_over ) return 0;
\r
1357 if ( _tcscmp( *pp, Path ) == 0 ) break;
\r
1360 memmove( pp, pp+1, (char*)pp - (char*)pp_over - sizeof(TCHAR) );
\r
1364 *( pp_over - 1 ) = NULL;
\r
1372 /***********************************************************************
\r
1373 <<< [Writables_enable] >>>
\r
1374 ************************************************************************/
\r
1375 int Writables_enable( Writables* m )
\r
1379 e= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, m ); IF(e)goto fin;
\r
1380 e= Writables_copyToConst( &g_CurrentWritables, &g_CurrentWritablesPrivate.m_CurrentWritables ); IF(e)goto fin;
\r
1388 int Writables_disable( Writables* m, int e )
\r
1392 UNREFERENCED_VARIABLES( m );
\r
1394 ee= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, NULL ); IF(ee&&!e)goto fin;
\r
1395 ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)goto fin;
\r
1403 static int Writables_copyToConst( Writables* To, Writables* From )
\r
1412 if ( To->m_Paths != NULL ) {
\r
1413 free( To->m_Paths );
\r
1414 To->m_Paths = NULL;
\r
1418 if ( From != NULL && From->m_nPath > 0 ) {
\r
1421 pp_over = From->m_Paths + From->m_nPath;
\r
1422 for ( pp = From->m_Paths; pp < pp_over; pp++ ) {
\r
1423 path_size += _tcslen( *pp ) + 1;
\r
1426 path_size = From->m_nPath * sizeof(TCHAR*) + path_size * sizeof(TCHAR);
\r
1427 To->m_Paths = (TCHAR**) malloc( path_size );
\r
1428 IF( To->m_Paths == NULL ) goto err;
\r
1430 p2 = (TCHAR*)( (char*)To->m_Paths + From->m_nPath * sizeof(TCHAR*) );
\r
1431 pp2 = To->m_Paths;
\r
1432 for ( pp = From->m_Paths; pp < pp_over; pp++ ) {
\r
1434 path_size = (_tcslen( *pp ) + 1) * sizeof(TCHAR);
\r
1435 memcpy( p2, *pp, path_size );
\r
1436 p2 = (TCHAR*)( (char*)p2 + path_size );
\r
1439 To->m_nPath = From->m_nPath;
\r
1446 err: e = E_OTHERS; goto fin;
\r
1450 /***********************************************************************
\r
1451 <<< [CurrentWritables] >>>
\r
1452 ************************************************************************/
\r
1453 static void CurrentWritables_initConst( CurrentWritables* m )
\r
1455 Writables_initConst( &m->m_CurrentWritables );
\r
1456 m->m_ProgramFiles = NULL;
\r
1457 m->m_windir = NULL;
\r
1458 m->m_APPDATA = NULL;
\r
1459 m->m_LOCALAPPDATA = NULL;
\r
1463 static int CurrentWritables_init( CurrentWritables* m )
\r
1466 #if Uses_OutMallocIDTool
\r
1467 bool is_prev_out_malloc;
\r
1469 is_prev_out_malloc = OutMallocID_setEnable( false );
\r
1472 e= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(e)goto fin;
\r
1474 e= env_malloc( &m->m_ProgramFiles, &m->m_ProgramFiles_Len, _T("ProgramFiles") ); IF(e)goto fin;
\r
1475 e= env_malloc( &m->m_windir, &m->m_windir_Len, _T("windir") ); IF(e)goto fin;
\r
1476 e= env_malloc( &m->m_APPDATA, &m->m_APPDATA_Len, _T("APPDATA") ); IF(e)goto fin;
\r
1477 // e= env_malloc( &m->m_LOCALAPPDATA, &m->m_LOCALAPPDATA_Len, _T("LOCALAPPDATA") ); IF(e)goto fin;
\r
1481 #if Uses_OutMallocIDTool
\r
1482 OutMallocID_setEnable( is_prev_out_malloc );
\r
1488 static int CurrentWritables_finish( CurrentWritables* m, int e )
\r
1492 ee= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(ee&&!e)e=ee;
\r
1494 if ( m->m_ProgramFiles != NULL ) free( m->m_ProgramFiles );
\r
1495 if ( m->m_windir != NULL ) free( m->m_windir );
\r
1496 if ( m->m_APPDATA != NULL ) free( m->m_APPDATA );
\r
1497 if ( m->m_LOCALAPPDATA != NULL ) free( m->m_LOCALAPPDATA );
\r
1499 m->m_ProgramFiles = NULL;
\r
1500 m->m_windir = NULL;
\r
1501 m->m_APPDATA = NULL;
\r
1502 m->m_LOCALAPPDATA = NULL;
\r
1508 static int CurrentWritables_askFileAccess_sub(
\r
1509 const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* AbsPath, size_t AbsPath_Len );
\r
1511 static int CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* AbsPath )
\r
1516 abs_len = _tcslen( AbsPath );
\r
1517 e= CurrentWritables_askFileAccess_sub( m->m_ProgramFiles, m->m_ProgramFiles_Len, AbsPath, abs_len ); IF(e)goto fin;
\r
1518 e= CurrentWritables_askFileAccess_sub( m->m_windir, m->m_windir_Len, AbsPath, abs_len ); IF(e)goto fin;
\r
1519 e= CurrentWritables_askFileAccess_sub( m->m_APPDATA, m->m_APPDATA_Len, AbsPath, abs_len ); IF(e)goto fin;
\r
1520 e= CurrentWritables_askFileAccess_sub( m->m_LOCALAPPDATA, m->m_LOCALAPPDATA_Len, AbsPath, abs_len ); IF(e)goto fin;
\r
1528 static int CurrentWritables_askFileAccess_sub(
\r
1529 const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* AbsPath, size_t AbsPath_Len )
\r
1531 if ( SystemPath == NULL ) return 0;
\r
1533 IF ( _tcsncmp( SystemPath, AbsPath, SystemPath_Len ) == 0 )
\r
1534 return E_OUT_OF_WRITABLE; //
\83V
\83X
\83e
\83\80\83t
\83H
\83\8b\83_
\82Ì
\92\86\82ð
\8f\91\82«
\8d\9e\82Ý
\8b\96\89Â
\82µ
\82æ
\82¤
\82Æ
\82µ
\82Ä
\82¢
\82é
\r
1536 IF ( _tcsncmp( SystemPath, AbsPath, AbsPath_Len ) == 0 )
\r
1537 return E_OUT_OF_WRITABLE; //
\83V
\83X
\83e
\83\80\83t
\83H
\83\8b\83_
\82ð
\8aÜ
\82ß
\82Ä
\8b\96\89Â
\8f\91\82«
\8d\9e\82Ý
\8b\96\89Â
\82µ
\82æ
\82¤
\82Æ
\82µ
\82Ä
\82¢
\82é
\r
1544 /*=================================================================*/
\r
1545 /* <<< [StrT/StrT.c] >>> */
\r
1546 /*=================================================================*/
\r
1548 /***********************************************************************
\r
1549 <<< [StrT_cpy] >>>
\r
1550 - _tcscpy is raising exception, if E_FEW_ARRAY
\r
1551 ************************************************************************/
\r
1552 errnum_t StrT_cpy( TCHAR* Dst, size_t DstSize, const TCHAR* Src )
\r
1556 size = ( _tcslen( Src ) + 1 ) * sizeof(TCHAR);
\r
1557 if ( size <= DstSize ) {
\r
1558 memcpy( Dst, Src, size );
\r
1562 memcpy( Dst, Src, DstSize - sizeof(TCHAR) );
\r
1563 *(TCHAR*)( (char*) Dst + DstSize ) = _T('\0');
\r
1564 return E_FEW_ARRAY;
\r
1569 /***********************************************************************
\r
1570 <<< [MallocAndCopyString] >>>
\r
1571 ************************************************************************/
\r
1572 errnum_t MallocAndCopyString( TCHAR** out_NewString, const TCHAR* SourceString )
\r
1575 size_t size = ( _tcslen( SourceString ) + 1 ) * sizeof(TCHAR);
\r
1577 ASSERT_D( *out_NewString == NULL, __noop() );
\r
1579 str = (TCHAR*) malloc( size );
\r
1580 if ( str == NULL ) { return E_FEW_MEMORY; }
\r
1582 memcpy( str, SourceString, size );
\r
1584 *out_NewString = str;
\r
1590 /***********************************************************************
\r
1591 <<< [MallocAndCopyString_char] >>>
\r
1592 ************************************************************************/
\r
1594 errnum_t MallocAndCopyString_char( TCHAR** out_NewString, const char* SourceString )
\r
1597 size_t size = ( strlen( SourceString ) + 1 ) * sizeof(TCHAR);
\r
1600 str = (TCHAR*) malloc( size );
\r
1601 if ( str == NULL ) { return E_FEW_MEMORY; }
\r
1603 r = MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED, SourceString, -1, str, size / sizeof(TCHAR) );
\r
1606 return E_GET_LAST_ERROR;
\r
1608 *out_NewString = str;
\r
1615 /***********************************************************************
\r
1616 <<< [MallocAndCopyStringByLength] >>>
\r
1617 ************************************************************************/
\r
1618 errnum_t MallocAndCopyStringByLength( TCHAR** out_NewString, const TCHAR* SourceString,
\r
1619 unsigned CountOfCharacter )
\r
1622 size_t size = ( CountOfCharacter + 1 ) * sizeof(TCHAR);
\r
1624 ASSERT_D( *out_NewString == NULL, __noop() );
\r
1626 str = (TCHAR*) malloc( size );
\r
1627 if ( str == NULL ) { return E_FEW_MEMORY; }
\r
1629 memcpy( str, SourceString, size - sizeof(TCHAR) );
\r
1630 str[ CountOfCharacter ] = _T('\0');
\r
1632 *out_NewString = str;
\r
1638 /***********************************************************************
\r
1639 <<< [StrT_chrs] >>>
\r
1640 ************************************************************************/
\r
1641 TCHAR* StrT_chrs( const TCHAR* s, const TCHAR* keys )
\r
1643 if ( *keys == _T('\0') ) return NULL;
\r
1645 for ( ; *s != _T('\0'); s++ ) {
\r
1646 if ( _tcschr( keys, *s ) != NULL )
\r
1647 return (TCHAR*) s;
\r
1654 /***********************************************************************
\r
1655 <<< [StrT_skip] >>>
\r
1656 ************************************************************************/
\r
1657 TCHAR* StrT_skip( const TCHAR* s, const TCHAR* keys )
\r
1659 if ( *keys == _T('\0') ) return (TCHAR*) s;
\r
1661 for ( ; *s != _T('\0'); s++ ) {
\r
1662 if ( _tcschr( keys, *s ) == NULL )
\r
1665 return (TCHAR*) s;
\r
1670 /***********************************************************************
\r
1671 <<< [StrT_refFName] >>>
\r
1672 ************************************************************************/
\r
1673 TCHAR* StrT_refFName( const TCHAR* s )
\r
1678 p = _tcschr( s, _T('\0') );
\r
1680 if ( p == s ) return (TCHAR*) s;
\r
1682 for ( p--; p>s; p-- ) {
\r
1684 if ( c == _T('\\') || c == _T('/') ) return (TCHAR*) p+1;
\r
1686 if ( *p == _T('\\') || *p == _T('/') ) return (TCHAR*) p+1;
\r
1688 return (TCHAR*) s;
\r
1691 /***********************************************************************
\r
1692 <<< [StrT_refExt] >>>
\r
1693 ************************************************************************/
\r
1694 TCHAR* StrT_refExt( const TCHAR* s )
\r
1698 p = _tcschr( s, _T('\0') );
\r
1700 if ( p == s ) return (TCHAR*) s;
\r
1702 for ( p--; p>s; p-- ) {
\r
1703 if ( *p == _T('.') ) return (TCHAR*) p+1;
\r
1704 if ( *p == _T('/') || *p == _T('\\') ) return (TCHAR*) _tcschr( p, _T('\0') );
\r
1706 if ( *p == _T('.') ) return (TCHAR*) p+1;
\r
1708 return (TCHAR*) _tcschr( s, _T('\0') );
\r
1713 /***********************************************************************
\r
1714 <<< [StrT_replace1] >>>
\r
1715 ************************************************************************/
\r
1716 errnum_t StrT_replace1( TCHAR* in_out_String, TCHAR FromCharacter, TCHAR ToCharacter,
\r
1721 UNREFERENCED_VARIABLE( Opt );
\r
1723 IF ( FromCharacter == _T('\0') ) { return E_OTHERS; }
\r
1725 p = in_out_String;
\r
1727 p = _tcschr( p, FromCharacter );
\r
1728 if ( p == NULL ) { break; }
\r
1738 /***********************************************************************
\r
1739 <<< [StrT_trim] >>>
\r
1740 ************************************************************************/
\r
1741 errnum_t StrT_trim( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str )
\r
1747 p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;
\r
1748 for ( p2 = _tcschr( p1, _T('\0') ) - 1; p2 >= p1; p2-- ) {
\r
1750 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )
\r
1753 return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );
\r
1758 /***********************************************************************
\r
1759 <<< [StrT_cutLastOf] >>>
\r
1760 ************************************************************************/
\r
1761 errnum_t StrT_cutLastOf( TCHAR* in_out_Str, TCHAR Charactor )
\r
1763 TCHAR* last = _tcschr( in_out_Str, _T('\0') );
\r
1765 if ( last > in_out_Str ) {
\r
1766 if ( *( last - 1 ) == Charactor )
\r
1767 { *( last - 1 ) = _T('\0'); }
\r
1774 /***********************************************************************
\r
1775 <<< [StrT_cutLineComment] >>>
\r
1776 ************************************************************************/
\r
1777 errnum_t StrT_cutLineComment( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str, const TCHAR* CommentSign )
\r
1783 p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;
\r
1785 p2 = _tcsstr( p1, CommentSign );
\r
1786 if ( p2 == NULL ) p2 = _tcschr( p1, _T('\0') );
\r
1788 for ( p2 = p2 - 1; p2 >= p1; p2-- ) {
\r
1790 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )
\r
1793 return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );
\r
1798 /**************************************************************************
\r
1799 <<< [StrT_meltCSV] >>>
\r
1800 *************************************************************************/
\r
1801 errnum_t StrT_meltCSV( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pCSV )
\r
1805 TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );
\r
1812 if ( out_Str_Size <= 1 ) { t = dummy; t_last = dummy; }
\r
1814 if ( s == NULL ) { *t = _T('\0'); return 0; }
\r
1817 /*
\93ª
\82Ì
\8bó
\94\92\82ð
\8f\9c\82 */
\r
1818 while ( *s == _T(' ') || *s == _T('\t') ) s++;
\r
1822 /* ""
\82Å
\88Í
\82Ü
\82ê
\82Ä
\82¢
\82é
\8fê
\8d\87 */
\r
1826 while ( c != _T('"') || *(s+1) == _T('"') ) { /* "
\95¶
\8e\9a\82Ü
\82Å */
\r
1827 if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }
\r
1828 if ( c == *(s+1) && c == _T('"') ) s++; /* "
\95¶
\8e\9a\8e©
\91Ì */
\r
1829 if ( c == _T('\0') ) break;
\r
1830 *t = c; t++; s++; c = *s;
\r
1836 if ( *s == _T(',') ) { s = s+1; break; }
\r
1837 if ( *s == _T('\0') ) { s = NULL; break; }
\r
1843 /*
\8bó
\82Ì
\8d\80\96Ú
\82Ì
\8fê
\8d\87 */
\r
1854 /* ""
\82Å
\88Í
\82Ü
\82ê
\82Ä
\82¢
\82È
\82¢
\8fê
\8d\87 */
\r
1856 TCHAR* sp = NULL; /*
\8dÅ
\8cã
\82Ì
\98A
\91±
\82µ
\82½
\8bó
\94\92\82Ì
\90æ
\93ª */
\r
1859 while ( c != _T(',') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /* ,
\95¶
\8e\9a\82Ü
\82Å */
\r
1861 /* sp
\82ð
\90Ý
\92è
\82·
\82é */
\r
1863 if ( sp == NULL ) sp = t;
\r
1867 if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }
\r
1869 /*
\83R
\83s
\81[
\82·
\82é */
\r
1870 *t = c; t++; s++; c = *s;
\r
1873 /*
\95Ô
\82è
\92l
\82ð
\8c\88\92è
\82·
\82é */
\r
1874 if ( c == _T(',') ) s = s + 1;
\r
1877 /*
\96\96\94ö
\82Ì
\8bó
\94\92\82ð
\8eæ
\82è
\8f\9c\82 */
\r
1878 if ( sp != NULL ) *sp = '\0';
\r
1879 else *t = _T('\0');
\r
1889 /***********************************************************************
\r
1890 <<< [StrT_getExistSymbols] >>>
\r
1891 ************************************************************************/
\r
1892 errnum_t StrT_getExistSymbols( unsigned* out, bool bCase, const TCHAR* Str, const TCHAR* Symbols, ... )
\r
1896 TCHAR** syms = NULL;
\r
1897 bool* syms_exists = NULL;
\r
1898 bool b_nosym = false;
\r
1899 TCHAR* sym = NULL;
\r
1900 size_t sym_size = ( _tcslen( Symbols ) + 1 ) * sizeof(TCHAR);
\r
1904 UNREFERENCED_VARIABLES(( bCase ));
\r
1906 sym = (TCHAR*) malloc( sym_size ); IF(sym==NULL)goto err_fm;
\r
1912 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;
\r
1913 if ( sym[0] != _T('\0') ) n_sym ++;
\r
1914 } while ( p != NULL );
\r
1916 syms = (TCHAR**) malloc( n_sym * sizeof(TCHAR*) ); IF(syms==NULL)goto err_fm;
\r
1917 memset( syms, 0, n_sym * sizeof(TCHAR*) );
\r
1918 syms_exists = (bool*) malloc( n_sym * sizeof(bool) ); IF(syms_exists==NULL)goto err_fm;
\r
1919 memset( syms_exists, 0, n_sym * sizeof(bool) );
\r
1921 p = Symbols; i = 0;
\r
1923 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;
\r
1924 if ( sym[0] != _T('\0') ) {
\r
1925 e= MallocAndCopyString( &syms[i], sym ); IF(e)goto fin;
\r
1928 } while ( p != NULL );
\r
1931 //=== Check Str whether having Symbols
\r
1934 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;
\r
1935 if ( sym[0] != _T('\0') ) {
\r
1936 for ( i = 0; i < n_sym; i++ ) {
\r
1937 if ( _tcscmp( sym, syms[i] ) == 0 ) { syms_exists[i] = true; break; }
\r
1939 if ( i == n_sym ) b_nosym = true;
\r
1941 } while ( p != NULL );
\r
1949 va_start( va, Symbols );
\r
1951 for ( i = 0; i < n_sym; i++ ) {
\r
1952 num = va_arg( va, unsigned );
\r
1953 if ( syms_exists[i] ) *out |= num;
\r
1958 e = ( b_nosym ? E_NOT_FOUND_SYMBOL : 0 );
\r
1960 if ( syms != NULL ) {
\r
1961 for ( i = 0; i < n_sym; i++ ) {
\r
1962 if ( syms[i] != NULL ) free( syms[i] );
\r
1966 if ( syms_exists != NULL ) free( syms_exists );
\r
1967 if ( sym != NULL ) free( sym );
\r
1969 err_fm: e= E_FEW_MEMORY; goto fin;
\r
1973 /**************************************************************************
\r
1974 <<< [StrT_meltCmdLine] >>>
\r
1975 *************************************************************************/
\r
1976 errnum_t StrT_meltCmdLine( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pLine )
\r
1980 TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );
\r
1987 if ( out_Str_Size <= 1 ) { t = &dummy; t_last = &dummy; }
\r
1989 if ( s == NULL ) { *t = _T('\0'); return 0; }
\r
1992 /*
\93ª
\82Ì
\8bó
\94\92\82ð
\8f\9c\82 */
\r
1993 while ( *s == _T(' ') || *s == _T('\t') ) s++;
\r
1997 /* ""
\82Å
\88Í
\82Ü
\82ê
\82Ä
\82¢
\82é
\8fê
\8d\87 */
\r
2001 while ( c != _T('"') || *(s+1) == _T('"') ) { /* "
\95¶
\8e\9a\82Ü
\82Å */
\r
2002 if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }
\r
2003 if ( c == *(s+1) && c == _T('"') ) s++; /* "
\95¶
\8e\9a\8e©
\91Ì */
\r
2004 if ( c == _T('\0') ) break;
\r
2005 *t = c; t++; s++; c = *s;
\r
2011 if ( *s == _T(' ') ) { s = s+1; break; }
\r
2012 if ( *s == _T('\0') ) { s = NULL; break; }
\r
2023 /* ""
\82Å
\88Í
\82Ü
\82ê
\82Ä
\82¢
\82È
\82¢
\8fê
\8d\87 */
\r
2026 while ( c != _T(' ') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /*
\8bó
\94\92\95¶
\8e\9a\82Ü
\82Å */
\r
2028 if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }
\r
2030 /*
\83R
\83s
\81[
\82·
\82é */
\r
2031 *t = c; t++; s++; c = *s;
\r
2034 /* *pLine
\82ð
\8c\88\92è
\82·
\82é */
\r
2035 while ( *s == _T(' ') ) s = s + 1;
\r
2036 if ( *s == _T('\0') ) s = NULL;
\r
2049 /***********************************************************************
\r
2050 <<< [StrT_isAbsPath] >>>
\r
2051 ************************************************************************/
\r
2052 bool StrT_isAbsPath( const TCHAR* s )
\r
2054 const TCHAR* bs = _tcschr( s, _T('\\') );
\r
2055 const TCHAR* sl = _tcschr( s, _T('/') );
\r
2056 const TCHAR* co = _tcschr( s, _T(':') );
\r
2058 return ( co != NULL && ( bs == co+1 || sl == co+1 ) );
\r
2062 /**************************************************************************
\r
2063 <<< [StrT_getAbsPath_part] >>>
\r
2064 *************************************************************************/
\r
2065 errnum_t StrT_getAbsPath_part( TCHAR* out_AbsPath, size_t AbsPathSize, TCHAR* OutStart,
\r
2066 TCHAR** out_OutLast, const TCHAR* StepPath, const TCHAR* BasePath )
\r
2069 TCHAR separator = (TCHAR) DUMMY_INITIAL_VALUE_TCHAR;
\r
2070 const TCHAR* separator_path;
\r
2071 TCHAR* out_abs_path_over = (TCHAR*)( (uint8_t*) out_AbsPath + AbsPathSize );
\r
2072 TCHAR* null_position = NULL;
\r
2076 /* "BasePath" must be out of "out_AbsPath" */
\r
2077 ASSERT_R( BasePath < out_AbsPath ||
\r
2078 (uint8_t*) BasePath >= (uint8_t*) out_AbsPath + AbsPathSize,
\r
2083 /* If "StepPath" == "", out_AbsPath = "" */
\r
2084 if ( StepPath[0] == _T('\0') ) {
\r
2085 ASSERT_R( AbsPathSize >= sizeof(TCHAR), goto err_fm );
\r
2086 out_AbsPath[0] = _T('\0');
\r
2091 /* Set "OutStart" */
\r
2092 if ( OutStart == NULL )
\r
2093 { OutStart = out_AbsPath; }
\r
2096 /* Set "separator" : \ or / from "BasePath" */
\r
2097 if ( StrT_isAbsPath( StepPath ) ) {
\r
2098 separator_path = StepPath;
\r
2100 else if ( BasePath == NULL ) {
\r
2101 separator = _T('\\');
\r
2102 separator_path = NULL;
\r
2105 separator_path = BasePath;
\r
2107 if ( separator_path != NULL ) {
\r
2111 p = _tcschr( separator_path, _T('\\') );
\r
2112 p2 = _tcschr( separator_path, _T('/') );
\r
2113 if ( p == NULL ) {
\r
2115 { separator = _T('\\'); }
\r
2117 { separator = _T('/'); }
\r
2120 { separator = _T('\\'); }
\r
2123 { separator = _T('\\'); }
\r
2125 { separator = _T('/'); }
\r
2131 /* Set "OutStart" : "BasePath" + / + "StepPath" */
\r
2132 if ( StrT_isAbsPath( StepPath ) ) {
\r
2133 size_t step_path_length = _tcslen( StepPath );
\r
2135 IF( OutStart + step_path_length >= out_abs_path_over ) goto err_fa;
\r
2136 memmove( OutStart, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );
\r
2138 /* Set "null_position" */
\r
2139 null_position = OutStart + step_path_length;
\r
2144 size_t base_path_length;
\r
2145 size_t step_path_length = _tcslen( StepPath );
\r
2147 if ( BasePath == NULL ) {
\r
2148 base_path_length = GetCurrentDirectory( 0, NULL ) - 1;
\r
2151 base_path_length = _tcslen( BasePath );
\r
2152 c = BasePath[ base_path_length - 1 ];
\r
2153 if ( c == _T('\\') || c == _T('/') )
\r
2154 { base_path_length -= 1; }
\r
2157 p = OutStart + base_path_length + 1;
\r
2158 IF( p + step_path_length >= out_abs_path_over ) goto err_fa;
\r
2159 memmove( p, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );
\r
2160 /* memmove is for "out_AbsPath" == "StepPath" */
\r
2162 if ( BasePath == NULL ) {
\r
2163 GetCurrentDirectory( base_path_length + 1, OutStart );
\r
2164 if ( OutStart[ base_path_length - 1 ] == _T('\\') )
\r
2165 { base_path_length -= 1; }
\r
2167 memcpy( OutStart, BasePath, base_path_length * sizeof(TCHAR) );
\r
2169 OutStart[ base_path_length ] = separator;
\r
2172 /* Set "null_position" */
\r
2173 null_position = p + step_path_length;
\r
2177 /* Replace \ and / to "separator" in "OutStart" */
\r
2179 TCHAR other_separator;
\r
2181 if ( separator == _T('/') )
\r
2182 { other_separator = _T('\\'); }
\r
2184 { other_separator = _T('/'); }
\r
2186 e= StrT_replace1( OutStart, other_separator, separator, 0 ); IF(e)goto fin;
\r
2190 /* Replace \*\..\ to \ */
\r
2192 enum { length = 4 };
\r
2193 TCHAR parent[ length + 1 ]; /* \..\ or /../ */
\r
2194 TCHAR* parent_position;
\r
2197 parent[0] = separator;
\r
2198 parent[1] = _T('.');
\r
2199 parent[2] = _T('.');
\r
2200 parent[3] = separator;
\r
2201 parent[4] = _T('\0');
\r
2204 parent_position = _tcsstr( OutStart, parent );
\r
2205 if ( parent_position == NULL ) { break; }
\r
2207 p = parent_position - 1;
\r
2209 IF( p < OutStart ) goto err; /* "../" are too many */
\r
2210 if ( *p == separator ) { break; }
\r
2215 parent_position + length,
\r
2216 ( null_position - ( parent_position + length ) + 1 ) * sizeof(TCHAR) );
\r
2218 null_position -= ( parent_position + length ) - ( p + 1 );
\r
2223 /* Cut last \*\.. */
\r
2225 enum { length = 3 };
\r
2228 while ( null_position - length >= OutStart ) {
\r
2229 if ( *( null_position - 3 ) != separator ||
\r
2230 *( null_position - 2 ) != _T('.') ||
\r
2231 *( null_position - 1 ) != _T('.') )
\r
2234 p = null_position - 4;
\r
2236 IF( p < OutStart ) goto err; /* "../" are too many */
\r
2237 if ( *p == separator ) { break; }
\r
2243 null_position = p;
\r
2248 /* Replace \.\ to \ */
\r
2250 enum { length = 3 };
\r
2251 TCHAR current[ length + 1 ]; /* \.\ or /./ */
\r
2252 TCHAR* current_position;
\r
2254 current[0] = separator;
\r
2255 current[1] = _T('.');
\r
2256 current[2] = separator;
\r
2257 current[3] = _T('\0');
\r
2260 current_position = _tcsstr( OutStart, current );
\r
2261 if ( current_position == NULL ) { break; }
\r
2263 memmove( current_position + 1,
\r
2264 current_position + length,
\r
2265 ( null_position - ( current_position + length ) + 1 ) * sizeof(TCHAR) );
\r
2267 null_position -= length - 1;
\r
2274 TCHAR* over = _tcschr( OutStart, _T('\0') );
\r
2276 while ( over - 2 >= OutStart &&
\r
2277 *( over - 1 ) == _T('.') && *( over - 2 ) == separator ) {
\r
2285 if ( null_position - 1 >= OutStart ) {
\r
2286 if ( *( null_position - 1 ) == _T(':') ) {
\r
2287 IF( null_position + 1 >= out_abs_path_over ) goto err_fa;
\r
2289 *( null_position + 0 ) = separator;
\r
2290 *( null_position + 1 ) = _T('\0');
\r
2291 null_position += 1;
\r
2296 /* Set "*out_OutLast" */
\r
2297 if ( out_OutLast != NULL )
\r
2298 { *out_OutLast = null_position; }
\r
2304 err: e = E_OTHERS; goto fin;
\r
2305 err_fa: e = E_FEW_ARRAY; goto fin;
\r
2306 err_fm: e = E_FEW_MEMORY; goto fin;
\r
2311 /***********************************************************************
\r
2312 <<< [StrT_getParentAbsPath_part] >>>
\r
2313 ************************************************************************/
\r
2314 errnum_t StrT_getParentAbsPath_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,
\r
2315 TCHAR** out_StrLast, const TCHAR* StepPath, const TCHAR* BasePath )
\r
2320 IF_D( StrStart < Str || (char*) StrStart >= (char*)Str + StrSize )goto err;
\r
2322 if ( StepPath[0] == _T('\0') ) {
\r
2323 *StrStart = _T('\0');
\r
2327 /*
\90â
\91Î
\83p
\83X
\82É
\82·
\82é */
\r
2328 e= StrT_getAbsPath( StrStart,
\r
2329 StrSize - ( (char*)StrStart - (char*)Str ),
\r
2330 StepPath, BasePath ); IF(e)goto fin;
\r
2334 p = _tcschr( StrStart, _T('\0') );
\r
2335 if ( p > StrStart ) {
\r
2336 TCHAR c = *( p - 1 );
\r
2337 if ( c == _T('\\') || c == _T('/') )
\r
2338 { *( p - 1 ) = _T('\0'); }
\r
2343 p = StrT_refFName( StrStart );
\r
2344 if ( p > StrStart ) p--;
\r
2348 /*
\83\8b\81[
\83g
\82È
\82ç \
\82ð
\95t
\82¯
\82é */
\r
2349 if ( p == StrStart + 2 ) {
\r
2350 *p = _T('\\'); p++; *p = _T('\0');
\r
2353 if ( out_StrLast != NULL ) *out_StrLast = p;
\r
2359 err: e = E_OTHERS; goto fin;
\r
2364 /***********************************************************************
\r
2365 <<< [StrT_isOverOfFileName] >>>
\r
2366 - "" or "\" or "/"
\r
2367 ************************************************************************/
\r
2368 inline bool StrT_isOverOfFileName( const TCHAR* PointerInPath )
\r
2370 return PointerInPath == NULL ||
\r
2371 *PointerInPath == _T('\0') ||
\r
2372 ( ( *PointerInPath == _T('\\') || *PointerInPath == _T('/') ) &&
\r
2373 *(PointerInPath + 1) == _T('\0') );
\r
2378 /***********************************************************************
\r
2379 <<< [StrT_getStepPath] >>>
\r
2380 ************************************************************************/
\r
2381 errnum_t StrT_getStepPath( TCHAR* out_StepPath, size_t StepPathSize,
\r
2382 const TCHAR* AbsPath, const TCHAR* BasePath )
\r
2385 const TCHAR* abs_pointer;
\r
2386 const TCHAR* base_pointer;
\r
2390 const TCHAR* abs_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;
\r
2391 const TCHAR* base_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;
\r
2392 TCHAR* step_pointer;
\r
2393 TCHAR parent_symbol[4] = { _T('.'), _T('.'), _T('\\'), _T('\0') };
\r
2394 TCHAR base_path_2[ MAX_PATH ];
\r
2397 ASSERT_D( out_StepPath != AbsPath, goto err );
\r
2399 abs_pointer = AbsPath;
\r
2402 /* Set "base_pointer" */
\r
2403 if ( BasePath == NULL ) {
\r
2404 base_pointer = _tgetcwd( base_path_2, _countof(base_path_2) );
\r
2405 IF( base_pointer == NULL ) goto err;
\r
2408 base_pointer = BasePath;
\r
2412 /* Set "abs_separator_pointer", "base_separator_pointer" : after same parent folder path */
\r
2414 for (;;) { /* while abs_char == base_char */
\r
2415 abs_char = *abs_pointer;
\r
2416 base_char = *base_pointer;
\r
2418 abs_char = (TCHAR) _totlower( abs_char );
\r
2419 base_char = (TCHAR) _totlower( base_char );
\r
2421 if ( abs_char == _T('\0') ) {
\r
2423 /* out_StepPath = ".", if AbsPath == BasePath */
\r
2424 if ( base_char == _T('\0') ) {
\r
2425 e= StrT_cpy( out_StepPath, StepPathSize, _T(".") ); IF(e)goto fin;
\r
2430 if ( base_char == _T('\0') ) { break; }
\r
2432 if ( abs_char != base_char ) {
\r
2433 if ( ( abs_char == _T('/') || abs_char == _T('\\') ) &&
\r
2434 ( base_char == _T('/') || base_char == _T('\\') ) )
\r
2435 { /* Do nothing */ }
\r
2440 /* Set "separator", "abs_separator_pointer", "base_separator_pointer" */
\r
2441 if ( base_char == _T('/') || base_char == _T('\\') ) {
\r
2442 if ( separator == 0 )
\r
2443 { separator = base_char; }
\r
2445 abs_separator_pointer = abs_pointer;
\r
2446 base_separator_pointer = base_pointer;
\r
2450 base_pointer += 1;
\r
2454 /* AbsPath
\82Æ BasePath
\82Ì
\8aÖ
\8cW
\82ª
\81A
\95Ð
\95û
\82Ì
\88ê
\95\94\82ª
\82à
\82¤
\95Ð
\95û
\82Ì
\91S
\91Ì
\82Å
\82 \82é
\82Æ
\82« */
\r
2455 if ( abs_char == _T('/') || abs_char == _T('\\') ||
\r
2456 base_char == _T('/') || base_char == _T('\\') ) {
\r
2457 /* other character is '\0' */
\r
2459 if ( separator == 0 )
\r
2460 { separator = abs_char; }
\r
2462 abs_separator_pointer = abs_pointer;
\r
2463 base_separator_pointer = base_pointer;
\r
2467 /* out_StepPath = AbsPath, if there is not same folder */
\r
2468 if ( separator == 0 ) {
\r
2469 e= StrT_cpy( out_StepPath, StepPathSize, AbsPath ); IF(e)goto fin;
\r
2474 /* Add "..\" to "out_StepPath" */
\r
2475 parent_symbol[2] = separator;
\r
2476 step_pointer = out_StepPath;
\r
2481 if ( StrT_isOverOfFileName( base_separator_pointer ) )
\r
2485 /* Set "base_separator_pointer" : next separator */
\r
2486 p1 = _tcschr( base_separator_pointer + 1, _T('/') );
\r
2487 p2 = _tcschr( base_separator_pointer + 1, _T('\\') );
\r
2489 if ( p1 == NULL ) {
\r
2491 { base_separator_pointer = NULL; }
\r
2493 { base_separator_pointer = p2; }
\r
2496 if ( p2 == NULL ) {
\r
2497 base_separator_pointer = p1;
\r
2500 { base_separator_pointer = p1; }
\r
2502 { base_separator_pointer = p2; }
\r
2507 /* Add "..\" to "out_StepPath" */
\r
2508 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, &step_pointer,
\r
2509 parent_symbol, NULL ); IF(e)goto fin;
\r
2513 /* Copy a part of "AbsPath" to "out_StepPath" */
\r
2514 if ( StrT_isOverOfFileName( abs_separator_pointer ) ) {
\r
2515 ASSERT_D( step_pointer > out_StepPath, goto err );
\r
2516 *( step_pointer - 1 ) = _T('\0');
\r
2519 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, NULL,
\r
2520 abs_separator_pointer + 1, NULL ); IF(e)goto fin;
\r
2527 err: e = E_OTHERS; goto fin;
\r
2532 /***********************************************************************
\r
2533 <<< [StrT_getBaseName_part] >>>
\r
2534 ************************************************************************/
\r
2535 errnum_t StrT_getBaseName_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,
\r
2536 TCHAR** out_StrLast, const TCHAR* SrcPath )
\r
2543 p1 = StrT_refFName( SrcPath );
\r
2546 //=== #
\82ª
\96³
\82¢
\82Æ
\82«
\81A
\8dÅ
\8cã
\82Ì
\83s
\83\8a\83I
\83h
\82Ì
\91O
\82Ü
\82Å
\82ª
\81ABaseName
\r
2547 ps = _tcschr( p1, _T('#') );
\r
2548 if ( ps == NULL ) {
\r
2549 p2 = _tcsrchr( p1, _T('.') );
\r
2550 if ( p2 == NULL ) p2 = _tcsrchr( p1, _T('\0') );
\r
2553 //=== #
\82ª
\82 \82é
\82Æ
\82«
\81A#
\82æ
\82è
\91O
\82Å
\81A
\8dÅ
\8cã
\82Ì
\83s
\83\8a\83I
\83h
\82Ì
\91O
\82Ü
\82Å
\82ª
\81ABaseName
\r
2559 p3 = _tcschr( p3, _T('.') );
\r
2560 if ( p3 == NULL || p3 > ps ) break;
\r
2566 return stcpy_part_r( Str, StrSize, StrStart, out_StrLast, p1, p2 );
\r
2570 /***********************************************************************
\r
2571 <<< [StrT_addLastOfFileName] >>>
\r
2572 ************************************************************************/
\r
2573 errnum_t StrT_addLastOfFileName( TCHAR* out_Path, size_t PathSize,
\r
2574 const TCHAR* BasePath, const TCHAR* AddName )
\r
2580 const TCHAR* last_pos_in_base = _tcschr( BasePath, _T('\0') );
\r
2581 const TCHAR* term_pos_in_base;
\r
2582 const TCHAR* add_pos_in_base;
\r
2583 const TCHAR* period_pos_in_base = _tcsrchr( BasePath, _T('.') ); // > term_pos_in_base
\r
2584 const TCHAR* last_pos_in_add = _tcschr( AddName, _T('\0') );
\r
2585 const TCHAR* term_pos_in_add;
\r
2586 const TCHAR* period_pos_in_add = _tcsrchr( AddName, _T('.') ); // > term_pos_in_add
\r
2589 MEMSET_TO_NOT_INIT( out_Path, PathSize );
\r
2592 //=== term_pos_in_base
\r
2593 for ( term_pos_in_base = last_pos_in_base; term_pos_in_base >= BasePath; term_pos_in_base -- ) {
\r
2594 c = *term_pos_in_base;
\r
2595 if ( c == _T('/') || c == _T('\\') ) break;
\r
2599 //=== term_pos_in_add
\r
2600 for ( term_pos_in_add = last_pos_in_add; term_pos_in_add >= AddName; term_pos_in_add -- ) {
\r
2601 c = *term_pos_in_add;
\r
2602 if ( c == _T('/') || c == _T('\\') ) break;
\r
2606 //=== add_pos_in_base
\r
2607 if ( term_pos_in_base < period_pos_in_base ) {
\r
2608 add_pos_in_base = period_pos_in_base;
\r
2611 if ( term_pos_in_base < BasePath )
\r
2612 add_pos_in_base = _tcschr( BasePath, _T('\0') );
\r
2614 add_pos_in_base = _tcschr( term_pos_in_base, _T('\0') );
\r
2618 //=== setup output parameters
\r
2619 out_pos = (char*) out_Path;
\r
2620 free_size = PathSize;
\r
2623 //=== copy BasePath .. add_pos_in_base
\r
2624 copy_size = (char*)add_pos_in_base - (char*)BasePath;
\r
2625 if ( copy_size > free_size ) goto err_fa;
\r
2626 memcpy( out_pos, BasePath, copy_size );
\r
2627 out_pos += copy_size;
\r
2628 free_size -= copy_size;
\r
2631 //=== copy AddName .. last_pos_in_add
\r
2632 copy_size = (char*)last_pos_in_add - (char*)AddName;
\r
2633 if ( copy_size > free_size ) goto err_fa;
\r
2634 memcpy( out_pos, AddName, copy_size );
\r
2635 out_pos += copy_size;
\r
2636 free_size -= copy_size;
\r
2639 //=== add name and not change extension
\r
2640 if ( period_pos_in_add == NULL ) {
\r
2642 //=== copy period_pos_in_base .. last_pos_in_base
\r
2643 if ( period_pos_in_base > term_pos_in_base ) {
\r
2644 copy_size = (char*)last_pos_in_base - (char*)period_pos_in_base + sizeof(TCHAR);
\r
2645 if ( copy_size > free_size ) goto err_fa;
\r
2646 memcpy( out_pos, period_pos_in_base, copy_size );
\r
2649 *(TCHAR*)out_pos = _T('\0');
\r
2654 //=== add name and change extension
\r
2657 if ( *(period_pos_in_add + 1) == _T('\0') )
\r
2658 *( (TCHAR*)out_pos - 1 ) = _T('\0');
\r
2660 *(TCHAR*)out_pos = _T('\0');
\r
2666 return E_FEW_ARRAY;
\r
2671 /***********************************************************************
\r
2672 <<< [Strs_init] >>>
\r
2673 ************************************************************************/
\r
2674 enum { Strs_FirstSize = 0x0F00 };
\r
2676 errnum_t Strs_init( Strs* self )
\r
2680 self->MemoryAddress = NULL;
\r
2682 p = (char*) malloc( Strs_FirstSize );
\r
2683 IF( p == NULL ) return E_FEW_MEMORY;
\r
2685 self->MemoryAddress = p;
\r
2686 self->MemoryOver = p + Strs_FirstSize;
\r
2687 self->NextElem = p + sizeof(TCHAR*);
\r
2688 self->PointerToNextStrInPrevElem = (TCHAR**) p;
\r
2689 self->Prev_PointerToNextStrInPrevElem = NULL;
\r
2690 *(TCHAR**) p = NULL;
\r
2692 self->FirstOfStrs = self;
\r
2693 self->NextStrs = NULL;
\r
2700 /***********************************************************************
\r
2701 <<< [Strs_finish] >>>
\r
2702 ************************************************************************/
\r
2703 errnum_t Strs_finish( Strs* self, errnum_t e )
\r
2708 if ( self->MemoryAddress == NULL ) return 0;
\r
2710 mp = self->FirstOfStrs;
\r
2712 free( mp->MemoryAddress );
\r
2713 if ( mp == self ) break;
\r
2715 next_mp = mp->NextStrs;
\r
2719 self->MemoryAddress = NULL;
\r
2726 /***********************************************************************
\r
2727 <<< [Strs_toEmpty] >>>
\r
2728 ************************************************************************/
\r
2729 errnum_t Strs_toEmpty( Strs* self )
\r
2731 Strs_finish( self, 0 );
\r
2732 return Strs_init( self );
\r
2737 /***********************************************************************
\r
2738 <<< [Strs_add] >>>
\r
2739 ************************************************************************/
\r
2740 errnum_t Strs_add( Strs* self, const TCHAR* Str, const TCHAR** out_AllocStr )
\r
2742 return Strs_addBinary( self, Str, _tcschr( Str, _T('\0') ) + 1, out_AllocStr );
\r
2746 errnum_t Strs_addBinary( Strs* self, const TCHAR* Str, const TCHAR* StrOver, const TCHAR** out_AllocStr )
\r
2752 str_size = ( (char*) StrOver - (char*) Str );
\r
2753 elem_size = ( sizeof(TCHAR*) + str_size + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);
\r
2755 if ( self->NextElem + elem_size > self->MemoryOver )
\r
2756 { e= Strs_expandSize( self, str_size ); IF(e)goto fin; }
\r
2760 // [ FirstStr | NULL | TCHAR[] | ... ]
\r
2761 // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]
\r
2762 // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]
\r
2764 if ( out_AllocStr != NULL ) *out_AllocStr = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );
\r
2767 *(TCHAR**) self->NextElem = NULL;
\r
2768 memcpy( self->NextElem + sizeof(TCHAR*), Str, str_size );
\r
2770 //=== link to elem from previous elem
\r
2771 *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );
\r
2774 self->Prev_PointerToNextStrInPrevElem = self->PointerToNextStrInPrevElem;
\r
2775 self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;
\r
2776 self->NextElem = self->NextElem + elem_size;
\r
2785 /***********************************************************************
\r
2786 <<< [Strs_freeLast] >>>
\r
2787 ************************************************************************/
\r
2788 errnum_t Strs_freeLast( Strs* self, TCHAR* AllocStr )
\r
2793 TCHAR* prev_of_last_str;
\r
2795 Strs* prev_of_last_mp;
\r
2797 if ( self->Prev_PointerToNextStrInPrevElem == NULL ) {
\r
2798 prev_of_last_str = NULL;
\r
2800 for ( Strs_forEach( self, &str ) ) {
\r
2801 prev_of_last_str = last_str;
\r
2806 prev_of_last_str = (TCHAR*)( self->Prev_PointerToNextStrInPrevElem + 1 );
\r
2807 last_str = (TCHAR*)( self->PointerToNextStrInPrevElem + 1 );
\r
2811 IF( last_str != AllocStr ) goto err;
\r
2813 // [ FirstStr | NULL | TCHAR[] | ... ]
\r
2814 if ( prev_of_last_str == NULL ) {
\r
2815 self->NextElem = self->MemoryAddress + sizeof(TCHAR*);
\r
2816 self->PointerToNextStrInPrevElem = (TCHAR**) self->MemoryAddress;
\r
2819 // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]
\r
2820 else if ( (char*) prev_of_last_str >= self->MemoryAddress &&
\r
2821 (char*) prev_of_last_str < self->MemoryOver ) {
\r
2822 self->NextElem = (char*)last_str - sizeof(TCHAR*);
\r
2823 self->PointerToNextStrInPrevElem = (TCHAR**)( (char*)prev_of_last_str - sizeof(TCHAR*) );
\r
2826 // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]
\r
2828 prev_of_last_mp = NULL;
\r
2829 for ( mp = self->FirstOfStrs; mp->NextStrs != self; mp = mp->NextStrs ) {
\r
2830 prev_of_last_mp = mp;
\r
2833 free( self->MemoryAddress );
\r
2837 if ( prev_of_last_mp == NULL ) {
\r
2838 self->FirstOfStrs = self;
\r
2839 self->NextStrs = NULL;
\r
2842 prev_of_last_mp->NextStrs = self;
\r
2847 *self->PointerToNextStrInPrevElem = NULL;
\r
2848 self->Prev_PointerToNextStrInPrevElem = NULL;
\r
2854 err: e = E_OTHERS; goto fin;
\r
2859 /***********************************************************************
\r
2860 <<< [Strs_expandSize] >>>
\r
2861 ************************************************************************/
\r
2862 errnum_t Strs_expandSize( Strs* self, size_t FreeSize )
\r
2866 size_t elem_size = ( sizeof(TCHAR*) + FreeSize + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);
\r
2867 size_t memory_size;
\r
2871 // [ FirstStr | NULL | TCHAR[] | ... ]
\r
2872 // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]
\r
2873 // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]
\r
2875 while ( self->NextElem + elem_size > self->MemoryOver ) {
\r
2878 mp = (Strs*) malloc( sizeof(Strs) ); IF(mp==NULL) goto err_fm;
\r
2879 memory_size = ( self->MemoryOver - self->MemoryAddress ) * 2;
\r
2880 new_memory = (char*) malloc( memory_size );
\r
2881 IF( new_memory == NULL ) { free( mp ); goto err_fm; }
\r
2883 //=== move old memory
\r
2884 if ( self->FirstOfStrs == self ) {
\r
2885 self->FirstOfStrs = mp;
\r
2888 for ( mp2 = self->FirstOfStrs; mp2->NextStrs != self; mp2 = mp2->NextStrs );
\r
2889 mp2->NextStrs = mp;
\r
2892 mp->NextStrs = self;
\r
2894 //=== setup new memory
\r
2895 self->MemoryAddress = new_memory;
\r
2896 self->MemoryOver = new_memory + memory_size;
\r
2897 self->NextElem = new_memory;
\r
2898 // self->PointerToNextStrInPrevElem is same value
\r
2899 // self->FirstOfStrs is same value
\r
2900 // self->NextStrs is always NULL
\r
2904 err_fm: return E_FEW_ARRAY;
\r
2908 /***********************************************************************
\r
2909 <<< [Strs_commit] >>>
\r
2910 ************************************************************************/
\r
2911 errnum_t Strs_commit( Strs* self, TCHAR* StrOver )
\r
2915 if ( StrOver == NULL )
\r
2916 { StrOver = _tcschr( (TCHAR*)( self->NextElem + sizeof(TCHAR*) ), _T('\0') ) + 1; }
\r
2917 elem_size = ( ( (char*)StrOver - self->NextElem ) + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);
\r
2920 *(TCHAR**) self->NextElem = NULL;
\r
2922 //=== link to elem from previous elem
\r
2923 *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );
\r
2926 self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;
\r
2927 self->NextElem = self->NextElem + elem_size;
\r
2934 /***********************************************************************
\r
2936 ************************************************************************/
\r
2939 errnum_t StrArr_init( StrArr* self )
\r
2943 Set2_initConst( &self->Array );
\r
2944 Strs_initConst( &self->Chars );
\r
2946 e= Set2_init( &self->Array, 0x100 ); IF(e)goto cancel;
\r
2947 e= Strs_init( &self->Chars ); IF(e)goto cancel;
\r
2950 cancel: StrArr_finish( self, e ); return e;
\r
2954 /*[StrArr_finish]*/
\r
2955 errnum_t StrArr_finish( StrArr* self, errnum_t e )
\r
2957 if ( ! Set2_isInited( &self->Array ) ) return 0;
\r
2959 e= Set2_finish( &self->Array, e );
\r
2960 e= Strs_finish( &self->Chars, e );
\r
2966 errnum_t StrArr_add( StrArr* self, const TCHAR* Str, int* out_I )
\r
2970 e= StrArr_expandCount( self, _tcslen( Str ) ); IF(e)goto fin;
\r
2971 _tcscpy_s( StrArr_getFreeAddr( self ), StrArr_getFreeCount( self ), Str );
\r
2972 e= StrArr_commit( self ); IF(e)goto fin;
\r
2973 if ( out_I != NULL ) *out_I = Set2_getCount( &self->Array, TCHAR* ) - 1;
\r
2981 /*[StrArr_commit]*/
\r
2982 errnum_t StrArr_commit( StrArr* self )
\r
2986 TCHAR** pp = NULL;
\r
2987 Set2* arr = &self->Array;
\r
2988 Strs* ss = &self->Chars;
\r
2990 p = Strs_getFreeAddr( ss );
\r
2991 e= Set2_alloc( arr, &pp, TCHAR* ); IF(e)goto fin;
\r
2992 e= Strs_commit( ss, NULL ); IF(e)goto fin;
\r
2997 if ( e && pp != NULL ) e= Set2_freeLast( arr, pp, TCHAR*, e );
\r
3002 /*[StrArr_fillTo]*/
\r
3003 errnum_t StrArr_fillTo( StrArr* self, int n, const TCHAR* Str )
\r
3008 const TCHAR** pp_over;
\r
3010 n -= Set2_getCount( &self->Array, TCHAR* );
\r
3011 if ( n <= 0 ) return 0;
\r
3013 if ( Str == NULL ) {
\r
3017 e= Strs_add( &self->Chars, Str, &p ); IF(e)goto fin;
\r
3020 e= Set2_allocMulti( &self->Array, &pp, TCHAR*, n ); IF(e)goto fin;
\r
3022 for ( ; pp < pp_over; pp++ )
\r
3031 /*[StrArr_toEmpty]*/
\r
3032 errnum_t StrArr_toEmpty( StrArr* self )
\r
3037 ee= Set2_toEmpty( &self->Array ); IF(ee&&!e)e=ee;
\r
3038 ee= Strs_toEmpty( &self->Chars ); IF(ee&&!e)e=ee;
\r
3044 /***********************************************************************
\r
3045 <<< [StrArr_parseCSV] >>>
\r
3046 ************************************************************************/
\r
3047 errnum_t StrArr_parseCSV( StrArr* self, const TCHAR* CSVLine )
\r
3050 const TCHAR* p = CSVLine;
\r
3052 e= StrArr_toEmpty( self ); IF(e)goto fin;
\r
3055 e= StrT_meltCSV( StrArr_getFreeAddr( self ), StrArr_getFreeSize( self ), &p );
\r
3056 if ( e == E_FEW_ARRAY ) {
\r
3057 e= StrArr_expandSize( self, StrArr_getFreeSize( self ) * 2 ); IF(e)goto fin;
\r
3062 e = StrArr_commit( self ); IF(e)goto fin;
\r
3063 } while ( p != NULL );
\r
3072 /*=================================================================*/
\r
3073 /* <<< [SetX/SetX.c] >>> */
\r
3074 /*=================================================================*/
\r
3076 /***********************************************************************
\r
3077 <<< [Set2_init] >>>
\r
3078 ************************************************************************/
\r
3079 int Set2_init( Set2* m, int FirstSize )
\r
3081 m->First = malloc( FirstSize );
\r
3082 if ( m->First == NULL ) return E_FEW_MEMORY;
\r
3083 m->Next = m->First;
\r
3084 m->Over = (char*)m->First + FirstSize;
\r
3087 m->PointerOfDebugArray = NULL;
\r
3093 /***********************************************************************
\r
3094 <<< [Set2_finish] >>>
\r
3095 ************************************************************************/
\r
3096 int Set2_finish( Set2* m, int e )
\r
3098 if ( m->First != NULL ) { free( m->First ); m->First = NULL; }
\r
3103 /***********************************************************************
\r
3104 <<< [Set2_ref_imp] >>>
\r
3105 ************************************************************************/
\r
3106 int Set2_ref_imp( Set2* m, int iElem, void* out_pElem, size_t ElemSize )
\r
3111 IF( iElem < 0 ) goto err_ns;
\r
3112 p = (char*) m->First + ( (unsigned)iElem * ElemSize );
\r
3113 IF( p >= (char*)m->Next ) goto err_ns;
\r
3114 *(char**)out_pElem = p;
\r
3120 err_ns: e = E_NOT_FOUND_SYMBOL; goto fin;
\r
3125 /***********************************************************************
\r
3126 <<< [Set2_alloc_imp] >>>
\r
3127 ************************************************************************/
\r
3128 int Set2_alloc_imp( Set2* m, void* pp, size_t size )
\r
3132 e= Set2_expandIfOverByAddr( m, (char*) m->Next + size ); IF(e)goto fin;
\r
3133 *(void**)pp = m->Next;
\r
3134 m->Next = (char*) m->Next + size;
\r
3136 MEMSET_TO_NOT_INIT( *(void**)pp, size );
\r
3144 int Set2_allocMulti_sub( Set2* m, void* out_pElem, size_t ElemsSize )
\r
3149 e= Set2_expandIfOverByAddr( m, (char*) m->Next + ElemsSize ); IF(e)goto fin;
\r
3150 p = (char*) m->Next;
\r
3151 m->Next = p + ElemsSize;
\r
3152 *(char**)out_pElem = p;
\r
3161 /***********************************************************************
\r
3162 <<< [Set2_expandIfOverByAddr_imp] >>>
\r
3163 ************************************************************************/
\r
3164 int Set2_expandIfOverByAddr_imp( Set2* m, void* OverAddrBasedOnNowFirst )
\r
3167 unsigned offset_of_over;
\r
3168 unsigned offset_of_next;
\r
3170 if ( OverAddrBasedOnNowFirst <= m->Over ) return E_OTHERS;
\r
3172 offset_of_next = (unsigned)( (char*)OverAddrBasedOnNowFirst - (char*)m->First );
\r
3173 offset_of_over = (unsigned)( ( (char*)m->Over - (char*)m->First ) ) * 2;
\r
3174 IF_D( offset_of_next >= 0x80000000 ) goto err;
\r
3175 while ( offset_of_over < offset_of_next ) offset_of_over *= 2;
\r
3176 IF( offset_of_over >= 0x10000000 ) goto err;
\r
3178 new_first = realloc( m->First, offset_of_over * 2 );
\r
3179 IF( new_first == NULL ) goto err_fm;
\r
3181 m->Next = (char*) new_first + ( (char*)m->Next - (char*)m->First );
\r
3182 m->Over = (char*) new_first + offset_of_over * 2;
\r
3183 m->First = new_first;
\r
3186 if ( m->PointerOfDebugArray != NULL )
\r
3187 { *m->PointerOfDebugArray = m->First; }
\r
3192 err: return E_OTHERS;
\r
3193 err_fm: return E_FEW_MEMORY;
\r
3197 /***********************************************************************
\r
3198 <<< [Set2_separate] >>>
\r
3199 ************************************************************************/
\r
3200 int Set2_separate( Set2* m, int NextSize, void** allocate_Array )
\r
3203 void* p = m->First;
\r
3205 if ( NextSize == 0 ) {
\r
3206 MEMSET_TO_NOT_INIT( m, sizeof(*m) );
\r
3210 e= Set2_init( m, NextSize ); IF(e)goto fin;
\r
3212 *allocate_Array = p;
\r
3221 /***********************************************************************
\r
3222 <<< [Set2_setDebug] >>>
\r
3223 ************************************************************************/
\r
3225 void Set2_setDebug( Set2* m, void** PointerOfDebugArray )
\r
3227 m->PointerOfDebugArray = PointerOfDebugArray;
\r
3228 *m->PointerOfDebugArray = m->First;
\r
3234 /*=================================================================*/
\r
3235 /* <<< [Print/Print2.c] >>> */
\r
3236 /*=================================================================*/
\r
3238 /***********************************************************************
\r
3239 <<< [PrintfCounterClass] >>>
\r
3240 ************************************************************************/
\r
3241 #if USE_PRINTF_COUNTER
\r
3242 PrintfCounterClass g_PrintfCounter;
\r
3247 /***********************************************************************
\r
3248 <<< [printf_to_debugger] >>>
\r
3249 ************************************************************************/
\r
3251 void printf_to_debugger( const char* format, ... )
\r
3256 va_start( va, format );
\r
3257 vsprintf_r( s, sizeof(s), format, va );
\r
3260 OutputDebugStringA( s );
\r
3266 /***********************************************************************
\r
3267 <<< [wprintf_to_debugger] >>>
\r
3268 ************************************************************************/
\r
3270 void wprintf_to_debugger( const wchar_t* format, ... )
\r
3275 va_start( va, format );
\r
3276 vswprintf_r( s, sizeof(s), format, va );
\r
3279 OutputDebugStringW( s );
\r
3285 /***********************************************************************
\r
3286 <<< [vsprintf_r] >>>
\r
3287 ************************************************************************/
\r
3288 errnum_t vsprintf_r( char* s, size_t s_size, const char* format, va_list va )
\r
3291 #pragma warning(push)
\r
3292 #pragma warning(disable: 4996)
\r
3295 int r = _vsnprintf( s, s_size, format, va );
\r
3298 #pragma warning(pop)
\r
3301 IF( r == (int) s_size )
\r
3302 { s[s_size-1] = '\0'; return E_FEW_ARRAY; }
\r
3304 { return E_NOT_FOUND_SYMBOL; } /* Bad character code */
\r
3311 /***********************************************************************
\r
3312 <<< [vswprintf_r] >>>
\r
3313 ************************************************************************/
\r
3315 errnum_t vswprintf_r( wchar_t* s, size_t s_size, const wchar_t* format, va_list va )
\r
3317 size_t tsize = s_size / sizeof(wchar_t);
\r
3319 #pragma warning(push)
\r
3320 #pragma warning(disable: 4996)
\r
3321 int r = _vsnwprintf( s, tsize, format, va );
\r
3322 #pragma warning(pop)
\r
3324 if ( r == (int) tsize || r == -1 ) { s[tsize-1] = '\0'; return E_FEW_ARRAY; }
\r
3331 /***********************************************************************
\r
3332 <<< [stprintf_r] >>>
\r
3333 ************************************************************************/
\r
3334 errnum_t stprintf_r( TCHAR* s, size_t s_size, const TCHAR* format, ... )
\r
3339 va_start( va, format );
\r
3340 e = vstprintf_r( s, s_size, format, va );
\r
3347 /***********************************************************************
\r
3348 <<< [stcpy_part_r] >>>
\r
3349 ************************************************************************/
\r
3350 errnum_t stcpy_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,
\r
3351 const TCHAR* src, const TCHAR* src_over )
\r
3353 size_t s_space = (char*)s + s_size - (char*)s_start;
\r
3356 IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) { return 1; }
\r
3358 if ( src_over == NULL ) { src_over = _tcschr( src, _T('\0') ); }
\r
3359 src_size = (char*)src_over - (char*)src;
\r
3360 IF ( src_size >= s_space ) {
\r
3361 s_space -= sizeof(TCHAR);
\r
3362 memcpy( s, src, s_space );
\r
3364 s_start = (TCHAR*)((char*)s_start + s_space );
\r
3367 if ( p_s_last != NULL ) { *p_s_last=s_start; }
\r
3368 return E_FEW_ARRAY;
\r
3371 memcpy( s_start, src, src_size + sizeof(TCHAR) );
\r
3372 s_start = (TCHAR*)((char*)s_start + src_size); *s_start = _T('\0');
\r
3373 if ( p_s_last != NULL ) { *p_s_last = s_start; }
\r
3380 /***********************************************************************
\r
3381 <<< [stprintf_part_r] >>>
\r
3382 ************************************************************************/
\r
3383 errnum_t stprintf_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,
\r
3384 const TCHAR* format, ... )
\r
3388 va_start( va, format );
\r
3390 IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) {return E_OTHERS;}
\r
3392 e = vstprintf_r( s_start, s_size - ( (char*)s_start - (char*)s), format, va );
\r
3393 va_end( va ); if ( p_s_last != NULL ) *p_s_last = _tcschr( s_start, '\0' );
\r
3398 /*=================================================================*/
\r
3399 /* <<< [Error4/Error4.c] >>> */
\r
3400 /*=================================================================*/
\r
3402 /***********************************************************************
\r
3403 <<< [Get_Error4_Variables] >>>
\r
3404 ************************************************************************/
\r
3405 static Error4_VariablesClass gs;
\r
3407 extern Error4_VariablesClass* g_Error4_Variables = &gs;
\r
3410 Error4_VariablesClass* Get_Error4_Variables()
\r
3417 /***********************************************************************
\r
3418 <<< [SetBreakErrorID] >>>
\r
3419 ************************************************************************/
\r
3420 #if ERR2_ENABLE_ERROR_BREAK
\r
3422 dll_global_g_DebugBreakCount Err2 g_Err2; /*
\8f\89\8aú
\92l
\82Í
\82·
\82×
\82Ä
\83[
\83\8d */
\r
3424 void SetBreakErrorID( int ID )
\r
3426 Err2* m = &g_Err2;
\r
3428 m->BreakErrID = ID;
\r
3432 int TryOnIfTrue_imp( const char* FilePath, int LineNum )
\r
3433 //
\95Ô
\82è
\92l
\82Í
\81A
\83u
\83\8c\81[
\83N
\82·
\82é
\82©
\82Ç
\82¤
\82©
\r
3435 //===
\83G
\83\89\81[
\8e\9e\82Ì
\92\86\92f
\8f\88\97\9d\81i
\83W
\83\83\83\93\83v
\81j
\82ð
\82µ
\82Ä
\82¢
\82é
\82Æ
\82«
\r
3436 if ( g_Err2.IsErr ) return 0;
\r
3439 //===
\83G
\83\89\81[
\82ª
\8f\89\82ß
\82Ä
\8bN
\82«
\82½
\82Æ
\82«
\r
3441 Err2* m = &g_Err2;
\r
3445 m->FilePath = FilePath;
\r
3446 m->LineNum = LineNum;
\r
3448 #if ERR2_ENABLE_ERROR_LOG
\r
3449 printf( "<ERRORLOG msg=\"raised\" err_id=\"%d\" g_err2=\"0x%08X\"/>\n", m->ErrID, (int) m );
\r
3452 return ( m->ErrID == m->BreakErrID );
\r
3460 Err2* m = &g_Err2;
\r
3462 #if ERR2_ENABLE_ERROR_LOG
\r
3463 if ( m->IsErr != 0 )
\r
3464 printf( "<ERRORLOG msg=\"cleared\" err_id=\"%d\" g_err2=\"0x%08X\"/>\n", m->ErrID, (int) m );
\r
3472 bool IsErrorMode()
\r
3474 return ( g_Err2.IsErr != 0 );
\r
3478 //[IfErrThenBreak]
\r
3479 void IfErrThenBreak()
\r
3481 if ( g_Err2.IsErr && ( g_Err2.ErrID != g_Err2.BreakErrID || g_Err2.BreakErrID == 0 ) ) { TestableDebugBreak();
\r
3482 //
\83E
\83H
\83b
\83`
\82Å
\81Ag_Err2.ErrID
\82Ì
\92l(N
\82Æ
\82·
\82é)
\82ð
\8am
\94F
\82µ
\82Ä
\81A
\r
3483 //
\83\81\83C
\83\93\8aÖ
\90\94\82Å SetBreakErrorID( N );
\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B
\r
3484 //
\83G
\83\89\81[
\82ª
\94
\90¶
\82µ
\82½
\8fê
\8f\8a\82Í
\81Ag_Err2.FilePath, g_Err2.LineNum
\82Å
\82·
\81B
\r
3485 //
\90³
\8fí
\8fI
\97¹
\82µ
\82Ä
\82¢
\82é
\82Â
\82à
\82è
\82È
\82Ì
\82É
\82±
\82±
\82Å
\83u
\83\8c\81[
\83N
\82·
\82é
\82Æ
\82«
\82Í
\81A
\r
3486 // ClearError()
\82ð
\96Y
\82ê
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82è
\82Ü
\82·
\81B
\r
3487 #if ERR2_ENABLE_ERROR_LOG
\r
3488 printf( "<ERRORLOG msg=\"IfErrThenBreak\" ErrID=\"%d\" BreakErrID=\"%d\"/>\n", g_Err2.ErrID, g_Err2.BreakErrID );
\r
3493 sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n", g_Err2.FilePath, g_Err2.LineNum );
\r
3494 OutputDebugStringA( str );
\r
3501 void PushErr( ErrStackAreaClass* ErrStackArea )
\r
3503 ErrStackArea->ErrID = g_Err2.ErrID;
\r
3504 ErrStackArea->IsErr = g_Err2.IsErr;
\r
3509 void PopErr( ErrStackAreaClass* ErrStackArea )
\r
3511 if ( ErrStackArea->IsErr )
\r
3516 #endif // ERR2_ENABLE_ERROR_BREAK
\r
3519 /***********************************************************************
\r
3520 <<< [g_Error4_String] >>>
\r
3521 ************************************************************************/
\r
3522 TCHAR g_Error4_String[4096];
\r
3526 /***********************************************************************
\r
3527 <<< [Error4_printf] >>>
\r
3528 ************************************************************************/
\r
3529 void Error4_printf( const TCHAR* format, ... )
\r
3532 va_start( va, format );
\r
3533 vstprintf_r( g_Error4_String, sizeof(g_Error4_String), format, va );
\r
3539 /***********************************************************************
\r
3540 <<< [Error4_getErrStr] >>>
\r
3541 ************************************************************************/
\r
3542 void Error4_getErrStr( int ErrNum, TCHAR* out_ErrStr, size_t ErrStrSize )
\r
3544 switch ( ErrNum ) {
\r
3547 stprintf_r( out_ErrStr, ErrStrSize, _T("no error") );
\r
3551 case E_GET_LAST_ERROR: {
\r
3553 TCHAR* str_pointer;
\r
3555 err_win = gs.WindowsLastError;
\r
3556 if ( err_win == 0 ) { err_win = GetLastError(); }
\r
3558 stprintf_part_r( out_ErrStr, ErrStrSize, out_ErrStr, &str_pointer,
\r
3559 _T("<ERROR GetLastError=\"0x%08X\" GetLastErrorStr=\""), err_win );
\r
3560 FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
\r
3561 NULL, err_win, LANG_USER_DEFAULT,
\r
3562 str_pointer, (TCHAR*)( (char*)out_ErrStr + ErrStrSize ) - str_pointer, NULL );
\r
3563 str_pointer = _tcschr( str_pointer, _T('\0') );
\r
3564 if ( *( str_pointer - 2 ) == _T('\r') && *( str_pointer - 1 ) == _T('\n') )
\r
3566 stcpy_part_r( out_ErrStr, ErrStrSize, str_pointer, NULL, _T("\"/>"), NULL );
\r
3572 if ( g_Error4_String[0] != '\0' )
\r
3573 stprintf_r( out_ErrStr, ErrStrSize, _T("%s"), g_Error4_String );
\r
3575 stprintf_r( out_ErrStr, ErrStrSize, _T("<ERROR errnum=\"%d\"/>"), ErrNum );
\r
3582 /***********************************************************************
\r
3583 <<< [SaveWindowsLastError] >>>
\r
3584 ************************************************************************/
\r
3585 errnum_t SaveWindowsLastError()
\r
3587 gs.WindowsLastError = GetLastError();
\r
3588 return E_GET_LAST_ERROR;
\r
3593 /*=================================================================*/
\r
3594 /* <<< [DebugTools/DebugTools.c] >>> */
\r
3595 /*=================================================================*/
\r
3597 /***********************************************************************
\r
3598 <<< [TestableDebugBreak] >>>
\r
3599 ************************************************************************/
\r
3600 dll_global_g_DebugBreakCount int g_bTestableDebugBreak_Disable;
\r
3601 dll_global_g_DebugBreakCount int g_DebugBreakCount;
\r
3605 /***********************************************************************
\r
3606 <<< [TestableDebugBreak_isEnabled] >>>
\r
3607 ************************************************************************/
\r
3608 int TestableDebugBreak_isEnabled()
\r
3610 return g_bTestableDebugBreak_Disable == 0;
\r