1 /* Character Code Encoding: "WHITE SQUARE" is
\81 */
\r
2 /* The source file was composed by module mixer */
\r
4 #include "include_c.h"
\r
8 /*=================================================================*/
\r
9 /* <<< [Global0/Global0.c] >>> */
\r
10 /*=================================================================*/
\r
12 /***********************************************************************
\r
13 <<< [Globals_initConst] >>>
\r
14 ************************************************************************/
\r
16 void Globals_initConst()
\r
18 AppKey_initGlobal_const();
\r
23 /***********************************************************************
\r
24 <<< [Globals_initialize] >>>
\r
25 ************************************************************************/
\r
26 int Globals_initialize()
\r
30 e= Locale_init(); IF(e)goto fin;
\r
33 goto fin; // for avoid warning of no goto fin
\r
40 /***********************************************************************
\r
41 <<< [Globals_finalize] >>>
\r
42 ************************************************************************/
\r
43 int Globals_finalize( int e )
\r
45 HeapLogClass_finalize();
\r
46 e= AppKey_finishGlobal( e );
\r
53 /*=================================================================*/
\r
54 /* <<< [PlatformSDK_plus/PlatformSDK_plus.c] >>> */
\r
55 /*=================================================================*/
\r
57 /***********************************************************************
\r
58 <<< [GetCommandLineUnnamed] >>>
\r
59 ************************************************************************/
\r
60 int GetCommandLineUnnamed( int Index1, TCHAR* out_AParam, size_t AParamSize )
\r
62 TCHAR* line = GetCommandLine();
\r
71 IF( Index1 < 0 ) goto err_nf;
\r
77 while ( *p == _T(' ') ) p++;
\r
81 if ( c == _T('\0') ) goto err_nf; // Here is not decided to error or not
\r
84 //=== Skip named option
\r
85 else if ( c == _T('/') ) {
\r
89 if ( c == _T('"') || c == _T(' ') || c == _T('\0') ) break;
\r
93 if ( c == _T('"') ) {
\r
95 while ( *p != _T('"') && *p != _T('\0') ) p++;
\r
96 if ( *p == _T('"') ) p++;
\r
100 //=== Skip or Get unnamed parameter
\r
102 while ( *p == _T(' ') ) p++;
\r
107 if ( c == _T('"') ) {
\r
109 while ( *p2 != _T('"') && *p2 != _T('\0') ) p2++;
\r
112 while ( *p2 != _T(' ') && *p2 != _T('\0') ) p2++;
\r
115 if ( index == 0 ) {
\r
118 e= stcpy_part_r( out_AParam, AParamSize, out_AParam, NULL, p, p2 );
\r
119 ASSERT_D( !e, __noop() );
\r
123 p = ( *p2 == _T('"') ) ? p2+1 : p2;
\r
130 if ( AParamSize >= sizeof(TCHAR) ) *out_AParam = _T('\0');
\r
131 IF ( Index1 >= 2 ) return E_NOT_FOUND_SYMBOL;
\r
137 /***********************************************************************
\r
138 <<< [GetCommandLineNamed] >>>
\r
139 ************************************************************************/
\r
140 int GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize );
\r
142 int GetCommandLineNamed( const TCHAR* Name, bool bCase, TCHAR* out_Value, size_t ValueSize )
\r
145 return GetCommandLineNamed_sub( Name, bCase, &is_exist, out_Value, ValueSize );
\r
149 int GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize )
\r
151 TCHAR* line = GetCommandLine();
\r
155 const size_t name_len = _tcslen( Name );
\r
158 *out_IsExist = true;
\r
164 //=== Compare option name
\r
165 if ( c == _T('/') ) {
\r
170 if ( c == _T(':') || c == _T(' ') || c == _T('\0') ) break;
\r
174 bMatch = ( p2-p == (int)name_len && _tcsncmp( p, Name, p2-p ) == 0 );
\r
176 bMatch = ( p2-p == (int)name_len && _tcsnicmp( p, Name, p2-p ) == 0 );
\r
179 //=== Get the value
\r
180 if ( c == _T(':') ) {
\r
182 if ( *p == _T('"') ) {
\r
185 while ( *p2 != _T('"') && *p2 != _T('\0') ) p2++;
\r
187 return stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );
\r
193 while ( *p2 != _T(' ') && *p2 != _T('\0') ) p2++;
\r
195 return stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );
\r
201 IF( bMatch ) return E_NOT_FOUND_SYMBOL; // no value error
\r
205 else if ( c == _T('\0') ) break;
\r
208 else if ( c == _T('"') ) {
\r
210 while ( *p != _T('"') && *p != _T('\0') ) p++;
\r
211 while ( *p != _T(' ') && *p != _T('\0') ) p++;
\r
214 while ( *p != _T(' ') && *p != _T('\0') ) p++;
\r
216 while ( *p == _T(' ') ) p++;
\r
219 *out_IsExist = false;
\r
220 return E_NOT_FOUND_SYMBOL;
\r
225 /***********************************************************************
\r
226 <<< [GetCommandLineNamedI] >>>
\r
227 ************************************************************************/
\r
228 int GetCommandLineNamedI( const TCHAR* Name, bool bCase, int* out_Value )
\r
234 e= GetCommandLineNamed_sub( Name, bCase, &is_exist, s, sizeof(s) ); IF(e)goto fin; //[out] s
\r
235 if ( s[0] == _T('0') && s[1] == _T('x') )
\r
236 *out_Value = _tcstoul( s, NULL, 16 );
\r
238 *out_Value = _ttoi( s );
\r
246 /***********************************************************************
\r
247 <<< [GetCommandLineNamedC8] >>>
\r
248 ************************************************************************/
\r
250 int GetCommandLineNamedC8( const TCHAR* Name, bool bCase, char* out_Value, size_t ValueSize )
\r
256 s = (TCHAR*) malloc( ValueSize * sizeof(TCHAR) );
\r
257 e= GetCommandLineNamed_sub( Name, bCase, &is_exist, (TCHAR*) s, ValueSize * sizeof(TCHAR) ); IF(e)goto fin;
\r
259 sprintf_s( out_Value, ValueSize, "%S", s );
\r
261 if ( s != NULL ) free( s );
\r
268 /***********************************************************************
\r
269 <<< [GetCommandLineExist] >>>
\r
270 ************************************************************************/
\r
271 bool GetCommandLineExist( const TCHAR* Name, bool bCase )
\r
277 e = GetCommandLineNamed_sub( Name, bCase, &is_exist, v, sizeof(v) );
\r
278 if ( e == E_NOT_FOUND_SYMBOL ) ClearError();
\r
284 /***********************************************************************
\r
285 * Function: GetProcessInformation
\r
286 ************************************************************************/
\r
287 errnum_t GetProcessInformation( DWORD in_ProcessID, PROCESSENTRY32* out_Info )
\r
291 HANDLE snapshot = (HANDLE) -1;
\r
293 snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
\r
294 IF ( snapshot == (HANDLE) -1 ) { e=E_OTHERS; goto fin; }
\r
295 b= Process32First( snapshot, /*Set*/ out_Info );
\r
296 IF (!b) { e=E_OTHERS; goto fin; }
\r
298 if ( out_Info->th32ProcessID == in_ProcessID ) {
\r
301 b= Process32Next( snapshot, /*Set*/ out_Info );
\r
302 IF (!b) { e=E_OTHERS; goto fin; }
\r
307 if ( snapshot != (HANDLE) -1 ) { CloseHandle( snapshot ); }
\r
313 /***********************************************************************
\r
314 <<< [env_part] >>>
\r
315 ************************************************************************/
\r
316 int env_part( TCHAR* Str, unsigned StrSize, TCHAR* StrStart, TCHAR** out_StrLast,
\r
317 const TCHAR* Input )
\r
329 p = Input; o = StrStart; o_last = (TCHAR*)( (char*)Str + StrSize - sizeof(TCHAR) );
\r
330 IF_D( StrStart < Str || StrStart >= o_last ) goto err;
\r
333 IF_D( StrSize <= 2 ) return E_FEW_ARRAY;
\r
335 while ( c != _T('\0') ) {
\r
336 if ( c == _T('%') ) {
\r
338 if ( *p == _T('%') ) {
\r
340 //=== %
\95¶
\8e\9a\82ð
\83R
\83s
\81[
\82·
\82é
\r
341 IF( o == o_last )goto err_fa;
\r
347 //===
\8aÂ
\8b«
\95Ï
\90\94\96¼
\82ð name
\82É
\8eæ
\93¾
\82·
\82é
\r
348 p2 = _tcschr( p, _T('%') ); IF( p2 == NULL )goto err_ns;
\r
349 e= StrT_cpy( name, sizeof(name), _T("abc") ); IF(e)goto fin;
\r
350 e= stcpy_part_r( name, sizeof(name), name, NULL, p, p2 ); IF(e)goto fin;
\r
352 //===
\8aÂ
\8b«
\95Ï
\90\94\82Ì
\92l
\82ð o
\82É
\8eæ
\93¾
\82·
\82é
\r
353 count = ( o_last + sizeof(TCHAR) - o ) / sizeof(TCHAR);
\r
354 r= GetEnvironmentVariable( name, o, count );
\r
355 IF( r==0 ) goto err_ns; //
\8aÂ
\8b«
\95Ï
\90\94\82ª
\8c©
\82Â
\82©
\82ç
\82È
\82¢
\r
356 IF( r > count ) goto err_fa;
\r
358 //=== p, o
\82ð
\8dX
\90V
\82·
\82é
\r
360 o = StrT_chr( o, _T('\0') );
\r
365 //===
\8aÂ
\8b«
\95Ï
\90\94\82Å
\82Í
\82È
\82¢
\95\94\95ª
\82ð
\83R
\83s
\81[
\82·
\82é
\r
366 IF( o == o_last )goto err_fa;
\r
376 if ( out_StrLast != NULL ) *out_StrLast = o;
\r
379 err_fa: e = E_FEW_ARRAY; goto fin;
\r
380 err_ns: e = E_NOT_FOUND_SYMBOL; goto fin;
\r
381 err: e = E_OTHERS; goto fin;
\r
386 /***********************************************************************
\r
387 <<< [env_malloc] >>>
\r
388 ************************************************************************/
\r
389 int env_malloc( TCHAR** out_Value, size_t* out_ValueLen, const TCHAR* Name )
\r
393 TCHAR* value = NULL;
\r
395 r= GetEnvironmentVariable( Name, NULL, 0 );
\r
398 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
401 value = (TCHAR*) malloc( r * sizeof(TCHAR) );
\r
402 IF( value == NULL ) goto err_fm;
\r
403 GetEnvironmentVariable( Name, value, r );
\r
405 *out_Value = value;
\r
406 if ( out_ValueLen != NULL ) *out_ValueLen = r - 1;
\r
412 err_fm: e = E_FEW_MEMORY; goto fin;
\r
417 /*=================================================================*/
\r
418 /* <<< [Parse2/Parse2.c] >>> */
\r
419 /*=================================================================*/
\r
421 /***********************************************************************
\r
422 <<< [g_NaturalDocsKeywords] >>>
\r
423 ************************************************************************/
\r
424 TCHAR* g_NaturalDocsKeywords[] = {
\r
426 /*===========================================================*/
\r
427 /* General Topics */
\r
429 _T("topic"), _T("topics"), _T("about"), _T("list"),
\r
431 /* Section (Ends Scope) */
\r
432 _T("section"), _T("title"),
\r
437 /* File (Always Global) */
\r
438 _T("file"), _T("files"), _T("program"), _T("programs"), _T("script"), _T("scripts"),
\r
439 _T("document"), _T("documents"), _T("doc"), _T("docs"), _T("header"), _T("headers"),
\r
441 /*===========================================================*/
\r
443 /* Class (Starts Scope) */
\r
444 _T("class"), _T("classes"), _T("structure"), _T("structures"), _T("struct"), _T("structs"),
\r
445 _T("package"), _T("packages"), _T("namespace"), _T("namespaces"),
\r
447 /* Interface (Starts Scope) */
\r
448 _T("interface"), _T("interfaces"),
\r
451 _T("type"), _T("types"), _T("typedef"), _T("typedefs"),
\r
454 _T("constant"), _T("constants"), _T("const"), _T("consts"),
\r
456 /* Enumeration (Topic indexed under Types Members indexed under Constants) */
\r
457 _T("enumeration"), _T("enumerations"), _T("enum"), _T("enums"),
\r
459 /* Function (List topics break apart) */
\r
460 _T("function"), _T("functions"), _T("func"), _T("funcs"),
\r
461 _T("procedure"), _T("procedures"), _T("proc"), _T("procs"),
\r
462 _T("routine"), _T("routines"), _T("subroutine"), _T("subroutines"),
\r
463 _T("sub"), _T("subs"), _T("method"), _T("methods"),
\r
464 _T("callback"), _T("callbacks"), _T("constructor"), _T("constructors"),
\r
465 _T("destructor"), _T("destructors"), _T("operator"), _T("operators"),
\r
468 _T("property"), _T("properties"), _T("prop"), _T("props"),
\r
471 _T("event"), _T("events"),
\r
474 _T("delegate"), _T("delegates"),
\r
477 _T("macro"), _T("macros"),
\r
478 _T("define"), _T("defines"), _T("def"), _T("defs"),
\r
481 _T("variable"), _T("variables"), _T("var"), _T("vars"),
\r
482 _T("integer"), _T("integers"), _T("int"), _T("ints"),
\r
483 _T("uint"), _T("uints"), _T("long"), _T("longs"),
\r
484 _T("ulong"), _T("ulongs"), _T("short"), _T("shorts"),
\r
485 _T("ushort"), _T("ushorts"), _T("byte"), _T("bytes"),
\r
486 _T("ubyte"), _T("ubytes"), _T("sbyte"), _T("sbytes"),
\r
487 _T("float"), _T("floats"), _T("double"), _T("doubles"),
\r
488 _T("real"), _T("reals"), _T("decimal"), _T("decimals"),
\r
489 _T("scalar"), _T("scalars"), _T("array"), _T("arrays"),
\r
490 _T("arrayref"), _T("arrayrefs"), _T("hash"), _T("hashes"),
\r
491 _T("hashref"), _T("hashrefs"), _T("bool"), _T("bools"),
\r
492 _T("boolean"), _T("booleans"), _T("flag"), _T("flags"),
\r
493 _T("bit"), _T("bits"), _T("bitfield"), _T("bitfields"),
\r
494 _T("field"), _T("fields"), _T("pointer"), _T("pointers"),
\r
495 _T("ptr"), _T("ptrs"), _T("reference"), _T("references"),
\r
496 _T("ref"), _T("refs"), _T("object"), _T("objects"),
\r
497 _T("obj"), _T("objs"), _T("character"), _T("characters"),
\r
498 _T("wcharacter"), _T("wcharacters"), _T("char"), _T("chars"),
\r
499 _T("wchar"), _T("wchars"), _T("string"), _T("strings"),
\r
500 _T("wstring"), _T("wstrings"), _T("str"), _T("strs"),
\r
501 _T("wstr"), _T("wstrs"), _T("handle"), _T("handles"),
\r
503 /*===========================================================*/
\r
504 /* Database Topics */
\r
506 _T("database"), _T("databases"), _T("db"), _T("dbs"),
\r
508 /* Database Table (Starts Scope) */
\r
509 _T("table"), _T("tables"),
\r
510 _T("database table"), _T("database tables"), _T("db table"), _T("db tables"),
\r
512 /* Database View (Starts Scope) */
\r
513 _T("view"), _T("views"),
\r
514 _T("database view"), _T("database views"), _T("db view"), _T("db views"),
\r
516 /* Database Cursor */
\r
517 _T("cursor"), _T("cursors"),
\r
518 _T("database cursor"), _T("database cursors"), _T("db cursor"), _T("db cursors"),
\r
520 /* Database Index */
\r
521 _T("index"), _T("indexes"), _T("indices"),
\r
522 _T("database index"), _T("database indexes"), _T("database indices"),
\r
523 _T("db index"), _T("db indexes"), _T("db indices"),
\r
524 _T("key"), _T("keys"),
\r
525 _T("database key"), _T("database keys"), _T("db key"), _T("db keys"),
\r
526 _T("primary key"), _T("primary keys"),
\r
527 _T("database primary key"), _T("database primary keys"),
\r
528 _T("db primary key"), _T("db primary keys"),
\r
530 /* Database Trigger */
\r
531 _T("trigger"), _T("triggers"),
\r
532 _T("database trigger"), _T("database triggers"), _T("db trigger"), _T("db triggers"),
\r
534 /*===========================================================*/
\r
535 /* Miscellaneous Topics */
\r
536 /* Cookie (Always global) */
\r
537 _T("cookie"), _T("cookies"),
\r
540 _T("target"), _T("targets"),
\r
541 _T("build target"), _T("build targets"),
\r
546 /***********************************************************************
\r
547 <<< [NaturalDocsHeaderClass_initConst] >>>
\r
548 ************************************************************************/
\r
549 void NaturalDocsHeaderClass_initConst( NaturalDocsHeaderClass* self )
\r
551 self->Keyword = NULL;
\r
553 self->Brief = NULL;
\r
554 Set2_initConst( &self->Arguments );
\r
555 self->ReturnValue = NULL;
\r
556 self->Descriptions = NULL;
\r
557 Set2_initConst( &self->DescriptionItems );
\r
562 /***********************************************************************
\r
563 <<< [NaturalDocsHeaderClass_finalize] >>>
\r
564 ************************************************************************/
\r
565 errnum_t NaturalDocsHeaderClass_finalize( NaturalDocsHeaderClass* self, errnum_t e )
\r
567 Set2_IteratorClass iterator;
\r
568 NaturalDocsDefinitionClass* p1;
\r
569 NaturalDocsDescriptionClass* p2;
\r
572 e= HeapMemory_free( &self->Keyword, e );
\r
573 e= HeapMemory_free( &self->Name, e );
\r
574 e= HeapMemory_free( &self->Brief, e );
\r
576 for ( Set2_forEach2( &self->Arguments, &iterator, &p1 ) ) {
\r
577 e= NaturalDocsDefinitionClass_finalize( p1, e );
\r
579 e= Set2_finish( &self->Arguments, e );
\r
581 e= HeapMemory_free( &self->ReturnValue, e );
\r
582 e= HeapMemory_free( &self->Descriptions, e );
\r
584 for ( Set2_forEach2( &self->DescriptionItems, &iterator, &p2 ) ) {
\r
585 e= NaturalDocsDescriptionClass_finalize( p2, e );
\r
587 e= Set2_finish( &self->DescriptionItems, e );
\r
594 /***********************************************************************
\r
595 <<< [NaturalDocsDefinitionClass_initConst] >>>
\r
596 ************************************************************************/
\r
597 void NaturalDocsDefinitionClass_initConst( NaturalDocsDefinitionClass* self )
\r
600 self->Brief = NULL;
\r
605 /***********************************************************************
\r
606 <<< [NaturalDocsDefinitionClass_finalize] >>>
\r
607 ************************************************************************/
\r
608 errnum_t NaturalDocsDefinitionClass_finalize( NaturalDocsDefinitionClass* self, errnum_t e )
\r
610 e= HeapMemory_free( &self->Name, e );
\r
611 e= HeapMemory_free( &self->Brief, e );
\r
617 /***********************************************************************
\r
618 <<< [NaturalDocsDescriptionTypeEnum_to_String] >>>
\r
619 ************************************************************************/
\r
621 static const TCHAR* gs_NaturalDocsDescriptionTypeEnum_to_String[ NaturalDocsDescriptionType_Count ] = {
\r
622 _T("Unknown"), _T("SubTitle"), _T("Paragraph"), _T("Code")
\r
624 static_assert_global( NaturalDocsDescriptionType_Unknown == 0, "" );
\r
625 static_assert_global( NaturalDocsDescriptionType_SubTitle == 1, "" );
\r
626 static_assert_global( NaturalDocsDescriptionType_Paragraph == 2, "" );
\r
627 static_assert_global( NaturalDocsDescriptionType_Code == 3, "" );
\r
629 const TCHAR* NaturalDocsDescriptionTypeEnum_to_String( int in, const TCHAR* in_OutOfRange )
\r
633 if ( in >= NaturalDocsDescriptionType_Unknown && in < NaturalDocsDescriptionType_Count )
\r
634 { ret = gs_NaturalDocsDescriptionTypeEnum_to_String[ in - NaturalDocsDescriptionType_Unknown ]; }
\r
636 { ret = in_OutOfRange; }
\r
643 /***********************************************************************
\r
644 <<< [NaturalDocsDescriptionClass_initConst] >>>
\r
645 ************************************************************************/
\r
646 void NaturalDocsDescriptionClass_initConst( NaturalDocsDescriptionClass* self )
\r
648 self->Type = NaturalDocsDescriptionType_Unknown;
\r
649 self->Start = NULL;
\r
651 self->u.Unknown = NULL;
\r
656 /***********************************************************************
\r
657 <<< [NaturalDocsDescriptionClass_finalize] >>>
\r
658 ************************************************************************/
\r
659 errnum_t NaturalDocsDescriptionClass_finalize( NaturalDocsDescriptionClass* self, errnum_t e )
\r
661 if ( self->Type == NaturalDocsDescriptionType_DefinitionList ) {
\r
662 if ( self->u.Definition != NULL )
\r
663 { e= NaturalDocsDefinitionClass_finalize( self->u.Definition, e ); }
\r
664 e= HeapMemory_free( &self->u.Definition, e );
\r
666 self->Type = NaturalDocsDescriptionType_Unknown;
\r
673 /***********************************************************************
\r
674 <<< [ParseNaturalDocsComment] >>>
\r
675 - HeapMemory_free( out_NaturalDocsHeader );
\r
676 ************************************************************************/
\r
678 void ParseNaturalDocsLine( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,
\r
679 const TCHAR** out_LineStart, const TCHAR** out_LineOver );
\r
680 void ParseNaturalDocsDefinitionList( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,
\r
681 const TCHAR** out_NameStart, const TCHAR** out_NameOver,
\r
682 const TCHAR** out_BriefStart, const TCHAR** out_BriefOver, bool in_IsSkipFirstLine );
\r
685 errnum_t ParseNaturalDocsComment( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,
\r
686 NaturalDocsHeaderClass** out_NaturalDocsHeader, NaturalDocsParserConfigClass* config )
\r
690 const TCHAR* p_over;
\r
692 bool is_found = false;
\r
693 const TCHAR* descriptions = NULL;
\r
695 NaturalDocsHeaderClass* header = NULL;
\r
696 NaturalDocsDefinitionClass* definition_a = NULL; /* a = for Argument */
\r
697 NaturalDocsDefinitionClass* definition_p = NULL; /* p = for in Paragraph */
\r
698 NaturalDocsDescriptionClass* description = NULL;
\r
700 e= HeapMemory_allocate( &header ); IF(e){goto fin;}
\r
701 NaturalDocsHeaderClass_initConst( header );
\r
702 e= Set2_init( &header->Arguments, 0x10 ); IF(e){goto fin;}
\r
703 e= Set2_init( &header->DescriptionItems, 0x40 ); IF(e){goto fin;}
\r
706 /* Parse keyword */
\r
708 for ( p = in_SourceStart; p < in_SourceOver; p += 1 ) {
\r
709 if ( ! StrT_isCIdentifier( *p ) ) { continue; }
\r
711 if ( step_num == 0 ) {
\r
712 p_over = StrT_searchOverOfIdiom( p );
\r
714 if ( *p_over != _T(':') ) {
\r
715 break; /* This comment is not parsed */
\r
717 if ( StrT_searchPartStringIndexI( p, p_over,
\r
718 g_NaturalDocsKeywords, _countof(g_NaturalDocsKeywords),
\r
720 == NOT_FOUND_INDEX )
\r
722 if ( StrT_searchPartStringIndexI( p, p_over,
\r
723 config->AdditionalKeywords, config->AdditionalKeywordsLength,
\r
725 == NOT_FOUND_INDEX )
\r
727 break; /* This comment is not parsed */
\r
731 e= MallocAndCopyStringByLength( &header->Keyword, p, p_over - p );
\r
733 header->KeywordStart = p;
\r
734 header->KeywordOver = p_over;
\r
737 else if ( step_num == 1 ) {
\r
738 TCHAR* name = NULL;
\r
740 p_over = StrT_chrs( p, _T("\r\n") );
\r
741 ASSERT_R( p_over != NULL, e=E_OTHERS; goto fin );
\r
742 if ( p_over >= p + 2 ) {
\r
743 if ( p_over[-2] == _T('*') && p_over[-1] == _T('/') )
\r
746 p_over = StrT_rskip( p, p_over - 1, _T(" \t"), NULL );
\r
747 ASSERT_R( p_over != NULL, e=E_OTHERS; goto fin );
\r
750 e= MallocAndCopyStringByLength( &name, p, p_over - p );
\r
752 e= StrT_trim( name, sizeof(TCHAR) * ( _tcslen( name ) + 1 ), name );
\r
754 header->Name = name;
\r
755 header->NameStart = p;
\r
756 header->NameOver = p_over;
\r
763 if ( header->Keyword != NULL && header->Name == NULL ) {
\r
764 e= MallocAndCopyString( &header->Name, _T("") );
\r
770 /* Parse 2nd line */
\r
771 ParseNaturalDocsLine( p, in_SourceOver, &p, &p_over );
\r
772 if ( p_over >= in_SourceOver ) {
\r
775 else if ( p == NULL ) {
\r
777 descriptions = p_over;
\r
780 e= MallocAndCopyStringByLength( &header->Brief, p, p_over - p );
\r
782 header->BriefStart = p;
\r
783 header->BriefOver = p_over;
\r
785 p = StrT_rskip( in_SourceStart, p - 1, _T(" \t"), NULL );
\r
786 IF ( p == NULL ) { e=E_OTHERS; goto fin; }
\r
787 header->BriefNoIndent = p + 2;
\r
796 for ( /* p */; p < in_SourceOver; p += 1 ) {
\r
797 if ( ! StrT_isCIdentifier( *p ) ) { continue; }
\r
799 p_over = StrT_searchOverOfIdiom( p );
\r
801 if ( *p_over != _T(':') ) { continue; }
\r
803 /* Parse Argument Label */
\r
804 if ( StrT_cmp_i_part( p, p_over, _T("Arguments") ) == 0 ) {
\r
806 const TCHAR* p1_over;
\r
808 const TCHAR* p2_over;
\r
810 header->ArgumentsLabel = p;
\r
813 ParseNaturalDocsDefinitionList( p, in_SourceOver,
\r
814 &p1, &p1_over, &p2, &p2_over, true );
\r
818 e= Set2_allocate( &header->Arguments, &definition_a );
\r
820 NaturalDocsDefinitionClass_initConst( definition_a );
\r
822 e= MallocAndCopyStringByLength( &definition_a->Name, p1, p1_over - p1 );
\r
824 definition_a->NameStart = p1;
\r
825 definition_a->NameOver = p1_over;
\r
827 e= MallocAndCopyStringByLength( &definition_a->Brief, p2, p2_over - p2 );
\r
829 definition_a->BriefStart = p2;
\r
830 definition_a->BriefOver = p2_over;
\r
832 definition_a = NULL;
\r
834 descriptions = p2_over;
\r
840 /* Parse Return Value Label */
\r
841 else if ( StrT_cmp_i_part( p, p_over, _T("Return Value") ) == 0 ) {
\r
843 header->ReturnValueLabel = p;
\r
845 ParseNaturalDocsLine( p, in_SourceOver, &p, &p_over );
\r
848 ASSERT_D( p_over != NULL, __noop() );
\r
851 e= MallocAndCopyStringByLength( &header->ReturnValue, p, p_over - p );
\r
853 header->ReturnValueStart = p;
\r
854 header->ReturnValueOver = p_over;
\r
858 descriptions = p_over;
\r
863 /* Set "header->Descriptions" */
\r
864 if ( descriptions != NULL ) {
\r
865 const TCHAR* descriptions_over;
\r
867 descriptions_over = StrT_rstr( in_SourceStart, in_SourceOver, _T("\n"), NULL );
\r
868 if ( descriptions_over != NULL ) {
\r
869 const TCHAR* over2 = StrT_rstr( in_SourceStart, descriptions_over - 1, _T("\n"), NULL );
\r
872 /* If last line was only "*******" Then "descriptions_over = over2". */
\r
873 if ( over2 != NULL ) {
\r
874 p2 = StrT_skip( over2 + 1, _T("* /\t") );
\r
875 IF ( p2 == NULL ) { e=E_OTHERS; goto fin; }
\r
876 if ( p2 >= descriptions_over ) {
\r
877 descriptions_over = over2;
\r
881 if ( descriptions_over != NULL ) {
\r
884 if ( *( descriptions_over - 1 ) == _T('\r') )
\r
885 { descriptions_over -= 1; }
\r
887 /* Set "descriptions_over" to before end of comment */
\r
888 p2 = StrT_rskip( descriptions, descriptions_over - 1, _T(" \t"), NULL );
\r
889 if ( p2 != NULL ) {
\r
890 if ( *p2 == _T('/') && *( p2 - 1 ) == _T('*') ) {
\r
891 p2 = StrT_rskip( descriptions, p2 - 2, _T(" \t"), NULL );
\r
892 if ( p2 == NULL ) {
\r
893 descriptions_over = descriptions;
\r
895 descriptions_over = p2 + 1;
\r
901 header->DescriptionsStart = descriptions;
\r
902 header->DescriptionsOver = descriptions_over;
\r
903 e= MallocAndCopyStringByLength( &header->Descriptions,
\r
904 descriptions, descriptions_over - descriptions );
\r
910 /* Set "header->DescriptionItems" */
\r
911 if ( descriptions != NULL && header->DescriptionsOver != NULL ) {
\r
913 const TCHAR* p_last;
\r
914 const TCHAR* p_line_feed;
\r
915 const TCHAR* descriptions_over = header->DescriptionsOver;
\r
916 bool is_definition_list;
\r
919 line = _tcschr( descriptions, _T('\n') ) + 1;
\r
920 line < descriptions_over;
\r
921 line = p_line_feed + 1 )
\r
923 p_line_feed = _tcschr( line, _T('\n') );
\r
926 /* Set "p" : Skip space or "*" */
\r
927 for ( p = line; p < p_line_feed; p += 1 ) {
\r
930 if ( a_char == ' ' || a_char == '\t' || a_char == '*' )
\r
937 for ( p_last = p_line_feed - 1; p_last > p; p_last -= 1 ) {
\r
938 TCHAR a_char = *p_last;
\r
940 if ( a_char == ' ' || a_char == '\t' || a_char == '\n' )
\r
947 /* Set "is_definition_list", "definition_p" */
\r
950 const TCHAR* p1_over;
\r
952 const TCHAR* p2_over;
\r
954 is_definition_list = false;
\r
955 p1 = _tcschr( p, _T('-') );
\r
956 p2 = _tcschr( p, _T('\n') );
\r
959 if ( p1 != NULL && p1 < p2 ) {
\r
961 for ( p1_over = p2 - 1; p1_over > p1; p1_over -= 1 ) {
\r
962 if ( ! _istspace( *p1_over ) )
\r
965 if ( p1_over == p1 ) {
\r
966 p1 = NULL; /* For next if */
\r
967 p2_over = NULL; /* For warning C4701 */
\r
969 ParseNaturalDocsDefinitionList( p, in_SourceOver,
\r
970 &p1, &p1_over, &p2, &p2_over, false );
\r
972 if ( p1 != NULL && p2 != NULL ) {
\r
973 e= HeapMemory_allocate( &definition_p ); IF(e){goto fin;}
\r
974 NaturalDocsDefinitionClass_initConst( definition_p );
\r
976 e= MallocAndCopyStringByLength( &definition_p->Name,
\r
977 p1, p1_over - p1 );
\r
979 definition_p->NameStart = p1;
\r
980 definition_p->NameOver = p1_over;
\r
982 e= MallocAndCopyStringByLength( &definition_p->Brief,
\r
983 p2, p2_over - p2 );
\r
985 definition_p->BriefStart = p2;
\r
986 definition_p->BriefOver = p2_over;
\r
987 is_definition_list = true;
\r
993 /* End of Paragraph */
\r
994 if ( description != NULL &&
\r
995 description->Type == NaturalDocsDescriptionType_Paragraph &&
\r
998 description = NULL;
\r
1002 if ( description != NULL &&
\r
1003 description->Type == NaturalDocsDescriptionType_Code &&
\r
1006 description = NULL;
\r
1011 if ( *p == _T('>') ) {
\r
1012 if ( description == NULL ||
\r
1013 description->Type != NaturalDocsDescriptionType_Code )
\r
1015 e= Set2_allocate( &header->DescriptionItems, &description );
\r
1017 NaturalDocsDescriptionClass_initConst( description );
\r
1019 description->Type = NaturalDocsDescriptionType_Code;
\r
1020 description->Start = line;
\r
1022 description->Over = p_line_feed + 1;
\r
1025 /* Add SubTitle */
\r
1026 else if ( *p_last == _T(':') ) {
\r
1027 e= Set2_allocate( &header->DescriptionItems, &description );
\r
1029 NaturalDocsDescriptionClass_initConst( description );
\r
1031 description->Type = NaturalDocsDescriptionType_SubTitle;
\r
1032 description->Start = p;
\r
1033 description->Over = p_last;
\r
1035 description = NULL;
\r
1038 /* Add DefinitionList */
\r
1039 else if ( is_definition_list ) {
\r
1040 e= Set2_allocate( &header->DescriptionItems, &description );
\r
1042 NaturalDocsDescriptionClass_initConst( description );
\r
1044 description->Type = NaturalDocsDescriptionType_DefinitionList;
\r
1045 description->Start = line;
\r
1046 description->Over = p_line_feed + 1;
\r
1047 description->u.Definition = definition_p;
\r
1049 description = NULL;
\r
1050 definition_p = NULL;
\r
1053 /* Add Paragraph */
\r
1055 bool is_exist_content = false;
\r
1057 if ( description == NULL ||
\r
1058 description->Type != NaturalDocsDescriptionType_Paragraph )
\r
1062 for ( p = line; p < p_line_feed; p += 1 ) {
\r
1064 case ' ': case '\t': case '*':
\r
1067 is_exist_content = true;
\r
1073 if ( is_exist_content ) {
\r
1075 e= Set2_allocate( &header->DescriptionItems, &description );
\r
1077 NaturalDocsDescriptionClass_initConst( description );
\r
1079 description->Type = NaturalDocsDescriptionType_Paragraph;
\r
1080 description->Start = line;
\r
1082 if ( description != NULL ) {
\r
1083 description->Over = p_line_feed + 1;
\r
1088 /* Delete not used data */
\r
1090 if ( definition_p != NULL )
\r
1091 { e= NaturalDocsDefinitionClass_finalize( definition_p, e ); }
\r
1092 e= HeapMemory_free( &definition_p, e );
\r
1098 *out_NaturalDocsHeader = header;
\r
1103 if ( header != NULL ) {
\r
1104 e= Set2_free( &header->Arguments, &definition_a, e );
\r
1105 if ( definition_p != NULL )
\r
1106 { e= NaturalDocsDefinitionClass_finalize( definition_p, e ); }
\r
1107 e= HeapMemory_free( &definition_p, e );
\r
1108 e= Set2_free( &header->DescriptionItems, &description, e );
\r
1110 if ( ! is_found || e != 0 ) {
\r
1111 if ( header == NULL )
\r
1112 { header = *out_NaturalDocsHeader; }
\r
1113 e= NaturalDocsHeaderClass_finalize( header, e );
\r
1114 e= HeapMemory_free( &header, e );
\r
1115 *out_NaturalDocsHeader = NULL;
\r
1122 /***********************************************************************
\r
1123 <<< [ParseNaturalDocsLine] >>>
\r
1124 ************************************************************************/
\r
1125 void ParseNaturalDocsLine( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,
\r
1126 const TCHAR** out_LineStart, const TCHAR** out_LineOver )
\r
1129 const TCHAR* p_over; /* position of over */
\r
1130 TCHAR a_char; /* char = charcter */
\r
1133 *out_LineStart = NULL;
\r
1134 *out_LineOver = NULL;
\r
1137 /* Move to next line */
\r
1138 for ( p = in_SourceStart; p < in_SourceOver; p += 1 ) {
\r
1139 if ( *p == '\n' ) {
\r
1145 /* Skip space or "*" */
\r
1146 for ( /* p */ ; p < in_SourceOver; p += 1 ) {
\r
1149 if ( a_char == ' ' || a_char == '\t' || a_char == '*' )
\r
1155 /* Move to right of line */
\r
1156 for ( p_over = p; p_over < in_SourceOver; p_over += 1 ) {
\r
1159 if ( a_char == '\n' ) {
\r
1160 for ( p_over -= 1; /* p_over >= p */; p_over -= 1 ) {
\r
1161 if ( p_over <= p ) {
\r
1168 if ( a_char == ' ' || a_char == '\t' ) {
\r
1176 if ( p != p_over ) {
\r
1177 *out_LineStart = p;
\r
1182 *out_LineOver = p_over;
\r
1184 if ( p_over > p + 2 && *( p_over - 2 ) == _T('*') && *( p_over - 1 ) == _T('/') && *out_LineStart == NULL ) {
\r
1185 for ( p_over -= 3; p_over > p; p_over -= 1 ) {
\r
1188 if ( a_char == ' ' || a_char == '\t' )
\r
1194 *out_LineStart = p;
\r
1195 *out_LineOver = p_over + 1;
\r
1201 /***********************************************************************
\r
1202 <<< [ParseNaturalDocsDefinitionList] >>>
\r
1203 ************************************************************************/
\r
1204 void ParseNaturalDocsDefinitionList( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,
\r
1205 const TCHAR** out_NameStart, const TCHAR** out_NameOver,
\r
1206 const TCHAR** out_BriefStart, const TCHAR** out_BriefOver, bool in_IsSkipFirstLine )
\r
1209 const TCHAR* p_over;
\r
1210 TCHAR a_char; /* char = charcter */
\r
1213 *out_NameStart = NULL;
\r
1214 *out_BriefStart = NULL;
\r
1216 if ( in_IsSkipFirstLine ) {
\r
1217 for ( p = in_SourceStart; p < in_SourceOver; p += 1 ) {
\r
1218 if ( *p == '\n' ) {
\r
1225 p = in_SourceStart;
\r
1228 for ( /* p */ ; p < in_SourceOver; p += 1 ) {
\r
1231 if ( a_char == ' ' || a_char == '\t' || a_char == '*' )
\r
1236 for ( p_over = p; p_over < in_SourceOver; p_over += 1 ) {
\r
1239 if ( a_char == '-' ) {
\r
1240 if ( p_over == p ) {
\r
1241 break; /* Not definition list but normal list */
\r
1244 const TCHAR* p2_over;
\r
1246 for ( p2_over = p_over - 1; /* p2_over >= p */; p2_over -= 1 ) {
\r
1247 a_char = *p2_over;
\r
1248 if ( a_char == ' ' || a_char == '\t' ) {
\r
1256 *out_NameStart = p;
\r
1257 *out_NameOver = p2_over;
\r
1261 else if ( a_char == '\n' ) {
\r
1265 for ( p = p_over + 1; p < in_SourceOver; p += 1 ) {
\r
1268 if ( a_char == ' ' || a_char == '\t' || a_char == '*' )
\r
1273 for ( p_over = p; p_over < in_SourceOver; p_over += 1 ) {
\r
1276 if ( a_char == '\n' ) {
\r
1277 for ( p_over -= 1; /* p_over >= p */; p_over -= 1 ) {
\r
1279 if ( a_char == ' ' || a_char == '\t' ) {
\r
1287 *out_BriefStart = p;
\r
1288 *out_BriefOver = p_over;
\r
1299 /***********************************************************************
\r
1300 <<< (NaturalCommentClass) >>>
\r
1301 ************************************************************************/
\r
1303 static const FinalizerVTableClass gs_NaturalCommentClass_FinalizerVTable = {
\r
1304 offsetof( NaturalCommentClass, FinalizerVTable ),
\r
1305 NaturalCommentClass_finalize,
\r
1307 static const PrintXML_VTableClass gs_NaturalCommentClass_PrintXML_VTable = {
\r
1308 offsetof( NaturalCommentClass, PrintXML_VTable ),
\r
1309 NaturalCommentClass_printXML,
\r
1311 static const InterfaceToVTableClass gs_NaturalCommentClass_InterfaceToVTables[] = {
\r
1312 { &g_FinalizerInterface_ID, &gs_NaturalCommentClass_FinalizerVTable },
\r
1313 { &g_PrintXML_Interface_ID, &gs_NaturalCommentClass_PrintXML_VTable },
\r
1315 static const ClassID_Class* gs_NaturalCommentClass_SuperClassIDs[] = {
\r
1316 &g_ClassID_SuperClass_ID, &g_ParsedRangeClass_ID, &g_SyntaxSubNodeClass_ID,
\r
1317 &g_SyntaxNodeClass_ID, &g_NaturalCommentClass_ID,
\r
1320 /*[g_NaturalCommentClass_ID]*/
\r
1321 const ClassID_Class g_NaturalCommentClass_ID = {
\r
1322 "NaturalCommentClass",
\r
1323 gs_NaturalCommentClass_SuperClassIDs,
\r
1324 _countof( gs_NaturalCommentClass_SuperClassIDs ),
\r
1325 sizeof( NaturalCommentClass ),
\r
1327 gs_NaturalCommentClass_InterfaceToVTables,
\r
1328 _countof( gs_NaturalCommentClass_InterfaceToVTables ),
\r
1333 /***********************************************************************
\r
1334 <<< [NaturalCommentClass_initConst] >>>
\r
1335 ************************************************************************/
\r
1336 void NaturalCommentClass_initConst( NaturalCommentClass* self )
\r
1338 SyntaxNodeClass_initConst( (SyntaxNodeClass*) self );
\r
1339 self->ClassID = &g_NaturalCommentClass_ID;
\r
1340 self->FinalizerVTable = &gs_NaturalCommentClass_FinalizerVTable;
\r
1341 self->PrintXML_VTable = &gs_NaturalCommentClass_PrintXML_VTable;
\r
1342 self->NaturalDocsHeader = NULL;
\r
1347 /***********************************************************************
\r
1348 <<< [NaturalCommentClass_finalize] >>>
\r
1349 ************************************************************************/
\r
1350 errnum_t NaturalCommentClass_finalize( NaturalCommentClass* self, errnum_t e )
\r
1352 if ( self->NaturalDocsHeader != NULL ) {
\r
1353 e= NaturalDocsHeaderClass_finalize( self->NaturalDocsHeader, e );
\r
1354 e= HeapMemory_free( &self->NaturalDocsHeader, e );
\r
1361 /***********************************************************************
\r
1362 <<< [NaturalCommentClass_printXML] >>>
\r
1363 ************************************************************************/
\r
1364 errnum_t NaturalCommentClass_printXML( NaturalCommentClass* self, FILE* OutputStream )
\r
1368 Set2_IteratorClass iterator;
\r
1369 NaturalDocsHeaderClass* header;
\r
1370 NaturalDocsDefinitionClass* definition;
\r
1371 NaturalDocsDescriptionClass* description;
\r
1374 r= _ftprintf_s( OutputStream, _T("<NaturalCommentClass") );
\r
1375 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1377 header = self->NaturalDocsHeader;
\r
1378 if ( header != NULL ) {
\r
1379 r= _ftprintf_s( OutputStream, _T(" NaturalDocsKeyword=\"%s\""), header->Keyword );
\r
1380 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1382 ASSERT_D( StrT_cmp_part( header->KeywordStart, header->KeywordOver, header->Keyword ) == 0,
\r
1383 e=E_OTHERS; goto fin );
\r
1386 r= _ftprintf_s( OutputStream, _T(" Name=\"%s\""), header->Name );
\r
1387 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1389 ASSERT_D( StrT_cmp_part( header->NameStart, header->NameOver, header->Name ) == 0,
\r
1390 e=E_OTHERS; goto fin );
\r
1392 r= _ftprintf_s( OutputStream, _T(" StartLineNum=\"%d\""), self->StartLineNum );
\r
1393 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1395 r= _ftprintf_s( OutputStream, _T(" LastLineNum=\"%d\""), self->LastLineNum );
\r
1396 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1398 if ( self->ParentComment != NULL ) {
\r
1399 r= _ftprintf_s( OutputStream, _T(" ParentComment=\"%s\""), self->ParentComment->NaturalDocsHeader->Name );
\r
1400 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1402 r= _ftprintf_s( OutputStream, _T(">\n") );
\r
1403 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1406 if ( header != NULL ) {
\r
1407 if ( header->Brief != NULL ) {
\r
1408 r= _ftprintf_s( OutputStream, _T("\t<Brief><![CDATA[%s]]></Brief>\n"), header->Brief );
\r
1409 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1411 ASSERT_D( StrT_cmp_part( header->BriefStart, header->BriefOver, header->Brief ) == 0,
\r
1412 e=E_OTHERS; goto fin );
\r
1413 ASSERT_D( header->BriefNoIndent > header->NameOver &&
\r
1414 header->BriefNoIndent < header->BriefStart,
\r
1415 e=E_OTHERS; goto fin );
\r
1418 if ( header->Arguments.First < header->Arguments.Next ) {
\r
1419 ASSERT_D( StrT_cmp_part( header->ArgumentsLabel, header->ArgumentsLabel + 10,
\r
1420 _T("Arguments:") ) == 0, e=E_OTHERS; goto fin );
\r
1422 for ( Set2_forEach2( &header->Arguments, &iterator, &definition ) ) {
\r
1423 r= _ftprintf_s( OutputStream, _T("\t<Arguments Name=\"%s\"><![CDATA[%s]]></Arguments>\n"),
\r
1424 definition->Name, definition->Brief );
\r
1425 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1427 ASSERT_D( StrT_cmp_part( definition->NameStart, definition->NameOver, definition->Name )
\r
1428 == 0, e=E_OTHERS; goto fin );
\r
1429 ASSERT_D( StrT_cmp_part( definition->BriefStart, definition->BriefOver, definition->Brief )
\r
1430 == 0, e=E_OTHERS; goto fin );
\r
1433 if ( header->ReturnValue != NULL ) {
\r
1434 r= _ftprintf_s( OutputStream, _T("\t<ReturnValue><![CDATA[%s]]></ReturnValue>\n"), header->ReturnValue );
\r
1435 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1437 ASSERT_D( StrT_cmp_part( header->ReturnValueStart, header->ReturnValueOver,
\r
1438 header->ReturnValue ) == 0, e=E_OTHERS; goto fin );
\r
1439 ASSERT_D( StrT_cmp_part( header->ReturnValueLabel, header->ReturnValueLabel + 13,
\r
1440 _T("Return Value:") ) == 0, e=E_OTHERS; goto fin );
\r
1443 if ( ! Set2_isEmpty( &header->DescriptionItems ) ) {
\r
1444 r= _ftprintf_s( OutputStream, _T("\t<DescriptionItems>\n") );
\r
1445 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1447 for ( Set2_forEach2( &header->DescriptionItems, &iterator, &description ) ) {
\r
1448 r= _ftprintf_s( OutputStream, _T("\t\t<DescriptionItem type=\"%s\"><![CDATA["),
\r
1449 NaturalDocsDescriptionTypeEnum_to_String( description->Type, _T("UNKNOWN") ) );
\r
1450 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1451 e= ftcopy_part_r( OutputStream, description->Start, description->Over );
\r
1452 r= _ftprintf_s( OutputStream, _T("]]></DescriptionItem>\n") );
\r
1453 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1455 if ( ! Set2_isEmpty( &header->DescriptionItems ) ) {
\r
1456 r= _ftprintf_s( OutputStream, _T("\t</DescriptionItems>\n") );
\r
1457 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1462 r= _ftprintf_s( OutputStream, _T("</NaturalCommentClass>\n") );
\r
1463 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
1472 /***********************************************************************
\r
1473 <<< [MakeNaturalComments_C_Language] >>>
\r
1474 ************************************************************************/
\r
1476 errnum_t MakeNaturalComments_C_Language__Sub( C_LanguageTokenClass* StartToken,
\r
1477 LineNumberIndexClass* LineNumbers,
\r
1478 NaturalCommentClass** out_NewComment,
\r
1479 NaturalDocsParserConfigClass* config );
\r
1481 errnum_t MakeNaturalComments_C_Language( ListClass* /*<C_LanguageTokenClass*>*/ TokenList,
\r
1482 LineNumberIndexClass* LineNumbers,
\r
1483 ListClass* /*<NaturalCommentClass*>*/ TopSyntaxNodeList,
\r
1484 NaturalDocsParserConfigClass* config )
\r
1487 const ClassID_Class* class_ID;
\r
1488 ListIteratorClass iterator;
\r
1489 C_LanguageTokenClass* token;
\r
1490 NaturalCommentClass* comment;
\r
1491 NaturalCommentClass* new_comment;
\r
1492 NaturalDocsParserConfigClass config_body;
\r
1495 if ( config == NULL ) {
\r
1496 config = &config_body;
\r
1497 config->Flags = 0;
\r
1500 if ( IsBitNotSet( config->Flags, NaturalDocsParserConfig_AdditionalKeywords ) ) {
\r
1501 config->AdditionalKeywords = NULL;
\r
1502 config->AdditionalKeywordsLength = 0;
\r
1505 ASSERT_R( IsBitSet( config->Flags, NaturalDocsParserConfig_AdditionalKeywordsLength ),
\r
1506 e=E_OTHERS; goto fin );
\r
1509 if ( IsBitSet( config->Flags, NaturalDocsParserConfig_AdditionalKeywordsEndsScopesFirstIndex ) ) {
\r
1510 if ( IsBitNotSet( config->Flags, NaturalDocsParserConfig_AdditionalKeywordsEndsScopesLength ) ) {
\r
1511 config->AdditionalKeywordsEndsScopesLength = 1;
\r
1515 config->AdditionalKeywordsEndsScopesFirstIndex = 0;
\r
1516 config->AdditionalKeywordsEndsScopesLength = 0;
\r
1520 for ( ListClass_forEach( TokenList, &iterator, &token ) ) {
\r
1521 class_ID = token->ClassID;
\r
1522 if ( class_ID == &g_C_LanguageTokenClass_ID ) {
\r
1523 C_LanguageTokenEnum token_type = token->TokenType;
\r
1525 if ( token_type == TwoChar8( '/', '*' ) ) {
\r
1526 e= MakeNaturalComments_C_Language__Sub( token, LineNumbers, &new_comment, config );
\r
1528 if ( new_comment != NULL ) {
\r
1529 e= ListClass_addLast( TopSyntaxNodeList, &new_comment->ListElement );
\r
1536 /* Set "comment->ParentComment" */
\r
1539 starts_scope_start = 19,
\r
1540 starts_scope_end = 30,
\r
1541 ends_scope_start = 4,
\r
1542 ends_scope_end = 5,
\r
1545 NaturalCommentClass* parent = NULL;
\r
1548 ASSERT_D( _tcscmp( g_NaturalDocsKeywords[ starts_scope_start ], _T("class") ) == 0, e=E_OTHERS; goto fin );
\r
1549 ASSERT_D( _tcscmp( g_NaturalDocsKeywords[ starts_scope_end ], _T("interfaces") ) == 0, e=E_OTHERS; goto fin );
\r
1550 ASSERT_D( _tcscmp( g_NaturalDocsKeywords[ ends_scope_start ], _T("section") ) == 0, e=E_OTHERS; goto fin );
\r
1551 ASSERT_D( _tcscmp( g_NaturalDocsKeywords[ ends_scope_end ], _T("title") ) == 0, e=E_OTHERS; goto fin );
\r
1554 for ( ListClass_forEach( TopSyntaxNodeList, &iterator, &comment ) ) {
\r
1555 NaturalDocsHeaderClass* header = comment->NaturalDocsHeader;
\r
1558 index = StrT_searchPartStringIndexI( header->KeywordStart, header->KeywordOver,
\r
1559 g_NaturalDocsKeywords, _countof(g_NaturalDocsKeywords),
\r
1560 NOT_FOUND_INDEX );
\r
1562 if ( index == NOT_FOUND_INDEX ) {
\r
1563 index = StrT_searchPartStringIndexI( header->KeywordStart, header->KeywordOver,
\r
1564 config->AdditionalKeywords, config->AdditionalKeywordsLength,
\r
1565 NOT_FOUND_INDEX );
\r
1567 if ( index >= config->AdditionalKeywordsEndsScopesFirstIndex &&
\r
1568 index < config->AdditionalKeywordsEndsScopesFirstIndex +
\r
1569 config->AdditionalKeywordsEndsScopesLength )
\r
1571 index = ends_scope_start;
\r
1574 index = NOT_FOUND_INDEX;
\r
1578 if ( index >= starts_scope_start && index <= starts_scope_end ) {
\r
1580 comment->ParentComment = NULL;
\r
1582 else if ( index >= ends_scope_start && index <= ends_scope_end ) {
\r
1584 comment->ParentComment = NULL;
\r
1587 comment->ParentComment = parent;
\r
1598 errnum_t MakeNaturalComments_C_Language__Sub( C_LanguageTokenClass* StartToken,
\r
1599 LineNumberIndexClass* LineNumbers,
\r
1600 NaturalCommentClass** out_NewComment,
\r
1601 NaturalDocsParserConfigClass* config )
\r
1604 C_LanguageTokenClass* token;
\r
1605 NaturalCommentClass* new_comment;
\r
1608 *out_NewComment = NULL;
\r
1610 e= HeapMemory_allocate( &new_comment ); IF(e){goto fin;}
\r
1611 NaturalCommentClass_initConst( new_comment );
\r
1614 /* Set members of "new_comment" */
\r
1615 new_comment->Start = StartToken->Start;
\r
1616 e= LineNumberIndexClass_searchLineNumber( LineNumbers, new_comment->Start, &line_num );
\r
1618 new_comment->StartLineNum = line_num;
\r
1621 token = StartToken;
\r
1623 token = (C_LanguageTokenClass*) token->ListElement.Next->Data;
\r
1624 IF ( token == NULL ) { e=E_OTHERS; goto fin; }
\r
1625 if ( token->TokenType == TwoChar8( '*', '/' ) )
\r
1629 new_comment->Over = token->Over;
\r
1630 e= LineNumberIndexClass_searchLineNumber( LineNumbers, new_comment->Over - 1, &line_num );
\r
1632 new_comment->LastLineNum = line_num;
\r
1636 e= ParseNaturalDocsComment( new_comment->Start, new_comment->Over,
\r
1637 &new_comment->NaturalDocsHeader, config ); IF(e){goto fin;}
\r
1640 /* Set "*out_NewComment" */
\r
1641 if ( new_comment->NaturalDocsHeader != NULL ) {
\r
1642 *out_NewComment = new_comment;
\r
1643 new_comment = NULL;
\r
1647 if ( new_comment != NULL ) {
\r
1648 e= NaturalCommentClass_finalize( new_comment, e );
\r
1649 HeapMemory_free( &new_comment, e );
\r
1657 /***********************************************************************
\r
1658 <<< [LexicalAnalize_C_Language] >>>
\r
1659 ************************************************************************/
\r
1660 errnum_t LexicalAnalize_C_Language( const TCHAR* in_Text,
\r
1661 ListClass* /*<C_LanguageTokenClass>*/ in_TokenList )
\r
1668 bool is_in_c_comment = false; /* Slash asterisk */
\r
1669 bool is_in_cpp_comment = false; /* Double slash */
\r
1671 C_LanguageTokenEnum token_type;
\r
1672 C_LanguageTokenClass* token = NULL;
\r
1677 while ( c != '\0' ) {
\r
1680 if ( c >= 'A' && c <= 'Z' ) { token_type = gc_TokenOfCIdentifier; }
\r
1681 else if ( c >= 'a' && c <= 'z' ) { token_type = gc_TokenOfCIdentifier; }
\r
1682 else if ( c == '_' ) { token_type = gc_TokenOfCIdentifier; }
\r
1683 else if ( c >= '0' && c <= '9' ) { token_type = gc_TokenOfNumber; }
\r
1684 else if ( c == '=' ) {
\r
1686 if ( c2 == '=' ) { token_type = TwoChar8( '=', '=' ); next_plus = 2; }
\r
1687 else { token_type = '='; }
\r
1689 else if ( c == '+' ) {
\r
1691 if ( c2 == '+' ) { token_type = TwoChar8( '+', '+' ); next_plus = 2; }
\r
1692 else if ( c2 == '=' ) { token_type = TwoChar8( '+', '=' ); next_plus = 2; }
\r
1693 else { token_type = '+'; }
\r
1695 else if ( c == '-' ) {
\r
1697 if ( c2 == '>' ) { token_type = TwoChar8( '-', '>' ); next_plus = 2; }
\r
1698 else if ( c2 == '-' ) { token_type = TwoChar8( '-', '-' ); next_plus = 2; }
\r
1699 else if ( c2 == '=' ) { token_type = TwoChar8( '-', '=' ); next_plus = 2; }
\r
1700 else { token_type = '-'; }
\r
1702 else if ( c == '*' ) {
\r
1704 if ( c2 == '/' ) { token_type = TwoChar8( '*', '/' ); next_plus = 2; }
\r
1705 else if ( c2 == '=' ) { token_type = TwoChar8( '*', '=' ); next_plus = 2; }
\r
1706 else { token_type = '*'; }
\r
1708 if ( c2 == '/' ) {
\r
1709 if ( ! is_in_cpp_comment )
\r
1710 { is_in_c_comment = false; }
\r
1713 else if ( c == '/' ) {
\r
1715 if ( c2 == '/' ) { token_type = TwoChar8( '/', '/' ); next_plus = 2; }
\r
1716 else if ( c2 == '*' ) { token_type = TwoChar8( '/', '*' ); next_plus = 2; }
\r
1717 else if ( c2 == '=' ) { token_type = TwoChar8( '/', '=' ); next_plus = 2; }
\r
1718 else { token_type = '/'; }
\r
1720 if ( ! is_in_c_comment && ! is_in_cpp_comment ) {
\r
1722 { is_in_cpp_comment = true; }
\r
1723 else if ( c2 == '*' )
\r
1724 { is_in_c_comment = true; }
\r
1727 else if ( c == '<' ) {
\r
1729 if ( c2 == '<' ) { token_type = TwoChar8( '<', '<' ); next_plus = 2; }
\r
1730 else if ( c2 == '=' ) { token_type = TwoChar8( '<', '=' ); next_plus = 2; }
\r
1731 else { token_type = '<'; }
\r
1733 else if ( c == '>' ) {
\r
1735 if ( c2 == '>' ) { token_type = TwoChar8( '>', '>' ); next_plus = 2; }
\r
1736 else if ( c2 == '=' ) { token_type = TwoChar8( '>', '=' ); next_plus = 2; }
\r
1737 else { token_type = '>'; }
\r
1739 else if ( c == '!' ) {
\r
1741 if ( c2 == '=' ) { token_type = TwoChar8( '!', '=' ); next_plus = 2; }
\r
1742 else { token_type = '!'; }
\r
1744 else if ( c == '&' ) {
\r
1746 if ( c2 == '&' ) { token_type = TwoChar8( '&', '&' ); next_plus = 2; }
\r
1747 else if ( c2 == '=' ) { token_type = TwoChar8( '&', '=' ); next_plus = 2; }
\r
1748 else { token_type = '&'; }
\r
1750 else if ( c == '|' ) {
\r
1752 if ( c2 == '|' ) { token_type = TwoChar8( '|', '|' ); next_plus = 2; }
\r
1753 else if ( c2 == '=' ) { token_type = TwoChar8( '|', '=' ); next_plus = 2; }
\r
1754 else { token_type = '|'; }
\r
1756 else if ( c == '%' ) {
\r
1758 if ( c2 == '=' ) { token_type = TwoChar8( '%', '=' ); next_plus = 2; }
\r
1759 else { token_type = '%'; }
\r
1761 else if ( c == '^' ) {
\r
1763 if ( c2 == '=' ) { token_type = TwoChar8( '^', '=' ); next_plus = 2; }
\r
1764 else { token_type = '^'; }
\r
1768 case '(': token_type = c; break;
\r
1769 case ')': token_type = c; break;
\r
1770 case '{': token_type = c; break;
\r
1771 case '}': token_type = c; break;
\r
1772 case '[': token_type = c; break;
\r
1773 case ']': token_type = c; break;
\r
1774 case '"': token_type = gc_TokenOfString; break;
\r
1775 case '\'': token_type = gc_TokenOfChar; break;
\r
1776 case '.': token_type = c; break;
\r
1777 case ',': token_type = c; break;
\r
1778 case ':': token_type = c; break;
\r
1779 case ';': token_type = c; break;
\r
1780 case '\n': token_type = c; is_in_cpp_comment = false; break;
\r
1781 case '?': token_type = c; break;
\r
1782 case '~': token_type = c; break;
\r
1783 default: token_type = gc_TokenOfOther; break;
\r
1787 if ( token_type == gc_TokenOfCIdentifier ) {
\r
1788 bool is_in_identifier;
\r
1791 c2 = *( p + next_plus );
\r
1792 if ( c2 >= 'A' && c2 <= 'Z' ) { is_in_identifier = true; }
\r
1793 else if ( c2 >= 'a' && c2 <= 'z' ) { is_in_identifier = true; }
\r
1794 else if ( c2 >= '0' && c2 <= '9' ) { is_in_identifier = true; }
\r
1795 else if ( c2 == '_' ) { is_in_identifier = true; }
\r
1796 else { is_in_identifier = false; }
\r
1798 if ( ! is_in_identifier )
\r
1804 else if ( ( token_type == gc_TokenOfString || token_type == gc_TokenOfChar ) &&
\r
1805 ( ! is_in_c_comment && ! is_in_cpp_comment ) )
\r
1807 bool is_escape = false;
\r
1810 c2 = *( p + next_plus );
\r
1811 if ( ! is_escape ) {
\r
1816 else if ( c2 == '\\' ) {
\r
1821 is_escape = false;
\r
1828 if ( token_type != gc_TokenOfOther ) {
\r
1829 e= HeapMemory_allocate( &token ); IF(e){goto fin;}
\r
1830 C_LanguageTokenClass_initConst( token );
\r
1832 token->Over = p + next_plus;
\r
1833 token->TokenType = token_type;
\r
1835 e= ListClass_addLast( in_TokenList, &token->ListElement ); IF(e){goto fin;}
\r
1845 e= HeapMemory_free( &token, e );
\r
1851 /***********************************************************************
\r
1852 <<< [CutComment_C_LanguageToken] >>>
\r
1853 ************************************************************************/
\r
1854 errnum_t CutComment_C_LanguageToken( ListClass* /*<C_LanguageTokenClass>*/ TokenList )
\r
1857 C_LanguageTokenClass* p;
\r
1858 C_LanguageTokenEnum token_type;
\r
1859 bool is_in_c_comment;
\r
1860 bool is_in_cpp_comment;
\r
1862 ListIteratorClass iterator;
\r
1865 is_in_c_comment = false;
\r
1866 is_in_cpp_comment = false;
\r
1867 e= ListClass_getListIterator( TokenList, &iterator ); IF(e){goto fin;}
\r
1869 p = (C_LanguageTokenClass*) ListIteratorClass_getNext( &iterator );
\r
1870 if ( p == NULL ) { break; }
\r
1871 ASSERT_D( p->ClassID == &g_C_LanguageTokenClass_ID, e=E_OTHERS; goto fin );
\r
1873 token_type = p->TokenType;
\r
1874 if ( token_type == TwoChar8( '/', '*' ) ) {
\r
1875 if ( ! is_in_cpp_comment ) {
\r
1876 is_in_c_comment = true;
\r
1880 else if ( token_type == TwoChar8( '*', '/' ) ) {
\r
1881 if ( ! is_in_cpp_comment ) {
\r
1882 is_in_c_comment = false;
\r
1886 else if ( token_type == TwoChar8( '/', '/' ) ) {
\r
1887 if ( ! is_in_c_comment ) {
\r
1888 is_in_cpp_comment = true;
\r
1892 else if ( token_type == '\n' ){
\r
1893 is_in_cpp_comment = false;
\r
1897 is_cut = ( is_in_c_comment || is_in_cpp_comment );
\r
1901 e= ListIteratorClass_remove( &iterator );
\r
1902 e= HeapMemory_free( &p, e );
\r
1913 /***********************************************************************
\r
1914 * Function: CutCommentC_1
\r
1915 ************************************************************************/
\r
1916 errnum_t CutCommentC_1( const TCHAR* in_InputPath, const TCHAR* in_OutputPath )
\r
1919 FILE* file = NULL;
\r
1920 TCHAR* text = NULL;
\r
1923 ListClass_initConst( &tokens );
\r
1925 e= FileT_openForRead( &file, in_InputPath ); IF(e){goto fin;}
\r
1926 e= FileT_readAll( file, &text, NULL ); IF(e){goto fin;}
\r
1927 e= FileT_closeAndNULL( &file, 0 ); IF(e){goto fin;}
\r
1929 e= LexicalAnalize_C_Language( text, &tokens ); IF(e){goto fin;}
\r
1930 e= FileT_openForWrite( &file, in_OutputPath, 0 ); IF(e){goto fin;}
\r
1931 e= CopyWithoutComment_C_Language( &tokens, text, file ); IF(e){goto fin;}
\r
1932 e= FileT_closeAndNULL( &file, 0 ); IF(e){goto fin;}
\r
1936 e= Delete_C_LanguageToken( &tokens, e );
\r
1937 e= HeapMemory_free( &text, e );
\r
1938 e= FileT_closeAndNULL( &file, e );
\r
1944 /***********************************************************************
\r
1945 * Function: CopyWithoutComment_C_Language
\r
1946 ************************************************************************/
\r
1947 errnum_t CopyWithoutComment_C_Language( ListClass* in_Tokens, TCHAR* in_Text, FILE* in_OutStream )
\r
1951 TCHAR* source = in_Text;
\r
1952 TCHAR* comment_start = NULL;
\r
1953 TCHAR* comment_over = NULL;
\r
1954 bool is_new_space = false;
\r
1956 C_LanguageTokenClass* token;
\r
1957 ListIteratorClass iterator;
\r
1958 const ClassID_Class* class_ID;
\r
1961 /* BOM
\82È
\82µ Unicode
\81A
\89ü
\8ds=LF
\82Å
\95Û
\91¶
\82µ
\82½
\83t
\83@
\83C
\83\8b\82Ì
\93à
\97e
\82Æ
\88ê
\92v
\82µ
\82Ü
\82·
\81B */
\r
1964 for ( ListClass_forEach( in_Tokens, &iterator, &token ) ) {
\r
1965 class_ID = token->ClassID;
\r
1966 if ( class_ID == &g_C_LanguageTokenClass_ID ) {
\r
1967 C_LanguageTokenEnum token_type = token->TokenType;
\r
1969 if ( ( token_type == TwoChar8( '/', '*' ) || token_type == TwoChar8( '/', '/' )
\r
1970 ) && source <= token->Start && comment_start == NULL ) {
\r
1972 p = StrT_rskip( in_Text, p - 1, _T(" \t"), NULL );
\r
1974 if ( p != NULL ) {
\r
1975 comment_start = (TCHAR*) p + 1;
\r
1977 comment_start = in_Text;
\r
1979 if ( source > comment_start )
\r
1980 { comment_start = source; }
\r
1983 if ( token_type == TwoChar8( '/', '/' ) ) {
\r
1984 p = StrT_chr( comment_start, _T('\n') );
\r
1985 if ( p != NULL ) {
\r
1986 if ( comment_start == in_Text || *( comment_start - 1 ) == _T('\n') )
\r
1987 { p += 1; } /* This line has comment only */
\r
1989 p = StrT_chr( comment_start, _T('\0') );
\r
1992 comment_over = (TCHAR*) p;
\r
1995 else if ( token_type == TwoChar8( '*', '/' ) && comment_start != NULL ) {
\r
1997 p = StrT_skip( p, _T(" \t") );
\r
1998 if ( comment_start > in_Text ) {
\r
1999 if ( *( comment_start - 1 ) == _T('\n') ) {
\r
2000 if ( *p == _T('\n') )
\r
2003 else if ( *p != _T('\n') ) {
\r
2004 /* Keeps spaces */
\r
2005 TCHAR* p2 = _tcschr( comment_start, _T('/') );
\r
2007 if ( p2 != comment_start ) {
\r
2008 comment_start = p2;
\r
2010 is_new_space = true;
\r
2015 comment_over = (TCHAR*) p;
\r
2019 if ( comment_over != NULL ) {
\r
2020 e= FileT_writePart( in_OutStream, source, comment_start ); IF(e){goto fin;}
\r
2022 if ( is_new_space ) {
\r
2023 _TINT rt= _fputtc( _T(' '), in_OutStream );
\r
2024 IF(rt==_TEOF){e=E_OTHERS; goto fin;}
\r
2025 is_new_space = false;
\r
2028 source = comment_over;
\r
2029 comment_start = NULL;
\r
2030 comment_over = NULL;
\r
2034 e= FileT_writePart( in_OutStream, source, StrT_chr( source, _T('\0') ) ); IF(e){goto fin;}
\r
2043 /***********************************************************************
\r
2044 <<< [Delete_C_LanguageToken] >>>
\r
2045 ************************************************************************/
\r
2046 errnum_t Delete_C_LanguageToken( ListClass* /*<C_LanguageTokenClass*>*/ TokenList, errnum_t e )
\r
2048 return ListClass_finalizeWithVTable( TokenList, true, e );
\r
2053 /***********************************************************************
\r
2054 <<< (C_LanguageTokenClass) >>>
\r
2055 ************************************************************************/
\r
2057 static const FinalizerVTableClass gs_C_LanguageTokenClass_FinalizerVTable = {
\r
2058 offsetof( C_LanguageTokenClass, FinalizerVTable ),
\r
2059 DefaultFunction_Finalize,
\r
2061 static const PrintXML_VTableClass gs_C_LanguageTokenClass_PrintXML_VTable = {
\r
2062 offsetof( C_LanguageTokenClass, PrintXML_VTable ),
\r
2063 C_LanguageTokenClass_printXML,
\r
2065 static const InterfaceToVTableClass gs_C_LanguageTokenClass_InterfaceToVTables[] = {
\r
2066 { &g_FinalizerInterface_ID, &gs_C_LanguageTokenClass_FinalizerVTable },
\r
2067 { &g_PrintXML_Interface_ID, &gs_C_LanguageTokenClass_PrintXML_VTable },
\r
2069 static const ClassID_Class* gs_C_LanguageTokenClass_SuperClassIDs[] = {
\r
2070 &g_ClassID_SuperClass_ID, &g_ParsedRangeClass_ID, &g_SyntaxSubNodeClass_ID,
\r
2071 &g_C_LanguageTokenClass_ID,
\r
2074 /*[g_C_LanguageTokenClass_ID]*/
\r
2075 const ClassID_Class g_C_LanguageTokenClass_ID = {
\r
2076 "C_LanguageTokenClass",
\r
2077 gs_C_LanguageTokenClass_SuperClassIDs,
\r
2078 _countof( gs_C_LanguageTokenClass_SuperClassIDs ),
\r
2079 sizeof( C_LanguageTokenClass ),
\r
2081 gs_C_LanguageTokenClass_InterfaceToVTables,
\r
2082 _countof( gs_C_LanguageTokenClass_InterfaceToVTables ),
\r
2087 /***********************************************************************
\r
2088 <<< [C_LanguageTokenClass_initConst] >>>
\r
2089 ************************************************************************/
\r
2090 void C_LanguageTokenClass_initConst( C_LanguageTokenClass* self )
\r
2092 self->ClassID = &g_C_LanguageTokenClass_ID;
\r
2093 self->FinalizerVTable = &gs_C_LanguageTokenClass_FinalizerVTable;
\r
2094 self->Start = NULL;
\r
2095 self->Over = NULL;
\r
2096 self->PrintXML_VTable = &gs_C_LanguageTokenClass_PrintXML_VTable;
\r
2097 self->Parent = NULL;
\r
2098 ListElementClass_initConst( &self->SubNodeListElement, self );
\r
2099 self->TokenType = gc_TokenOfOther;
\r
2100 ListElementClass_initConst( &self->ListElement, self );
\r
2101 self->ParentBlock = NULL;
\r
2106 /***********************************************************************
\r
2107 <<< [C_LanguageTokenClass_printXML] >>>
\r
2108 ************************************************************************/
\r
2109 errnum_t C_LanguageTokenClass_printXML( C_LanguageTokenClass* self, FILE* OutputStream )
\r
2114 r= _ftprintf_s( OutputStream, _T("<C_LanguageTokenClass") );
\r
2115 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
2118 r= _ftprintf_s( OutputStream, _T(" Address=\"0x%08X\""), self );
\r
2119 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
2122 r= _ftprintf_s( OutputStream, _T(" TokenType=\"%s\""),
\r
2123 C_LanguageTokenEnum_convertToStr( self->TokenType ) );
\r
2124 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
2126 r= _ftprintf_s( OutputStream, _T(" Token=\"") );
\r
2127 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
2128 e= ftcopy_part_r( OutputStream, self->Start, self->Over ); IF(e){goto fin;}
\r
2129 r= _ftprintf_s( OutputStream, _T("\"") );
\r
2130 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
2132 r= _ftprintf_s( OutputStream, _T("/>\n") );
\r
2133 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
2142 /***********************************************************************
\r
2143 <<< [C_LanguageTokenEnum_convertToStr] >>>
\r
2144 ************************************************************************/
\r
2146 static const NameAndNumClass C_LanguageTokenEnum_ConvertTable[] = {
\r
2147 { _T("Other"), gc_TokenOfOther },
\r
2148 { _T("Number"), gc_TokenOfNumber },
\r
2149 { _T("CIdentifier"), gc_TokenOfCIdentifier },
\r
2150 { _T("("), gc_TokenOf_28 },
\r
2151 { _T(")"), gc_TokenOf_29 },
\r
2152 { _T("{"), gc_TokenOf_7B },
\r
2153 { _T("}"), gc_TokenOf_7D },
\r
2154 { _T("["), gc_TokenOf_5B },
\r
2155 { _T("]"), gc_TokenOf_5D },
\r
2156 { _T(":"), gc_TokenOf_3A },
\r
2157 { _T(";"), gc_TokenOf_3B },
\r
2158 { _T("*"), gc_TokenOf_2A },
\r
2159 { _T("\\n"), gc_TokenOf_0A },
\r
2160 { _T("/*"), gc_TokenOf_2A2F },
\r
2161 { _T("*/"), gc_TokenOf_2F2A },
\r
2162 { _T("//"), gc_TokenOf_2F2F },
\r
2165 TCHAR* C_LanguageTokenEnum_convertToStr( C_LanguageTokenEnum Value )
\r
2167 return StrT_convertNumToStr( Value, C_LanguageTokenEnum_ConvertTable,
\r
2168 _countof( C_LanguageTokenEnum_ConvertTable ), _T("Unknown") );
\r
2173 /***********************************************************************
\r
2174 <<< [Parse_PP_Directive] >>>
\r
2175 ************************************************************************/
\r
2177 errnum_t Parse_PP_Directive_Step1( const TCHAR* Text, Set2* DirectivePointerArray );
\r
2178 errnum_t Parse_PP_Directive_ConnectIf( Set2* DirectivePointerArray );
\r
2179 errnum_t Parse_PP_Directive_Parameter( Set2* DirectivePointerArray );
\r
2182 errnum_t Parse_PP_Directive( const TCHAR* Text,
\r
2183 Set2* /*<PP_DirectiveClass*>*/ DirectivePointerArray )
\r
2187 e= Parse_PP_Directive_Step1( Text, DirectivePointerArray ); IF(e){goto fin;}
\r
2188 e= Parse_PP_Directive_ConnectIf( DirectivePointerArray ); IF(e){goto fin;}
\r
2189 e= Parse_PP_Directive_Parameter( DirectivePointerArray ); IF(e){goto fin;}
\r
2197 /*[Parse_PP_Directive_Step1]*/
\r
2198 errnum_t Parse_PP_Directive_Step1( const TCHAR* Text, Set2* DirectivePointerArray )
\r
2203 PP_DirectiveClass* directive = NULL;
\r
2204 PP_DirectiveClass directive_0;
\r
2205 PP_DirectiveClass** directive_pp;
\r
2206 ClassID_Class* class_ID;
\r
2209 PP_DirectiveClass_initConst( &directive_0 );
\r
2213 /* Set "DirectiveName_Start" */
\r
2214 p = _tcschr( pos, _T('#') );
\r
2217 p = StrT_skip( p + 1, _T(" \t") );
\r
2218 ASSERT_R( *p != _T('\0'), e=E_OTHERS; goto fin );
\r
2219 directive_0.DirectiveName_Start = p;
\r
2222 /* Set "DirectiveName_Over" */
\r
2223 directive_0.DirectiveName_Over =
\r
2224 StrT_searchOverOfCIdentifier( directive_0.DirectiveName_Start );
\r
2228 p = StrT_rstr( Text, directive_0.DirectiveName_Start, _T("\n"), NULL );
\r
2229 if ( p == NULL ) { p = Text; }
\r
2231 directive_0.Start = p;
\r
2235 p = directive_0.DirectiveName_Over;
\r
2237 const TCHAR* p2 = _tcschr( p, _T('\n') );
\r
2238 if ( p2 == NULL ) {
\r
2239 p = _tcschr( p, _T('\0') );
\r
2241 } else if ( *( p2 - 1 ) == _T('\\') ) {
\r
2249 directive_0.Over = p;
\r
2252 /* Set "directive" */
\r
2254 static NameOnlyClass table[] = {
\r
2255 { _T("define"), (void*) &g_PP_SharpDefineClass_ID },
\r
2256 { _T("include"),(void*) &g_PP_SharpIncludeClass_ID },
\r
2257 { _T("if"), (void*) &g_PP_SharpIfClass_ID },
\r
2258 { _T("else"), (void*) &g_PP_SharpElseClass_ID },
\r
2259 { _T("endif"), (void*) &g_PP_SharpEndifClass_ID },
\r
2260 { _T("ifdef"), (void*) &g_PP_SharpIfdefClass_ID },
\r
2261 { _T("ifndef"), (void*) &g_PP_SharpIfndefClass_ID },
\r
2264 class_ID = StrT_convPartStrToPointer(
\r
2265 directive_0.DirectiveName_Start,
\r
2266 directive_0.DirectiveName_Over,
\r
2267 table, sizeof(table), (void*) &g_PP_DirectiveClass_ID );
\r
2270 e= ClassID_Class_createObject( class_ID, &directive, NULL ); IF(e){goto fin;}
\r
2272 directive->DirectiveName_Start = directive_0.DirectiveName_Start;
\r
2273 directive->DirectiveName_Over = directive_0.DirectiveName_Over;
\r
2274 directive->Start = directive_0.Start;
\r
2275 directive->Over = directive_0.Over;
\r
2278 /* Add to "DirectivePointerArray" (1) */
\r
2279 e= Set2_alloc( DirectivePointerArray, &directive_pp, PP_DirectiveClass* );
\r
2283 /* Add to "DirectivePointerArray" (2) */
\r
2284 *directive_pp = directive;
\r
2289 pos = directive_0.Over;
\r
2290 PP_DirectiveClass_initConst( &directive_0 );
\r
2295 if ( directive != NULL ) { e= HeapMemory_free( &directive, e ); }
\r
2300 /*[Parse_PP_Directive_ConnectIf]*/
\r
2301 errnum_t Parse_PP_Directive_ConnectIf( Set2* DirectivePointerArray )
\r
2304 PP_DirectiveClass** pp;
\r
2305 PP_DirectiveClass** pp_over;
\r
2306 PP_DirectiveClass* directive;
\r
2307 PP_SharpIfClass** pp_sh_if; /* pp is pointer of pointer, sh = sharp */
\r
2308 PP_SharpElseClass** pp_sh_else;
\r
2311 PP_SharpIfClass* sh_if; /* sh = sharp */
\r
2312 PP_SharpElseClass* sh_else; /* sh = sharp */
\r
2313 PP_SharpEndifClass* sh_endif; /* sh = sharp */
\r
2314 PP_DirectiveClass* sh_if_or_else; /* sh = sharp */
\r
2317 Set2_initConst( &if_stack );
\r
2318 Set2_initConst( &else_stack );
\r
2319 e= Set2_init( &if_stack, 0x10 ); IF(e){goto fin;}
\r
2320 e= Set2_init( &else_stack, 0x10 ); IF(e){goto fin;}
\r
2324 sh_if_or_else = NULL;
\r
2326 for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {
\r
2329 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfClass_ID ) ) {
\r
2331 /* Start of nest */
\r
2332 if ( sh_if_or_else != NULL ) {
\r
2333 e= Set2_alloc( &if_stack, &pp_sh_if, PP_SharpIfClass* );
\r
2335 *pp_sh_if = sh_if;
\r
2337 e= Set2_alloc( &else_stack, &pp_sh_else, PP_SharpElseClass* );
\r
2339 *pp_sh_else = sh_else;
\r
2343 sh_if = (PP_SharpIfClass*) directive;
\r
2344 sh_if_or_else = directive;
\r
2346 else if ( directive->ClassID == &g_PP_SharpElseClass_ID ) {
\r
2347 sh_else = (PP_SharpElseClass*) directive;
\r
2349 IF ( sh_if == NULL ) {
\r
2350 Error4_printf( _T("<ERROR msg=\"Not found #if\"/>") );
\r
2351 e= E_ORIGINAL; goto fin;
\r
2354 /* Link #if and #else */
\r
2355 sh_if->NextDirective = directive;
\r
2356 sh_else->StartDirective = sh_if;
\r
2357 sh_if_or_else = directive;
\r
2359 else if ( directive->ClassID == &g_PP_SharpEndifClass_ID ) {
\r
2360 sh_endif = (PP_SharpEndifClass*) directive;
\r
2362 IF ( sh_if_or_else == NULL ) {
\r
2363 Error4_printf( _T("<ERROR msg=\"Not found #if\"/>") );
\r
2364 e= E_ORIGINAL; goto fin;
\r
2367 /* Link ( #if or #else ) and #endif */
\r
2368 sh_if->EndDirective = sh_endif;
\r
2369 if ( sh_else == NULL )
\r
2370 { sh_if->NextDirective = directive; }
\r
2372 { sh_else->EndDirective = sh_endif; }
\r
2373 sh_endif->StartDirective = sh_if;
\r
2374 sh_endif->PreviousDirective = sh_if_or_else;
\r
2379 sh_if_or_else = NULL;
\r
2382 if ( if_stack.Next > if_stack.First ) {
\r
2383 e= Set2_pop( &if_stack, &pp_sh_if, PP_SharpIfClass* );
\r
2385 sh_if = *pp_sh_if;
\r
2387 e= Set2_pop( &else_stack, &pp_sh_else, PP_SharpElseClass* );
\r
2389 sh_else = *pp_sh_else;
\r
2391 if ( sh_else == NULL ) {
\r
2392 sh_if_or_else = (PP_DirectiveClass*) sh_if;
\r
2394 sh_if_or_else = (PP_DirectiveClass*) sh_else;
\r
2402 e= Set2_finish( &if_stack, e );
\r
2403 e= Set2_finish( &else_stack, e );
\r
2408 /*[Parse_PP_Directive_Parameter]*/
\r
2409 errnum_t Parse_PP_Directive_Parameter( Set2* DirectivePointerArray )
\r
2413 PP_DirectiveClass** pp;
\r
2414 PP_DirectiveClass** pp_over;
\r
2415 PP_DirectiveClass* directive;
\r
2417 for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {
\r
2420 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpDefineClass_ID ) ) {
\r
2421 PP_SharpDefineClass* sh_define = (PP_SharpDefineClass*) directive;
\r
2423 p = StrT_skip( sh_define->DirectiveName_Over, _T(" \t") );
\r
2424 IF ( p >= sh_define->Over ) { e=E_OTHERS; goto fin; }
\r
2425 sh_define->Symbol_Start = p;
\r
2427 p = StrT_searchOverOfCIdentifier( p );
\r
2428 sh_define->Symbol_Over = p;
\r
2431 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIncludeClass_ID ) ) {
\r
2434 PP_SharpIncludeClass* sh_include = (PP_SharpIncludeClass*) directive;
\r
2436 p = StrT_skip( sh_include->DirectiveName_Over, _T(" \t") );
\r
2437 IF ( p >= sh_include->Over ) { e=E_OTHERS; goto fin; }
\r
2440 sh_include->PathBracket = _T('<');
\r
2441 closers = _T(">");
\r
2445 sh_include->PathBracket = _T('"');
\r
2446 closers = _T("\"");
\r
2450 sh_include->PathBracket = _T('\0');
\r
2451 closers = _T(" \t\n");
\r
2455 sh_include->Path_Start = p + 1;
\r
2457 p = StrT_chrs( p + 1, closers );
\r
2458 IF ( p == NULL ) { e=E_OTHERS; goto fin; }
\r
2459 sh_include->Path_Over = p;
\r
2462 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfdefClass_ID ) ) {
\r
2464 PP_SharpIfdefClass* sh_ifdef; /* sh = sharp */
\r
2466 sh_ifdef = (PP_SharpIfdefClass*) directive;
\r
2468 p = StrT_skip( sh_ifdef->DirectiveName_Over, _T(" \t") );
\r
2469 IF ( p >= sh_ifdef->Over ) { e=E_OTHERS; goto fin; }
\r
2470 sh_ifdef->Symbol_Start = p;
\r
2472 p = StrT_searchOverOfCIdentifier( p );
\r
2473 sh_ifdef->Symbol_Over = p;
\r
2484 /***********************************************************************
\r
2485 <<< [Delete_PP_Directive] >>>
\r
2486 ************************************************************************/
\r
2487 errnum_t Delete_PP_Directive( Set2* DirectivePointerArray, errnum_t e )
\r
2489 PP_DirectiveClass** pp;
\r
2490 PP_DirectiveClass** pp_over;
\r
2491 PP_DirectiveClass* directive;
\r
2492 FinalizerVTableClass* finalizer;
\r
2494 if ( Set2_isInited( DirectivePointerArray ) ) {
\r
2495 for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {
\r
2497 finalizer = ClassID_Class_getVTable( directive->ClassID,
\r
2498 &g_FinalizerInterface_ID );
\r
2499 e= finalizer->Finalize( directive, e );
\r
2500 e= HeapMemory_free( &directive, e );
\r
2503 e= Set2_finish( DirectivePointerArray, e );
\r
2510 /***********************************************************************
\r
2511 <<< [CutPreprocessorDirectives_from_C_LanguageToken] >>>
\r
2512 ************************************************************************/
\r
2513 errnum_t CutPreprocessorDirectives_from_C_LanguageToken(
\r
2514 ListClass* /*<C_LanguageTokenClass*>*/ TokenList,
\r
2515 Set2* /*<PP_DirectiveClass*>*/ Directives )
\r
2518 C_LanguageTokenClass* token;
\r
2519 ListIteratorClass iterator;
\r
2520 PP_DirectiveClass** pp_directive = Directives->First;
\r
2521 PP_DirectiveClass** pp_directive_over = Directives->Next;
\r
2522 PP_DirectiveClass* directive = *pp_directive;
\r
2525 if ( pp_directive == pp_directive_over )
\r
2526 { e=0; goto fin; }
\r
2528 e= ListClass_getListIterator( TokenList, &iterator ); IF(e){goto fin;}
\r
2530 token = (C_LanguageTokenClass*) ListIteratorClass_getNext( &iterator );
\r
2531 if ( token == NULL ) { break; }
\r
2532 ASSERT_D( token->ClassID == &g_C_LanguageTokenClass_ID, e=E_OTHERS; goto fin );
\r
2534 if ( token->Start >= directive->Start ) {
\r
2535 if ( token->Over <= directive->Over ) {
\r
2536 e= ListIteratorClass_remove( &iterator );
\r
2537 e= HeapMemory_free( &token, 0 ); IF(e){goto fin;}
\r
2540 while ( token->Start > directive->Over ) {
\r
2541 pp_directive += 1;
\r
2542 if ( pp_directive >= pp_directive_over )
\r
2544 directive = *pp_directive;
\r
2557 /***********************************************************************
\r
2558 <<< (PP_DirectiveClass) >>>
\r
2559 ************************************************************************/
\r
2561 /*[PP_DirectiveClass_initConst]*/
\r
2562 void PP_DirectiveClass_initConst( PP_DirectiveClass* self )
\r
2564 self->ClassID = &g_PP_DirectiveClass_ID;
\r
2565 self->Start = NULL;
\r
2566 self->Over = NULL;
\r
2567 self->DirectiveName_Start = NULL;
\r
2568 self->DirectiveName_Over = NULL;
\r
2571 /*[g_PP_DirectiveClass_ID]*/
\r
2572 static const ClassID_Class* gs_PP_DirectiveClass_SuperClassIDs[] = {
\r
2573 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID
\r
2575 static const FinalizerVTableClass gs_PP_DirectiveClass_FinalizerVTable = {
\r
2576 offsetof( PP_DirectiveClass, FinalizerVTable ),
\r
2577 DefaultFunction_Finalize
\r
2579 static const InterfaceToVTableClass gs_PP_DirectiveClass_InterfaceToVTables[] = {
\r
2580 { &g_FinalizerInterface_ID, &gs_PP_DirectiveClass_FinalizerVTable }
\r
2582 const ClassID_Class g_PP_DirectiveClass_ID = {
\r
2583 "PP_DirectiveClass",
\r
2584 gs_PP_DirectiveClass_SuperClassIDs,
\r
2585 _countof( gs_PP_DirectiveClass_SuperClassIDs ),
\r
2586 sizeof( PP_DirectiveClass ),
\r
2588 gs_PP_DirectiveClass_InterfaceToVTables,
\r
2589 _countof( gs_PP_DirectiveClass_InterfaceToVTables )
\r
2593 /*[g_PP_SharpDefineClass_ID]*/
\r
2594 static const ClassID_Class* gs_PP_SharpDefineClass_SuperClassIDs[] = {
\r
2595 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,
\r
2596 &g_PP_DirectiveClass_ID
\r
2598 static const FinalizerVTableClass gs_PP_SharpDefineClass_FinalizerVTable = {
\r
2599 offsetof( PP_SharpDefineClass, FinalizerVTable ),
\r
2600 DefaultFunction_Finalize
\r
2602 static const InterfaceToVTableClass gs_PP_SharpDefineClass_InterfaceToVTables[] = {
\r
2603 { &g_FinalizerInterface_ID, &gs_PP_SharpDefineClass_FinalizerVTable }
\r
2605 const ClassID_Class g_PP_SharpDefineClass_ID = {
\r
2606 "PP_SharpDefineClass",
\r
2607 gs_PP_SharpDefineClass_SuperClassIDs,
\r
2608 _countof( gs_PP_SharpDefineClass_SuperClassIDs ),
\r
2609 sizeof( PP_SharpDefineClass ),
\r
2611 gs_PP_SharpDefineClass_InterfaceToVTables,
\r
2612 _countof( gs_PP_SharpDefineClass_InterfaceToVTables )
\r
2616 /*[g_PP_SharpIncludeClass_ID]*/
\r
2617 static const ClassID_Class* gs_PP_SharpIncludeClass_SuperClassIDs[] = {
\r
2618 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,
\r
2619 &g_PP_DirectiveClass_ID
\r
2621 static const FinalizerVTableClass gs_PP_SharpIncludeClass_FinalizerVTable = {
\r
2622 offsetof( PP_SharpIncludeClass, FinalizerVTable ),
\r
2623 DefaultFunction_Finalize
\r
2625 static const InterfaceToVTableClass gs_PP_SharpIncludeClass_InterfaceToVTables[] = {
\r
2626 { &g_FinalizerInterface_ID, &gs_PP_SharpIncludeClass_FinalizerVTable }
\r
2628 const ClassID_Class g_PP_SharpIncludeClass_ID = {
\r
2629 "PP_SharpIncludeClass",
\r
2630 gs_PP_SharpIncludeClass_SuperClassIDs,
\r
2631 _countof( gs_PP_SharpIncludeClass_SuperClassIDs ),
\r
2632 sizeof( PP_SharpIncludeClass ),
\r
2634 gs_PP_SharpIncludeClass_InterfaceToVTables,
\r
2635 _countof( gs_PP_SharpIncludeClass_InterfaceToVTables )
\r
2639 /*[g_PP_SharpIfClass_ID]*/
\r
2640 static const ClassID_Class* gs_PP_SharpIfClass_SuperClassIDs[] = {
\r
2641 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,
\r
2642 &g_PP_DirectiveClass_ID
\r
2644 static const FinalizerVTableClass gs_PP_SharpIfClass_FinalizerVTable = {
\r
2645 offsetof( PP_SharpIfClass, FinalizerVTable ),
\r
2646 DefaultFunction_Finalize
\r
2648 static const InterfaceToVTableClass gs_PP_SharpIfClass_InterfaceToVTables[] = {
\r
2649 { &g_FinalizerInterface_ID, &gs_PP_SharpIfClass_FinalizerVTable }
\r
2651 const ClassID_Class g_PP_SharpIfClass_ID = {
\r
2652 "PP_SharpIfClass",
\r
2653 gs_PP_SharpIfClass_SuperClassIDs,
\r
2654 _countof( gs_PP_SharpIfClass_SuperClassIDs ),
\r
2655 sizeof( PP_SharpIfClass ),
\r
2657 gs_PP_SharpIfClass_InterfaceToVTables,
\r
2658 _countof( gs_PP_SharpIfClass_InterfaceToVTables )
\r
2662 /*[g_PP_SharpElseClass_ID]*/
\r
2663 static const ClassID_Class* gs_PP_SharpElseClass_SuperClassIDs[] = {
\r
2664 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,
\r
2665 &g_PP_DirectiveClass_ID
\r
2667 static const FinalizerVTableClass gs_PP_SharpElseClass_FinalizerVTable = {
\r
2668 offsetof( PP_SharpElseClass, FinalizerVTable ),
\r
2669 DefaultFunction_Finalize
\r
2671 static const InterfaceToVTableClass gs_PP_SharpElseClass_InterfaceToVTables[] = {
\r
2672 { &g_FinalizerInterface_ID, &gs_PP_SharpElseClass_FinalizerVTable }
\r
2674 const ClassID_Class g_PP_SharpElseClass_ID = {
\r
2675 "PP_SharpElseClass",
\r
2676 gs_PP_SharpElseClass_SuperClassIDs,
\r
2677 _countof( gs_PP_SharpElseClass_SuperClassIDs ),
\r
2678 sizeof( PP_SharpElseClass ),
\r
2680 gs_PP_SharpElseClass_InterfaceToVTables,
\r
2681 _countof( gs_PP_SharpElseClass_InterfaceToVTables )
\r
2685 /*[g_PP_SharpEndifClass_ID]*/
\r
2686 static const ClassID_Class* gs_PP_SharpEndifClass_SuperClassIDs[] = {
\r
2687 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,
\r
2688 &g_PP_DirectiveClass_ID
\r
2690 static const FinalizerVTableClass gs_PP_SharpEndifClass_FinalizerVTable = {
\r
2691 offsetof( PP_SharpEndifClass, FinalizerVTable ),
\r
2692 DefaultFunction_Finalize
\r
2694 static const InterfaceToVTableClass gs_PP_SharpEndifClass_InterfaceToVTables[] = {
\r
2695 { &g_FinalizerInterface_ID, &gs_PP_SharpEndifClass_FinalizerVTable }
\r
2697 const ClassID_Class g_PP_SharpEndifClass_ID = {
\r
2698 "PP_SharpEndifClass",
\r
2699 gs_PP_SharpEndifClass_SuperClassIDs,
\r
2700 _countof( gs_PP_SharpEndifClass_SuperClassIDs ),
\r
2701 sizeof( PP_SharpEndifClass ),
\r
2703 gs_PP_SharpEndifClass_InterfaceToVTables,
\r
2704 _countof( gs_PP_SharpEndifClass_InterfaceToVTables )
\r
2708 /*[g_PP_SharpIfdefClass_ID]*/
\r
2709 static const ClassID_Class* gs_PP_SharpIfdefClass_SuperClassIDs[] = {
\r
2710 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,
\r
2711 &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID
\r
2713 static const FinalizerVTableClass gs_PP_SharpIfdefClass_FinalizerVTable = {
\r
2714 offsetof( PP_SharpIfdefClass, FinalizerVTable ),
\r
2715 DefaultFunction_Finalize
\r
2717 static const InterfaceToVTableClass gs_PP_SharpIfdefClass_InterfaceToVTables[] = {
\r
2718 { &g_FinalizerInterface_ID, &gs_PP_SharpIfdefClass_FinalizerVTable }
\r
2720 const ClassID_Class g_PP_SharpIfdefClass_ID = {
\r
2721 "PP_SharpIfdefClass",
\r
2722 gs_PP_SharpIfdefClass_SuperClassIDs,
\r
2723 _countof( gs_PP_SharpIfdefClass_SuperClassIDs ),
\r
2724 sizeof( PP_SharpIfdefClass ),
\r
2726 gs_PP_SharpIfdefClass_InterfaceToVTables,
\r
2727 _countof( gs_PP_SharpIfdefClass_InterfaceToVTables )
\r
2731 /*[g_PP_SharpIfndefClass_ID]*/
\r
2732 static const ClassID_Class* gs_PP_SharpIfndefClass_SuperClassIDs[] = {
\r
2733 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,
\r
2734 &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID, &g_PP_SharpIfdefClass_ID
\r
2736 static const FinalizerVTableClass gs_PP_SharpIfndefClass_FinalizerVTable = {
\r
2737 offsetof( PP_SharpIfndefClass, FinalizerVTable ),
\r
2738 DefaultFunction_Finalize
\r
2740 static const InterfaceToVTableClass gs_PP_SharpIfndefClass_InterfaceToVTables[] = {
\r
2741 { &g_FinalizerInterface_ID, &gs_PP_SharpIfndefClass_FinalizerVTable }
\r
2744 const ClassID_Class g_PP_SharpIfndefClass_ID = {
\r
2745 "PP_SharpIfndefClass",
\r
2746 gs_PP_SharpIfndefClass_SuperClassIDs,
\r
2747 _countof( gs_PP_SharpIfndefClass_SuperClassIDs ),
\r
2748 sizeof( PP_SharpIfndefClass ),
\r
2750 gs_PP_SharpIfndefClass_InterfaceToVTables,
\r
2751 _countof( gs_PP_SharpIfndefClass_InterfaceToVTables )
\r
2756 /***********************************************************************
\r
2757 <<< (SyntaxSubNodeClass) >>>
\r
2758 ************************************************************************/
\r
2760 /*[g_SyntaxSubNodeClass_ID]*/
\r
2761 const ClassID_Class g_SyntaxSubNodeClass_ID = {
\r
2762 "SyntaxSubNodeClass",
\r
2765 sizeof( SyntaxSubNodeClass ),
\r
2773 /***********************************************************************
\r
2774 <<< [Delete_SyntaxNodeList] >>>
\r
2775 ************************************************************************/
\r
2776 errnum_t Delete_SyntaxNodeList( ListClass* /*<SyntaxNodeClass*>*/ NodeList, errnum_t e )
\r
2778 return ListClass_finalizeWithVTable( NodeList, true, e );
\r
2783 /***********************************************************************
\r
2784 <<< (SyntaxNodeClass) >>>
\r
2785 ************************************************************************/
\r
2787 static const FinalizerVTableClass gs_SyntaxNodeClass_FinalizerVTable = {
\r
2788 offsetof( SyntaxNodeClass, FinalizerVTable ),
\r
2789 DefaultFunction_Finalize,
\r
2791 static const PrintXML_VTableClass gs_SyntaxNodeClass_PrintXML_VTable = {
\r
2792 offsetof( SyntaxNodeClass, PrintXML_VTable ),
\r
2793 SyntaxNodeClass_printXML,
\r
2795 static const InterfaceToVTableClass gs_SyntaxNodeClass_InterfaceToVTables[] = {
\r
2796 { &g_FinalizerInterface_ID, &gs_SyntaxNodeClass_FinalizerVTable },
\r
2797 { &g_PrintXML_Interface_ID, &gs_SyntaxNodeClass_PrintXML_VTable },
\r
2799 static const ClassID_Class* gs_SyntaxNodeClass_SuperClassIDs[] = {
\r
2800 &g_ClassID_SuperClass_ID, &g_ParsedRangeClass_ID, &g_SyntaxSubNodeClass_ID,
\r
2801 &g_SyntaxNodeClass_ID,
\r
2804 /*[g_SyntaxNodeClass_ID]*/
\r
2805 const ClassID_Class g_SyntaxNodeClass_ID = {
\r
2806 "SyntaxNodeClass",
\r
2807 gs_SyntaxNodeClass_SuperClassIDs,
\r
2808 _countof( gs_SyntaxNodeClass_SuperClassIDs ),
\r
2809 sizeof( SyntaxNodeClass ),
\r
2811 gs_SyntaxNodeClass_InterfaceToVTables,
\r
2812 _countof( gs_SyntaxNodeClass_InterfaceToVTables ),
\r
2817 /***********************************************************************
\r
2818 <<< [SyntaxNodeClass_initConst] >>>
\r
2819 ************************************************************************/
\r
2820 void SyntaxNodeClass_initConst( SyntaxNodeClass* self )
\r
2822 self->ClassID = &g_SyntaxNodeClass_ID;
\r
2823 self->FinalizerVTable = &gs_SyntaxNodeClass_FinalizerVTable;
\r
2824 self->Start = NULL;
\r
2825 self->Over = NULL;
\r
2826 self->PrintXML_VTable = &gs_SyntaxNodeClass_PrintXML_VTable;
\r
2827 self->Parent = NULL;
\r
2828 ListElementClass_initConst( &self->SubNodeListElement, self );
\r
2829 ListClass_initConst( &self->SubNodeList );
\r
2830 ListElementClass_initConst( &self->ListElement, self );
\r
2835 /***********************************************************************
\r
2836 <<< [SyntaxNodeClass_printXML] >>>
\r
2837 ************************************************************************/
\r
2838 errnum_t SyntaxNodeClass_printXML( SyntaxNodeClass* self, FILE* OutputStream )
\r
2843 r= _ftprintf_s( OutputStream, _T("<SyntaxNodeClass") );
\r
2844 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
2846 r= _ftprintf_s( OutputStream, _T(" Address=\"0x%08X\""), self );
\r
2847 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
2849 r= _ftprintf_s( OutputStream, _T("/>\n") );
\r
2850 IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }
\r
2859 /***********************************************************************
\r
2860 <<< [SyntaxNodeClass_addSubNode] >>>
\r
2861 ************************************************************************/
\r
2862 errnum_t SyntaxNodeClass_addSubNode( SyntaxNodeClass* self, SyntaxSubNodeClass* SubNode )
\r
2866 ASSERT_D( ClassID_Class_isSuperClass( self->ClassID, &g_SyntaxNodeClass_ID ), e=E_OTHERS; goto fin );
\r
2867 ASSERT_D( ClassID_Class_isSuperClass( SubNode->ClassID, &g_SyntaxSubNodeClass_ID ), e=E_OTHERS; goto fin );
\r
2868 ASSERT_R( SubNode->Parent == NULL, e=E_OTHERS; goto fin );
\r
2870 e= ListClass_addLast( &self->SubNodeList, &SubNode->SubNodeListElement ); IF(e){goto fin;}
\r
2871 SubNode->Parent = self;
\r
2880 /***********************************************************************
\r
2881 <<< [LineNumberIndexClass_compare_sub] >>>
\r
2882 ************************************************************************/
\r
2883 int LineNumberIndexClass_compare_sub( const void* ppLeft, const void* ppRight, const void* Param,
\r
2886 UNREFERENCED_VARIABLE( Param );
\r
2887 *out_Result = (const uint8_t*) *(TCHAR**) ppLeft - (const uint8_t*) *(TCHAR**) ppRight;
\r
2893 /***********************************************************************
\r
2894 <<< (LineNumberIndexClass) >>>
\r
2895 ************************************************************************/
\r
2897 /*[LineNumberIndexClass_initConst]*/
\r
2898 void LineNumberIndexClass_initConst( LineNumberIndexClass* self )
\r
2900 Set2_initConst( &self->LeftsOfLine );
\r
2904 /*[LineNumberIndexClass_finalize]*/
\r
2905 errnum_t LineNumberIndexClass_finalize( LineNumberIndexClass* self, errnum_t e )
\r
2907 return Set2_finish( &self->LeftsOfLine, e );
\r
2911 /*[LineNumberIndexClass_initialize]*/
\r
2912 errnum_t LineNumberIndexClass_initialize( LineNumberIndexClass* self, const TCHAR* Text )
\r
2916 const TCHAR* line_feed;
\r
2917 const TCHAR** pp_left;
\r
2919 e= Set2_init( &self->LeftsOfLine, 1000 * sizeof(TCHAR*) ); IF(e){goto fin;}
\r
2923 e= Set2_alloc( &self->LeftsOfLine, &pp_left, const TCHAR* ); IF(e){goto fin;}
\r
2926 line_feed = _tcschr( p, _T('\n') );
\r
2927 if ( line_feed == NULL )
\r
2930 p = line_feed + 1;
\r
2934 p = _tcschr( p, _T('\0') );
\r
2935 e= Set2_alloc( &self->LeftsOfLine, &pp_left, const TCHAR* ); IF(e){goto fin;}
\r
2938 if ( *p != _T('\0') ) {
\r
2939 p = _tcschr( p, _T('\0') );
\r
2940 e= Set2_alloc( &self->LeftsOfLine, &pp_left, const TCHAR* ); IF(e){goto fin;}
\r
2951 /*[LineNumberIndexClass_searchLineNumber]*/
\r
2952 errnum_t LineNumberIndexClass_searchLineNumber( LineNumberIndexClass* self, const TCHAR* Position,
\r
2953 int* out_LineNumber )
\r
2959 e= PArray_doBinarySearch( self->LeftsOfLine.First,
\r
2960 (uint8_t*) self->LeftsOfLine.Next - (uint8_t*) self->LeftsOfLine.First,
\r
2961 Position, LineNumberIndexClass_compare_sub, NULL,
\r
2962 &found_index, &result );
\r
2965 *out_LineNumber = found_index + 1;
\r
2973 /*[LineNumberIndexClass_getCountOfLines]*/
\r
2974 int LineNumberIndexClass_getCountOfLines( LineNumberIndexClass* self )
\r
2976 return Set2_getCount( &self->LeftsOfLine, const TCHAR* ) - 1;
\r
2981 /***********************************************************************
\r
2982 <<< (ParsedRangeClass) >>>
\r
2983 ************************************************************************/
\r
2985 /*[ParsedRangeClass_initConst]*/
\r
2986 void ParsedRangeClass_initConst( ParsedRangeClass* self )
\r
2988 self->ClassID = &g_ParsedRangeClass_ID;
\r
2989 self->FinalizerVTable = NULL;
\r
2990 self->StaticAddress = NULL;
\r
2991 self->Start = NULL;
\r
2992 self->Over = NULL;
\r
2996 /*[g_ParsedRangeClass_ID]*/
\r
2997 static const ClassID_Class* gs_ParsedRangeClass_SuperClassIDs[] = {
\r
2998 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID
\r
3000 const ClassID_Class g_ParsedRangeClass_ID = {
\r
3001 "ParsedRangeClass",
\r
3002 gs_ParsedRangeClass_SuperClassIDs,
\r
3003 _countof( gs_ParsedRangeClass_SuperClassIDs ),
\r
3004 sizeof( ParsedRangeClass ),
\r
3010 /***********************************************************************
\r
3011 <<< [ParsedRanges_getCut_by_PP_Directive] >>>
\r
3012 ************************************************************************/
\r
3013 errnum_t ParsedRanges_getCut_by_PP_Directive(
\r
3014 Set2* /*<ParsedRangeClass>*/ CutRanges,
\r
3015 Set2* /*<PP_DirectiveClass*>*/ DirectivePointerArray,
\r
3016 const TCHAR* Symbol, bool IsCutDefine )
\r
3019 PP_DirectiveClass** p;
\r
3020 PP_DirectiveClass** p_over;
\r
3022 for ( Set2_forEach( DirectivePointerArray, &p, &p_over, PP_DirectiveClass* ) ) {
\r
3023 PP_DirectiveClass* directive = *p;
\r
3024 PP_SharpIfClass* sh_if = NULL; /* sh = sharp */
\r
3025 bool is_not_condition = false;
\r
3027 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfdefClass_ID ) ) {
\r
3028 PP_SharpIfdefClass* sh_ifdef = (PP_SharpIfdefClass*) directive; /* sh = sharp */
\r
3030 if ( StrT_cmp_part( sh_ifdef->Symbol_Start, sh_ifdef->Symbol_Over, Symbol ) == 0 ) {
\r
3031 sh_if = (PP_SharpIfClass*) sh_ifdef;
\r
3032 is_not_condition = ( sh_ifdef->ClassID == &g_PP_SharpIfndefClass_ID );
\r
3035 else if ( directive->ClassID == &g_PP_SharpIfClass_ID ) {
\r
3036 const TCHAR* condition_start;
\r
3037 const TCHAR* condition_over;
\r
3039 sh_if = (PP_SharpIfClass*) directive; /* sh = sharp */
\r
3040 condition_start = sh_if->DirectiveName_Over;
\r
3041 condition_over = sh_if->Over;
\r
3043 while ( condition_start < condition_over ) {
\r
3044 if ( _istspace( *condition_start ) ) {
\r
3045 condition_start += 1;
\r
3050 while ( condition_start < condition_over ) {
\r
3051 if ( _istspace( *( condition_over - 1 ) ) ) {
\r
3052 condition_over -= 1;
\r
3057 if ( ! StrT_cmp_part( condition_start, condition_over, Symbol ) == 0 ) {
\r
3062 if ( sh_if != NULL ) {
\r
3063 PP_SharpElseClass* sh_else; /* sh = sharp */
\r
3064 PP_SharpEndifClass* sh_endif; /* sh = sharp */
\r
3065 ParsedRangeClass* cut;
\r
3068 /* Set "sh_else", "sh_endif" */
\r
3069 if ( ClassID_Class_isSuperClass( sh_if->NextDirective->ClassID,
\r
3070 &g_PP_SharpElseClass_ID ) ) {
\r
3071 sh_else = (PP_SharpElseClass*) sh_if->NextDirective;
\r
3072 sh_endif = sh_if->EndDirective;
\r
3075 sh_endif = (PP_SharpEndifClass*) sh_if->NextDirective;
\r
3079 /* Add to "CutRanges" */
\r
3080 e= Set2_alloc( CutRanges, &cut, ParsedRangeClass ); IF(e){goto fin;}
\r
3081 cut->Start = sh_if->Start;
\r
3082 if ( is_not_condition == ! IsCutDefine ) {
\r
3083 if ( sh_else != NULL ) {
\r
3084 cut->Over = sh_else->Over;
\r
3086 e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );
\r
3088 cut->Start = sh_endif->Start;
\r
3090 cut->Over = sh_endif->Over;
\r
3093 cut->Over = sh_if->Over;
\r
3095 e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );
\r
3097 if ( sh_else != NULL ) {
\r
3098 cut->Start = sh_else->Start;
\r
3100 cut->Start = sh_endif->Start;
\r
3102 cut->Over = sh_endif->Over;
\r
3114 /***********************************************************************
\r
3115 <<< [ParsedRangeClass_onInitializedForDebug] >>>
\r
3116 ************************************************************************/
\r
3117 #if ! defined( NDEBUG )
\r
3118 void ParsedRangeClass_onInitializedForDebug( ParsedRangeClass* self )
\r
3120 /* These code can be modified for Debug. */
\r
3121 #if 0 // IS_USED_DEBUG_CHECK_CLASS
\r
3123 ptrdiff_t break_diff = 0x1FA6A;
\r
3126 text = GET_D( 1, TCHAR* );
\r
3127 PointerType_plus( &text, break_diff );
\r
3128 if ( text == self->Start ) {
\r
3129 if ( self->ClassID == &g_ParsedRangeClass_ID ) {
\r
3135 UNREFERENCED_VARIABLE( self );
\r
3142 /***********************************************************************
\r
3143 <<< [ParsedRanges_compareByStart] >>>
\r
3144 ************************************************************************/
\r
3145 int ParsedRanges_compareByStart( const void* _a1, const void* _a2 )
\r
3147 ParsedRangeClass* a1 = (ParsedRangeClass*) _a1;
\r
3148 ParsedRangeClass* a2 = (ParsedRangeClass*) _a2;
\r
3150 return a1->Start - a2->Start;
\r
3155 /***********************************************************************
\r
3156 <<< [ParsedRanges_write_by_Cut] >>>
\r
3157 ************************************************************************/
\r
3158 errnum_t ParsedRanges_write_by_Cut(
\r
3159 Set2* /*<ParsedRangeClass>*/ CutRanges,
\r
3160 const TCHAR* Text, FILE* OutFile )
\r
3163 const TCHAR* position;
\r
3164 ParsedRangeClass* p;
\r
3165 ParsedRangeClass* p_over;
\r
3167 qsort( CutRanges->First, Set2_getCount( CutRanges, ParsedRangeClass ),
\r
3168 sizeof(ParsedRangeClass), ParsedRanges_compareByStart );
\r
3171 for ( Set2_forEach( CutRanges, &p, &p_over, ParsedRangeClass ) ) {
\r
3172 const TCHAR* cut_start_position;
\r
3173 const TCHAR* cut_over_position;
\r
3175 cut_start_position = p->Start;
\r
3176 if ( position < cut_start_position ) {
\r
3177 e= FileT_writePart( OutFile, (TCHAR*)position, (TCHAR*)cut_start_position );
\r
3181 cut_over_position = p->Over;
\r
3182 if ( position < cut_over_position ) {
\r
3183 position = cut_over_position;
\r
3186 _fputts( position, OutFile ); IF(ferror(OutFile)){e=E_ERRNO; goto fin;}
\r
3195 /*=================================================================*/
\r
3196 /* <<< [Locale/Locale.c] >>> */
\r
3197 /*=================================================================*/
\r
3199 /***********************************************************************
\r
3200 <<< [g_LocaleSymbol] >>>
\r
3201 ************************************************************************/
\r
3202 char* g_LocaleSymbol = "";
\r
3206 /***********************************************************************
\r
3207 <<< [Locale_init] >>>
\r
3208 ************************************************************************/
\r
3211 g_LocaleSymbol = ".OCP";
\r
3212 setlocale( LC_ALL, ".OCP" );
\r
3218 /***********************************************************************
\r
3219 <<< [Locale_isInited] >>>
\r
3220 ************************************************************************/
\r
3221 int Locale_isInited()
\r
3223 return ( g_LocaleSymbol[0] != '\0' );
\r
3224 //
\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
3229 /*=================================================================*/
\r
3230 /* <<< [IniFile2/IniFile2.c] >>> */
\r
3231 /*=================================================================*/
\r
3233 /***********************************************************************
\r
3234 <<< [IniStr_isLeft] >>>
\r
3235 ************************************************************************/
\r
3236 bool IniStr_isLeft( const TCHAR* line, const TCHAR* symbol )
\r
3239 size_t symbol_len = _tcslen( symbol );
\r
3241 /* Skip spaces at the top of line */
\r
3242 for ( p = line; *p == _T(' ') || *p == _T('\t'); p++ );
\r
3244 /* Compare symbol */
\r
3245 if ( _tcsnicmp( p, symbol, symbol_len ) != 0 ) return false;
\r
3247 switch ( *(p + symbol_len) ) {
\r
3248 case _T(' '): case _T('\t'): case _T('='): return true;
\r
3249 default: return false;
\r
3256 /***********************************************************************
\r
3257 <<< [IniStr_refRight] >>>
\r
3258 ************************************************************************/
\r
3259 TCHAR* IniStr_refRight( const TCHAR* line, bool bTrimRight )
\r
3263 for ( p = line; *p != _T('\0') && *p != _T('='); p++ );
\r
3264 if ( *p == _T('=') ) {
\r
3266 //=== Skip spaces at the right of equal. Trim the left of value
\r
3267 for ( p++ ; *p == _T(' ') || *p == _T('\t'); p++ );
\r
3269 //=== Trim the right of value
\r
3270 if ( bTrimRight ) {
\r
3274 t = StrT_chr( p, _T('\0') );
\r
3276 for ( t--; ; t-- ) {
\r
3278 { p = StrT_chr( p, _T('\0') ); break; }
\r
3281 if ( c != ' ' && c != '\t' && c != '\n' && c != '\r' )
\r
3282 { *(TCHAR*)(t+1) = _T('\0'); break; }
\r
3287 return (TCHAR*) p;
\r
3292 /*=================================================================*/
\r
3293 /* <<< [FileT/FileT.c] >>> */
\r
3294 /*=================================================================*/
\r
3296 /***********************************************************************
\r
3297 <<< [FileT_isExist] >>>
\r
3298 ************************************************************************/
\r
3299 bool FileT_isExist( const TCHAR* path )
\r
3301 #if ! FileT_isExistWildcard
\r
3305 if ( path[0] == _T('\0') ) return false;
\r
3306 r = GetFileAttributes( path );
\r
3307 return r != (DWORD)-1;
\r
3312 WIN32_FIND_DATA data;
\r
3314 find = FindFirstFileEx( path, FindExInfoStandard, &data,
\r
3315 FindExSearchNameMatch, NULL, 0 );
\r
3317 if ( find == INVALID_HANDLE_VALUE ) {
\r
3321 FindClose( find );
\r
3330 /***********************************************************************
\r
3331 <<< [FileT_isFile] >>>
\r
3332 ************************************************************************/
\r
3333 bool FileT_isFile( const TCHAR* path )
\r
3335 DWORD r = GetFileAttributes( path );
\r
3336 return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == 0;
\r
3337 // 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
3342 /***********************************************************************
\r
3343 <<< [FileT_isDir] >>>
\r
3344 ************************************************************************/
\r
3345 bool FileT_isDir( const TCHAR* path )
\r
3347 DWORD r = GetFileAttributes( path );
\r
3348 return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == FILE_ATTRIBUTE_DIRECTORY;
\r
3349 // 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
3354 /***********************************************************************
\r
3355 <<< [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
3356 ************************************************************************/
\r
3358 /*--- inherit from FileT_CallByNestFindData */
\r
3359 void* CallerArgument;
\r
3360 TCHAR* FullPath; // abstruct path
\r
3363 DWORD FileAttributes;
\r
3367 FuncType CallbackFromNestFind;
\r
3368 TCHAR FullPathMem[4096];
\r
3369 } FileT_CallByNestFindDataIn;
\r
3371 int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m );
\r
3374 int FileT_callByNestFind( const TCHAR* Path, BitField Flags, void* Argument, FuncType Callback )
\r
3377 FileT_CallByNestFindDataIn data;
\r
3382 e= StrT_cpy( data.FullPathMem, sizeof(data.FullPathMem), Path ); IF(e)goto fin;
\r
3385 /* FullPathMem
\82Ì
\8dÅ
\8cã
\82É \
\82ª
\96³
\82¢
\82È
\82ç
\92Ç
\89Á
\82·
\82é */
\r
3386 p = StrT_chr( data.FullPathMem, _T('\0') );
\r
3388 if ( *p != _T('\\') ) {
\r
3390 IF( p >= data.FullPathMem + (sizeof(data.FullPathMem) / sizeof(TCHAR)) - 1 )goto err_fa;
\r
3395 /* data
\82ð
\8f\89\8aú
\89»
\82·
\82é */
\r
3396 data.CallerArgument = Argument;
\r
3397 data.FullPath = data.FullPathMem;
\r
3398 data.StepPath = p + 1;
\r
3399 data.FileName = p + 1;
\r
3400 data.Flags = Flags;
\r
3401 data.CallbackFromNestFind = Callback;
\r
3404 /*
\8dÄ
\8bN
\8cÄ
\82Ñ
\8fo
\82µ
\8aÖ
\90\94\82Ö */
\r
3405 e= FileT_callByNestFind_sub( &data ); IF(e)goto fin;
\r
3410 err_fa: e= E_FEW_ARRAY; goto fin;
\r
3414 int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m )
\r
3418 WIN32_FIND_DATA data;
\r
3423 /* 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
3424 if ( m->Flags & FileT_FolderBeforeFiles ) {
\r
3425 *( m->FileName - 1 ) = _T('\0'); // m->FullPath
\82Ì
\8dÅ
\8cã
\82Ì \
\82ð
\88ê
\8e\9e\93I
\82É
\83J
\83b
\83g
\r
3426 *( m->FileName ) = _T('\0'); // m->FileName, m->StepPath
\82ð ""
\82É
\82·
\82é
\r
3427 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
\r
3429 if ( m->StepPath[0] == _T('\0') ) {
\r
3430 TCHAR* step_path = m->StepPath;
\r
3431 TCHAR* fname = m->FileName;
\r
3433 m->StepPath = _T(".");
\r
3434 m->FileName = StrT_refFName( m->FullPath );
\r
3435 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
3436 m->StepPath = step_path;
\r
3437 m->FileName = fname;
\r
3439 else if ( m->FileName[0] == _T('\0') ) {
\r
3440 TCHAR* fname = m->FileName;
\r
3442 m->FileName = StrT_refFName( m->FullPath );
\r
3443 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
3444 m->FileName = fname;
\r
3447 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
3449 *( m->FileName - 1 ) = _T('\\');
\r
3453 /* *
\82ð
\92Ç
\89Á */
\r
3455 IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;
\r
3456 *p = _T('*'); *(p+1) = _T('\0');
\r
3459 /*
\83t
\83@
\83C
\83\8b\82©
\83t
\83H
\83\8b\83_
\82ð
\97ñ
\8b\93\82µ
\82Ü
\82· */
\r
3460 find = FindFirstFileEx( m->FullPathMem, FindExInfoStandard, &data,
\r
3461 FindExSearchNameMatch, NULL, 0 );
\r
3462 done = ( find == INVALID_HANDLE_VALUE );
\r
3466 if ( _tcscmp( data.cFileName, _T(".") ) == 0 ||
\r
3467 _tcscmp( data.cFileName, _T("..") ) == 0 ) {
\r
3468 done = ! FindNextFile( find, &data );
\r
3472 StrT_cpy( m->FileName,
\r
3473 sizeof(m->FullPathMem) - ( (char*)m->FileName - (char*)m->FullPathMem ),
\r
3475 m->FileAttributes = data.dwFileAttributes;
\r
3477 if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
\r
3478 TCHAR* prev_fname = m->FileName;
\r
3480 p = StrT_chr( m->FileName, _T('\0') );
\r
3482 IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;
\r
3483 *p = _T('\\'); *(p+1) = _T('\0');
\r
3484 m->FileName = p + 1;
\r
3486 e= FileT_callByNestFind_sub( m ); IF(e)goto fin; /*
\8dÄ
\8bN
\8cÄ
\82Ñ
\8fo
\82µ */
\r
3488 m->FileName = prev_fname;
\r
3491 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
3494 done = ! FindNextFile( find, &data );
\r
3496 FindClose( find );
\r
3499 /* 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
3500 if ( m->Flags & FileT_FolderAfterFiles ) {
\r
3501 TCHAR* step_path = m->StepPath;
\r
3502 TCHAR* fname = m->FileName;
\r
3504 *( m->FileName - 1 ) = _T('\0');
\r
3505 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
\r
3506 if ( ( *( m->StepPath - 1 ) == _T('\0') ) && ( m->StepPath > m->FullPath ) ) {
\r
3507 m->StepPath = _T(".");
\r
3509 m->FileName = StrT_refFName( m->FullPath );
\r
3511 e= m->CallbackFromNestFind( m ); IF(e)goto fin;
\r
3513 m->StepPath = step_path;
\r
3514 m->FileName = fname;
\r
3520 err_fa: e= E_FEW_ARRAY; goto fin;
\r
3525 /***********************************************************************
\r
3526 <<< [FileT_openForRead] >>>
\r
3527 ************************************************************************/
\r
3528 int FileT_openForRead( FILE** out_pFile, const TCHAR* Path )
\r
3532 assert( Locale_isInited() );
\r
3534 #if DEBUGTOOLS_USES
\r
3535 { int e= Debug_onOpen( Path ); if(e) return e; }
\r
3538 en = _tfopen_s( out_pFile, Path, _T("r")_T(fopen_ccs) );
\r
3539 if ( en == ENOENT ) {
\r
3544 if ( _tgetcwd( cwd, _countof(cwd) ) == NULL ) {
\r
3545 cwd[0] = _T('\0');
\r
3547 Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\" current=\"%s\"/>"),
\r
3551 Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\"/>"), Path );
\r
3554 return E_PATH_NOT_FOUND;
\r
3556 if ( en == EACCES ) {
\r
3557 Error4_printf( _T("access denied \"%s\"\n"), Path );
\r
3558 return E_ACCESS_DENIED;
\r
3560 IF(en)return E_OTHERS;
\r
3567 /***********************************************************************
\r
3568 <<< [FileT_openForWrite] >>>
\r
3569 ************************************************************************/
\r
3570 int FileT_openForWrite( FILE** out_pFile, const TCHAR* Path, bit_flags_fast32_t Flags )
\r
3578 IF_D( ! Locale_isInited() ) return E_NOT_INIT_GLOBAL;
\r
3581 e= AppKey_addNewWritableFolder( Path ); IF(e)goto fin;
\r
3584 if ( Flags & F_Append )
\r
3585 open_type = ( Flags & F_Unicode ? _T("a")_T(fopen_ccs) : _T("at") );
\r
3587 open_type = ( Flags & F_Unicode ? _T("w")_T(fopen_ccs) : _T("wt") );
\r
3589 #if DEBUGTOOLS_USES
\r
3590 { int e= Debug_onOpen( Path ); if(e) return e; }
\r
3593 for ( retry_count = 0; ; retry_count ++ ) {
\r
3594 en = _tfopen_s( out_pFile, Path, open_type );
\r
3595 if ( en != EACCES ) break;
\r
3596 IF ( GetFileAttributes( Path ) == FILE_ATTRIBUTE_DIRECTORY ) { goto err_gt; }
\r
3599 if ( retry_count == 15 ) break;
\r
3602 if ( en == 2 ) { // ENOENT
\r
3603 e= FileT_mkdir( Path ); IF(e)goto fin;
\r
3604 b= RemoveDirectory( Path ); IF(!b)goto err_gt;
\r
3605 en = _tfopen_s( out_pFile, Path, open_type );
\r
3608 _tprintf( _T("cannot open \"%s\"\n"), Path );
\r
3614 if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )
\r
3615 _tprintf( _T("current = \"%s\"\n"), cwd );
\r
3619 e = E_NOT_FOUND_SYMBOL;
\r
3629 err: e = E_OTHERS; goto fin;
\r
3630 err_gt: e = SaveWindowsLastError(); goto fin;
\r
3635 /***********************************************************************
\r
3636 <<< [FileT_close] >>>
\r
3637 ************************************************************************/
\r
3638 int FileT_close( FILE* File, int e )
\r
3640 if ( File != NULL ) {
\r
3641 int r = fclose( File );
\r
3642 IF(r&&!e)e=E_ERRNO;
\r
3650 /***********************************************************************
\r
3651 <<< [FileT_closeAndNULL] >>>
\r
3652 ************************************************************************/
\r
3653 errnum_t FileT_closeAndNULL( FILE** in_out_File, errnum_t e )
\r
3655 FILE* file = *in_out_File;
\r
3657 if ( file != NULL ) {
\r
3658 int r = fclose( file );
\r
3659 IF ( r && e == 0 ) { e = E_ERRNO; }
\r
3660 *in_out_File = NULL;
\r
3669 /***********************************************************************
\r
3670 <<< [FileT_readAll] >>>
\r
3671 ************************************************************************/
\r
3672 #ifdef IsTest_FileT_readAll
\r
3673 #define _CV(x) CoverageLogClass_output( x, _T("FileT_readAll") )
\r
3678 errnum_t FileT_readAll( FILE* File, TCHAR** out_Text, size_t* out_TextLength )
\r
3680 #ifdef IsTest_FileT_readAll
\r
3681 enum { text_max_size_first = 0x10 };
\r
3683 enum { text_max_size_first = 0xFF00 };
\r
3686 TCHAR* text = NULL;
\r
3687 TCHAR* text_over = (TCHAR*) DUMMY_INITIAL_VALUE;
\r
3688 size_t text_max_size = text_max_size_first;
\r
3689 TCHAR* text_max_over;
\r
3692 text = (TCHAR*) malloc( text_max_size ); IF( text == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
3694 text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );
\r
3696 text[0] = _T('\0'); /* for empty file */
\r
3699 _fgetts( text_over, text_max_over - text_over, File );
\r
3701 if ( *text_over == _T('\0') ) { /* End of file. If space line, *text_over == _T('\n'). */
\r
3703 ASSERT_R( feof( File ), e=E_OTHERS; goto fin );
\r
3706 text_over = StrT_chr( text_over, _T('\0') );
\r
3707 if ( feof( File ) ) { break; }
\r
3709 if ( (uint8_t*) text_over - (uint8_t*) text == (int)( text_max_size - sizeof(TCHAR) ) ) {
\r
3710 /* if full in text */
\r
3712 size_t old_text_max_size = text_max_size;
\r
3714 #ifdef IsTest_FileT_readAll
\r
3715 EmptyHeapMemoryEmulation( _T("T_FileT_readAll_FewMemory"), 1 );
\r
3718 text_max_size *= 4;
\r
3719 new_text = (TCHAR*) realloc( text, text_max_size );
\r
3720 IF( new_text == NULL ) { e=E_FEW_MEMORY; _CV(2); goto fin; }
\r
3722 text_over = (TCHAR*)( (uint8_t*) new_text + old_text_max_size - sizeof(TCHAR) );
\r
3723 text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );
\r
3733 if ( text != NULL ) { _CV(4); free( text ); }
\r
3737 if ( out_TextLength != NULL ) { *out_TextLength = text_over - text; }
\r
3745 /***********************************************************************
\r
3746 <<< [FileT_writePart] >>>
\r
3747 ************************************************************************/
\r
3748 errnum_t FileT_writePart( FILE* File, const TCHAR* Start, TCHAR* Over )
\r
3754 back_char = *Over;
\r
3756 IF ( Start > Over ) { e=E_OTHERS; goto fin; }
\r
3759 r= _ftprintf_s( File, _T("%s"), Start ); IF(r<0){ e=E_ERRNO; goto fin; }
\r
3763 *Over = back_char;
\r
3769 /***********************************************************************
\r
3770 <<< [FileT_mkdir] >>>
\r
3771 ************************************************************************/
\r
3772 int FileT_mkdir( const TCHAR* Path )
\r
3776 TCHAR* p = (TCHAR*) DUMMY_INITIAL_VALUE;
\r
3779 TCHAR path2[MAX_PATH];
\r
3782 e= StrT_getFullPath( path2, sizeof(path2), Path, NULL ); IF(e)goto fin;
\r
3784 e= AppKey_addNewWritableFolder( path2 ); IF(e)goto fin;
\r
3788 //===
\91¶
\8dÝ
\82·
\82é
\83t
\83H
\83\8b\83_
\82ð
\92T
\82·
\r
3790 r = GetFileAttributes( path2 );
\r
3791 if ( r != (DWORD)-1 ) break; // "C:"
\82à
\83t
\83H
\83\8b\83_
\82Æ
\94»
\92è
\82³
\82ê
\82é
\r
3793 p = StrT_refFName( path2 ) - 1; //
\90â
\91Î
\83p
\83X
\82È
\82Ì
\82Å
\95K
\82¸ *p=='\\'
\r
3797 IF ( ! (r & FILE_ATTRIBUTE_DIRECTORY) ) goto err; //
\83t
\83@
\83C
\83\8b\82È
\82ç
\83G
\83\89\81[
\r
3800 //===
\83t
\83H
\83\8b\83_
\82ð
\8dì
\90¬
\82·
\82é
\r
3801 for ( ; n_folder > 0; n_folder -- ) {
\r
3803 b= CreateDirectory( path2, NULL ); IF(!b)goto err;
\r
3804 p = StrT_chr( p, _T('\0') );
\r
3811 err: e = E_OTHERS; goto fin;
\r
3817 /***********************************************************************
\r
3818 <<< [FileT_copy] >>>
\r
3819 ************************************************************************/
\r
3820 int FileT_copy_sub( FileT_CallByNestFindData* m );
\r
3822 int FileT_copy( const TCHAR* SrcPath, const TCHAR* DstPath )
\r
3824 const TCHAR* p_last;
\r
3827 TCHAR path[MAX_PATH*4];
\r
3831 e= AppKey_addNewWritableFolder( DstPath ); IF(e)goto fin;
\r
3834 p_last = StrT_chr( SrcPath, _T('\0') );
\r
3835 IF_D( p_last <= SrcPath + 1 )goto err_ni;
\r
3838 //===
\83t
\83H
\83\8b\83_
\82ð
\83R
\83s
\81[
\82·
\82é
\r
3839 if ( *(p_last - 1) == _T('*') ) {
\r
3840 IF_D( *(p_last - 2) != _T('\\') ) goto err_ni;
\r
3842 e= StrT_getParentFullPath( path, sizeof(path), SrcPath, NULL ); IF(e)goto fin;
\r
3843 IF_D( ! FileT_isDir( path ) )goto err_nf;
\r
3845 e= FileT_callByNestFind( path, FileT_FolderBeforeFiles, (void*) DstPath, (FuncType) FileT_copy_sub );
\r
3850 //===
\83t
\83@
\83C
\83\8b\82ð
\83R
\83s
\81[
\82·
\82é
\r
3852 IF_D( _tcschr( SrcPath, _T('*') ) != NULL )goto err_ni;
\r
3853 IF_D( ! FileT_isFile( SrcPath ) ) goto err_nf;
\r
3855 b= CopyFile( SrcPath, DstPath, FALSE );
\r
3857 if ( FileT_isDir( DstPath ) ) {
\r
3858 e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;
\r
3859 b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;
\r
3864 p_last = StrT_chr( DstPath, _T('\0') ) - 1;
\r
3865 IF_D( p_last < DstPath )goto err;
\r
3866 if ( *p_last == _T('\\') ) {
\r
3867 ee= FileT_mkdir( DstPath ); IF(ee)goto fin;
\r
3868 e= stprintf_r( path, sizeof(path), _T("%s%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;
\r
3869 b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;
\r
3872 e = E_ACCESS_DENIED;
\r
3873 ee= StrT_getParentFullPath( path, sizeof(path), DstPath, NULL ); IF(ee)goto fin;
\r
3874 ee= FileT_mkdir( path ); IF(ee)goto fin;
\r
3875 b= CopyFile( SrcPath, DstPath, FALSE ); IF(!b)goto err_gt;
\r
3885 err_ni: e = E_NOT_IMPLEMENT_YET; goto fin;
\r
3886 err_nf: e = E_PATH_NOT_FOUND; goto fin;
\r
3887 err_gt: e = SaveWindowsLastError(); goto fin;
\r
3888 err: e = E_OTHERS; goto fin;
\r
3892 int FileT_copy_sub( FileT_CallByNestFindData* m )
\r
3894 const TCHAR* DstPath = (const TCHAR*) m->CallerArgument;
\r
3897 TCHAR path[MAX_PATH*4];
\r
3899 e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, m->StepPath ); IF(e)goto fin;
\r
3901 if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
\r
3902 if ( ! FileT_isDir( path ) )
\r
3903 { b= CreateDirectory( path, NULL ); IF(!b)goto err_gt; }
\r
3906 b= CopyFile( m->FullPath, path, FALSE ); IF(!b)goto err_gt;
\r
3913 err_gt: e = SaveWindowsLastError(); goto fin;
\r
3919 /***********************************************************************
\r
3920 <<< [FileT_del] >>>
\r
3921 ************************************************************************/
\r
3922 int FileT_del_sub( FileT_CallByNestFindData* m );
\r
3924 int FileT_del( const TCHAR* Path )
\r
3928 TCHAR abs_path[MAX_PATH];
\r
3930 e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto fin;
\r
3932 e= AppKey_addNewWritableFolder( abs_path ); IF(e)goto fin;
\r
3935 r= GetFileAttributes( Path );
\r
3936 if ( r != (DWORD)-1 ) {
\r
3937 if ( r & FILE_ATTRIBUTE_DIRECTORY ) {
\r
3938 e= FileT_callByNestFind( Path, FileT_FolderAfterFiles, NULL, (FuncType) FileT_del_sub );
\r
3941 BOOL b= DeleteFile( Path ); IF(!b)goto err_gt;
\r
3944 IF_D( FileT_isExist( Path ) )goto err_ad;
\r
3950 err_gt: e = SaveWindowsLastError(); goto fin;
\r
3951 err_ad: e = E_ACCESS_DENIED; goto fin;
\r
3955 int FileT_del_sub( FileT_CallByNestFindData* m )
\r
3960 if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
\r
3961 b= RemoveDirectory( m->FullPath ); IF(!b)goto err_gt;
\r
3964 b= DeleteFile( m->FullPath ); IF(!b)goto err_gt;
\r
3971 err_gt: e = SaveWindowsLastError(); goto fin;
\r
3974 /***********************************************************************
\r
3975 <<< [FileT_writeSizedStruct_WinAPI] >>>
\r
3976 ************************************************************************/
\r
3977 int FileT_writeSizedStruct_WinAPI( HANDLE* Stream, SizedStruct* OutputSizedStruct )
\r
3983 r= WriteFile( Stream, &OutputSizedStruct->ThisStructSize,
\r
3984 sizeof(OutputSizedStruct->ThisStructSize), &wrote_size, NULL );
\r
3985 IF(!r) goto err_gt;
\r
3987 r= WriteFile( Stream, &OutputSizedStruct->OthersData,
\r
3988 OutputSizedStruct->ThisStructSize - sizeof(OutputSizedStruct->ThisStructSize),
\r
3989 &wrote_size, NULL );
\r
3990 IF(!r) goto err_gt;
\r
3995 err_gt: e = SaveWindowsLastError(); goto fin;
\r
3999 /***********************************************************************
\r
4000 <<< [FileT_readSizedStruct_WinAPI] >>>
\r
4001 ************************************************************************/
\r
4002 int FileT_readSizedStruct_WinAPI( HANDLE* Stream, void** out_SizedStruct )
\r
4010 b= ReadFile( Stream, &data_size, sizeof(data_size), &read_size, NULL ); IF(!b) goto err_gt;
\r
4011 IF( data_size & 0xC0000000 ) goto err_fm;
\r
4013 out = malloc( data_size ); IF( out == NULL ) goto err_fm;
\r
4014 *(size_t*) out = data_size;
\r
4016 b= ReadFile( Stream, (size_t*) out + 1, data_size - sizeof(size_t), &read_size, NULL ); IF(!b) goto err_gt;
\r
4018 *out_SizedStruct = out;
\r
4024 err_gt: e = SaveWindowsLastError(); goto rollback;
\r
4025 err_fm: e = E_FEW_MEMORY; goto rollback;
\r
4027 if ( out != NULL ) free( out );
\r
4033 /***********************************************************************
\r
4034 * Implement: FileT_readUnicodeFileBOM
\r
4035 ************************************************************************/
\r
4036 errnum_t FileT_readUnicodeFileBOM( const TCHAR* Path, FileFormatEnum* out_Format )
\r
4039 HANDLE file = INVALID_HANDLE_VALUE;
\r
4040 unsigned char data[4];
\r
4044 if ( ! FileT_isExist( Path ) ) {
\r
4045 *out_Format = FILE_FORMAT_NOT_EXIST;
\r
4048 file = CreateFile( Path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
\r
4049 FILE_ATTRIBUTE_NORMAL, 0 );
\r
4050 IF( file == INVALID_HANDLE_VALUE ) goto err_gt;
\r
4053 b= ReadFile( file, data, 3, &read_size, NULL ); IF(!b)goto err;
\r
4054 if ( read_size < 2 ) {
\r
4055 *out_Format = FILE_FORMAT_NO_BOM;
\r
4057 else if ( ( data[0] == 0xFF ) && ( data[1] == 0xFE ) ) {
\r
4058 *out_Format = FILE_FORMAT_UNICODE;
\r
4060 else if ( ( read_size >= 3 ) &&
\r
4061 ( data[0] == 0xEF ) && ( data[1] == 0xBB ) && ( data[2] == 0xBF ) ) {
\r
4063 *out_Format = FILE_FORMAT_UTF_8;
\r
4066 *out_Format = FILE_FORMAT_NO_BOM;
\r
4072 if ( file != INVALID_HANDLE_VALUE ) { b= CloseHandle( file ); IF(!b&&!e) e = E_OTHERS; }
\r
4075 err_gt: e = SaveWindowsLastError(); goto fin;
\r
4076 err: e = E_OTHERS; goto fin;
\r
4081 /***********************************************************************
\r
4082 * Implement: FileT_cutFFFE
\r
4083 ************************************************************************/
\r
4084 errnum_t FileT_cutFFFE( const TCHAR* in_InputPath, const TCHAR* in_OutputPath, bool in_IsAppend )
\r
4087 HANDLE reading_file = INVALID_HANDLE_VALUE;
\r
4088 HANDLE writing_file = INVALID_HANDLE_VALUE;
\r
4089 wchar_t buffer[4096];
\r
4090 uint8_t* buffer8 = (uint8_t*) buffer;
\r
4091 wchar_t a_character;
\r
4092 uint8_t a_character8;
\r
4095 DWORD writing_size;
\r
4097 DWORD reading_index;
\r
4098 DWORD reading_index_over;
\r
4099 DWORD writing_index;
\r
4103 FileFormatEnum format;
\r
4105 e= FileT_readUnicodeFileBOM( in_InputPath, /*Set*/ &format ); IF(e){goto fin;}
\r
4107 if ( ! in_IsAppend ) {
\r
4108 creation = CREATE_ALWAYS;
\r
4110 creation = OPEN_ALWAYS;
\r
4113 reading_file = CreateFile( in_InputPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
\r
4114 FILE_ATTRIBUTE_NORMAL, 0 );
\r
4115 IF( reading_file == INVALID_HANDLE_VALUE ) { e=E_GET_LAST_ERROR; goto fin; }
\r
4117 writing_file = CreateFile( in_OutputPath, GENERIC_WRITE, 0, NULL, creation,
\r
4118 FILE_ATTRIBUTE_NORMAL, 0 );
\r
4119 IF ( writing_file == INVALID_HANDLE_VALUE ) { e=E_GET_LAST_ERROR; goto fin; }
\r
4121 if ( in_IsAppend ) {
\r
4122 SetFilePointer( writing_file, 0, NULL, FILE_END );
\r
4128 b= ReadFile( reading_file, buffer, sizeof( buffer ), &read_size, NULL );
\r
4129 IF(!b){ e=SaveWindowsLastError(); goto fin; }
\r
4130 if ( read_size == 0 )
\r
4133 if ( format == FILE_FORMAT_UNICODE ) {
\r
4134 writing_index = 0;
\r
4135 reading_index_over = read_size / sizeof( buffer[0] );
\r
4136 for ( reading_index = 0; reading_index < reading_index_over; reading_index += 1 ) {
\r
4138 a_character = buffer[ reading_index ];
\r
4140 if ( a_character != 0xFEFF ) { /* FEFF = BOM character */
\r
4142 buffer[ writing_index ] = a_character;
\r
4143 writing_index += 1;
\r
4146 writing_size = writing_index * sizeof( buffer[0] );
\r
4148 else if ( format == FILE_FORMAT_UTF_8 ) {
\r
4149 writing_index = 0;
\r
4151 reading_index_over = read_size / sizeof( buffer8[0] );
\r
4152 for ( reading_index = 0; reading_index < reading_index_over; reading_index += 1 ) {
\r
4154 a_character8 = buffer8[ reading_index ];
\r
4156 if ( a_character8 == 0xEF ) {
\r
4157 if ( index_of_BOM >= 1 ) {
\r
4158 buffer8[ writing_index ] = 0xEF;
\r
4159 writing_index += 1;
\r
4160 if ( index_of_BOM >= 2 ) {
\r
4161 buffer8[ writing_index ] = 0xBB;
\r
4162 writing_index += 1;
\r
4167 else if ( a_character8 == 0xBB && index_of_BOM == 1 ) {
\r
4170 else if ( a_character8 == 0xBF && index_of_BOM == 2 ) {
\r
4176 if ( index_of_BOM >= 1 ) {
\r
4177 buffer8[ writing_index ] = 0xEF;
\r
4178 writing_index += 1;
\r
4179 if ( index_of_BOM >= 2 ) {
\r
4180 buffer8[ writing_index ] = 0xBB;
\r
4181 writing_index += 1;
\r
4185 buffer8[ writing_index ] = a_character8;
\r
4186 writing_index += 1;
\r
4191 writing_size = writing_index * sizeof( buffer8[0] );
\r
4194 writing_size = read_size;
\r
4197 b= WriteFile( writing_file, buffer, writing_size, &wrote_size, NULL );
\r
4198 IF(!b) { e=E_GET_LAST_ERROR; goto fin; }
\r
4203 e= CloseHandleInFin( writing_file, e );
\r
4204 e= CloseHandleInFin( reading_file, e );
\r
4210 /***********************************************************************
\r
4211 <<< [ParseXML2_StatusClass_getAttribute] >>>
\r
4212 ************************************************************************/
\r
4213 errnum_t ParseXML2_StatusClass_getAttribute( ParseXML2_StatusClass* self,
\r
4214 const TCHAR* AttributeName, TCHAR** out_AttribyteValue )
\r
4218 for ( attr = (TCHAR**) self->u.OnStartElement.Attributes; *attr != NULL; attr += 2 ) {
\r
4219 if ( _tcsicmp( *attr, AttributeName ) == 0 ) {
\r
4220 *out_AttribyteValue = *( attr + 1 );
\r
4224 *out_AttribyteValue = NULL;
\r
4230 /***********************************************************************
\r
4231 <<< [ParseXML2_StatusClass_mallocCopyText] >>>
\r
4232 ************************************************************************/
\r
4233 errnum_t ParseXML2_StatusClass_mallocCopyText( ParseXML2_StatusClass* self,
\r
4234 TCHAR** out_Text )
\r
4236 return MallocAndCopyStringByLength( out_Text,
\r
4237 self->u.OnText.Text, self->u.OnText.TextLength );
\r
4242 /***********************************************************************
\r
4243 <<< [ParseXML2] >>>
\r
4244 ************************************************************************/
\r
4246 /*[ParseXML2_WorkClass]*/
\r
4247 typedef struct _ParseXML2_WorkClass ParseXML2_WorkClass;
\r
4248 struct _ParseXML2_WorkClass {
\r
4249 ParseXML2_StatusClass Status;
\r
4250 ParseXML2_CallbackType OnStartElement;
\r
4251 ParseXML2_CallbackType OnEndElement;
\r
4252 ParseXML2_CallbackType OnText;
\r
4253 Set2 XPath; /* Array of TCHAR */
\r
4254 Set2 XPathLengths; /* Array of int. Element is TCHAR count. Array count is Status.Depth */
\r
4255 StrFile TextBuffer;
\r
4256 int TextStartLineNum; /* 0 = no text */
\r
4261 enum { BOM = 0xFEFF };
\r
4264 static errnum_t ParseXML2_makeXML_Declare_Sub( XML_Parser parser, ParseXML2_WorkClass* work,
\r
4265 const TCHAR* XML_Path, TCHAR* line, bool* is_xml_declare );
\r
4266 static void Expat_printfToError4( XML_Parser parser, const TCHAR* XML_Path );
\r
4267 static void ParseXML2_onStartElement( void* UserData, const XML_Char* Name, const XML_Char** Atts );
\r
4268 static void ParseXML2_onEndElement( void* UserData, const XML_Char* name );
\r
4269 static void ParseXML2_onText( void* UserData, const XML_Char* Text, int TextLength );
\r
4270 static void ParseXML2_callOnText( ParseXML2_WorkClass* work );
\r
4273 errnum_t ParseXML2( const TCHAR* XML_Path, ParseXML2_ConfigClass* in_out_Config )
\r
4276 FILE* file = NULL;
\r
4277 XML_Parser parser = (XML_Parser) DUMMY_INITIAL_VALUE;
\r
4278 bool is_parser = false;
\r
4280 wchar_t bom[1] = { BOM };
\r
4281 bool is_xml_declare = false; /* <?xml ... ?> */
\r
4282 enum XML_Status xs;
\r
4283 ParseXML2_ConfigClass* config = in_out_Config;
\r
4284 ParseXML2_ConfigClass default_config;
\r
4285 ParseXML2_WorkClass work_x;
\r
4286 ParseXML2_WorkClass* work = &work_x;
\r
4289 Set2_initConst( &work->XPath );
\r
4290 Set2_initConst( &work->XPathLengths );
\r
4291 StrFile_initConst( &work->TextBuffer );
\r
4294 /* Set "config" */
\r
4295 if ( config == NULL ) { config = &default_config; }
\r
4296 if ( ! ( config->Flags & F_ParseXML2_Delegate ) ) { config->Delegate = NULL; }
\r
4297 if ( ! ( config->Flags & F_ParseXML2_OnStartElement ) ) { config->OnStartElement = DefaultFunction; }
\r
4298 if ( ! ( config->Flags & F_ParseXML2_OnEndElement ) ) { config->OnEndElement = DefaultFunction; }
\r
4299 if ( ! ( config->Flags & F_ParseXML2_OnText ) ) { config->OnText = DefaultFunction; }
\r
4302 work->Status.Delegate = config->Delegate;
\r
4303 work->Status.LineNum = 0;
\r
4304 work->Status.Depth = -1;
\r
4305 work->Status.PreviousCallbackType = 0;
\r
4306 work->Status.TagName = NULL;
\r
4307 work->Status.u.OnStartElement.Attributes = NULL;
\r
4308 work->OnStartElement = config->OnStartElement;
\r
4309 work->OnEndElement = config->OnEndElement;
\r
4310 work->OnText = config->OnText;
\r
4313 /* Set "work->XPath", "work->XPathLengths" */
\r
4317 e= Set2_init( &work->XPath, MAX_PATH * sizeof(TCHAR) ); IF(e)goto fin;
\r
4318 e= Set2_init( &work->XPathLengths, 10 * sizeof(int) ); IF(e)goto fin;
\r
4319 xpath = (TCHAR*) work->XPath.First;
\r
4321 xpath[0] = _T('/');
\r
4322 xpath[1] = _T('\0');
\r
4325 /* Set "work->TextBuffer" */
\r
4326 e= StrFile_init_toHeap( &work->TextBuffer, 0 );
\r
4327 work->TextStartLineNum = 0;
\r
4329 /* Set "parser" */
\r
4330 parser = XML_ParserCreate( NULL );
\r
4332 XML_SetUserData( parser, work );
\r
4333 XML_SetElementHandler( parser, ParseXML2_onStartElement, ParseXML2_onEndElement );
\r
4334 XML_SetCharacterDataHandler( parser, ParseXML2_onText );
\r
4337 xs= XML_Parse( parser, (char*)bom, sizeof(bom), 0 );
\r
4338 IF( xs == XML_STATUS_ERROR ) goto err_ex;
\r
4341 /* Loop of lines of XML file */
\r
4342 e= FileT_openForRead( &file, XML_Path ); IF(e)goto fin;
\r
4344 line[0] = _T('\0');
\r
4345 _fgetts( line, _countof(line), file );
\r
4346 is_EOF = feof( file );
\r
4347 work->Status.LineNum += 1;
\r
4349 /* _fgetts
\82ª UTF-16
\82É
\95¶
\8e\9a\97ñ
\82ð
\93\9d\88ê
\82µ
\81A
\82»
\82ê
\82ð XML_Parser
\82É
\93n
\82·
\82½
\82ß
\81A*/
\r
4350 /* <?xml encoding="UTF-16" ?>
\82É
\95Ï
\8dX
\82·
\82é */
\r
4351 if ( ! is_xml_declare ) {
\r
4352 e= ParseXML2_makeXML_Declare_Sub( parser, work, XML_Path, line, &is_xml_declare );
\r
4357 xs= XML_Parse( parser, (char*)line, _tcslen( line ) * sizeof(TCHAR), is_EOF );
\r
4358 IF( xs == XML_STATUS_ERROR ) goto err_ex;
\r
4359 IF( work->e != 0 ) { e = work->e; goto fin; }
\r
4360 if ( is_EOF ) { break; }
\r
4364 if ( is_parser ) { XML_ParserFree( parser ); }
\r
4365 e= FileT_close( file, e );
\r
4366 e= StrFile_finish( &work->TextBuffer, e );
\r
4367 e= Set2_finish( &work->XPath, e );
\r
4368 e= Set2_finish( &work->XPathLengths, e );
\r
4371 err_ex: Expat_printfToError4( parser, XML_Path ); e= E_XML_PARSER; goto fin;
\r
4375 /*[ParseXML2_makeXML_Declare_Sub]*/
\r
4376 static errnum_t ParseXML2_makeXML_Declare_Sub( XML_Parser parser, ParseXML2_WorkClass* work,
\r
4377 const TCHAR* XML_Path, TCHAR* line, bool* is_xml_declare )
\r
4381 TCHAR* str = NULL;
\r
4382 enum XML_Status xs;
\r
4384 UNREFERENCED_VARIABLE( work );
\r
4386 if ( _tcschr( line, _T('<') ) > 0 ) {
\r
4387 if ( _tcsstr( line, _T("<?") ) > 0 ) {
\r
4388 bool is_replaced = false;
\r
4391 static const TCHAR* enc_sjis = _T("encoding=\"Shift_JIS\"");
\r
4392 static const TCHAR* enc_sjis_utf16 = _T("encoding=\"UTF-16\" ");
\r
4394 p = _tcsstr( line, enc_sjis );
\r
4395 if ( p != NULL ) {
\r
4396 memcpy( p, enc_sjis_utf16, _tcslen( enc_sjis_utf16 ) * sizeof(TCHAR) );
\r
4397 is_replaced = true;
\r
4400 if ( ! is_replaced ) {
\r
4401 static const TCHAR* enc_utf8 = _T("encoding=\"UTF-8\"");
\r
4402 static const TCHAR* enc_utf8_utf16 = _T("encoding=\"UTF-16\"");
\r
4405 p = _tcsstr( line, enc_utf8 );
\r
4406 if ( p != NULL ) {
\r
4407 str_size = ( _tcslen( line ) + 2 ) * sizeof(TCHAR);
\r
4408 str = (TCHAR*) malloc( str_size ); IF(str==NULL) goto err_fm;
\r
4410 e= StrT_replace( str, str_size, line, enc_utf8, enc_utf8_utf16, 0 );
\r
4413 xs= XML_Parse( parser, (char*)str, _tcslen( str ) * sizeof(TCHAR), 0 );
\r
4414 IF( xs == XML_STATUS_ERROR ) goto err_ex;
\r
4416 line[0] = _T('\0');
\r
4417 *is_xml_declare = true;
\r
4424 static const TCHAR* xml_declare = _T("<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n");
\r
4426 XML_Parse( parser, (char*)xml_declare, _tcslen( xml_declare ) * sizeof(TCHAR), 0 );
\r
4427 *is_xml_declare = true;
\r
4432 if ( _tcsstr( line, _T("?>") ) != NULL ) {
\r
4433 *is_xml_declare = true;
\r
4438 if ( str != NULL ) { free( str ); }
\r
4441 err_fm: e = E_FEW_MEMORY; goto fin;
\r
4442 err_ex: Expat_printfToError4( parser, XML_Path ); e= E_XML_PARSER; goto fin;
\r
4446 /*[Expat_printfToError4]*/
\r
4447 static void Expat_printfToError4( XML_Parser parser, const TCHAR* XML_Path )
\r
4449 Error4_printf( _T("<ERROR msg=\"%s\" file=\"%s(%lu)\"/>\n"),
\r
4450 XML_ErrorString( XML_GetErrorCode( parser ) ),
\r
4452 XML_GetCurrentLineNumber(parser) );
\r
4456 /*[ParseXML2_onStartElement]*/
\r
4457 static void ParseXML2_onStartElement( void* UserData, const XML_Char* Name, const XML_Char** Atts )
\r
4459 ParseXML2_WorkClass* work = (ParseXML2_WorkClass*) UserData;
\r
4460 TCHAR* xpath = (TCHAR*) DUMMY_INITIAL_VALUE;
\r
4461 int* xpath_lengths;
\r
4462 int old_depth = work->Status.Depth;
\r
4463 int new_depth = work->Status.Depth + 1;
\r
4465 if ( work->e != 0 ) return;
\r
4468 /* Call "work->OnText" */
\r
4469 if ( work->OnText != DefaultFunction )
\r
4470 { ParseXML2_callOnText( work ); }
\r
4473 /* Set "work->XPath" : Add "Name" */
\r
4476 int old_xpath_length;
\r
4477 int name_length = _tcslen( Name );
\r
4480 /* Set "old_xpath_length" */
\r
4481 xpath_lengths = (int*) work->XPathLengths.First;
\r
4482 if ( old_depth >= 0 )
\r
4483 { old_xpath_length = xpath_lengths[ old_depth ]; }
\r
4485 { old_xpath_length = 0; } /* Length("/") == 1, But 0 for next operation */
\r
4487 /* Add "Name" to "work->XPath" */
\r
4488 e= Set2_expandIfOverByOffset( &work->XPath,
\r
4489 ( old_xpath_length + name_length + 2 ) * sizeof(TCHAR) );
\r
4491 xpath = (TCHAR*) work->XPath.First;
\r
4492 xpath[ old_xpath_length ] = _T('/');
\r
4493 memcpy( &xpath[ old_xpath_length + 1 ], Name, name_length * sizeof(TCHAR) );
\r
4494 xpath[ old_xpath_length + 1 + name_length ] = _T('\0');
\r
4496 /* "work->XPathLengths[]" = new XPath length */
\r
4497 e= Set2_expandIfOverByOffset( &work->XPathLengths, ( new_depth + 1 ) * sizeof(int) );
\r
4499 xpath_lengths = (int*) work->XPathLengths.First;
\r
4500 xpath_lengths[ new_depth ] = old_xpath_length + 1 + name_length;
\r
4511 /* Call "work->OnStartElement" */
\r
4512 work->Status.XPath = xpath;
\r
4513 if ( old_depth >= 0 )
\r
4514 { work->Status.TagName = &xpath[ xpath_lengths[ old_depth ] + 1 ]; }
\r
4516 { work->Status.TagName = &xpath[ 1 ]; }
\r
4517 work->Status.u.OnStartElement.Attributes = Atts;
\r
4518 work->Status.Depth += 1;
\r
4520 work->e = work->OnStartElement( &work->Status );
\r
4522 work->Status.u.OnStartElement.Attributes = NULL;
\r
4524 work->Status.PreviousCallbackType = F_ParseXML2_OnStartElement;
\r
4528 /*[ParseXML2_onEndElement]*/
\r
4529 static void ParseXML2_onEndElement( void* UserData, const XML_Char* Name )
\r
4531 ParseXML2_WorkClass* work = (ParseXML2_WorkClass*) UserData;
\r
4532 TCHAR* xpath = (TCHAR*) work->XPath.First;
\r
4533 int* xpath_lengths = (int*) work->XPathLengths.First;
\r
4534 int new_depth = work->Status.Depth - 1;
\r
4536 UNREFERENCED_VARIABLE( Name );
\r
4538 if ( work->e != 0 ) return;
\r
4540 if ( new_depth >= 0 )
\r
4541 { work->Status.TagName = &xpath[ xpath_lengths[ new_depth ] + 1 ]; }
\r
4543 { work->Status.TagName = &xpath[ 1 ]; }
\r
4546 /* Call "work->OnText" */
\r
4547 if ( work->OnText != DefaultFunction )
\r
4548 { ParseXML2_callOnText( work ); }
\r
4551 /* Call "work->OnEndElement" */
\r
4552 work->e = work->OnEndElement( &work->Status );
\r
4553 work->Status.Depth -= 1;
\r
4556 /* Set "work->XPath" : Remove "Name" */
\r
4557 if ( new_depth >= 0 ) {
\r
4558 xpath[ xpath_lengths[ new_depth ] ] = _T('\0');
\r
4559 if ( new_depth - 1 >= 0 )
\r
4560 { work->Status.TagName = &xpath[ xpath_lengths[ new_depth - 1 ] + 1 ]; }
\r
4562 { work->Status.TagName = &xpath[ 1 ]; }
\r
4565 xpath[ 1 ] = _T('\0'); /* xpath = "/" */
\r
4566 work->Status.TagName = &xpath[ 0 ];
\r
4569 work->Status.PreviousCallbackType = F_ParseXML2_OnEndElement;
\r
4573 /*[ParseXML2_onText]*/
\r
4574 static void ParseXML2_onText( void* UserData, const XML_Char* Text, int TextLength )
\r
4576 ParseXML2_WorkClass* work = (ParseXML2_WorkClass*) UserData;
\r
4578 if ( work->e != 0 ) return;
\r
4580 if ( work->OnText != DefaultFunction ) {
\r
4583 work->e = StrFile_writeBinary( &work->TextBuffer, Text, TextLength * sizeof(TCHAR) );
\r
4585 if ( work->TextStartLineNum == 0 )
\r
4586 { work->TextStartLineNum = work->Status.LineNum; }
\r
4588 work->Status.u.OnText.Text = Text;
\r
4589 work->Status.u.OnText.TextLength = TextLength;
\r
4591 work->e = work->OnText( &work->Status );
\r
4593 work->Status.u.OnText.Text = NULL;
\r
4594 work->Status.u.OnText.TextLength = 0;
\r
4596 work->Status.PreviousCallbackType = F_ParseXML2_OnText;
\r
4602 /*[ParseXML2_callOnText]*/
\r
4603 static void ParseXML2_callOnText( ParseXML2_WorkClass* work )
\r
4605 if ( work->TextStartLineNum != 0 ) {
\r
4606 int line_num_back_up = work->Status.LineNum;
\r
4608 work->Status.u.OnText.Text = work->TextBuffer.Buffer;
\r
4609 work->Status.u.OnText.TextLength = (TCHAR*) work->TextBuffer.Pointer -
\r
4610 (TCHAR*) work->TextBuffer.Buffer;
\r
4611 work->Status.LineNum = work->TextStartLineNum;
\r
4613 work->e = work->OnText( &work->Status );
\r
4615 if ( work->e == 0 ) {
\r
4616 work->e = StrFile_setPointer( &work->TextBuffer, 0 );
\r
4617 IF( work->e ) __noop();
\r
4619 work->Status.LineNum = line_num_back_up;
\r
4620 work->TextStartLineNum = 0;
\r
4621 work->Status.PreviousCallbackType = F_ParseXML2_OnText;
\r
4627 /***********************************************************************
\r
4629 ************************************************************************/
\r
4630 static errnum_t AppKey_create( AppKey** out_m );
\r
4631 static bool AppKey_isSame( AppKey* m );
\r
4632 static void Writables_initConst( Writables* m );
\r
4633 static errnum_t Writables_init( Writables* m, AppKey* Key );
\r
4634 static errnum_t Writables_finish( Writables* m, int e );
\r
4635 static bool Writables_isInited( Writables* m );
\r
4636 static errnum_t Writables_clearPaths( Writables* m );
\r
4637 static errnum_t Writables_create( Writables** out_m, AppKey* Key );
\r
4638 static errnum_t Writables_copyToConst( Writables* To, Writables* From );
\r
4641 typedef struct _CurrentWritables CurrentWritables;
\r
4642 struct _CurrentWritables {
\r
4643 Writables m_CurrentWritables;
\r
4644 TCHAR* m_ProgramFiles; size_t m_ProgramFiles_Len;
\r
4645 TCHAR* m_windir; size_t m_windir_Len;
\r
4646 TCHAR* m_APPDATA; size_t m_APPDATA_Len;
\r
4647 TCHAR* m_LOCALAPPDATA; size_t m_LOCALAPPDATA_Len;
\r
4649 static void CurrentWritables_initConst( CurrentWritables* m );
\r
4650 static errnum_t CurrentWritables_init( CurrentWritables* m );
\r
4651 static errnum_t CurrentWritables_finish( CurrentWritables* m, int e );
\r
4652 static errnum_t CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath );
\r
4655 //////////////////////////////
\r
4657 static AppKey g_AppKey;
\r
4658 static AppKey* g_AppKeyPrivate;
\r
4661 Writables g_DefaultWritables;
\r
4662 Writables g_CurrentWritables; // public
\r
4663 static CurrentWritables g_CurrentWritablesPrivate;
\r
4666 static errnum_t AppKey_create( AppKey** out_m )
\r
4670 IF( g_AppKeyPrivate != NULL ) { e=1; goto fin; }
\r
4671 // 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
4673 Writables_initConst( &g_DefaultWritables );
\r
4674 CurrentWritables_initConst( &g_CurrentWritablesPrivate );
\r
4676 e= CurrentWritables_init( &g_CurrentWritablesPrivate ); IF(e)goto fin;
\r
4677 e= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(e)goto fin;
\r
4679 *out_m = &g_AppKey;
\r
4680 g_AppKeyPrivate = &g_AppKey;
\r
4688 static bool AppKey_isSame( AppKey* m )
\r
4690 return ( m == g_AppKeyPrivate );
\r
4694 void AppKey_initGlobal_const()
\r
4696 Writables_initConst( &g_DefaultWritables );
\r
4700 errnum_t AppKey_finishGlobal( errnum_t e )
\r
4704 e= Writables_finish( &g_DefaultWritables, e );
\r
4705 e= CurrentWritables_finish( &g_CurrentWritablesPrivate, e );
\r
4706 ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)e=ee;
\r
4713 /***********************************************************************
\r
4714 <<< [AppKey_newWritable_Sub] >>>
\r
4715 ************************************************************************/
\r
4716 errnum_t AppKey_newWritable_Sub( AppKey** in_out_m, Writables** out_Writable,
\r
4718 TCHAR** in_Paths, int in_PathCount )
\r
4722 Writables* wr = NULL;
\r
4723 #if Uses_OutMallocIDTool
\r
4724 bool is_prev_out_malloc;
\r
4726 is_prev_out_malloc = OutMallocID_setEnable( false );
\r
4730 //=== AppKey* m
\82ð
\97L
\8cø
\82É
\82·
\82é
\r
4731 if ( in_out_m == NULL ) { //
\8d¡
\89ñ
\82Ì
\8aÖ
\90\94\82Ì
\92\86\82¾
\82¯
\82Å
\8eQ
\8fÆ
\82·
\82é
\r
4732 e= AppKey_create( &m ); IF(e)goto resume;
\r
4734 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
4735 e= AppKey_create( &m ); IF(e)goto resume;
\r
4738 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
4743 //===
\90³
\8bK
\82Ì AppKey
\82©
\83`
\83F
\83b
\83N
\82·
\82é
\r
4744 IF( ! AppKey_isSame( m ) )goto err;
\r
4747 //=== Writable
\82ð
\90¶
\90¬
\82·
\82é
\r
4748 if ( out_Writable == NULL ) {
\r
4749 wr = &g_DefaultWritables;
\r
4750 e= Writables_finish( wr, 0 ); IF(e)goto resume;
\r
4751 e= Writables_init( wr, m ); IF(e)goto resume;
\r
4754 e= Writables_create( &wr, m ); IF(e)goto resume;
\r
4755 *out_Writable = wr;
\r
4759 //=== Writable
\82É
\83p
\83X
\82ð
\93o
\98^
\82·
\82é
\r
4760 if ( in_Paths == NULL ) {
\r
4764 for ( i=0; ; i++ ) {
\r
4765 path = va_arg( va, TCHAR* );
\r
4766 if ( path == NULL ) break;
\r
4767 IF( i == 5 ) goto err; //
\8dÅ
\8cã
\82Ì NULL
\96Y
\82ê
\91Î
\8dô
\r
4769 e= Writables_add( wr, m, path ); IF(e)goto resume;
\r
4775 for ( i = 0; i < in_PathCount; i += 1 ) {
\r
4776 e= Writables_add( wr, m, in_Paths[i] ); IF(e){goto fin;}
\r
4780 #if defined(TempFile_get)
\r
4784 e= TempFile_get( &temp ); IF(e)goto resume;
\r
4785 e= Writables_add( wr, m, temp->TempPath ); IF(e)goto resume;
\r
4790 //===
\82·
\82®
\82É Writable
\82ð
\97L
\8cø
\82É
\82·
\82é
\r
4791 if ( out_Writable == NULL ) {
\r
4792 e= Writables_enable( wr ); IF(e)goto resume;
\r
4797 #if Uses_OutMallocIDTool
\r
4798 OutMallocID_setEnable( is_prev_out_malloc );
\r
4802 err: e = E_OTHERS; goto resume;
\r
4804 if ( wr != NULL ) {
\r
4805 if ( out_Writable == NULL )
\r
4806 e= Writables_finish( wr, e ); // g_DefaultWritables
\r
4808 e= Writables_delete( wr, e );
\r
4815 /***********************************************************************
\r
4816 <<< [AppKey_newWritable] >>>
\r
4817 ************************************************************************/
\r
4818 errnum_t AppKey_newWritable( AppKey** in_out_m, Writables** out_Writable, ... )
\r
4823 va_start( va, out_Writable );
\r
4824 e = AppKey_newWritable_Sub( in_out_m, out_Writable, va, NULL, 0 );
\r
4832 /***********************************************************************
\r
4833 <<< [AppKey_newWritable_byArray] >>>
\r
4834 ************************************************************************/
\r
4835 errnum_t AppKey_newWritable_byArray( AppKey** in_out_m, Writables** out_Writable,
\r
4836 TCHAR** in_Paths, int in_PathCount )
\r
4838 IF ( in_Paths == NULL ) {
\r
4841 return AppKey_newWritable_Sub( in_out_m, out_Writable, NULL,
\r
4842 in_Paths, in_PathCount );
\r
4848 /***********************************************************************
\r
4849 <<< [AppKey_addNewWritableFolder]
\83`
\83F
\83b
\83N
\82·
\82é
\81A
\82Ü
\82½
\82Í
\92Ç
\89Á
\82·
\82é >>>
\r
4850 ************************************************************************/
\r
4851 errnum_t AppKey_addNewWritableFolder_Sub( const TCHAR* Path, bool* out_IsWritable );
\r
4853 errnum_t AppKey_addNewWritableFolder( const TCHAR* Path )
\r
4858 e= AppKey_addNewWritableFolder_Sub( Path, &is_writable ); IF(e){goto fin;}
\r
4859 IF ( ! is_writable ) { e=E_OUT_OF_WRITABLE; goto fin; }
\r
4860 // Path (abs_path)
\82Í
\81AAppKey_newWritable
\82Å
\8b\96\89Â
\82³
\82ê
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B
\r
4861 //
\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
4862 //
\8b\96\89Â
\82³
\82ê
\82Ä
\82¢
\82é
\83p
\83X
\82ð
\8am
\94F
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B
\r
4869 errnum_t AppKey_addNewWritableFolder_Sub( const TCHAR* Path, bool* out_IsWritable )
\r
4874 Writables* wr = &g_CurrentWritablesPrivate.m_CurrentWritables;
\r
4876 TCHAR abs_path[MAX_PATH];
\r
4878 *out_IsWritable = true;
\r
4880 if ( g_AppKeyPrivate == NULL ) {
\r
4881 e= AppKey_newWritable( NULL, NULL, ".", NULL ); IF(e){goto fin;}
\r
4884 e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e){goto fin;}
\r
4886 pp_over = wr->m_Paths + wr->m_nPath;
\r
4887 for ( pp = wr->m_Paths; ; pp++ ) {
\r
4888 if ( pp >= pp_over ) {
\r
4889 *out_IsWritable = false;
\r
4892 path_len = _tcslen( *pp );
\r
4893 if ( _tcsnicmp( *pp, abs_path, path_len ) == 0 &&
\r
4894 ( abs_path[ path_len ] == _T('\\') || abs_path[ path_len ] == _T('\0') ) )
\r
4907 /***********************************************************************
\r
4908 <<< [AppKey_addWritableFolder]
\83`
\83F
\83b
\83N
\82µ
\82È
\82¢
\82Å
\81A
\92Ç
\89Á
\82·
\82é >>>
\r
4909 ************************************************************************/
\r
4910 errnum_t AppKey_addWritableFolder( AppKey* m, const TCHAR* Path )
\r
4913 Writables* wr = &g_CurrentWritablesPrivate.m_CurrentWritables;
\r
4916 e= AppKey_addNewWritableFolder_Sub( Path, &is_writable ); IF(e){goto fin;}
\r
4917 if ( ! is_writable ) {
\r
4918 e= Writables_add( wr, m, Path ); IF(e){goto fin;}
\r
4928 /***********************************************************************
\r
4929 <<< [AppKey_checkWritable] >>>
\r
4930 ************************************************************************/
\r
4931 errnum_t AppKey_checkWritable( const TCHAR* Path )
\r
4933 return AppKey_addNewWritableFolder( Path );
\r
4938 /***********************************************************************
\r
4939 <<< [Writables_init] >>>
\r
4940 ************************************************************************/
\r
4941 static void Writables_initConst( Writables* m )
\r
4943 m->m_Paths = NULL;
\r
4948 static errnum_t Writables_init( Writables* m, AppKey* Key )
\r
4950 IF( ! AppKey_isSame( Key ) ) return E_OTHERS;
\r
4952 m->m_Paths = NULL;
\r
4958 static errnum_t Writables_finish( Writables* m, int e )
\r
4962 ee= Writables_clearPaths( m ); IF(ee&&!e) e=ee;
\r
4968 static bool Writables_isInited( Writables* m )
\r
4970 return ( m->m_nPath != -1 );
\r
4974 static errnum_t Writables_clearPaths( Writables* m )
\r
4979 if ( m->m_Paths != NULL ) {
\r
4980 p_over = m->m_Paths + m->m_nPath;
\r
4981 for ( p = m->m_Paths; p < p_over; p++ ) {
\r
4984 free( m->m_Paths ); m->m_Paths = NULL;
\r
4991 static errnum_t Writables_create( Writables** out_m, AppKey* Key )
\r
4996 m = (Writables*) malloc( sizeof(*m) ); IF(m==NULL)return E_FEW_MEMORY;
\r
4997 Writables_initConst( m );
\r
4998 e= Writables_init( m, Key ); IF(e)goto resume;
\r
5001 resume: Writables_delete( m, 0 ); free(m); return e;
\r
5005 errnum_t Writables_delete( Writables* m, errnum_t e )
\r
5007 if ( m == NULL ) goto fin;
\r
5008 e= Writables_finish( m, e );
\r
5016 /***********************************************************************
\r
5017 <<< [Writables_add] >>>
\r
5018 ************************************************************************/
\r
5019 int Writables_add( Writables* m, AppKey* Key, const TCHAR* Path )
\r
5025 TCHAR abs_path[MAX_PATH];
\r
5027 IF( ! AppKey_isSame( Key ) )goto err;
\r
5028 if ( Path[0] == _T('\0') ) return 0;
\r
5030 e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto resume;
\r
5032 e= CurrentWritables_askFileAccess( &g_CurrentWritablesPrivate, abs_path ); IF(e)goto resume;
\r
5034 pp = (TCHAR**) realloc( m->m_Paths, (m->m_nPath + 1) * sizeof(TCHAR*) );
\r
5035 IF( pp == NULL ) goto err;
\r
5038 path_size = (_tcslen( abs_path ) + 1) * sizeof(TCHAR);
\r
5039 p = (TCHAR*) malloc( path_size );
\r
5040 m->m_Paths[ m->m_nPath ] = p;
\r
5041 IF( p == NULL )goto err;
\r
5043 memcpy( p, abs_path, path_size );
\r
5044 if ( p[ path_size/sizeof(TCHAR) - 2 ] == _T('\\') )
\r
5045 p[ path_size/sizeof(TCHAR) - 2 ] = _T('\0');
\r
5052 err: e = E_OTHERS; goto resume;
\r
5054 if ( p != NULL ) free( p );
\r
5059 int Writables_remove( Writables* m, const TCHAR* Path )
\r
5064 pp_over = m->m_Paths + m->m_nPath;
\r
5065 for ( pp = m->m_Paths; ; pp++ ) {
\r
5066 if ( pp >= pp_over ) return 0;
\r
5067 if ( _tcscmp( *pp, Path ) == 0 ) break;
\r
5070 memmove( pp, pp+1, (char*)pp - (char*)pp_over - sizeof(TCHAR) );
\r
5074 *( pp_over - 1 ) = NULL;
\r
5082 /***********************************************************************
\r
5083 <<< [Writables_enable] >>>
\r
5084 ************************************************************************/
\r
5085 int Writables_enable( Writables* m )
\r
5089 e= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, m ); IF(e)goto fin;
\r
5090 e= Writables_copyToConst( &g_CurrentWritables, &g_CurrentWritablesPrivate.m_CurrentWritables ); IF(e)goto fin;
\r
5098 int Writables_disable( Writables* m, int e )
\r
5102 UNREFERENCED_VARIABLE( m );
\r
5104 ee= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, NULL ); IF(ee&&!e)goto fin;
\r
5105 ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)goto fin;
\r
5113 static int Writables_copyToConst( Writables* To, Writables* From )
\r
5122 if ( To->m_Paths != NULL ) {
\r
5123 free( To->m_Paths );
\r
5124 To->m_Paths = NULL;
\r
5128 if ( From != NULL && From->m_nPath > 0 ) {
\r
5131 pp_over = From->m_Paths + From->m_nPath;
\r
5132 for ( pp = From->m_Paths; pp < pp_over; pp++ ) {
\r
5133 path_size += _tcslen( *pp ) + 1;
\r
5136 path_size = From->m_nPath * sizeof(TCHAR*) + path_size * sizeof(TCHAR);
\r
5137 To->m_Paths = (TCHAR**) malloc( path_size );
\r
5138 IF( To->m_Paths == NULL ) goto err;
\r
5140 p2 = (TCHAR*)( (char*)To->m_Paths + From->m_nPath * sizeof(TCHAR*) );
\r
5141 pp2 = To->m_Paths;
\r
5142 for ( pp = From->m_Paths; pp < pp_over; pp++ ) {
\r
5144 path_size = (_tcslen( *pp ) + 1) * sizeof(TCHAR);
\r
5145 memcpy( p2, *pp, path_size );
\r
5146 p2 = (TCHAR*)( (char*)p2 + path_size );
\r
5149 To->m_nPath = From->m_nPath;
\r
5156 err: e = E_OTHERS; goto fin;
\r
5160 /***********************************************************************
\r
5161 <<< [CurrentWritables] >>>
\r
5162 ************************************************************************/
\r
5163 static void CurrentWritables_initConst( CurrentWritables* m )
\r
5165 Writables_initConst( &m->m_CurrentWritables );
\r
5166 m->m_ProgramFiles = NULL;
\r
5167 m->m_windir = NULL;
\r
5168 m->m_APPDATA = NULL;
\r
5169 m->m_LOCALAPPDATA = NULL;
\r
5173 static int CurrentWritables_init( CurrentWritables* m )
\r
5176 #if Uses_OutMallocIDTool
\r
5177 bool is_prev_out_malloc;
\r
5179 is_prev_out_malloc = OutMallocID_setEnable( false );
\r
5182 e= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(e)goto fin;
\r
5184 e= env_malloc( &m->m_ProgramFiles, &m->m_ProgramFiles_Len, _T("ProgramFiles") ); IF(e)goto fin;
\r
5185 e= env_malloc( &m->m_windir, &m->m_windir_Len, _T("windir") ); IF(e)goto fin;
\r
5186 e= env_malloc( &m->m_APPDATA, &m->m_APPDATA_Len, _T("APPDATA") ); IF(e)goto fin;
\r
5187 // e= env_malloc( &m->m_LOCALAPPDATA, &m->m_LOCALAPPDATA_Len, _T("LOCALAPPDATA") ); IF(e)goto fin;
\r
5191 #if Uses_OutMallocIDTool
\r
5192 OutMallocID_setEnable( is_prev_out_malloc );
\r
5198 static int CurrentWritables_finish( CurrentWritables* m, int e )
\r
5202 ee= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(ee&&!e)e=ee;
\r
5204 if ( m->m_ProgramFiles != NULL ) free( m->m_ProgramFiles );
\r
5205 if ( m->m_windir != NULL ) free( m->m_windir );
\r
5206 if ( m->m_APPDATA != NULL ) free( m->m_APPDATA );
\r
5207 if ( m->m_LOCALAPPDATA != NULL ) free( m->m_LOCALAPPDATA );
\r
5209 m->m_ProgramFiles = NULL;
\r
5210 m->m_windir = NULL;
\r
5211 m->m_APPDATA = NULL;
\r
5212 m->m_LOCALAPPDATA = NULL;
\r
5218 static int CurrentWritables_askFileAccess_sub(
\r
5219 const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* FullPath, size_t FullPath_Len );
\r
5221 static int CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath )
\r
5226 abs_len = _tcslen( FullPath );
\r
5227 e= CurrentWritables_askFileAccess_sub( m->m_ProgramFiles, m->m_ProgramFiles_Len, FullPath, abs_len ); IF(e)goto fin;
\r
5228 e= CurrentWritables_askFileAccess_sub( m->m_windir, m->m_windir_Len, FullPath, abs_len ); IF(e)goto fin;
\r
5229 e= CurrentWritables_askFileAccess_sub( m->m_APPDATA, m->m_APPDATA_Len, FullPath, abs_len ); IF(e)goto fin;
\r
5230 e= CurrentWritables_askFileAccess_sub( m->m_LOCALAPPDATA, m->m_LOCALAPPDATA_Len, FullPath, abs_len ); IF(e)goto fin;
\r
5238 static int CurrentWritables_askFileAccess_sub(
\r
5239 const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* FullPath, size_t FullPath_Len )
\r
5241 if ( SystemPath == NULL ) return 0;
\r
5243 IF ( _tcsncmp( SystemPath, FullPath, SystemPath_Len ) == 0 )
\r
5244 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
5246 IF ( _tcsncmp( SystemPath, FullPath, FullPath_Len ) == 0 )
\r
5247 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
5254 /*=================================================================*/
\r
5255 /* <<< [Error4/Error4.c] >>> */
\r
5256 /*=================================================================*/
\r
5258 /***********************************************************************
\r
5259 <<< [Get_Error4_Variables] >>>
\r
5260 ************************************************************************/
\r
5261 static Error4_VariablesClass gs;
\r
5263 extern Error4_VariablesClass* g_Error4_Variables = &gs;
\r
5266 Error4_VariablesClass* Get_Error4_Variables()
\r
5273 /***********************************************************************
\r
5274 <<< (SetBreakErrorID) >>>
\r
5275 ************************************************************************/
\r
5278 void DebugBreakR()
\r
5280 printf( "
\83u
\83\8c\81[
\83N
\82µ
\82Ü
\82·
\81B
\82à
\82µ
\83f
\83o
\83b
\83K
\81[
\82ª
\90Ú
\91±
\82³
\82ê
\82Ä
\82¢
\82È
\82¯
\82ê
\82Î
\8b
\90§
\8fI
\97¹
\82µ
\82Ü
\82·
\81B\n" );
\r
5282 // Visual Studio 2008
\82Å
\82Í
\81A
\82±
\82±
\82Å [
\83f
\83o
\83b
\83O >
\83X
\83e
\83b
\83v
\83A
\83E
\83g ]
\82µ
\82È
\82¢
\82Æ
\r
5283 //
\8cÄ
\82Ñ
\8fo
\82µ
\97\9a\97ð
\82â
\83E
\83H
\83b
\83`
\82Ì
\93à
\97e
\82ª
\90³
\82µ
\82
\82È
\82è
\82Ü
\82¹
\82ñ
\81B
\r
5287 #if ENABLE_ERROR_BREAK_IN_ERROR_CLASS
\r
5290 #if ! IS_MULTI_THREAD_ERROR_CLASS
\r
5291 dll_global_g_DebugBreakCount ErrorClass g_Error; /*
\8f\89\8aú
\92l
\82Í
\82·
\82×
\82Ä
\83[
\83\8d */
\r
5293 dll_global_g_DebugBreakCount GlobalErrorClass g_GlobalError;
\r
5295 static errnum_t ErrorClass_initializeIfNot_Sub( ErrorClass** out_Error );
\r
5296 static errnum_t ErrorClass_initializeIfNot_Sub2(void);
\r
5300 #define IF_ if /* Error check for in "IF" macro */
\r
5303 /*[SetBreakErrorID]*/
\r
5304 void SetBreakErrorID( int ErrorID )
\r
5306 #if ! IS_MULTI_THREAD_ERROR_CLASS
\r
5308 ErrorClass* err = &g_Error;
\r
5311 is_print = ( err->BreakErrorID != ErrorID );
\r
5313 err->BreakErrorID = ErrorID;
\r
5314 /* printf
\82Ì
\92\86\82Å
\94
\90¶
\82·
\82é
\83G
\83\89\81[
\82Å
\8e~
\82ß
\82é
\82½
\82ß */
\r
5317 { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }
\r
5321 GlobalErrorClass* err_global = &g_GlobalError;
\r
5323 if ( err_global->BreakGlobalErrorID != ErrorID )
\r
5324 { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }
\r
5325 err_global->BreakGlobalErrorID = ErrorID;
\r
5332 bool OnRaisingError_Sub( const char* FilePath, int LineNum )
\r
5333 //
\96{
\8aÖ
\90\94\82Í
\81AIF
\83}
\83N
\83\8d\82Ì
\92\86\82©
\82ç
\8cÄ
\82Î
\82ê
\82Ü
\82·
\r
5334 //
\95Ô
\82è
\92l
\82Í
\81A
\83u
\83\8c\81[
\83N
\82·
\82é
\82©
\82Ç
\82¤
\82©
\r
5336 #if ! IS_MULTI_THREAD_ERROR_CLASS
\r
5338 ErrorClass* err = &g_Error;
\r
5341 /*
\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«
\81i
\8d\82\91¬
\83\8a\83^
\81[
\83\93\81j */
\r
5342 if ( err->IsError ) {
\r
5346 /*
\83G
\83\89\81[
\82ª
\94
\90¶
\82µ
\82½
\92¼
\8cã
\82Ì
\82Æ
\82« */
\r
5347 err->ErrorID += 1;
\r
5348 err->IsError = true;
\r
5349 err->FilePath = FilePath;
\r
5350 err->LineNum = LineNum;
\r
5352 #if ERR2_ENABLE_ERROR_LOG
\r
5353 printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",
\r
5354 err->ErrorID, (int) err );
\r
5357 is_break = ( err->ErrorID == err->BreakErrorID );
\r
5360 printf( "Break in (%d) %s\n", LineNum, FilePath );
\r
5362 return ( err->ErrorID == err->BreakErrorID );
\r
5364 #else /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5367 bool is_break = false;
\r
5370 e= ErrorClass_initializeIfNot_Sub( &err ); IF_(e){goto fin;}
\r
5373 /*
\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«
\81i
\8d\82\91¬
\83\8a\83^
\81[
\83\93\81j */
\r
5374 if ( err->IsError ) {
\r
5378 /*
\83G
\83\89\81[
\82ª
\94
\90¶
\82µ
\82½
\92¼
\8cã
\82Ì
\82Æ
\82« */
\r
5380 GlobalErrorClass* err_global = &g_GlobalError;
\r
5382 EnterCriticalSection( &err_global->CriticalSection );
\r
5385 err_global->ErrorThreadCount += 1;
\r
5386 err_global->RaisedGlobalErrorID += 1;
\r
5387 err->GlobalErrorID = err_global->RaisedGlobalErrorID;
\r
5389 err->ErrorID += 1;
\r
5390 err->IsError = true;
\r
5391 err->FilePath = FilePath;
\r
5392 err->LineNum = LineNum;
\r
5394 is_break = ( err->ErrorID == err->BreakErrorID ) ||
\r
5395 ( err->GlobalErrorID == err_global->BreakGlobalErrorID );
\r
5398 /*
\82±
\82±
\82æ
\82è
\88È
\8d~
\82Í
\81AIF
\83}
\83N
\83\8d\82È
\82Ç
\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\89Â
\94\
\81i
\83\8a\83G
\83\93\83g
\83\89\83\93\83g
\89Â
\94\
\81j */
\r
5399 /*
\8fã
\8bL
\82Ì if ( err->IsError )
\82Å
\81A
\82·
\82®
\96ß
\82é
\82½
\82ß */
\r
5402 #if ERR2_ENABLE_ERROR_LOG
\r
5403 printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",
\r
5404 err->GlobalErrorID, (int) err );
\r
5408 if ( err->ErrorID == 1 ) {
\r
5409 FinalizerClass_initConst( &err->Finalizer, err, ErrorClass_finalize );
\r
5410 e= AddThreadLocalFinalizer( &err->Finalizer );
\r
5415 LeaveCriticalSection( &err_global->CriticalSection );
\r
5422 printf( "Break in (%d) %s\n", LineNum, FilePath );
\r
5426 #endif /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5433 #if ! IS_MULTI_THREAD_ERROR_CLASS
\r
5435 ErrorClass* err = &g_Error;
\r
5437 #if ERR2_ENABLE_ERROR_LOG
\r
5438 if ( err->IsError ) {
\r
5439 printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",
\r
5440 err->ErrorID, (int) err );
\r
5444 err->IsError = false;
\r
5446 #else /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5451 e= ErrorClass_initializeIfNot_Sub( &err );
\r
5453 #if ERR2_ENABLE_ERROR_LOG
\r
5454 if ( err->IsError )
\r
5455 printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",
\r
5456 err->GlobalErrorID, (int) err );
\r
5459 if ( err->IsError ) {
\r
5460 GlobalErrorClass* err_global = &g_GlobalError;
\r
5462 EnterCriticalSection( &err_global->CriticalSection );
\r
5463 err_global->ErrorThreadCount -= 1;
\r
5464 LeaveCriticalSection( &err_global->CriticalSection );
\r
5466 err->IsError = false;
\r
5470 #if ERR2_ENABLE_ERROR_LOG
\r
5471 printf( "<ERROR_LOG msg=\"clear_miss\"/>\n" );
\r
5475 #endif /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5479 //[IfErrThenBreak]
\r
5480 void IfErrThenBreak()
\r
5482 #if ! IS_MULTI_THREAD_ERROR_CLASS
\r
5484 ErrorClass* err = &g_Error;
\r
5486 if ( err->IsError &&
\r
5487 ( err->ErrorID != err->BreakErrorID || err->BreakErrorID == 0 )
\r
5489 printf( "in IfErrThenBreak\n" );
\r
5492 //
\83E
\83H
\83b
\83`
\82Å
\81Aerr->ErrorID
\82Ì
\92l(N
\82Æ
\82·
\82é)
\82ð
\8am
\94F
\82µ
\82Ä
\81A
\r
5493 //
\83\81\83C
\83\93\8aÖ
\90\94\82Å SetBreakErrorID( N );
\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B
\r
5494 //
\83G
\83\89\81[
\82ª
\94
\90¶
\82µ
\82½
\8fê
\8f\8a\82Í
\81Aerr->FilePath, err->LineNum
\82Å
\82·
\81B
\r
5495 //
\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
5496 // ClearError()
\82ð
\96Y
\82ê
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82è
\82Ü
\82·
\81B
\r
5497 #if ERR2_ENABLE_ERROR_LOG
\r
5498 printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",
\r
5499 err->ErrorID, err->BreakErrorID );
\r
5504 sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",
\r
5505 err->FilePath, err->LineNum );
\r
5506 OutputDebugStringA( str );
\r
5511 #else /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5514 GlobalErrorClass* err_global = &g_GlobalError;
\r
5517 e= ErrorClass_initializeIfNot_Sub( &err );
\r
5518 if ( e ) { DebugBreakR(); ClearError(); return; } /*
\93à
\95\94\83G
\83\89\81[ */
\r
5520 if ( err_global->ErrorThreadCount != 0 &&
\r
5521 ( err->GlobalErrorID != err_global->BreakGlobalErrorID || err_global->BreakGlobalErrorID == 0 )
\r
5523 printf( "in IfErrThenBreak\n" );
\r
5526 //
\83E
\83H
\83b
\83`
\82Å
\81Aerr->GlobalErrorID
\82Ì
\92l(N
\82Æ
\82·
\82é)
\82ð
\8am
\94F
\82µ
\82Ä
\81A
\r
5527 //
\83\81\83C
\83\93\8aÖ
\90\94\82Å SetBreakErrorID( N );
\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B
\r
5528 //
\83G
\83\89\81[
\82ª
\94
\90¶
\82µ
\82½
\8fê
\8f\8a\82Í
\81Aerr->FilePath, err->LineNum
\82Å
\82·
\81B
\r
5529 //
\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
5530 // ClearError()
\82ð
\96Y
\82ê
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82è
\82Ü
\82·
\81B
\r
5531 #if ERR2_ENABLE_ERROR_LOG
\r
5532 printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",
\r
5533 err->ErrorID, err->BreakErrorID );
\r
5538 sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",
\r
5539 err->FilePath, err->LineNum );
\r
5540 OutputDebugStringA( str );
\r
5545 #endif /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5550 void PushErr( ErrStackAreaClass* ErrStackArea )
\r
5552 #if ! IS_MULTI_THREAD_ERROR_CLASS
\r
5554 ErrorClass* err = &g_Error;
\r
5556 ErrStackArea->ErrorID = err->ErrorID;
\r
5557 ErrStackArea->IsError = err->IsError;
\r
5558 err->IsError = false;
\r
5560 #else /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5565 e= ErrorClass_initializeIfNot_Sub( &err );
\r
5567 ErrStackArea->ErrorID = err->ErrorID;
\r
5568 ErrStackArea->IsError = err->IsError;
\r
5569 err->IsError = false;
\r
5572 #endif /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5576 void PopErr( ErrStackAreaClass* ErrStackArea )
\r
5578 #if ! IS_MULTI_THREAD_ERROR_CLASS
\r
5580 ErrorClass* err = &g_Error;
\r
5582 if ( ErrStackArea->IsError )
\r
5583 { err->IsError = true; }
\r
5585 #else /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5590 e= ErrorClass_initializeIfNot_Sub( &err );
\r
5592 if ( ErrStackArea->IsError )
\r
5593 { err->IsError = true; }
\r
5596 #endif /* IS_MULTI_THREAD_ERROR_CLASS */
\r
5601 /*[SetBreakErrorID:2]*/
\r
5605 #endif // ENABLE_ERROR_BREAK_IN_ERROR_CLASS
\r
5609 errnum_t MergeError( errnum_t e, errnum_t ee )
\r
5611 if ( e == 0 ) { return ee; }
\r
5612 else { /* ErrorLog_add( ee ); */ return e; }
\r
5617 /***********************************************************************
\r
5618 <<< [g_Error4_String] >>>
\r
5619 ************************************************************************/
\r
5620 TCHAR g_Error4_String[4096];
\r
5624 /***********************************************************************
\r
5625 <<< [Error4_printf] >>>
\r
5626 ************************************************************************/
\r
5627 void Error4_printf( const TCHAR* format, ... )
\r
5630 va_start( va, format );
\r
5631 vstprintf_r( g_Error4_String, sizeof(g_Error4_String), format, va );
\r
5637 /***********************************************************************
\r
5638 <<< [Error4_getErrStr] >>>
\r
5639 ************************************************************************/
\r
5640 void Error4_getErrStr( int ErrNum, TCHAR* out_ErrStr, size_t ErrStrSize )
\r
5642 switch ( ErrNum ) {
\r
5645 stprintf_r( out_ErrStr, ErrStrSize, _T("no error") );
\r
5649 stprintf_r( out_ErrStr, ErrStrSize,
\r
5650 _T("<ERROR msg=\"
\83v
\83\8d\83O
\83\89\83\80\93à
\95\94\82Ì
\94z
\97ñ
\83\81\83\82\83\8a\81[
\82ª
\95s
\91«
\82µ
\82Ü
\82µ
\82½
\81B\"/>") );
\r
5653 case E_FEW_MEMORY:
\r
5654 stprintf_r( out_ErrStr, ErrStrSize,
\r
5655 _T("<ERROR msg=\"
\83q
\81[
\83v
\81E
\83\81\83\82\83\8a\81[
\82ª
\95s
\91«
\82µ
\82Ü
\82µ
\82½
\81B\"/>") );
\r
5659 case E_GET_LAST_ERROR: {
\r
5661 TCHAR* str_pointer;
\r
5663 err_win = gs.WindowsLastError;
\r
5664 if ( err_win == 0 ) { err_win = GetLastError(); }
\r
5666 stprintf_part_r( out_ErrStr, ErrStrSize, out_ErrStr, &str_pointer,
\r
5667 _T("<ERROR GetLastError=\"0x%08X\" GetLastErrorStr=\""), err_win );
\r
5668 FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
\r
5669 NULL, err_win, LANG_USER_DEFAULT,
\r
5670 str_pointer, (TCHAR*)( (char*)out_ErrStr + ErrStrSize ) - str_pointer, NULL );
\r
5671 str_pointer = StrT_chr( str_pointer, _T('\0') );
\r
5672 if ( *( str_pointer - 2 ) == _T('\r') && *( str_pointer - 1 ) == _T('\n') )
\r
5674 stcpy_part_r( out_ErrStr, ErrStrSize, str_pointer, NULL, _T("\"/>"), NULL );
\r
5680 if ( g_Error4_String[0] != '\0' )
\r
5681 stprintf_r( out_ErrStr, ErrStrSize, _T("%s"), g_Error4_String );
\r
5683 stprintf_r( out_ErrStr, ErrStrSize, _T("<ERROR errnum=\"%d\"/>"), ErrNum );
\r
5690 /***********************************************************************
\r
5691 <<< [SaveWindowsLastError] >>>
\r
5692 ************************************************************************/
\r
5693 errnum_t SaveWindowsLastError()
\r
5695 gs.WindowsLastError = GetLastError();
\r
5696 return E_GET_LAST_ERROR;
\r
5701 /***********************************************************************
\r
5702 <<< [Error4_showToStdErr] >>>
\r
5703 ************************************************************************/
\r
5704 void Error4_showToStdErr( int err_num )
\r
5706 Error4_showToStdIO( stderr, err_num );
\r
5711 /***********************************************************************
\r
5712 <<< [Error4_showToStdIO] >>>
\r
5713 ************************************************************************/
\r
5714 void Error4_showToStdIO( FILE* out, int err_num )
\r
5721 if ( err_num != 0 ) {
\r
5722 Error4_getErrStr( err_num, msg, sizeof(msg) );
\r
5724 setlocale( LC_ALL, ".OCP" );
\r
5725 sprintf_s( msg2, sizeof(msg2), "%S", msg );
\r
5726 fprintf( out, "%s\n", msg2 ); // _ftprintf_s
\82Å
\82Í
\93ú
\96{
\8cê
\82ª
\8fo
\82Ü
\82¹
\82ñ
\r
5728 fprintf( out, "%s\n", msg );
\r
5731 #if ERR2_ENABLE_ERROR_BREAK
\r
5732 fprintf( out, "
\81i
\8aJ
\94
\8eÒ
\82Ö
\81j
\83\81\83C
\83\93\8aÖ
\90\94\82Å SetBreakErrorID( %d );
\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B\n",
\r
5736 if ( err_num == E_FEW_MEMORY || gs.WindowsLastError == ERROR_NOT_ENOUGH_MEMORY ) {
\r
5737 /* Not show the message for developper */
\r
5740 fprintf( out, "
\81i
\8aJ
\94
\8eÒ
\82Ö
\81jERR2_ENABLE_ERROR_BREAK
\82ð
\92è
\8b`
\82µ
\82Ä
\8dÄ
\83R
\83\93\83p
\83C
\83\8b\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B\n" );
\r
5750 /***********************************************************************
\r
5751 <<< [Error4_showToPrintf] >>>
\r
5752 ************************************************************************/
\r
5753 void Error4_showToPrintf( int err_num )
\r
5760 if ( err_num != 0 ) {
\r
5761 Error4_getErrStr( err_num, msg, sizeof(msg) );
\r
5763 setlocale( LC_ALL, ".OCP" );
\r
5764 sprintf_s( msg2, sizeof(msg2), "%S", msg );
\r
5765 printf( "%s\n", msg2 ); // _ftprintf_s
\82Å
\82Í
\93ú
\96{
\8cê
\82ª
\8fo
\82Ü
\82¹
\82ñ
\r
5767 printf( "%s\n", msg );
\r
5770 #if ERR2_ENABLE_ERROR_BREAK
\r
5771 fprintf( out, "
\81i
\8aJ
\94
\8eÒ
\82Ö
\81j
\83\81\83C
\83\93\8aÖ
\90\94\82Å SetBreakErrorID( %d );
\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B\n",
\r
5775 if ( err_num == E_FEW_MEMORY || gs.WindowsLastError == ERROR_NOT_ENOUGH_MEMORY ) {
\r
5776 /* Not show the message for developper */
\r
5779 fprintf( out, "
\81i
\8aJ
\94
\8eÒ
\82Ö
\81jERR2_ENABLE_ERROR_BREAK
\82ð
\92è
\8b`
\82µ
\82Ä
\8dÄ
\83R
\83\93\83p
\83C
\83\8b\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B\n" );
\r
5789 /*=================================================================*/
\r
5790 /* <<< [CRT_plus_2/CRT_plus_2.c] >>> */
\r
5791 /*=================================================================*/
\r
5793 /**************************************************************************
\r
5794 <<< [Interface] >>>
\r
5795 ***************************************************************************/
\r
5797 /*[DefaultFunction]*/
\r
5798 errnum_t DefaultFunction( void* self )
\r
5800 UNREFERENCED_VARIABLE( self );
\r
5804 /*[DefaultFunction_NotImplementYet]*/
\r
5805 errnum_t DefaultFunction_NotImplementYet( void* self )
\r
5807 UNREFERENCED_VARIABLE( self );
\r
5808 return E_NOT_IMPLEMENT_YET;
\r
5811 /*[DefaultFunction_Finalize]*/
\r
5812 errnum_t DefaultFunction_Finalize( void* self, errnum_t e )
\r
5814 UNREFERENCED_VARIABLE( self );
\r
5818 /*[VTableDefine_overwrite]*/
\r
5819 errnum_t VTableDefine_overwrite( VTableDefine* aVTable, size_t aVTable_ByteSize, int iMethod, void* Func )
\r
5821 VTableDefine* p = aVTable;
\r
5822 VTableDefine* p_over = (VTableDefine*)( (char*)aVTable + aVTable_ByteSize );
\r
5824 for ( ; p < p_over; p++ ) {
\r
5825 if ( p->m_IMethod == iMethod ) {
\r
5826 p->m_method = Func;
\r
5830 return E_NOT_FOUND_SYMBOL;
\r
5835 /*=================================================================*/
\r
5836 /* <<< [StrT/StrT.c] >>> */
\r
5837 /*=================================================================*/
\r
5839 /***********************************************************************
\r
5840 <<< [StrT_cpy] >>>
\r
5841 - _tcscpy is raising exception, if E_FEW_ARRAY
\r
5842 ************************************************************************/
\r
5843 errnum_t StrT_cpy( TCHAR* Dst, size_t DstSize, const TCHAR* Src )
\r
5847 size = ( _tcslen( Src ) + 1 ) * sizeof(TCHAR);
\r
5848 if ( size <= DstSize ) {
\r
5849 memcpy( Dst, Src, size );
\r
5853 memcpy( Dst, Src, DstSize - sizeof(TCHAR) );
\r
5854 *(TCHAR*)( (char*) Dst + DstSize ) = _T('\0');
\r
5855 return E_FEW_ARRAY;
\r
5860 /***********************************************************************
\r
5861 <<< [StrT_chr] >>>
\r
5862 ************************************************************************/
\r
5863 TCHAR* StrT_chr( const TCHAR* String, TCHAR Key )
\r
5865 const TCHAR* return_value = _tcschr( String, Key );
\r
5867 if ( return_value == NULL && Key == _T('\0') ) {
\r
5868 return_value = String + _tcslen( String );
\r
5871 return (TCHAR*) return_value;
\r
5875 /***********************************************************************
\r
5876 <<< [StrT_chrNext] >>>
\r
5877 ************************************************************************/
\r
5878 TCHAR* StrT_chrNext( const TCHAR* in_Start, TCHAR in_KeyCharactor )
\r
5880 const TCHAR* p = _tcschr( in_Start, in_KeyCharactor );
\r
5885 return (TCHAR*) p;
\r
5889 /***********************************************************************
\r
5890 <<< [CharPointerArray_free] >>>
\r
5891 ************************************************************************/
\r
5892 errnum_t CharPointerArray_free( TCHAR*** in_out_Strings, int in_StringCount,
\r
5893 bool in_IsFreePointers, errnum_t e )
\r
5895 TCHAR** strings = *in_out_Strings;
\r
5898 for ( i = 0; i < in_StringCount; i += 1 ) {
\r
5899 e= HeapMemory_free( &strings[i], e );
\r
5902 if ( in_IsFreePointers ) {
\r
5903 e= HeapMemory_free( in_out_Strings, e );
\r
5911 /***********************************************************************
\r
5912 <<< [MallocAndCopyString] >>>
\r
5913 ************************************************************************/
\r
5914 errnum_t MallocAndCopyString( const TCHAR** out_NewString, const TCHAR* SourceString )
\r
5917 size_t size = ( _tcslen( SourceString ) + 1 ) * sizeof(TCHAR);
\r
5919 ASSERT_D( *out_NewString == NULL, __noop() );
\r
5921 str = (TCHAR*) malloc( size );
\r
5922 if ( str == NULL ) { return E_FEW_MEMORY; }
\r
5924 memcpy( str, SourceString, size );
\r
5926 *out_NewString = str;
\r
5932 /***********************************************************************
\r
5933 <<< [MallocAndCopyString_char] >>>
\r
5934 ************************************************************************/
\r
5936 errnum_t MallocAndCopyString_char( const TCHAR** out_NewString, const char* SourceString )
\r
5939 size_t size = ( strlen( SourceString ) + 1 ) * sizeof(TCHAR);
\r
5942 str = (TCHAR*) malloc( size );
\r
5943 if ( str == NULL ) { return E_FEW_MEMORY; }
\r
5945 r = MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED, SourceString, -1, str, size / sizeof(TCHAR) );
\r
5948 return E_GET_LAST_ERROR;
\r
5950 *out_NewString = str;
\r
5957 /***********************************************************************
\r
5958 <<< [MallocAndCopyStringByLength] >>>
\r
5959 ************************************************************************/
\r
5960 errnum_t MallocAndCopyStringByLength( const TCHAR** out_NewString, const TCHAR* SourceString,
\r
5961 unsigned CountOfCharacter )
\r
5964 size_t size = ( CountOfCharacter + 1 ) * sizeof(TCHAR);
\r
5966 ASSERT_D( *out_NewString == NULL, __noop() );
\r
5967 ASSERT_D( CountOfCharacter < 0x7FFFFFFF, __noop() );
\r
5969 str = (TCHAR*) malloc( size );
\r
5970 if ( str == NULL ) { return E_FEW_MEMORY; }
\r
5972 memcpy( str, SourceString, size - sizeof(TCHAR) );
\r
5973 str[ CountOfCharacter ] = _T('\0');
\r
5975 *out_NewString = str;
\r
5981 /***********************************************************************
\r
5982 <<< [StrT_chrs] >>>
\r
5983 ************************************************************************/
\r
5984 TCHAR* StrT_chrs( const TCHAR* s, const TCHAR* keys )
\r
5986 if ( *keys == _T('\0') ) return NULL;
\r
5988 for ( ; *s != _T('\0'); s++ ) {
\r
5989 if ( _tcschr( keys, *s ) != NULL )
\r
5990 return (TCHAR*) s;
\r
5997 /***********************************************************************
\r
5998 <<< [StrT_rstr] >>>
\r
5999 ************************************************************************/
\r
6000 TCHAR* StrT_rstr( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keyword,
\r
6001 void* NullConfig )
\r
6004 int keyword_length = _tcslen( Keyword );
\r
6005 TCHAR keyword_first = Keyword[0];
\r
6007 UNREFERENCED_VARIABLE( NullConfig );
\r
6010 while ( p >= String ) {
\r
6011 if ( *p == keyword_first ) {
\r
6012 if ( _tcsncmp( p, Keyword, keyword_length ) == 0 ) {
\r
6013 return (TCHAR*) p;
\r
6024 /***********************************************************************
\r
6025 <<< [StrT_skip] >>>
\r
6026 ************************************************************************/
\r
6027 TCHAR* StrT_skip( const TCHAR* String, const TCHAR* Keys )
\r
6029 if ( *Keys == _T('\0') ) { return (TCHAR*) String; }
\r
6031 for ( ; *String != _T('\0'); String += 1 ) {
\r
6032 if ( _tcschr( Keys, *String ) == NULL )
\r
6035 return (TCHAR*) String;
\r
6040 /***********************************************************************
\r
6041 <<< [StrT_rskip] >>>
\r
6042 ************************************************************************/
\r
6043 TCHAR* StrT_rskip( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keys,
\r
6044 void* NullConfig )
\r
6046 const TCHAR* pointer;
\r
6048 UNREFERENCED_VARIABLE( NullConfig );
\r
6050 if ( *Keys == _T('\0') ) { return (TCHAR*) SearchStart; }
\r
6052 for ( pointer = SearchStart; pointer >= String; pointer -= 1 ) {
\r
6053 if ( _tcschr( Keys, *pointer ) == NULL )
\r
6054 { return (TCHAR*) pointer; }
\r
6061 /***********************************************************************
\r
6062 <<< [StrT_isCIdentifier] >>>
\r
6063 ************************************************************************/
\r
6064 bool StrT_isCIdentifier( TCHAR Character )
\r
6066 const TCHAR c = Character;
\r
6069 ( c >= _T('A') && c <= _T('Z') ) ||
\r
6070 ( c >= _T('a') && c <= _T('z') ) ||
\r
6071 ( c >= _T('0') && c <= _T('9') ) ||
\r
6077 /***********************************************************************
\r
6078 <<< [StrT_searchOverOfCIdentifier] >>>
\r
6079 ************************************************************************/
\r
6080 TCHAR* StrT_searchOverOfCIdentifier( const TCHAR* Text )
\r
6085 StrT_isCIdentifier( *p );
\r
6089 return (TCHAR*) p;
\r
6094 /***********************************************************************
\r
6095 <<< [StrT_searchOverOfIdiom] >>>
\r
6096 ************************************************************************/
\r
6097 TCHAR* StrT_searchOverOfIdiom( const TCHAR* Text )
\r
6103 StrT_isCIdentifier( *p ) || *p == _T(' ');
\r
6109 *p == _T(' ') && p >= Text;
\r
6114 return (TCHAR*) p + 1;
\r
6119 /***********************************************************************
\r
6120 <<< [StrT_convPartStrToPointer] >>>
\r
6121 ************************************************************************/
\r
6122 void* StrT_convPartStrToPointer( const TCHAR* StringStart, const TCHAR* StringOver,
\r
6123 const NameOnlyClass* Table, size_t TableSize, void* Default )
\r
6125 const NameOnlyClass* p = Table;
\r
6126 const NameOnlyClass* p_over = (const NameOnlyClass*)( (uint8_t*) Table + TableSize );
\r
6128 while ( p < p_over ) {
\r
6129 if ( StrT_cmp_part( StringStart, StringOver, p->Name ) == 0 ) {
\r
6130 return (void*) p->Delegate;
\r
6139 /***********************************************************************
\r
6140 <<< [StrT_convertNumToStr] >>>
\r
6141 ************************************************************************/
\r
6142 TCHAR* StrT_convertNumToStr( int Number, const NameAndNumClass* Table, int TableCount,
\r
6143 const TCHAR* DefaultStr )
\r
6145 const NameAndNumClass* p;
\r
6146 const NameAndNumClass* p_over = Table + TableCount;
\r
6148 for ( p = Table; p < p_over; p += 1 ) {
\r
6149 if ( p->Number == Number ) {
\r
6153 return (TCHAR*) DefaultStr;
\r
6158 /***********************************************************************
\r
6159 <<< [StrT_cmp_part] >>>
\r
6160 ************************************************************************/
\r
6161 int StrT_cmp_part( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,
\r
6162 const TCHAR* in_StringB )
\r
6169 a = in_StringA_Start;
\r
6173 if ( a >= in_StringA_Over ) {
\r
6175 if ( bb == _T('\0') )
\r
6184 if ( bb == _T('\0') )
\r
6188 { return aa - bb; }
\r
6197 /***********************************************************************
\r
6198 <<< [StrT_cmp_i_part] >>>
\r
6199 ************************************************************************/
\r
6200 int StrT_cmp_i_part( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,
\r
6201 const TCHAR* in_StringB )
\r
6208 a = in_StringA_Start;
\r
6212 if ( a >= in_StringA_Over ) {
\r
6214 if ( bb == _T('\0') )
\r
6223 if ( bb == _T('\0') )
\r
6227 if ( _totlower( aa ) != _totlower( bb ) )
\r
6228 { return aa - bb; }
\r
6238 /***********************************************************************
\r
6239 <<< [StrT_cmp_part2] >>>
\r
6240 ************************************************************************/
\r
6241 int StrT_cmp_part2( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,
\r
6242 const TCHAR* in_StringB_Start, const TCHAR* in_StringB_Over )
\r
6244 int length_A = in_StringA_Over - in_StringA_Start;
\r
6245 int length_B = in_StringB_Over - in_StringB_Start;
\r
6247 if ( length_A != length_B ) {
\r
6248 return length_A - length_B;
\r
6251 return _tcsncmp( in_StringA_Start, in_StringB_Start, length_A );
\r
6257 /***********************************************************************
\r
6258 <<< [StrT_refFName] >>>
\r
6259 ************************************************************************/
\r
6260 TCHAR* StrT_refFName( const TCHAR* s )
\r
6265 p = StrT_chr( s, _T('\0') );
\r
6267 if ( p == s ) return (TCHAR*) s;
\r
6269 for ( p--; p>s; p-- ) {
\r
6271 if ( c == _T('\\') || c == _T('/') ) return (TCHAR*) p+1;
\r
6273 if ( *p == _T('\\') || *p == _T('/') ) return (TCHAR*) p+1;
\r
6275 return (TCHAR*) s;
\r
6278 /***********************************************************************
\r
6279 <<< [StrT_refExt] >>>
\r
6280 ************************************************************************/
\r
6281 TCHAR* StrT_refExt( const TCHAR* s )
\r
6285 p = StrT_chr( s, _T('\0') );
\r
6287 if ( p == s ) { return (TCHAR*) s; }
\r
6289 for ( p--; p>s; p-- ) {
\r
6290 if ( *p == _T('.') ) return (TCHAR*) p+1;
\r
6291 if ( *p == _T('/') || *p == _T('\\') )
\r
6292 { return (TCHAR*) StrT_chr( p, _T('\0') ); }
\r
6294 if ( *p == _T('.') ) return (TCHAR*) p+1;
\r
6296 return (TCHAR*) StrT_chr( s, _T('\0') );
\r
6301 /***********************************************************************
\r
6302 * Function: StrT_cutFragmentInPath
\r
6303 ************************************************************************/
\r
6304 void StrT_cutFragmentInPath( TCHAR* in_out_Path )
\r
6308 p = _tcschr( in_out_Path, _T('#') );
\r
6309 if ( p != NULL ) {
\r
6316 /***********************************************************************
\r
6317 <<< [StrT_searchPartStringIndex] >>>
\r
6318 ************************************************************************/
\r
6319 int StrT_searchPartStringIndex( const TCHAR* in_String, const TCHAR* in_StringOver,
\r
6320 const TCHAR** in_StringsArray, uint_fast32_t in_StringsArrayLength,
\r
6321 int in_DefaultIndex )
\r
6324 const TCHAR** p_over = in_StringsArray + in_StringsArrayLength;
\r
6325 size_t size = (byte_t*) in_StringOver - (byte_t*) in_String;
\r
6327 for ( p = in_StringsArray; p < p_over; p += 1 ) {
\r
6328 if ( memcmp( *p, in_String, size ) == 0 ) {
\r
6329 return p - in_StringsArray;
\r
6332 return in_DefaultIndex;
\r
6336 /***********************************************************************
\r
6337 <<< [StrT_searchPartStringIndexI] >>>
\r
6338 - This ignores case sensitive.
\r
6339 ************************************************************************/
\r
6340 int StrT_searchPartStringIndexI( const TCHAR* in_String, const TCHAR* in_StringOver,
\r
6341 const TCHAR** in_StringsArray, uint_fast32_t in_StringsArrayLength,
\r
6342 int in_DefaultIndex )
\r
6345 const TCHAR** p_over = in_StringsArray + in_StringsArrayLength;
\r
6346 size_t count = (TCHAR*) in_StringOver - (TCHAR*) in_String;
\r
6348 for ( p = in_StringsArray; p < p_over; p += 1 ) {
\r
6349 if ( _tcsnicmp( *p, in_String, count ) == 0 ) {
\r
6350 return p - in_StringsArray;
\r
6353 return in_DefaultIndex;
\r
6357 /***********************************************************************
\r
6358 <<< [StrT_convStrToId] >>>
\r
6359 ************************************************************************/
\r
6360 int StrT_convStrToId( const TCHAR* str, const TCHAR** strs, const int* ids,
\r
6361 int n, int default_id )
\r
6364 const TCHAR** p_over = strs + n;
\r
6366 for ( p = strs; p < p_over; p++ ) {
\r
6367 if ( _tcsicmp( *p, str ) == 0 ) return ids[p - strs];
\r
6369 return default_id;
\r
6373 /***********************************************************************
\r
6374 <<< [StrT_convStrLeftToId] >>>
\r
6375 ************************************************************************/
\r
6376 int StrT_convStrLeftToId( const TCHAR* Str, const TCHAR** Strs, const size_t* Lens, const int* Ids,
\r
6377 int CountOfStrs, TCHAR* Separeters, int DefaultId, TCHAR** out_PosOfLastOfStr )
\r
6380 const TCHAR** pp_over = Strs + CountOfStrs;
\r
6381 const size_t* p_len;
\r
6383 const TCHAR* p_last_of_str;
\r
6388 for ( pp = Strs; pp < pp_over; pp += 1 ) {
\r
6390 ASSERT_D( _tcslen( *pp ) == *p_len, goto err );
\r
6392 if ( _tcsncmp( Str, *pp, *p_len ) == 0 ) {
\r
6393 p_last_of_str = Str + *p_len;
\r
6394 c = *p_last_of_str;
\r
6395 if ( c == _T('\0') || _tcschr( Separeters, c ) != NULL ) {
\r
6396 *out_PosOfLastOfStr = (TCHAR*) p_last_of_str;
\r
6406 err: return DefaultId;
\r
6411 /***********************************************************************
\r
6412 <<< [StrT_replace] >>>
\r
6413 ************************************************************************/
\r
6414 errnum_t StrT_replace( TCHAR* Out, size_t OutSize, const TCHAR* In,
\r
6415 const TCHAR* FromStr, const TCHAR* ToStr, unsigned Opt )
\r
6418 unsigned from_size = _tcslen( FromStr ) * sizeof(TCHAR);
\r
6419 unsigned to_size = _tcslen( ToStr ) * sizeof(TCHAR);
\r
6420 const TCHAR* p_in = In;
\r
6421 TCHAR* p_out = Out;
\r
6422 const TCHAR* p_in_from;
\r
6424 int out_size = OutSize - 1;
\r
6427 /*
\92u
\8a·
\82µ
\82Ä
\8f¬
\82³
\82
\82È
\82é
\82Æ
\82«
\82Í
\81A
\8d¶
\82©
\82ç
\89E
\82Ö
\91\96\8d¸
\82·
\82é */
\r
6428 if ( to_size <= from_size ) {
\r
6432 /* In
\82Ì
\92\86\82Ì FromStr
\82Ì
\90æ
\93ª
\88Ê
\92u
\82ð p_in_from
\82Ö */
\r
6433 p_in_from = _tcsstr( p_in, FromStr );
\r
6434 if ( p_in_from == NULL ) break;
\r
6436 /* In
\82Ì
\92\86\82Ì FromStr
\82Ì
\91O
\82Ü
\82Å In
\82©
\82ç Out
\82Ö
\83R
\83s
\81[
\82·
\82é */
\r
6437 copy_size = (char*)p_in_from - (char*)p_in;
\r
6438 out_size -= copy_size + to_size;
\r
6439 IF( out_size < 0 ) goto err_fa;
\r
6441 if ( p_out != p_in )
\r
6442 memcpy( p_out, p_in, copy_size );
\r
6443 p_in = (TCHAR*)( (char*)p_in + copy_size );
\r
6444 p_out = (TCHAR*)( (char*)p_out + copy_size );
\r
6446 /* FromStr
\82ð ToStr
\82É
\92u
\82«
\8a·
\82¦
\82é */
\r
6447 memcpy( p_out, ToStr, to_size );
\r
6448 p_in = (TCHAR*)( (char*)p_in + from_size );
\r
6449 p_out = (TCHAR*)( (char*)p_out + to_size );
\r
6452 if ( Opt & STR_1TIME )
\r
6456 /*
\8ec
\82è
\82ð In
\82©
\82ç Out
\82Ö
\83R
\83s
\81[
\82·
\82é */
\r
6457 #pragma warning(push)
\r
6458 #pragma warning(disable:4996)
\r
6459 if ( p_out != p_in )
\r
6460 _tcscpy( p_out, p_in );
\r
6462 #pragma warning(pop)
\r
6466 /*
\92u
\8a·
\82µ
\82Ä
\91å
\82«
\82
\82È
\82é
\82Æ
\82«
\82Í
\81A
\89E
\82©
\82ç
\8d¶
\82Ö
\91\96\8d¸
\82·
\82é */
\r
6469 /* In
\82Ì
\92\86\82Ì FromStr
\82ª
\96³
\82¢
\82Æ
\82«
\82Í
\91S
\95\94\83R
\83s
\81[
\82·
\82é */
\r
6470 p_in_from = _tcsstr( p_in, FromStr );
\r
6471 if ( p_in_from == NULL ) {
\r
6472 if ( p_out != p_in )
\r
6473 StrT_cpy( Out, OutSize, In );
\r
6478 TCHAR* froms_X[10];
\r
6479 const TCHAR** pp_froms;
\r
6480 size_t plus_from_to;
\r
6482 Set2a_initConst( &froms, froms_X );
\r
6483 e= Set2a_init( &froms, froms_X, sizeof(froms_X) ); IF(e)goto fin2;
\r
6486 /* In
\82Ì
\92\86\82Ì FromStr
\82Ì
\91O
\82Ü
\82Å
\83R
\83s
\81[
\82·
\82é */
\r
6487 copy_size = (char*)p_in_from - (char*)p_in;
\r
6488 out_size -= copy_size;
\r
6489 IF( out_size < 0 ) goto err_fa2;
\r
6491 memcpy( p_out, p_in, copy_size );
\r
6492 // p_in = (TCHAR*)( (char*)p_in + copy_size ); //
\8cã
\82Å
\8eg
\82í
\82ê
\82È
\82¢
\r
6493 p_out = (TCHAR*)( (char*)p_out + copy_size );
\r
6496 /* In
\82Ì
\92\86\82Ì FromStr
\82Ì
\88Ê
\92u
\82ð froms
\82Ö
\8fW
\82ß
\82é */
\r
6499 e= Set2a_expandIfOverByAddr( &froms, froms_X, (TCHAR**)froms.Next + 1 ); IF(e)goto fin2;
\r
6500 pp_froms = (const TCHAR**)froms.Next; froms.Next = (void*)( pp_froms + 1 );
\r
6502 *pp_froms = p_in_from;
\r
6504 if ( Opt & STR_1TIME )
\r
6507 p_in = (const TCHAR*)( (char*)p_in_from + from_size );
\r
6508 p_in_from = _tcsstr( p_in, FromStr );
\r
6509 if ( p_in_from == NULL ) break;
\r
6512 plus_from_to = ( (TCHAR**)froms.Next - (TCHAR**)froms.First ) * (to_size - from_size);
\r
6515 /* In
\82Ì
\96\96\94ö
\82Ì '\0'
\82Ì
\88Ê
\92u
\82à froms
\82Ö */
\r
6516 e= Set2a_expandIfOverByAddr( &froms, froms_X, (TCHAR**)froms.Next + 1 ); IF(e)goto fin2;
\r
6517 pp_froms = (const TCHAR**)froms.Next; froms.Next = (void*)( pp_froms + 1 );
\r
6518 p_in = StrT_chr( p_in, _T('\0') );
\r
6521 copy_size = ( (char*)p_in - (char*)In ) + plus_from_to;
\r
6522 IF( copy_size >= OutSize ) goto err_fa2;
\r
6523 p_out = (TCHAR*)( (char*)Out + copy_size );
\r
6524 plus_from_to -= to_size - from_size;
\r
6527 /*
\89E
\82©
\82ç
\8d¶
\82Ö
\91\96\8d¸
\82·
\82é */
\r
6528 for ( pp_froms = (TCHAR**)froms.Next - 1;
\r
6529 pp_froms > (TCHAR**)froms.First;
\r
6532 const TCHAR* p_in_from = *(pp_froms - 1);
\r
6533 const TCHAR* p_in_other = (const TCHAR*)( (char*)p_in_from + from_size );
\r
6534 const TCHAR* p_in_other_over = *pp_froms;
\r
6535 TCHAR* p_out_to = (TCHAR*)( (char*)Out + ( (char*)p_in_from - (char*)In ) + plus_from_to );
\r
6536 TCHAR* p_out_other = (TCHAR*)( (char*)p_out_to + to_size );
\r
6538 memmove( p_out_other, p_in_other, (char*)p_in_other_over - (char*)p_in_other );
\r
6539 memcpy( p_out_to, ToStr, to_size );
\r
6541 plus_from_to -= to_size - from_size;
\r
6545 err_fa2: e = E_FEW_ARRAY; goto fin2;
\r
6547 e= Set2a_finish( &froms, froms_X, e );
\r
6548 if ( e ) goto fin;
\r
6554 if ( p_out != NULL ) *p_out = _T('\0');
\r
6557 err_fa: e = E_FEW_ARRAY; goto fin;
\r
6562 /***********************************************************************
\r
6563 <<< [StrT_replace1] >>>
\r
6564 ************************************************************************/
\r
6565 errnum_t StrT_replace1( TCHAR* in_out_String, TCHAR FromCharacter, TCHAR ToCharacter,
\r
6570 UNREFERENCED_VARIABLE( Opt );
\r
6572 IF ( FromCharacter == _T('\0') ) { return E_OTHERS; }
\r
6574 p = in_out_String;
\r
6576 p = _tcschr( p, FromCharacter );
\r
6577 if ( p == NULL ) { break; }
\r
6587 /***********************************************************************
\r
6588 <<< [StrT_trim] >>>
\r
6589 ************************************************************************/
\r
6590 errnum_t StrT_trim( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str )
\r
6596 p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;
\r
6597 for ( p2 = StrT_chr( p1, _T('\0') ) - 1; p2 >= p1; p2-- ) {
\r
6599 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )
\r
6602 return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );
\r
6607 /***********************************************************************
\r
6608 <<< [StrT_cutPart] >>>
\r
6609 ************************************************************************/
\r
6610 errnum_t StrT_cutPart( TCHAR* in_out_String, TCHAR* in_StartOfCut, TCHAR* in_OverOfCut )
\r
6613 TCHAR* over_of_cut = StrT_chr( in_StartOfCut, _T('\0') );
\r
6616 TCHAR* over_of_string = StrT_chr( in_out_String, _T('\0') );
\r
6618 ASSERT_D( over_of_cut == over_of_string, e=E_OTHERS; goto fin );
\r
6619 ASSERT_D( in_StartOfCut >= in_out_String, e=E_OTHERS; goto fin );
\r
6620 ASSERT_D( in_StartOfCut <= over_of_string, e=E_OTHERS; goto fin );
\r
6621 ASSERT_D( in_OverOfCut >= in_out_String, e=E_OTHERS; goto fin );
\r
6622 ASSERT_D( in_OverOfCut <= over_of_string, e=E_OTHERS; goto fin );
\r
6623 ASSERT_D( in_StartOfCut <= in_OverOfCut, e=E_OTHERS; goto fin );
\r
6625 UNREFERENCED_VARIABLE( in_out_String );
\r
6627 memmove( in_StartOfCut, in_OverOfCut,
\r
6628 PointerType_diff( over_of_cut + 1, in_OverOfCut ) );
\r
6639 /***********************************************************************
\r
6640 <<< [StrT_cutLastOf] >>>
\r
6641 ************************************************************************/
\r
6642 errnum_t StrT_cutLastOf( TCHAR* in_out_Str, TCHAR Charactor )
\r
6644 TCHAR* last = StrT_chr( in_out_Str, _T('\0') );
\r
6646 if ( last > in_out_Str ) {
\r
6647 if ( *( last - 1 ) == Charactor )
\r
6648 { *( last - 1 ) = _T('\0'); }
\r
6655 /***********************************************************************
\r
6656 <<< [StrT_cutLineComment] >>>
\r
6657 ************************************************************************/
\r
6658 errnum_t StrT_cutLineComment( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str, const TCHAR* CommentSign )
\r
6664 p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;
\r
6666 p2 = _tcsstr( p1, CommentSign );
\r
6667 if ( p2 == NULL ) p2 = StrT_chr( p1, _T('\0') );
\r
6669 for ( p2 = p2 - 1; p2 >= p1; p2-- ) {
\r
6671 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )
\r
6674 return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );
\r
6679 /***********************************************************************
\r
6680 <<< [StrT_insert] >>>
\r
6681 ************************************************************************/
\r
6682 errnum_t StrT_insert( TCHAR* in_out_WholeString, size_t in_MaxSize_of_WholeString,
\r
6683 TCHAR* in_out_Target_in_WholeString, TCHAR** out_NextTarget_in_WholeString,
\r
6684 const TCHAR* in_InsertString )
\r
6687 TCHAR* over_of_whole_string = StrT_chr( in_out_WholeString, _T('\0') );
\r
6688 size_t insert_length = _tcslen( in_InsertString );
\r
6690 ASSERT_D( in_out_Target_in_WholeString >= in_out_WholeString, e=E_OTHERS; goto fin );
\r
6691 ASSERT_D( in_out_Target_in_WholeString <= over_of_whole_string, e=E_OTHERS; goto fin );
\r
6693 ASSERT_R( PointerType_diff( over_of_whole_string + 1, in_out_WholeString ) + ( insert_length * sizeof(TCHAR) )
\r
6694 <= in_MaxSize_of_WholeString, e=E_FEW_ARRAY; goto fin );
\r
6696 memmove( in_out_Target_in_WholeString + insert_length, in_out_Target_in_WholeString,
\r
6697 PointerType_diff( over_of_whole_string + 1, in_out_Target_in_WholeString ) );
\r
6699 memcpy( in_out_Target_in_WholeString, in_InsertString, insert_length * sizeof(TCHAR) );
\r
6701 if ( out_NextTarget_in_WholeString != NULL ) {
\r
6702 *out_NextTarget_in_WholeString = in_out_Target_in_WholeString + insert_length;
\r
6712 /***********************************************************************
\r
6713 <<< [StrHS_insert] >>>
\r
6714 ************************************************************************/
\r
6715 errnum_t StrHS_insert( TCHAR** in_out_WholeString,
\r
6716 int in_TargetIndexInWholeString, int* out_NextWholeInWholeString,
\r
6717 const TCHAR* in_InsertString )
\r
6720 TCHAR* string = *in_out_WholeString;
\r
6721 size_t target_length = _tcslen( string );
\r
6722 size_t insert_length = _tcslen( in_InsertString );
\r
6723 size_t max_size = _msize( string ) / sizeof( TCHAR );
\r
6724 size_t new_max_size = target_length + insert_length + 1;
\r
6725 TCHAR* next_target;
\r
6728 if ( max_size < new_max_size ) {
\r
6729 TCHAR* new_string = (TCHAR*) realloc( string, new_max_size * sizeof( TCHAR ) );
\r
6731 IF ( new_string == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
6732 max_size = new_max_size;
\r
6733 string = new_string;
\r
6736 e= StrT_insert( string, max_size * sizeof( TCHAR ),
\r
6737 string + in_TargetIndexInWholeString, &next_target,
\r
6738 in_InsertString ); IF(e){goto fin;}
\r
6740 if ( out_NextWholeInWholeString != NULL ) {
\r
6741 *out_NextWholeInWholeString = next_target - string;
\r
6746 *in_out_WholeString = string;
\r
6752 /***********************************************************************
\r
6753 <<< [StrHS_printfPartV] >>>
\r
6754 ************************************************************************/
\r
6755 errnum_t StrHS_printfPartV( TCHAR** in_out_String,
\r
6756 int in_IndexInString, int* out_NextIndexInString,
\r
6757 const TCHAR* in_Format, va_list in_VaList )
\r
6759 enum { first_max_size = 40 };
\r
6760 enum { size_times = 4 };
\r
6764 TCHAR* string = *in_out_String;
\r
6767 if ( string == NULL ) {
\r
6770 ASSERT_R( in_IndexInString == 0, e=E_OTHERS; goto fin );
\r
6773 max_size = _msize( string ) / sizeof( TCHAR );
\r
6775 ASSERT_R( in_IndexInString >= 0 && (size_t) in_IndexInString < max_size,
\r
6776 e=E_OTHERS; goto fin );
\r
6777 ASSERT_D( (size_t) in_IndexInString <= _tcslen( string ), __noop() );
\r
6781 if ( string == NULL ) {
\r
6782 string = (TCHAR*) malloc( first_max_size * sizeof( TCHAR ) );
\r
6783 max_size = first_max_size;
\r
6790 #pragma warning(push)
\r
6791 #pragma warning(disable: 4996)
\r
6795 int r = _vsnwprintf( string + in_IndexInString, max_size - in_IndexInString,
\r
6796 in_Format, in_VaList );
\r
6798 int r = _vsnprintf( string + in_IndexInString, max_size - in_IndexInString,
\r
6799 in_Format, in_VaList );
\r
6803 #pragma warning(pop)
\r
6807 if ( out_NextIndexInString != NULL ) {
\r
6808 *out_NextIndexInString = in_IndexInString + r;
\r
6815 size_t new_max_size = max_size * size_times + first_max_size;
\r
6816 TCHAR* new_string = (TCHAR*) realloc( string, new_max_size * sizeof( TCHAR ) );
\r
6818 IF ( new_string == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
6819 max_size = new_max_size;
\r
6820 string = new_string;
\r
6826 *in_out_String = string;
\r
6832 /***********************************************************************
\r
6833 <<< [StrHS_printfPart] >>>
\r
6834 ************************************************************************/
\r
6835 errnum_t StrHS_printfPart( TCHAR** in_out_String,
\r
6836 int in_IndexInString, int* out_NextIndexInString,
\r
6837 const TCHAR* in_Format, ... )
\r
6841 va_start( va, in_Format );
\r
6843 e = StrHS_printfPartV( in_out_String, in_IndexInString, out_NextIndexInString, in_Format, va );
\r
6851 /***********************************************************************
\r
6852 <<< [StrHS_printfV] >>>
\r
6853 ************************************************************************/
\r
6854 errnum_t StrHS_printfV( TCHAR** in_out_String,
\r
6855 const TCHAR* in_Format, va_list in_VaList )
\r
6857 return StrHS_printfPartV( in_out_String, 0, NULL, in_Format, in_VaList );
\r
6862 /***********************************************************************
\r
6863 <<< [StrHS_printf] >>>
\r
6864 ************************************************************************/
\r
6865 errnum_t StrHS_printf( TCHAR** in_out_String,
\r
6866 const TCHAR* in_Format, ... )
\r
6870 va_start( va, in_Format );
\r
6872 e = StrHS_printfPartV( in_out_String, 0, NULL, in_Format, va );
\r
6880 /**************************************************************************
\r
6881 <<< [StrT_meltCSV] >>>
\r
6882 *************************************************************************/
\r
6883 errnum_t StrT_meltCSV( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pCSV )
\r
6887 TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );
\r
6894 if ( out_Str_Size <= 1 ) { t = dummy; t_last = dummy; }
\r
6896 if ( s == NULL ) { *t = _T('\0'); return 0; }
\r
6899 /*
\93ª
\82Ì
\8bó
\94\92\82ð
\8f\9c\82 */
\r
6900 while ( *s == _T(' ') || *s == _T('\t') ) s++;
\r
6904 /* ""
\82Å
\88Í
\82Ü
\82ê
\82Ä
\82¢
\82é
\8fê
\8d\87 */
\r
6908 while ( c != _T('"') || *(s+1) == _T('"') ) { /* "
\95¶
\8e\9a\82Ü
\82Å */
\r
6909 if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }
\r
6910 if ( c == *(s+1) && c == _T('"') ) s++; /* "
\95¶
\8e\9a\8e©
\91Ì */
\r
6911 if ( c == _T('\0') ) break;
\r
6912 *t = c; t++; s++; c = *s;
\r
6918 if ( *s == _T(',') ) { s = s+1; break; }
\r
6919 if ( *s == _T('\0') ) { s = NULL; break; }
\r
6925 /*
\8bó
\82Ì
\8d\80\96Ú
\82Ì
\8fê
\8d\87 */
\r
6936 /* ""
\82Å
\88Í
\82Ü
\82ê
\82Ä
\82¢
\82È
\82¢
\8fê
\8d\87 */
\r
6938 TCHAR* sp = NULL; /*
\8dÅ
\8cã
\82Ì
\98A
\91±
\82µ
\82½
\8bó
\94\92\82Ì
\90æ
\93ª */
\r
6941 while ( c != _T(',') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /* ,
\95¶
\8e\9a\82Ü
\82Å */
\r
6943 /* sp
\82ð
\90Ý
\92è
\82·
\82é */
\r
6945 if ( sp == NULL ) sp = t;
\r
6949 if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }
\r
6951 /*
\83R
\83s
\81[
\82·
\82é */
\r
6952 *t = c; t++; s++; c = *s;
\r
6955 /*
\95Ô
\82è
\92l
\82ð
\8c\88\92è
\82·
\82é */
\r
6956 if ( c == _T(',') ) s = s + 1;
\r
6959 /*
\96\96\94ö
\82Ì
\8bó
\94\92\82ð
\8eæ
\82è
\8f\9c\82 */
\r
6960 if ( sp != NULL ) *sp = '\0';
\r
6961 else *t = _T('\0');
\r
6971 /***********************************************************************
\r
6972 <<< [StrT_parseCSV_f] >>>
\r
6973 ************************************************************************/
\r
6974 errnum_t StrT_parseCSV_f( const TCHAR* StringOfCSV, bit_flags32_t* out_ReadFlags, const TCHAR* Types, ... )
\r
6980 bool is_next_omittable;
\r
6981 bool is_next_omit;
\r
6982 const TCHAR* column_pointer;
\r
6984 TCHAR column[ 32 ];
\r
6985 bit_flags32_t read_flags;
\r
6986 bit_flags32_t next_read_flag;
\r
6988 size_t str_size = SIZE_MAX; /* SIZE_MAX = Avoid warning */
\r
6991 va_start( va, Types );
\r
6993 is_next_omittable = false;
\r
6994 column_pointer = StringOfCSV;
\r
6996 next_read_flag = 1;
\r
6997 while ( column_pointer != NULL ) {
\r
7000 type = Types[ types_index ];
\r
7006 is_next_omittable = true;
\r
7010 out_str = va_arg( va, TCHAR* );
\r
7011 str_size = va_arg( va, size_t );
\r
7012 ASSERT_D( str_size >= 1, e=E_OTHERS; goto fin );
\r
7017 str_size = sizeof( column );
\r
7021 if ( out_str != NULL ) {
\r
7023 // Set "out_str" : Column string in CSV
\r
7024 column_pointer = StrT_skip( column_pointer, _T(" \t") );
\r
7025 a_char = *column_pointer;
\r
7026 if ( is_next_omittable && ( a_char == _T('\0') || a_char == _T(',') ) ) {
\r
7027 column_pointer = StrT_chrs( column_pointer, _T(",") );
\r
7028 if ( column_pointer != NULL ) { column_pointer += 1; }
\r
7029 is_next_omit = true;
\r
7031 e= StrT_meltCSV( out_str, str_size, &column_pointer ); IF(e){goto fin;}
\r
7033 is_next_omit = false;
\r
7034 read_flags |= next_read_flag;
\r
7039 /* "va_arg" was already called */
\r
7043 int* pointer_of_int = va_arg( va, int* );
\r
7045 if ( ! is_next_omit ) {
\r
7046 *pointer_of_int = ttoi_ex( column, 0 );
\r
7051 double* pointer_of_double = va_arg( va, double* );
\r
7053 if ( ! is_next_omit ) {
\r
7054 *pointer_of_double = _tstof( column );
\r
7059 bool* pointer_of_bool = va_arg( va, bool* );
\r
7060 int strings_index;
\r
7061 static const TCHAR* strings[] = {
\r
7062 _T("1"), _T("true"), _T("yes"),
\r
7065 if ( ! is_next_omit ) {
\r
7066 *pointer_of_bool = false;
\r
7067 for ( strings_index = 0;
\r
7068 strings_index < _countof( strings );
\r
7069 strings_index += 1 )
\r
7071 if ( _tcsicmp( column, strings[ strings_index ] ) == 0 ) {
\r
7072 *pointer_of_bool = true;
\r
7080 SYSTEMTIME* pointer_of_time = va_arg( va, SYSTEMTIME* );
\r
7081 int* pointer_of_bias = va_arg( va, int* );
\r
7083 if ( ! is_next_omit ) {
\r
7084 e= W3CDTF_toSYSTEMTIME( column, pointer_of_time, pointer_of_bias );
\r
7091 ASSERT_R( false, e=E_OTHERS; goto fin );
\r
7094 is_next_omittable = false;
\r
7095 next_read_flag <<= 1;
\r
7101 if ( out_ReadFlags != NULL ) {
\r
7102 *out_ReadFlags = read_flags;
\r
7113 /**************************************************************************
\r
7114 <<< [StrT_changeToXML_Attribute] >>>
\r
7115 *************************************************************************/
\r
7116 errnum_t StrT_changeToXML_Attribute( TCHAR* out_Str, size_t Str_Size, const TCHAR* InputStr )
\r
7120 e= StrT_replace( out_Str, Str_Size, InputStr, _T("&"), _T("&"), 0 ); IF(e)goto fin;
\r
7121 e= StrT_replace( out_Str, Str_Size, out_Str, _T("\""), _T("""), 0 ); IF(e)goto fin;
\r
7122 e= StrT_replace( out_Str, Str_Size, out_Str, _T("<"), _T("<"), 0 ); IF(e)goto fin;
\r
7131 /**************************************************************************
\r
7132 <<< [StrT_resumeFromXML_Attribute] >>>
\r
7133 *************************************************************************/
\r
7134 errnum_t StrT_resumeFromXML_Attribute( TCHAR* out_Str, size_t Str_Size, const TCHAR* XML_Attr )
\r
7138 e= StrT_replace( out_Str, Str_Size, XML_Attr, _T("""), _T("\""), 0 ); IF(e)goto fin;
\r
7139 e= StrT_replace( out_Str, Str_Size, out_Str, _T("<"), _T("<"), 0 ); IF(e)goto fin;
\r
7140 e= StrT_replace( out_Str, Str_Size, out_Str, _T("&"), _T("&"), 0 ); IF(e)goto fin;
\r
7149 /**************************************************************************
\r
7150 <<< [StrT_changeToXML_Text] >>>
\r
7151 *************************************************************************/
\r
7152 errnum_t StrT_changeToXML_Text( TCHAR* out_Str, size_t Str_Size, const TCHAR* InputStr )
\r
7156 e= StrT_replace( out_Str, Str_Size, InputStr, _T("&"), _T("&"), 0 ); IF(e)goto fin;
\r
7157 e= StrT_replace( out_Str, Str_Size, out_Str, _T("<"), _T("<"), 0 ); IF(e)goto fin;
\r
7158 e= StrT_replace( out_Str, Str_Size, out_Str, _T(">"), _T(">"), 0 ); IF(e)goto fin;
\r
7167 /***********************************************************************
\r
7168 <<< [StrT_getExistSymbols] >>>
\r
7169 ************************************************************************/
\r
7170 errnum_t StrT_getExistSymbols( unsigned* out, bool bCase, const TCHAR* Str, const TCHAR* Symbols, ... )
\r
7174 bool* syms_exists = NULL;
\r
7175 bool b_nosym = false;
\r
7176 TCHAR* sym = NULL;
\r
7177 size_t sym_size = ( _tcslen( Symbols ) + 1 ) * sizeof(TCHAR);
\r
7179 const TCHAR** syms = NULL;
\r
7182 UNREFERENCED_VARIABLE( bCase );
\r
7184 sym = (TCHAR*) malloc( sym_size ); IF(sym==NULL)goto err_fm;
\r
7190 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;
\r
7191 if ( sym[0] != _T('\0') ) n_sym ++;
\r
7192 } while ( p != NULL );
\r
7194 syms = (const TCHAR**) malloc( n_sym * sizeof(TCHAR*) ); IF(syms==NULL)goto err_fm;
\r
7195 memset( (TCHAR**) syms, 0, n_sym * sizeof(TCHAR*) );
\r
7196 syms_exists = (bool*) malloc( n_sym * sizeof(bool) ); IF(syms_exists==NULL)goto err_fm;
\r
7197 memset( syms_exists, 0, n_sym * sizeof(bool) );
\r
7199 p = Symbols; i = 0;
\r
7201 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;
\r
7202 if ( sym[0] != _T('\0') ) {
\r
7203 e= MallocAndCopyString( &syms[i], sym ); IF(e)goto fin;
\r
7206 } while ( p != NULL );
\r
7209 //=== Check Str whether having Symbols
\r
7212 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;
\r
7213 if ( sym[0] != _T('\0') ) {
\r
7214 for ( i = 0; i < n_sym; i++ ) {
\r
7215 if ( _tcscmp( sym, syms[i] ) == 0 ) { syms_exists[i] = true; break; }
\r
7217 if ( i == n_sym ) b_nosym = true;
\r
7219 } while ( p != NULL );
\r
7227 va_start( va, Symbols );
\r
7229 for ( i = 0; i < n_sym; i++ ) {
\r
7230 num = va_arg( va, unsigned );
\r
7231 if ( syms_exists[i] ) *out |= num;
\r
7236 e = ( b_nosym ? E_NOT_FOUND_SYMBOL : 0 );
\r
7238 if ( syms != NULL ) {
\r
7239 for ( i = 0; i < n_sym; i++ ) {
\r
7240 e= HeapMemory_free( &syms[i], e );
\r
7242 free( (TCHAR**) syms );
\r
7244 e= HeapMemory_free( &syms_exists, e );
\r
7245 e= HeapMemory_free( &sym, e );
\r
7247 err_fm: e= E_FEW_MEMORY; goto fin;
\r
7251 /**************************************************************************
\r
7252 <<< [StrT_meltCmdLine] >>>
\r
7253 *************************************************************************/
\r
7254 errnum_t StrT_meltCmdLine( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pLine )
\r
7258 TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );
\r
7265 if ( out_Str_Size <= 1 ) { t = &dummy; t_last = &dummy; }
\r
7267 if ( s == NULL ) { *t = _T('\0'); return 0; }
\r
7270 /*
\93ª
\82Ì
\8bó
\94\92\82ð
\8f\9c\82 */
\r
7271 while ( *s == _T(' ') || *s == _T('\t') ) s++;
\r
7275 /* ""
\82Å
\88Í
\82Ü
\82ê
\82Ä
\82¢
\82é
\8fê
\8d\87 */
\r
7279 while ( c != _T('"') || *(s+1) == _T('"') ) { /* "
\95¶
\8e\9a\82Ü
\82Å */
\r
7280 if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }
\r
7281 if ( c == *(s+1) && c == _T('"') ) s++; /* "
\95¶
\8e\9a\8e©
\91Ì */
\r
7282 if ( c == _T('\0') ) break;
\r
7283 *t = c; t++; s++; c = *s;
\r
7289 if ( *s == _T(' ') ) { s = s+1; break; }
\r
7290 if ( *s == _T('\0') ) { s = NULL; break; }
\r
7301 /* ""
\82Å
\88Í
\82Ü
\82ê
\82Ä
\82¢
\82È
\82¢
\8fê
\8d\87 */
\r
7304 while ( c != _T(' ') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /*
\8bó
\94\92\95¶
\8e\9a\82Ü
\82Å */
\r
7306 if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }
\r
7308 /*
\83R
\83s
\81[
\82·
\82é */
\r
7309 *t = c; t++; s++; c = *s;
\r
7312 /* *pLine
\82ð
\8c\88\92è
\82·
\82é */
\r
7313 while ( *s == _T(' ') ) s = s + 1;
\r
7314 if ( *s == _T('\0') ) s = NULL;
\r
7327 /***********************************************************************
\r
7328 <<< [W3CDTF_fromSYSTEMTIME] >>>
\r
7329 ************************************************************************/
\r
7330 errnum_t W3CDTF_fromSYSTEMTIME( TCHAR* out_W3CDTF, size_t W3CDTF_ByteSize,
\r
7331 const SYSTEMTIME* Time, int TimeZoneMinute )
\r
7334 TCHAR* char_pointer = out_W3CDTF;
\r
7336 e= stprintf_part_r( out_W3CDTF, W3CDTF_ByteSize, char_pointer, &char_pointer,
\r
7337 _T("%04d-%02d-%02dT%02d:%02d:%02d.%03d"),
\r
7338 Time->wYear, Time->wMonth, Time->wDay,
\r
7339 Time->wHour, Time->wMinute, Time->wSecond, Time->wMilliseconds );
\r
7342 e= W3CDTF_getTimeZoneDesignator( char_pointer,
\r
7343 GetStringSizeFromPointer( out_W3CDTF, W3CDTF_ByteSize, char_pointer ),
\r
7344 TimeZoneMinute ); IF(e){goto fin;}
\r
7353 /***********************************************************************
\r
7354 <<< [W3CDTF_toSYSTEMTIME] >>>
\r
7355 ************************************************************************/
\r
7356 errnum_t W3CDTF_toSYSTEMTIME( const TCHAR* String, SYSTEMTIME* out_Time, int* out_BiasMinute )
\r
7359 size_t string_length = _tcslen( String );
\r
7361 /* 01234567890123456789012345678 */
\r
7362 /*"yyyy-mm-ddThh:mm:ss.sss+00:00"*/
\r
7363 /*"0000-00-00T00:00+00:00"*/
\r
7365 IF_D( out_BiasMinute == NULL ) { e=E_OTHERS; goto fin; }
\r
7368 if ( string_length >= 11 ) {
\r
7370 const TCHAR* time_zone;
\r
7373 IF ( String[10] != _T('T') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7374 IF ( String[4] != _T('-') || String[7] != _T('-') )
\r
7375 { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7377 IF ( string_length < 16 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7378 IF ( String[13] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7380 out_Time->wYear = (WORD) _ttoi( &String[0] );
\r
7381 out_Time->wMonth = (WORD) _ttoi( &String[5] );
\r
7382 out_Time->wDayOfWeek = 0;
\r
7383 out_Time->wDay = (WORD) _ttoi( &String[8] );
\r
7384 out_Time->wHour = (WORD) _ttoi( &String[11] );
\r
7385 out_Time->wMinute = (WORD) _ttoi( &String[14] );
\r
7387 a_char = String[16];
\r
7388 if ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) {
\r
7389 time_zone = &String[16];
\r
7390 out_Time->wSecond = 0;
\r
7391 out_Time->wMilliseconds = 0;
\r
7394 IF ( string_length < 19 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7395 IF ( a_char != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7396 out_Time->wSecond = (WORD) _ttoi( &String[17] );
\r
7399 /*
\8f¬
\90\94\93_ */
\r
7400 a_char = String[19];
\r
7401 if ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) {
\r
7402 time_zone = &String[19];
\r
7403 out_Time->wMilliseconds = 0;
\r
7406 IF ( a_char != _T('.') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7408 out_Time->wMilliseconds = 0;
\r
7410 number = String[20] - _T('0');
\r
7411 if ( number < 0 || number > 9 ) {
\r
7412 time_zone = &String[20];
\r
7414 out_Time->wMilliseconds += (WORD)( number * 100 );
\r
7416 number = String[21] - _T('0');
\r
7417 if ( number < 0 || number > 9 ) {
\r
7418 time_zone = &String[21];
\r
7420 out_Time->wMilliseconds += (WORD)( number * 10 );
\r
7422 number = String[22] - _T('0');
\r
7423 if ( number < 0 || number > 9 ) {
\r
7424 time_zone = &String[22];
\r
7426 const TCHAR* pointer = &String[23];
\r
7428 out_Time->wMilliseconds += (WORD)( number * 1 );
\r
7431 number = *pointer - _T('0');
\r
7432 if ( number < 0 || number > 9 )
\r
7437 time_zone = pointer;
\r
7442 a_char = *time_zone;
\r
7443 IF ( ! ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) )
\r
7444 { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7449 if ( a_char == _T('Z') ) {
\r
7450 *out_BiasMinute = 0;
\r
7453 size_t time_zone_length = string_length - ( time_zone - String );
\r
7456 IF ( time_zone_length < 6 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7457 IF ( time_zone[3] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7459 bias_minute = _ttoi( &time_zone[1] ) * 60 + _ttoi( &time_zone[4] );
\r
7460 if ( a_char == _T('-') ) { bias_minute = -bias_minute; }
\r
7461 *out_BiasMinute = bias_minute;
\r
7465 /* Without time */
\r
7467 out_Time->wDayOfWeek = 0;
\r
7468 out_Time->wHour = 0;
\r
7469 out_Time->wMinute = 0;
\r
7470 out_Time->wSecond = 0;
\r
7471 out_Time->wMilliseconds = 0;
\r
7472 *out_BiasMinute = 0;
\r
7474 IF ( string_length < 4 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7477 out_Time->wYear = (WORD) _ttoi( &String[0] );
\r
7480 if ( string_length > 4 ) {
\r
7481 IF ( string_length < 7 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7482 IF ( String[4] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7483 out_Time->wMonth = (WORD) _ttoi( &String[5] );
\r
7485 out_Time->wMonth = 1;
\r
7489 if ( string_length > 7 ) {
\r
7490 IF ( string_length < 10 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7491 IF ( String[7] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }
\r
7492 out_Time->wDay = (WORD) _ttoi( &String[8] );
\r
7494 out_Time->wDay = 1;
\r
7505 /***********************************************************************
\r
7506 <<< [W3CDTF_getTimeZoneDesignator] >>>
\r
7507 ************************************************************************/
\r
7508 errnum_t W3CDTF_getTimeZoneDesignator( TCHAR* out_TZD, size_t TZD_ByteSize,
\r
7513 TIME_ZONE_INFORMATION time_zone;
\r
7516 /* Set "BiasMinute" */
\r
7517 if ( BiasMinute == W3CDTF_CURRENT_TIME_ZONE ) {
\r
7518 GetTimeZoneInformation( &time_zone );
\r
7519 BiasMinute = -time_zone.Bias;
\r
7522 enum { minute_1day = 1440 };
\r
7524 IF_D ( BiasMinute < -minute_1day || BiasMinute > minute_1day )
\r
7525 { e=E_OTHERS; goto fin; }
\r
7530 if ( BiasMinute >= 0 ) {
\r
7534 BiasMinute = -BiasMinute;
\r
7538 /* Set "out_TZD" */
\r
7539 _stprintf_s( out_TZD, TZD_ByteSize / sizeof(TCHAR), _T("%c%02d:%02d"),
\r
7540 sign, BiasMinute / 60, BiasMinute % 60 );
\r
7549 /***********************************************************************
\r
7550 <<< [StrT_isFullPath] >>>
\r
7551 ************************************************************************/
\r
7552 bool StrT_isFullPath( const TCHAR* path )
\r
7556 if ( path[0] == _T('\\') && path[1] == _T('\\') ) {
\r
7559 const TCHAR* back_slash = _tcschr( path, _T('\\') );
\r
7560 const TCHAR* slash = _tcschr( path, _T('/') );
\r
7561 const TCHAR* colon = _tcschr( path, _T(':') );
\r
7563 if ( colon != NULL ) {
\r
7566 for ( p = path; p < colon; p += 1 ) {
\r
7567 if ( ! _istalnum( *p ) ) {
\r
7574 ret = ( colon != NULL ) &&
\r
7575 ( back_slash == colon + 1 || slash == colon + 1 );
\r
7582 /**************************************************************************
\r
7583 <<< [StrT_getFullPath_part] >>>
\r
7584 *************************************************************************/
\r
7585 errnum_t StrT_getFullPath_part( TCHAR* out_FullPath, size_t FullPathSize, TCHAR* OutStart,
\r
7586 TCHAR** out_OutLast, const TCHAR* StepPath, const TCHAR* BasePath )
\r
7589 TCHAR separator = (TCHAR) DUMMY_INITIAL_VALUE_TCHAR;
\r
7590 const TCHAR* separator_path;
\r
7591 TCHAR* out_full_path_over = (TCHAR*)( (uint8_t*) out_FullPath + FullPathSize );
\r
7592 TCHAR* null_position = NULL;
\r
7595 /* "BasePath" must be out of "out_FullPath" */
\r
7596 ASSERT_R( BasePath < out_FullPath ||
\r
7597 (uint8_t*) BasePath >= (uint8_t*) out_FullPath + FullPathSize,
\r
7602 /* If "StepPath" == "", out_FullPath = "" */
\r
7603 if ( StepPath[0] == _T('\0') ) {
\r
7604 ASSERT_R( FullPathSize >= sizeof(TCHAR), goto err_fm );
\r
7605 out_FullPath[0] = _T('\0');
\r
7610 /* Set "OutStart" */
\r
7611 if ( OutStart == NULL )
\r
7612 { OutStart = out_FullPath; }
\r
7615 /* Set "separator" : \ or / from "BasePath" */
\r
7616 if ( StrT_isFullPath( StepPath ) ) {
\r
7617 separator_path = StepPath;
\r
7619 else if ( BasePath == NULL ) {
\r
7620 separator = _T('\\');
\r
7621 separator_path = NULL;
\r
7624 separator_path = BasePath;
\r
7626 if ( separator_path != NULL ) {
\r
7630 p = _tcschr( separator_path, _T('\\') );
\r
7631 p2 = _tcschr( separator_path, _T('/') );
\r
7632 if ( p == NULL ) {
\r
7634 { separator = _T('\\'); }
\r
7636 { separator = _T('/'); }
\r
7639 { separator = _T('\\'); }
\r
7642 { separator = _T('\\'); }
\r
7644 { separator = _T('/'); }
\r
7650 /* Set "OutStart" : "BasePath" + / + "StepPath" */
\r
7651 if ( StrT_isFullPath( StepPath ) ) {
\r
7652 size_t step_path_length = _tcslen( StepPath );
\r
7654 IF( OutStart + step_path_length >= out_full_path_over ) goto err_fa;
\r
7655 memmove( OutStart, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );
\r
7657 /* Set "null_position" */
\r
7658 null_position = OutStart + step_path_length;
\r
7663 size_t base_path_length;
\r
7664 size_t step_path_length = _tcslen( StepPath );
\r
7666 if ( BasePath == NULL ) {
\r
7667 base_path_length = GetCurrentDirectory( 0, NULL ) - 1;
\r
7670 base_path_length = _tcslen( BasePath );
\r
7671 c = BasePath[ base_path_length - 1 ];
\r
7672 if ( c == _T('\\') || c == _T('/') )
\r
7673 { base_path_length -= 1; }
\r
7676 p = OutStart + base_path_length + 1;
\r
7677 IF( p + step_path_length >= out_full_path_over ) goto err_fa;
\r
7678 memmove( p, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );
\r
7679 /* memmove is for "out_FullPath" == "StepPath" */
\r
7681 if ( BasePath == NULL ) {
\r
7682 GetCurrentDirectory( base_path_length + 1, OutStart );
\r
7683 if ( OutStart[ base_path_length - 1 ] == _T('\\') )
\r
7684 { base_path_length -= 1; }
\r
7686 memcpy( OutStart, BasePath, base_path_length * sizeof(TCHAR) );
\r
7688 OutStart[ base_path_length ] = separator;
\r
7691 /* Set "null_position" */
\r
7692 null_position = p + step_path_length;
\r
7696 /* Replace \ and / to "separator" in "OutStart" */
\r
7698 TCHAR other_separator;
\r
7700 if ( separator == _T('/') )
\r
7701 { other_separator = _T('\\'); }
\r
7703 { other_separator = _T('/'); }
\r
7705 e= StrT_replace1( OutStart, other_separator, separator, 0 ); IF(e)goto fin;
\r
7709 /* Replace \*\..\ to \ */
\r
7711 enum { length = 4 };
\r
7712 TCHAR parent[ length + 1 ]; /* \..\ or /../ */
\r
7713 TCHAR* parent_position;
\r
7716 parent[0] = separator;
\r
7717 parent[1] = _T('.');
\r
7718 parent[2] = _T('.');
\r
7719 parent[3] = separator;
\r
7720 parent[4] = _T('\0');
\r
7723 parent_position = _tcsstr( OutStart, parent );
\r
7724 if ( parent_position == NULL ) { break; }
\r
7726 p = parent_position - 1;
\r
7728 IF( p < OutStart ) {goto err;} /* "../" are too many */
\r
7729 if ( *p == separator ) { break; }
\r
7734 parent_position + length,
\r
7735 ( null_position - ( parent_position + length ) + 1 ) * sizeof(TCHAR) );
\r
7737 null_position -= ( parent_position + length ) - ( p + 1 );
\r
7742 /* Cut last \*\.. */
\r
7744 enum { length = 3 };
\r
7747 while ( null_position - length >= OutStart ) {
\r
7748 if ( *( null_position - 3 ) != separator ||
\r
7749 *( null_position - 2 ) != _T('.') ||
\r
7750 *( null_position - 1 ) != _T('.') )
\r
7753 p = null_position - 4;
\r
7755 IF( p < OutStart ) {goto err;} /* "../" are too many */
\r
7756 if ( *p == separator ) { break; }
\r
7762 null_position = p;
\r
7767 /* Replace \.\ to \ */
\r
7769 enum { length = 3 };
\r
7770 TCHAR current[ length + 1 ]; /* \.\ or /./ */
\r
7771 TCHAR* current_position;
\r
7773 current[0] = separator;
\r
7774 current[1] = _T('.');
\r
7775 current[2] = separator;
\r
7776 current[3] = _T('\0');
\r
7779 current_position = _tcsstr( OutStart, current );
\r
7780 if ( current_position == NULL ) { break; }
\r
7782 memmove( current_position + 1,
\r
7783 current_position + length,
\r
7784 ( null_position - ( current_position + length ) + 1 ) * sizeof(TCHAR) );
\r
7786 null_position -= length - 1;
\r
7793 TCHAR* over = StrT_chr( OutStart, _T('\0') );
\r
7795 while ( over - 2 >= OutStart &&
\r
7796 *( over - 1 ) == _T('.') && *( over - 2 ) == separator ) {
\r
7804 if ( null_position - 1 >= OutStart ) {
\r
7805 if ( *( null_position - 1 ) == _T(':') ) {
\r
7806 IF( null_position + 1 >= out_full_path_over ) goto err_fa;
\r
7808 *( null_position + 0 ) = separator;
\r
7809 *( null_position + 1 ) = _T('\0');
\r
7810 null_position += 1;
\r
7815 /* Set "*out_OutLast" */
\r
7816 if ( out_OutLast != NULL )
\r
7817 { *out_OutLast = null_position; }
\r
7823 err: e = E_OTHERS; goto fin;
\r
7824 err_fa: e = E_FEW_ARRAY; goto fin;
\r
7825 err_fm: e = E_FEW_MEMORY; goto fin;
\r
7830 /***********************************************************************
\r
7831 <<< [StrT_allocateFullPath] >>>
\r
7832 ************************************************************************/
\r
7833 errnum_t StrT_allocateFullPath( TCHAR** out_FullPath, const TCHAR* StepPath, TCHAR* BasePath )
\r
7836 int step_path_length = _tcslen( StepPath );
\r
7837 int base_path_length;
\r
7838 int full_path_size;
\r
7840 if ( BasePath == NULL ) {
\r
7841 base_path_length = GetCurrentDirectory( 0, NULL ) - 1;
\r
7843 base_path_length = _tcslen( BasePath );
\r
7846 full_path_size = ( step_path_length + 1 + base_path_length + 1 ) * sizeof(TCHAR);
\r
7848 e= HeapMemory_allocateBytes( out_FullPath, full_path_size ); IF(e){goto fin;}
\r
7849 e= StrT_getFullPath( *out_FullPath, full_path_size, StepPath, BasePath ); IF(e){goto fin;}
\r
7858 /***********************************************************************
\r
7859 <<< [StrT_getParentFullPath_part] >>>
\r
7860 ************************************************************************/
\r
7861 errnum_t StrT_getParentFullPath_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,
\r
7862 TCHAR** out_StrLast, const TCHAR* StepPath, const TCHAR* BasePath )
\r
7867 IF_D( StrStart < Str || (char*) StrStart >= (char*)Str + StrSize ){goto err;}
\r
7869 if ( StepPath[0] == _T('\0') ) {
\r
7870 *StrStart = _T('\0');
\r
7874 /*
\90â
\91Î
\83p
\83X
\82É
\82·
\82é */
\r
7875 e= StrT_getFullPath( StrStart,
\r
7876 StrSize - ( (char*)StrStart - (char*)Str ),
\r
7877 StepPath, BasePath ); IF(e)goto fin;
\r
7881 p = StrT_chr( StrStart, _T('\0') );
\r
7882 if ( p > StrStart ) {
\r
7883 TCHAR c = *( p - 1 );
\r
7884 if ( c == _T('\\') || c == _T('/') )
\r
7885 { *( p - 1 ) = _T('\0'); }
\r
7890 p = StrT_refFName( StrStart );
\r
7891 if ( p > StrStart ) p--;
\r
7895 /*
\83\8b\81[
\83g
\82È
\82ç \
\82ð
\95t
\82¯
\82é */
\r
7896 if ( p == StrStart + 2 ) {
\r
7897 *p = _T('\\'); p++; *p = _T('\0');
\r
7900 if ( out_StrLast != NULL ) *out_StrLast = p;
\r
7906 err: e = E_OTHERS; goto fin;
\r
7911 /***********************************************************************
\r
7912 <<< [StrT_isOverOfFileName] >>>
\r
7913 - "" or "\" or "/"
\r
7914 ************************************************************************/
\r
7915 inline bool StrT_isOverOfFileName( const TCHAR* PointerInPath )
\r
7917 return PointerInPath == NULL ||
\r
7918 *PointerInPath == _T('\0') ||
\r
7919 ( ( *PointerInPath == _T('\\') || *PointerInPath == _T('/') ) &&
\r
7920 *(PointerInPath + 1) == _T('\0') );
\r
7925 /***********************************************************************
\r
7926 <<< [StrT_getStepPath] >>>
\r
7927 ************************************************************************/
\r
7928 errnum_t StrT_getStepPath( TCHAR* out_StepPath, size_t StepPathSize,
\r
7929 const TCHAR* FullPath, const TCHAR* BasePath )
\r
7932 const TCHAR* abs_pointer;
\r
7933 const TCHAR* base_pointer;
\r
7937 const TCHAR* abs_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;
\r
7938 const TCHAR* base_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;
\r
7939 TCHAR* step_pointer;
\r
7940 TCHAR parent_symbol[4] = { _T('.'), _T('.'), _T('\\'), _T('\0') };
\r
7941 TCHAR base_path_2[ MAX_PATH ];
\r
7944 ASSERT_D( out_StepPath != FullPath, goto err );
\r
7946 abs_pointer = FullPath;
\r
7949 /* Set "base_pointer" */
\r
7950 if ( BasePath == NULL ) {
\r
7951 base_pointer = _tgetcwd( base_path_2, _countof(base_path_2) );
\r
7952 IF( base_pointer == NULL ) {goto err;}
\r
7955 base_pointer = BasePath;
\r
7959 /* Set "abs_separator_pointer", "base_separator_pointer" : after same parent folder path */
\r
7961 for (;;) { /* while abs_char == base_char */
\r
7962 abs_char = *abs_pointer;
\r
7963 base_char = *base_pointer;
\r
7965 abs_char = (TCHAR) _totlower( abs_char );
\r
7966 base_char = (TCHAR) _totlower( base_char );
\r
7968 if ( abs_char == _T('\0') ) {
\r
7970 /* out_StepPath = ".", if FullPath == BasePath */
\r
7971 if ( base_char == _T('\0') ) {
\r
7972 e= StrT_cpy( out_StepPath, StepPathSize, _T(".") ); IF(e)goto fin;
\r
7977 if ( base_char == _T('\0') ) { break; }
\r
7979 if ( abs_char != base_char ) {
\r
7980 if ( ( abs_char == _T('/') || abs_char == _T('\\') ) &&
\r
7981 ( base_char == _T('/') || base_char == _T('\\') ) )
\r
7982 { /* Do nothing */ }
\r
7987 /* Set "separator", "abs_separator_pointer", "base_separator_pointer" */
\r
7988 if ( base_char == _T('/') || base_char == _T('\\') ) {
\r
7989 if ( separator == 0 )
\r
7990 { separator = base_char; }
\r
7992 abs_separator_pointer = abs_pointer;
\r
7993 base_separator_pointer = base_pointer;
\r
7997 base_pointer += 1;
\r
8001 /* FullPath
\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
8002 if ( ( ( abs_char == _T('/') || abs_char == _T('\\') ) && base_char == _T('\0') ) ||
\r
8003 ( base_char == _T('/') || base_char == _T('\\') ) && abs_char == _T('\0') ) {
\r
8005 if ( separator == 0 )
\r
8006 { separator = abs_char; }
\r
8008 abs_separator_pointer = abs_pointer;
\r
8009 base_separator_pointer = base_pointer;
\r
8013 /* out_StepPath = FullPath, if there is not same folder */
\r
8014 if ( separator == 0 ) {
\r
8015 e= StrT_cpy( out_StepPath, StepPathSize, FullPath ); IF(e)goto fin;
\r
8020 /* Add "..\" to "out_StepPath" */
\r
8021 parent_symbol[2] = separator;
\r
8022 step_pointer = out_StepPath;
\r
8027 if ( StrT_isOverOfFileName( base_separator_pointer ) )
\r
8031 /* Set "base_separator_pointer" : next separator */
\r
8032 p1 = _tcschr( base_separator_pointer + 1, _T('/') );
\r
8033 p2 = _tcschr( base_separator_pointer + 1, _T('\\') );
\r
8035 if ( p1 == NULL ) {
\r
8037 { base_separator_pointer = NULL; }
\r
8039 { base_separator_pointer = p2; }
\r
8042 if ( p2 == NULL ) {
\r
8043 base_separator_pointer = p1;
\r
8046 { base_separator_pointer = p1; }
\r
8048 { base_separator_pointer = p2; }
\r
8053 /* Add "..\" to "out_StepPath" */
\r
8054 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, &step_pointer,
\r
8055 parent_symbol, NULL ); IF(e)goto fin;
\r
8059 /* Copy a part of "FullPath" to "out_StepPath" */
\r
8060 if ( StrT_isOverOfFileName( abs_separator_pointer ) ) {
\r
8061 ASSERT_D( step_pointer > out_StepPath, goto err );
\r
8062 *( step_pointer - 1 ) = _T('\0');
\r
8065 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, NULL,
\r
8066 abs_separator_pointer + 1, NULL ); IF(e)goto fin;
\r
8073 err: e = E_OTHERS; goto fin;
\r
8078 /***********************************************************************
\r
8079 <<< [StrT_getBaseName_part] >>>
\r
8080 ************************************************************************/
\r
8081 errnum_t StrT_getBaseName_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,
\r
8082 TCHAR** out_StrLast, const TCHAR* SrcPath )
\r
8089 p1 = StrT_refFName( SrcPath );
\r
8092 //=== #
\82ª
\96³
\82¢
\82Æ
\82«
\81A
\8dÅ
\8cã
\82Ì
\83s
\83\8a\83I
\83h
\82Ì
\91O
\82Ü
\82Å
\82ª
\81ABaseName
\r
8093 ps = _tcschr( p1, _T('#') );
\r
8094 if ( ps == NULL ) {
\r
8095 p2 = _tcsrchr( p1, _T('.') );
\r
8096 if ( p2 == NULL ) p2 = _tcsrchr( p1, _T('\0') );
\r
8099 //=== #
\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
8105 p3 = _tcschr( p3, _T('.') );
\r
8106 if ( p3 == NULL || p3 > ps ) break;
\r
8112 return stcpy_part_r( Str, StrSize, StrStart, out_StrLast, p1, p2 );
\r
8116 /***********************************************************************
\r
8117 <<< [StrT_addLastOfFileName] >>>
\r
8118 ************************************************************************/
\r
8119 errnum_t StrT_addLastOfFileName( TCHAR* out_Path, size_t PathSize,
\r
8120 const TCHAR* BasePath, const TCHAR* AddName )
\r
8126 const TCHAR* last_pos_in_base = StrT_chr( BasePath, _T('\0') );
\r
8127 const TCHAR* term_pos_in_base;
\r
8128 const TCHAR* add_pos_in_base;
\r
8129 const TCHAR* period_pos_in_base = _tcsrchr( BasePath, _T('.') ); // > term_pos_in_base
\r
8130 const TCHAR* last_pos_in_add = StrT_chr( AddName, _T('\0') );
\r
8131 const TCHAR* term_pos_in_add;
\r
8132 const TCHAR* period_pos_in_add = _tcsrchr( AddName, _T('.') ); // > term_pos_in_add
\r
8135 DISCARD_BYTES( out_Path, PathSize );
\r
8138 //=== term_pos_in_base
\r
8139 for ( term_pos_in_base = last_pos_in_base; term_pos_in_base >= BasePath; term_pos_in_base -- ) {
\r
8140 c = *term_pos_in_base;
\r
8141 if ( c == _T('/') || c == _T('\\') ) break;
\r
8145 //=== term_pos_in_add
\r
8146 for ( term_pos_in_add = last_pos_in_add; term_pos_in_add >= AddName; term_pos_in_add -- ) {
\r
8147 c = *term_pos_in_add;
\r
8148 if ( c == _T('/') || c == _T('\\') ) break;
\r
8152 //=== add_pos_in_base
\r
8153 if ( term_pos_in_base < period_pos_in_base ) {
\r
8154 add_pos_in_base = period_pos_in_base;
\r
8157 if ( term_pos_in_base < BasePath )
\r
8158 add_pos_in_base = StrT_chr( BasePath, _T('\0') );
\r
8160 add_pos_in_base = StrT_chr( term_pos_in_base, _T('\0') );
\r
8164 //=== setup output parameters
\r
8165 out_pos = (char*) out_Path;
\r
8166 free_size = PathSize;
\r
8169 //=== copy BasePath .. add_pos_in_base
\r
8170 copy_size = (char*)add_pos_in_base - (char*)BasePath;
\r
8171 if ( copy_size > free_size ) goto err_fa;
\r
8172 memcpy( out_pos, BasePath, copy_size );
\r
8173 out_pos += copy_size;
\r
8174 free_size -= copy_size;
\r
8177 //=== copy AddName .. last_pos_in_add
\r
8178 copy_size = (char*)last_pos_in_add - (char*)AddName;
\r
8179 if ( copy_size > free_size ) goto err_fa;
\r
8180 memcpy( out_pos, AddName, copy_size );
\r
8181 out_pos += copy_size;
\r
8182 free_size -= copy_size;
\r
8185 //=== add name and not change extension
\r
8186 if ( period_pos_in_add == NULL ) {
\r
8188 //=== copy period_pos_in_base .. last_pos_in_base
\r
8189 if ( period_pos_in_base > term_pos_in_base ) {
\r
8190 copy_size = (char*)last_pos_in_base - (char*)period_pos_in_base + sizeof(TCHAR);
\r
8191 if ( copy_size > free_size ) goto err_fa;
\r
8192 memcpy( out_pos, period_pos_in_base, copy_size );
\r
8195 *(TCHAR*)out_pos = _T('\0');
\r
8200 //=== add name and change extension
\r
8203 if ( *(period_pos_in_add + 1) == _T('\0') )
\r
8204 *( (TCHAR*)out_pos - 1 ) = _T('\0');
\r
8206 *(TCHAR*)out_pos = _T('\0');
\r
8212 return E_FEW_ARRAY;
\r
8217 /***********************************************************************
\r
8218 <<< [StrT_encodeToValidPath] >>>
\r
8219 ************************************************************************/
\r
8220 errnum_t StrT_encodeToValidPath( TCHAR* out_Path, size_t in_OutPathSize, const TCHAR* in_Path, bool in_IsName )
\r
8224 int i_in; /* index of "in_Path" */
\r
8225 int i_out = 0; /* index of "out_Path" */
\r
8226 int i_out_over = (int)( in_OutPathSize / sizeof(TCHAR) );
\r
8227 bool is_colon = in_IsName;
\r
8229 ASSERT_R( in_Path != out_Path, e=E_OTHERS; goto fin );
\r
8231 for ( i_in = 0; ; i_in += 1 ) {
\r
8233 int chara = in_Path[ i_in ]; /* a character */
\r
8235 if ( chara == _T('\0') )
\r
8239 /* Set "is_percent" */
\r
8240 switch ( chara ) {
\r
8241 case _T(','): case _T(';'): case _T('*'): case _T('?'): case _T('"'):
\r
8242 case _T('<'): case _T('>'): case _T('|'): case _T('%'):
\r
8243 is_percent = true;
\r
8246 is_percent = is_colon;
\r
8249 case _T('\\'): case _T('/'):
\r
8250 is_percent = in_IsName;
\r
8254 is_percent = false;
\r
8259 /* Set "out_Path[ i_out ]" */
\r
8260 if ( is_percent ) {
\r
8261 int high = chara / 0x10;
\r
8262 int low = chara & 0xF;
\r
8264 if ( high <= 9 ) {
\r
8267 high = ( high - 0xA ) + _T('a');
\r
8273 low = ( low - 0xA ) + _T('a');
\r
8276 ASSERT_R( i_out + 3 < i_out_over, e=E_FEW_ARRAY; goto fin );
\r
8278 out_Path[ i_out + 0 ] = _T('%');
\r
8279 out_Path[ i_out + 1 ] = (TCHAR) high;
\r
8280 out_Path[ i_out + 2 ] = (TCHAR) low;
\r
8284 ASSERT_R( i_out + 1 < i_out_over, e=E_FEW_ARRAY; goto fin );
\r
8286 out_Path[ i_out ] = (TCHAR) chara;
\r
8293 out_Path[ i_out ] = _T('\0');
\r
8300 /***********************************************************************
\r
8301 <<< [Strs_init] >>>
\r
8302 ************************************************************************/
\r
8303 enum { Strs_FirstSize = 0x0F00 };
\r
8305 errnum_t Strs_init( Strs* self )
\r
8309 self->MemoryAddress = NULL;
\r
8311 p = (byte_t*) malloc( Strs_FirstSize );
\r
8312 IF( p == NULL ) return E_FEW_MEMORY;
\r
8314 self->MemoryAddress = p;
\r
8315 self->MemoryOver = p + Strs_FirstSize;
\r
8316 self->NextElem = p + sizeof(TCHAR*);
\r
8317 self->PointerToNextStrInPrevElem = (TCHAR**) p;
\r
8318 self->Prev_PointerToNextStrInPrevElem = NULL;
\r
8319 *(TCHAR**) p = NULL;
\r
8321 self->FirstOfStrs = self;
\r
8322 self->NextStrs = NULL;
\r
8329 /***********************************************************************
\r
8330 <<< [Strs_finish] >>>
\r
8331 ************************************************************************/
\r
8332 errnum_t Strs_finish( Strs* self, errnum_t e )
\r
8337 if ( self->MemoryAddress == NULL ) return 0;
\r
8339 mp = self->FirstOfStrs;
\r
8341 free( mp->MemoryAddress );
\r
8342 if ( mp == self ) break;
\r
8344 next_mp = mp->NextStrs;
\r
8348 self->MemoryAddress = NULL;
\r
8355 /***********************************************************************
\r
8356 <<< [Strs_toEmpty] >>>
\r
8357 ************************************************************************/
\r
8358 errnum_t Strs_toEmpty( Strs* self )
\r
8360 Strs_finish( self, 0 );
\r
8361 return Strs_init( self );
\r
8366 /***********************************************************************
\r
8367 <<< [Strs_add] >>>
\r
8368 ************************************************************************/
\r
8369 errnum_t Strs_add( Strs* self, const TCHAR* Str, const TCHAR** out_AllocStr )
\r
8371 return Strs_addBinary( self, Str, StrT_chr( Str, _T('\0') ) + 1, out_AllocStr );
\r
8375 errnum_t Strs_addBinary( Strs* self, const TCHAR* Str, const TCHAR* StrOver, const TCHAR** out_AllocStr )
\r
8381 str_size = ( (byte_t*) StrOver - (byte_t*) Str );
\r
8382 elem_size = ( sizeof(TCHAR*) + str_size + ( sizeof(void*) - 1 ) ) & ~(sizeof(void*) - 1);
\r
8384 if ( self->NextElem + elem_size > self->MemoryOver )
\r
8385 { e= Strs_expandSize( self, str_size ); IF(e)goto fin; }
\r
8389 // [ FirstStr | NULL | TCHAR[] | ... ]
\r
8390 // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]
\r
8391 // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]
\r
8393 if ( out_AllocStr != NULL ) *out_AllocStr = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );
\r
8396 *(TCHAR**) self->NextElem = NULL;
\r
8397 memcpy( self->NextElem + sizeof(TCHAR*), Str, str_size );
\r
8399 //=== link to elem from previous elem
\r
8400 *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );
\r
8403 self->Prev_PointerToNextStrInPrevElem = self->PointerToNextStrInPrevElem;
\r
8404 self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;
\r
8405 self->NextElem = self->NextElem + elem_size;
\r
8414 /***********************************************************************
\r
8415 <<< [Strs_freeLast] >>>
\r
8416 ************************************************************************/
\r
8417 errnum_t Strs_freeLast( Strs* self, TCHAR* AllocStr )
\r
8422 TCHAR* prev_of_last_str;
\r
8424 Strs* prev_of_last_mp;
\r
8426 if ( self->Prev_PointerToNextStrInPrevElem == NULL ) {
\r
8427 prev_of_last_str = NULL;
\r
8429 for ( Strs_forEach( self, &str ) ) {
\r
8430 prev_of_last_str = last_str;
\r
8435 prev_of_last_str = (TCHAR*)( self->Prev_PointerToNextStrInPrevElem + 1 );
\r
8436 last_str = (TCHAR*)( self->PointerToNextStrInPrevElem + 1 );
\r
8440 IF( last_str != AllocStr ) {goto err;}
\r
8442 // [ FirstStr | NULL | TCHAR[] | ... ]
\r
8443 if ( prev_of_last_str == NULL ) {
\r
8444 self->NextElem = self->MemoryAddress + sizeof(TCHAR*);
\r
8445 self->PointerToNextStrInPrevElem = (TCHAR**) self->MemoryAddress;
\r
8448 // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]
\r
8449 else if ( (byte_t*) prev_of_last_str >= self->MemoryAddress &&
\r
8450 (byte_t*) prev_of_last_str < self->MemoryOver ) {
\r
8451 self->NextElem = (byte_t*)last_str - sizeof(TCHAR*);
\r
8452 self->PointerToNextStrInPrevElem = (TCHAR**)( (byte_t*)prev_of_last_str - sizeof(TCHAR*) );
\r
8455 // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]
\r
8457 prev_of_last_mp = NULL;
\r
8458 for ( mp = self->FirstOfStrs; mp->NextStrs != self; mp = mp->NextStrs ) {
\r
8459 prev_of_last_mp = mp;
\r
8462 free( self->MemoryAddress );
\r
8466 if ( prev_of_last_mp == NULL ) {
\r
8467 self->FirstOfStrs = self;
\r
8468 self->NextStrs = NULL;
\r
8471 prev_of_last_mp->NextStrs = self;
\r
8476 *self->PointerToNextStrInPrevElem = NULL;
\r
8477 self->Prev_PointerToNextStrInPrevElem = NULL;
\r
8483 err: e = E_OTHERS; goto fin;
\r
8488 /***********************************************************************
\r
8489 <<< [Strs_expandSize] >>>
\r
8490 ************************************************************************/
\r
8491 errnum_t Strs_expandSize( Strs* self, size_t FreeSize )
\r
8495 size_t elem_size = ( sizeof(TCHAR*) + FreeSize + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);
\r
8496 size_t memory_size;
\r
8497 byte_t* new_memory;
\r
8500 // [ FirstStr | NULL | TCHAR[] | ... ]
\r
8501 // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]
\r
8502 // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]
\r
8504 while ( self->NextElem + elem_size > self->MemoryOver ) {
\r
8507 mp = (Strs*) malloc( sizeof(Strs) ); IF(mp==NULL) goto err_fm;
\r
8508 memory_size = ( self->MemoryOver - self->MemoryAddress ) * 2;
\r
8509 new_memory = (byte_t*) malloc( memory_size );
\r
8510 IF( new_memory == NULL ) { free( mp ); goto err_fm; }
\r
8512 //=== move old memory
\r
8513 if ( self->FirstOfStrs == self ) {
\r
8514 self->FirstOfStrs = mp;
\r
8517 for ( mp2 = self->FirstOfStrs; mp2->NextStrs != self; mp2 = mp2->NextStrs );
\r
8518 mp2->NextStrs = mp;
\r
8521 mp->NextStrs = self;
\r
8523 //=== setup new memory
\r
8524 self->MemoryAddress = new_memory;
\r
8525 self->MemoryOver = new_memory + memory_size;
\r
8526 self->NextElem = new_memory;
\r
8527 // self->PointerToNextStrInPrevElem is same value
\r
8528 // self->FirstOfStrs is same value
\r
8529 // self->NextStrs is always NULL
\r
8533 err_fm: return E_FEW_ARRAY;
\r
8537 /***********************************************************************
\r
8538 <<< [Strs_commit] >>>
\r
8539 ************************************************************************/
\r
8540 errnum_t Strs_commit( Strs* self, TCHAR* StrOver )
\r
8544 if ( StrOver == NULL )
\r
8545 { StrOver = StrT_chr( (TCHAR*)( self->NextElem + sizeof(TCHAR*) ), _T('\0') ) + 1; }
\r
8546 elem_size = ( ( (byte_t*)StrOver - self->NextElem ) + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);
\r
8549 *(TCHAR**) self->NextElem = NULL;
\r
8551 //=== link to elem from previous elem
\r
8552 *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );
\r
8555 self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;
\r
8556 self->NextElem = self->NextElem + elem_size;
\r
8563 /***********************************************************************
\r
8564 <<< [Strs_allocateArray] >>>
\r
8565 ************************************************************************/
\r
8566 errnum_t Strs_allocateArray( Strs* self, TCHAR*** out_PointerArray, int* out_Count )
\r
8574 for ( Strs_forEach( self, &p ) ) {
\r
8578 e= HeapMemory_allocateArray( &pp, count ); IF(e){goto fin;}
\r
8581 for ( Strs_forEach( self, &p ) ) {
\r
8586 *out_PointerArray = pp;
\r
8587 *out_Count = count;
\r
8596 /***********************************************************************
\r
8598 ************************************************************************/
\r
8601 errnum_t StrArr_init( StrArr* self )
\r
8605 Set2_initConst( &self->Array );
\r
8606 Strs_initConst( &self->Chars );
\r
8608 e= Set2_init( &self->Array, 0x100 ); IF(e)goto cancel;
\r
8609 e= Strs_init( &self->Chars ); IF(e)goto cancel;
\r
8612 cancel: StrArr_finish( self, e ); return e;
\r
8616 /*[StrArr_finish]*/
\r
8617 errnum_t StrArr_finish( StrArr* self, errnum_t e )
\r
8619 if ( ! Set2_isInited( &self->Array ) ) return e;
\r
8621 e= Set2_finish( &self->Array, e );
\r
8622 e= Strs_finish( &self->Chars, e );
\r
8628 errnum_t StrArr_add( StrArr* self, const TCHAR* Str, int* out_I )
\r
8632 e= StrArr_expandCount( self, _tcslen( Str ) ); IF(e)goto fin;
\r
8633 _tcscpy_s( StrArr_getFreeAddr( self ), StrArr_getFreeCount( self ), Str );
\r
8634 e= StrArr_commit( self ); IF(e)goto fin;
\r
8635 if ( out_I != NULL ) *out_I = Set2_getCount( &self->Array, TCHAR* ) - 1;
\r
8643 /*[StrArr_commit]*/
\r
8644 errnum_t StrArr_commit( StrArr* self )
\r
8648 TCHAR** pp = NULL;
\r
8649 Set2* arr = &self->Array;
\r
8650 Strs* ss = &self->Chars;
\r
8652 p = Strs_getFreeAddr( ss );
\r
8653 e= Set2_alloc( arr, &pp, TCHAR* ); IF(e)goto fin;
\r
8654 e= Strs_commit( ss, NULL ); IF(e)goto fin;
\r
8659 if ( e && pp != NULL ) e= Set2_freeLast( arr, pp, TCHAR*, e );
\r
8664 /*[StrArr_fillTo]*/
\r
8665 errnum_t StrArr_fillTo( StrArr* self, int n, const TCHAR* Str )
\r
8670 const TCHAR** pp_over;
\r
8672 n -= Set2_getCount( &self->Array, TCHAR* );
\r
8673 if ( n <= 0 ) return 0;
\r
8675 if ( Str == NULL ) {
\r
8679 e= Strs_add( &self->Chars, Str, &p ); IF(e)goto fin;
\r
8682 e= Set2_allocMulti( &self->Array, &pp, TCHAR*, n ); IF(e)goto fin;
\r
8684 for ( ; pp < pp_over; pp++ )
\r
8693 /*[StrArr_toEmpty]*/
\r
8694 errnum_t StrArr_toEmpty( StrArr* self )
\r
8699 ee= Set2_toEmpty( &self->Array ); IF(ee&&!e)e=ee;
\r
8700 ee= Strs_toEmpty( &self->Chars ); IF(ee&&!e)e=ee;
\r
8706 /***********************************************************************
\r
8707 <<< [StrArr_parseCSV] >>>
\r
8708 ************************************************************************/
\r
8709 errnum_t StrArr_parseCSV( StrArr* self, const TCHAR* CSVLine )
\r
8712 const TCHAR* p = CSVLine;
\r
8714 e= StrArr_toEmpty( self ); IF(e)goto fin;
\r
8717 e= StrT_meltCSV( StrArr_getFreeAddr( self ), StrArr_getFreeSize( self ), &p );
\r
8718 if ( e == E_FEW_ARRAY ) {
\r
8719 e= StrArr_expandSize( self, StrArr_getFreeSize( self ) * 2 ); IF(e)goto fin;
\r
8724 e = StrArr_commit( self ); IF(e)goto fin;
\r
8725 } while ( p != NULL );
\r
8734 /*-------------------------------------------------------------------------*/
\r
8735 /* <<<< ### (StrFile) Read Class implement >>>> */
\r
8736 /*-------------------------------------------------------------------------*/
\r
8738 errnum_t StrFile_init_sub( StrFile* self, void* Buffer, size_t BufferSize, int Flags );
\r
8740 /*[StrFile_init_fromStr]*/
\r
8741 errnum_t StrFile_init_fromStr( StrFile* self, TCHAR* LinkStr )
\r
8743 self->IsBufferInHeap = false;
\r
8745 StrFile_init_sub( self, LinkStr,
\r
8746 (char*)StrT_chr( LinkStr, _T('\0') ) - (char*)LinkStr, STR_FILE_WCHAR );
\r
8748 StrFile_init_sub( self, LinkStr,
\r
8749 (char*)StrT_chr( LinkStr, _T('\0') ) - (char*)LinkStr, 0 );
\r
8756 /*[StrFile_initConst]*/
\r
8757 void StrFile_initConst( StrFile* self )
\r
8759 self->Buffer = NULL;
\r
8763 /*[StrFile_init_withBuf]*/
\r
8764 errnum_t StrFile_init_withBuf( StrFile* self, void* LinkBuffer, size_t LinkBufferSize, int Flags )
\r
8766 self->IsBufferInHeap = false;
\r
8767 StrFile_init_sub( self, LinkBuffer, LinkBufferSize, Flags );
\r
8772 /*[StrFile_init_sub]*/
\r
8773 errnum_t StrFile_init_sub( StrFile* self, void* Buffer, size_t BufferSize, int Flags )
\r
8775 unsigned char* top = (unsigned char*) Buffer;
\r
8777 if ( Flags & STR_FILE_WCHAR ) {
\r
8778 self->CharSize = 2;
\r
8779 self->Pointer = top;
\r
8782 // UTF-16 BOM= { FF, FE }, UTF-8 BOM = { EF, BB, BF }
\r
8783 if ( BufferSize >= 2 && top[0] == 0xFF && top[1] == 0xFE ) {
\r
8784 self->CharSize = 2;
\r
8785 self->Pointer = top + 2;
\r
8786 if ( BufferSize % 2 == 1 ) BufferSize --;
\r
8788 else if ( BufferSize >= 3 && top[0] == 0xEF && top[1] == 0xBB && top[2] == 0xBF ) {
\r
8789 self->CharSize = 1;
\r
8790 self->Pointer = top + 3;
\r
8793 self->CharSize = 1;
\r
8794 self->Pointer = top;
\r
8798 self->Buffer = Buffer;
\r
8799 self->BufferSize = BufferSize;
\r
8800 // self->IsBufferInHeap // not init in this function
\r
8806 /*[StrFile_init_fromSizedStructInStream]*/
\r
8807 errnum_t StrFile_init_fromSizedStructInStream( StrFile* self, HANDLE* Stream )
\r
8811 self->IsBufferInHeap = false;
\r
8813 e= FileT_readSizedStruct_WinAPI( Stream, &self->Buffer ); IF(e)goto rollback;
\r
8814 self->IsBufferInHeap = true;
\r
8815 self->OffsetToHeapBlockFirst = - (int) sizeof(size_t);
\r
8816 e= StrFile_init_sub( self, (size_t*)self->Buffer + 1,
\r
8817 *(size_t*)self->Buffer - sizeof(size_t), STR_FILE_READ ); IF(e)goto rollback;
\r
8820 rollback: StrFile_finish( self, e ); return e;
\r
8824 /*[StrFile_finish]*/
\r
8825 errnum_t StrFile_finish( StrFile* self, errnum_t e )
\r
8827 if ( self->Buffer == NULL ) return e;
\r
8828 if ( self->IsBufferInHeap ) {
\r
8829 free( (char*) self->Buffer + self->OffsetToHeapBlockFirst );
\r
8830 self->IsBufferInHeap = false;
\r
8832 self->Buffer = NULL;
\r
8837 /*[StrFile_readLine]*/
\r
8838 errnum_t StrFile_readLine( StrFile* self, TCHAR* out_Line, size_t LineSize )
\r
8841 TCHAR* last_of_line;
\r
8843 if ( self->CharSize == 1 ) {
\r
8844 char* ptr = (char*) self->Pointer;
\r
8845 char* first = ptr;
\r
8846 char* over = (char*) self->Buffer + self->BufferSize;
\r
8849 if ( ptr >= over ) goto err_nn;
\r
8852 if ( ptr >= over ) { self->Pointer = (void*)0xFFFFFFFF; break; }
\r
8853 if ( *ptr == '\n' ) { ptr++; self->Pointer = ptr; break; }
\r
8856 size = ptr - first;
\r
8859 if ( ptr < over ) {
\r
8863 e= stprintf_r( out_Line, LineSize, _T("%S"), first );
\r
8867 else { // if cannot access *ptr
\r
8870 line = malloc( size + sizeof(char) );
\r
8871 line[ size ] = '\0';
\r
8872 memcpy( line, first, size );
\r
8874 e= stprintf_r( out_Line, LineSize, _T("%S"), line );
\r
8878 last_of_line = StrT_chr( out_Line, _T('\0') );
\r
8880 if ( size > LineSize - sizeof(char) ) goto err_fa;
\r
8882 last_of_line = out_Line + size;
\r
8883 *last_of_line = '\0';
\r
8884 memcpy( out_Line, first, size );
\r
8888 wchar_t* ptr = (wchar_t*) self->Pointer;
\r
8889 wchar_t* first = ptr;
\r
8890 wchar_t* over = (wchar_t*)( (char*) self->Buffer + self->BufferSize );
\r
8893 ASSERT_D( self->CharSize == 2, goto err );
\r
8895 if ( ptr >= over ) goto err_nn;
\r
8898 if ( ptr >= over ) { self->Pointer = (void*)0xFFFFFFFF; break; }
\r
8899 if ( *ptr == L'\n' ) { ptr++; self->Pointer = ptr; break; }
\r
8902 size = (char*) ptr - (char*) first;
\r
8905 IF( size > LineSize - sizeof(TCHAR) ) goto err_fa;
\r
8907 last_of_line = (TCHAR*)( (char*) out_Line + size );
\r
8908 *last_of_line = _T('\0');
\r
8909 memcpy( out_Line, first, size );
\r
8911 if ( ptr < over ) {
\r
8912 wchar_t ch = *ptr;
\r
8915 e= stprintf_r( out_Line, LineSize, _T("%S"), first );
\r
8918 last_of_line = StrT_chr( out_Line, _T('\0') );
\r
8920 else { // if cannot access *ptr
\r
8921 wchar_t last_str[2];
\r
8925 last_str[0] = *ptr;
\r
8926 last_str[1] = L'\0';
\r
8929 e= stprintf_r( out_Line, LineSize, "%S", first );
\r
8930 *ptr = last_str[0];
\r
8933 last_of_line = StrT_chr( out_Line, _T('\0') );
\r
8934 LineSize -= (char*) last_of_line - (char*) out_Line;
\r
8935 e= stprintf_r( last_of_line, LineSize, "%S", last_str ); IF(e)goto fin;
\r
8936 last_of_line = StrT_chr( last_of_line, _T('\0') );
\r
8941 // change from CR+LF to LF (text mode)
\r
8942 if ( last_of_line >= out_Line + 2 ) {
\r
8943 if ( *(last_of_line - 2) == _T('\r') && *(last_of_line - 1) == _T('\n') ) {
\r
8944 *(last_of_line - 2) = _T('\n'); *(last_of_line - 1) = _T('\0');
\r
8952 err_fa: e = E_FEW_ARRAY; goto fin;
\r
8953 err_nn: self->Pointer = (void*)0xFFFFFFFF; e=0; goto fin; // not [e = E_NO_NEXT], because ferror()==0
\r
8955 err: e = E_OTHERS; goto fin;
\r
8961 /*-------------------------------------------------------------------------*/
\r
8962 /* <<<< ### (StrFile) Write Class implement >>>> */
\r
8963 /*-------------------------------------------------------------------------*/
\r
8965 errnum_t StrFile_expandIfOver_sub( StrFile* self, size_t DataSize );
\r
8968 //[StrFile_init_toHeap]
\r
8969 errnum_t StrFile_init_toHeap( StrFile* self, int Flags )
\r
8972 enum { start_size = 480 };
\r
8974 mem = malloc( start_size ); IF ( mem == NULL ) return E_FEW_MEMORY;
\r
8976 self->Buffer = (char*) mem + sizeof(size_t);
\r
8977 self->BufferSize = start_size - sizeof(size_t);
\r
8978 self->IsBufferInHeap = true;
\r
8979 self->IsTextMode = ( (Flags & STR_FILE_BINARY) == 0 );
\r
8980 self->OffsetToHeapBlockFirst = - (int) sizeof(size_t);
\r
8981 if ( Flags & STR_FILE_WCHAR ) {
\r
8982 wchar_t* wp = (wchar_t*) self->Buffer;
\r
8987 self->CharSize = 2;
\r
8988 self->Pointer = (char*) self->Buffer + sizeof(wchar_t);
\r
8991 char* ap = (char*) self->Buffer;
\r
8995 self->CharSize = 1;
\r
8996 self->Pointer = (char*) self->Buffer;
\r
9002 //[StrFile_write_s]
\r
9003 errnum_t StrFile_write_s( StrFile* self, const TCHAR* Text )
\r
9014 str_size = (_tcslen( Text ) + 1) * sizeof(wchar_t); // max is for all 2byte charactors
\r
9015 str = malloc( str_size ); IF( str == NULL )goto err_fm;
\r
9016 sprintf_s( str, str_size, "%S", Text ); // conver to multi byte char
\r
9022 if ( self->IsTextMode ) {
\r
9024 pos2 = strchr( pos1, '\n' );
\r
9025 if ( pos2 == NULL ) break;
\r
9027 // write 1 line and change from \n to CR LF
\r
9028 e= StrFile_writeBinary( self, pos1, (char*) pos2 - (char*) pos1 + 2 * sizeof(char) );
\r
9030 ( (char*) self->Pointer )[-2] = '\r';
\r
9031 ( (char*) self->Pointer )[-1] = '\n';
\r
9037 // if "IsTextMode", write last line
\r
9038 // if not "IsTextMode", write whole text
\r
9039 pos2 = strchr( pos1, '\0' );
\r
9040 e= StrFile_writeBinary( self, pos1, (char*) pos2 - (char*) pos1 + sizeof(char) );
\r
9042 self->Pointer = (char*) self->Pointer - sizeof(char);
\r
9048 if ( str != NULL ) free( str );
\r
9053 err_fm: e = E_FEW_MEMORY; goto fin;
\r
9058 //[StrFile_write_w]
\r
9059 errnum_t StrFile_write_w( StrFile* self, const TCHAR* Text )
\r
9062 const wchar_t* pos1;
\r
9063 const wchar_t* pos2;
\r
9065 wchar_t* str = NULL;
\r
9072 str_size = (_tcslen( Text ) + 1) * sizeof(wchar_t); // max is for all 1byte char to wchar_t
\r
9073 str = malloc( str_size ); IF( str == NULL )goto err_fm;
\r
9074 swprintf_s( str, str_size / sizeof(wchar_t), L"%S", Text ); // conver to wide byte char
\r
9078 if ( self->IsTextMode ) {
\r
9080 pos2 = wcschr( pos1, L'\n' );
\r
9081 if ( pos2 == NULL ) break;
\r
9083 // write 1 line and change from \n to CR LF
\r
9084 e= StrFile_writeBinary( self, pos1, (char*) pos2 - (char*) pos1 + 2 * sizeof(wchar_t) );
\r
9086 ( (wchar_t*) self->Pointer )[-2] = L'\r';
\r
9087 ( (wchar_t*) self->Pointer )[-1] = L'\n';
\r
9093 // if "IsTextMode", write last line
\r
9094 // if not "IsTextMode", write whole text
\r
9095 pos2 = wcschr( pos1, L'\0' );
\r
9096 e= StrFile_writeBinary( self, pos1, (char*) pos2 - (char*) pos1 + sizeof(wchar_t) );
\r
9098 self->Pointer = (char*) self->Pointer - sizeof(wchar_t);
\r
9103 if ( str != NULL ) free( str );
\r
9108 err_fm: e = E_FEW_MEMORY; goto fin;
\r
9114 errnum_t StrFile_write( StrFile* self, const TCHAR* Text )
\r
9116 if ( self->CharSize == 1 ) return StrFile_write_s( self, Text );
\r
9117 else return StrFile_write_w( self, Text );
\r
9121 //[StrFile_expandIfOver]
\r
9122 errnum_t StrFile_expandIfOver( StrFile* self, size_t DataSize )
\r
9124 if ( (char*) self->Pointer + DataSize <= (char*) self->Buffer + self->BufferSize ) return 0;
\r
9125 else return StrFile_expandIfOver_sub( self, DataSize );
\r
9129 //[StrFile_writeBinary]
\r
9130 errnum_t StrFile_writeBinary( StrFile* self, const void* Data, size_t DataSize )
\r
9134 e= StrFile_expandIfOver( self, DataSize ); if(e)return e;
\r
9135 memcpy( self->Pointer, Data, DataSize );
\r
9136 self->Pointer = (char*) self->Pointer + DataSize;
\r
9141 //[StrFile_expandIfOver_sub]
\r
9142 errnum_t StrFile_expandIfOver_sub( StrFile* self, size_t DataSize )
\r
9146 size_t old_size = (char*) self->Pointer - (char*) self->Buffer;
\r
9147 size_t new_size = ( self->BufferSize + sizeof(size_t) ) * 2 + DataSize;
\r
9149 IF( ! self->IsBufferInHeap ) {goto err;}
\r
9150 // Writing must expand self->Buffer from heap when self->Buffer is small
\r
9152 mem = realloc( (char*) self->Buffer + self->OffsetToHeapBlockFirst, new_size );
\r
9153 IF(mem == NULL) goto err_fa;
\r
9155 self->Buffer = (char*) mem + sizeof(size_t);
\r
9156 self->BufferSize = new_size - sizeof(size_t);
\r
9157 self->OffsetToHeapBlockFirst = - (int) sizeof(size_t);
\r
9158 self->Pointer = (char*) self->Buffer + old_size;
\r
9164 err_fa: e = E_FEW_ARRAY; goto fin;
\r
9165 err: e = E_OTHERS; goto fin;
\r
9169 //[StrFile_peekWrittenStringW]
\r
9170 errnum_t StrFile_peekWrittenStringW( StrFile* self, wchar_t** out_String )
\r
9174 ASSERT_R( self->CharSize == 2, e=E_OTHERS; goto fin );
\r
9175 *out_String = (wchar_t*)( (char*) self->Buffer + sizeof(wchar_t) );
\r
9183 //[StrFile_peekWrittenStringA]
\r
9184 errnum_t StrFile_peekWrittenStringA( StrFile* self, char** out_String )
\r
9188 ASSERT_R( self->CharSize == 1, e=E_OTHERS; goto fin );
\r
9189 *out_String = self->Buffer;
\r
9197 //[StrFile_pickupSizedStruct]
\r
9198 errnum_t StrFile_pickupSizedStruct( StrFile* self, SizedStruct** out_Struct )
\r
9200 *out_Struct = (SizedStruct*)( (char*) self->Buffer - sizeof(size_t) );
\r
9201 *( (size_t*) self->Buffer - 1 ) = (char*) self->Pointer - (char*) self->Buffer + sizeof(size_t);
\r
9202 self->IsBufferInHeap = false;
\r
9207 //[StrFile_restoreSizedStruct]
\r
9208 errnum_t StrFile_restoreSizedStruct( StrFile* self, SizedStruct* Struct, errnum_t e )
\r
9210 ASSERT_R( ! self->IsBufferInHeap, goto err );
\r
9212 self->Buffer = (char*) Struct + sizeof(size_t);
\r
9213 self->IsBufferInHeap = true;
\r
9219 err: e = E_OTHERS; goto fin;
\r
9223 //[StrFile_moveSizedStructToStream]
\r
9224 errnum_t StrFile_moveSizedStructToStream( StrFile* self, HANDLE Stream )
\r
9227 SizedStruct* data = NULL;
\r
9229 e= StrFile_pickupSizedStruct( self, &data ); IF(e)goto fin;
\r
9230 e= FileT_writeSizedStruct_WinAPI( Stream, data ); IF(e)goto fin;
\r
9233 if ( data != NULL ) { e= StrFile_restoreSizedStruct( self, data, e ); }
\r
9238 //[StrFile_setPointer]
\r
9239 errnum_t StrFile_setPointer( StrFile* self, int OffsetOfPointer )
\r
9241 if ( self->CharSize == 2 ) OffsetOfPointer += sizeof(wchar_t);
\r
9242 IF( OffsetOfPointer < 0 || OffsetOfPointer >= (int) self->BufferSize ) return E_INVALID_VALUE;
\r
9243 self->Pointer = (char*) self->Buffer + OffsetOfPointer;
\r
9248 /*[StrFile_getPointer]*/
\r
9249 errnum_t StrFile_getPointer( StrFile* self, int* out_OffsetOfPointer )
\r
9251 if ( (uintptr_t) self->Pointer == 0xFFFFFFFF )
\r
9252 { *out_OffsetOfPointer = self->BufferSize; }
\r
9254 { *out_OffsetOfPointer = (char*) self->Pointer - (char*) self->Buffer; }
\r
9259 //[StrFile_isAtEndOfStream]
\r
9260 bool StrFile_isAtEndOfStream( StrFile* self )
\r
9262 return self->Pointer == (void*)0xFFFFFFFF;
\r
9266 //[StrFile_isInited]
\r
9267 errnum_t StrFile_isInited( StrFile* self )
\r
9269 return self->Buffer != NULL;
\r
9274 /***********************************************************************
\r
9275 <<< (SearchStringByBM_Class) >>>
\r
9276 ************************************************************************/
\r
9277 errnum_t SearchStringByBM_Class_allocateSkipArray_Sub( SearchStringByBM_Class* self );
\r
9280 /*[SearchStringByBM_Class_initConst]*/
\r
9281 void SearchStringByBM_Class_initConst( SearchStringByBM_Class* self )
\r
9283 self->SkipArray = NULL;
\r
9287 /*[SearchStringByBM_Class_initialize]*/
\r
9288 errnum_t SearchStringByBM_Class_initialize( SearchStringByBM_Class* self,
\r
9289 const TCHAR* TextString, const TCHAR* Keyword )
\r
9291 return SearchStringByBM_Class_initializeFromPart( self,
\r
9292 TextString, _tcslen( TextString ), Keyword );
\r
9296 /*[SearchStringByBM_Class_initializeFromPart]*/
\r
9297 errnum_t SearchStringByBM_Class_initializeFromPart( SearchStringByBM_Class* self,
\r
9298 const TCHAR* TextString, size_t TextString_Length, const TCHAR* Keyword )
\r
9300 self->TextString = TextString;
\r
9301 self->TextStringLength = TextString_Length;
\r
9302 self->Keyword = Keyword;
\r
9304 /*
\91¼
\82Ì
\83\81\83\93\83o
\81[
\95Ï
\90\94\82Í
\81A
\8e\9f\82Ì
\8aÖ
\90\94\82Ì
\92\86\82Å
\8f\89\8aú
\89»
\82·
\82é */
\r
9305 return SearchStringByBM_Class_allocateSkipArray_Sub( self );
\r
9309 /*[SearchStringByBM_Class_finalize]*/
\r
9310 errnum_t SearchStringByBM_Class_finalize( SearchStringByBM_Class* self, errnum_t e )
\r
9312 if ( self->SkipArray != NULL ) {
\r
9313 free( self->SkipArray );
\r
9314 self->SkipArray = NULL;
\r
9321 /***********************************************************************
\r
9322 <<< [SearchStringByBM_Class_getSkipCount_Sub] >>>
\r
9323 - Boyer-Moore
\96@
\82Ì skip
\8aÖ
\90\94\r
9324 ************************************************************************/
\r
9325 inline int SearchStringByBM_Class_getSkipCount_Sub(
\r
9326 TCHAR TextCharacter, int KeywordLastIndex,
\r
9327 int* SkipArray, int SkipArray_MinCharacter, int SkipArray_MaxCharacter )
\r
9330 TextCharacter < SkipArray_MinCharacter ||
\r
9331 TextCharacter > SkipArray_MaxCharacter ) {
\r
9332 return KeywordLastIndex + 1;
\r
9335 return SkipArray[ TextCharacter - SkipArray_MinCharacter ];
\r
9340 /***********************************************************************
\r
9341 <<< [SearchStringByBM_Class_search] >>>
\r
9343 -
\8fî
\95ñ
\8c\9f\8dõ
\83A
\83\8b\83S
\83\8a\83Y
\83\80 p106
\82Ì C
\8c¾
\8cê
\94Å
\r
9344 ************************************************************************/
\r
9345 errnum_t SearchStringByBM_Class_search( SearchStringByBM_Class* self, int* out_KeywordIndex )
\r
9347 const TCHAR* test_string = self->TextString;
\r
9348 const TCHAR* keyword = self->Keyword;
\r
9349 int text_string_length = self->TextStringLength; /* m */
\r
9350 int keyword_last_index = self->KeywordLastIndex; /* n - 1 */
\r
9351 int keyword_last_position = self->KeywordLastPosition; /* pos - 1 */
\r
9353 int* skip_array = self->SkipArray;
\r
9354 TCHAR min_character = self->SkipArray_MinCharacter;
\r
9355 TCHAR max_character = self->SkipArray_MaxCharacter;
\r
9357 *out_KeywordIndex = SearchString_NotFound;
\r
9360 while ( keyword_last_position < text_string_length ) {
\r
9362 /*
\8e\9f\82Ì
\8fÆ
\8d\87\88Ê
\92u
\82Ö (1) */
\r
9363 skip_count = SearchStringByBM_Class_getSkipCount_Sub(
\r
9364 test_string[ keyword_last_position ],
\r
9365 keyword_last_index, skip_array, min_character, max_character );
\r
9368 /*
\96\96\94ö
\82Ì
\8fÆ
\8d\87\82ª
\90¬
\8c÷
\82µ
\82½
\82ç */
\r
9369 if ( test_string[ keyword_last_position ] == keyword[ keyword_last_index ] ) {
\r
9371 /*
\96\96\94ö
\82©
\82ç
\8fÆ
\8d\87\82·
\82é */
\r
9372 int text_string_index = keyword_last_position - 1; /* k - 1 */
\r
9373 int keyword_index = keyword_last_index - 1; /* j - 1 */
\r
9376 /*
\83L
\81[
\83\8f\81[
\83h
\91S
\91Ì
\82Ì
\8fÆ
\8d\87\82É
\90¬
\8c÷
\82µ
\82½
\82ç */
\r
9377 if ( keyword_index < 0 ) {
\r
9378 *out_KeywordIndex = text_string_index + 1;
\r
9379 self->KeywordLastPosition = keyword_last_position + skip_count;
\r
9383 /*
\8fÆ
\8d\87\82ª
\8e¸
\94s
\82µ
\82½
\82ç */
\r
9384 if ( test_string[ text_string_index ] != keyword[ keyword_index ] ) {
\r
9388 /*
\82P
\82Â
\91O
\82Ì
\95¶
\8e\9a\82Ö */
\r
9389 text_string_index -= 1;
\r
9390 keyword_index -= 1;
\r
9393 /*
\8e\9f\82Ì
\8fÆ
\8d\87\88Ê
\92u
\82Ö (2) */
\r
9394 keyword_last_position += skip_count;
\r
9402 /***********************************************************************
\r
9403 <<< [SearchStringByBM_Class_allocateSkipArray_Sub] >>>
\r
9404 - Boyer-Moore
\96@
\82Ì skip
\8aÖ
\90\94\82ð
\8dì
\90¬
\82·
\82é
\8aÖ
\90\94\r
9405 -
\8fî
\95ñ
\8c\9f\8dõ
\83A
\83\8b\83S
\83\8a\83Y
\83\80 p107
\82Ì C
\8c¾
\8cê
\94Å
\82Í
\81A
\89º
\8bL Set "self->SkipArray"
\88È
\8d~
\r
9406 ************************************************************************/
\r
9407 errnum_t SearchStringByBM_Class_allocateSkipArray_Sub( SearchStringByBM_Class* self )
\r
9409 const TCHAR* keyword = self->Keyword;
\r
9410 const TCHAR* p; /* Pointer to "keyword" */
\r
9411 TCHAR c; /* Character in "keyword" */
\r
9412 TCHAR min_character;
\r
9413 TCHAR max_character;
\r
9414 int keyword_length;
\r
9415 const TCHAR* keyword_last_pointer;
\r
9416 int* skip_array = NULL;
\r
9420 /* Set "self->SkipArray_MinCharacter", "self->SkipArray_MaxCharacter" */
\r
9422 IF ( c == _T('\0') ) { e=E_OTHERS; goto fin; }
\r
9423 min_character = c;
\r
9424 max_character = c;
\r
9428 if ( c == _T('\0') ) { break; }
\r
9430 if ( c < min_character ) { min_character = c; }
\r
9431 if ( c > max_character ) { max_character = c; }
\r
9435 self->SkipArray_MinCharacter = min_character;
\r
9436 self->SkipArray_MaxCharacter = max_character;
\r
9440 keyword_length = p - keyword;
\r
9441 self->KeywordLastIndex = keyword_length - 1;
\r
9442 self->KeywordLastPosition = keyword_length - 1;
\r
9445 /* Set "self->SkipArray" */
\r
9446 skip_array = malloc( ( max_character - min_character + 1 ) * sizeof(int) );
\r
9447 IF ( skip_array == NULL ) { e=E_FEW_ARRAY; goto fin; }
\r
9449 for ( c = min_character; c <= max_character; c += 1 ) {
\r
9450 /*
\83L
\81[
\83\8f\81[
\83h
\82É
\8eg
\82í
\82ê
\82Ä
\82¢
\82È
\82¢
\95¶
\8e\9a\82É
\82Â
\82¢
\82Ä */
\r
9451 skip_array[ c - min_character ] = keyword_length;
\r
9454 keyword_last_pointer = &keyword[ keyword_length - 1 ];
\r
9457 p < keyword_last_pointer;
\r
9460 /*
\83L
\81[
\83\8f\81[
\83h
\82É
\8eg
\82í
\82ê
\82Ä
\82¢
\82é
\95¶
\8e\9a\82É
\82Â
\82¢
\82Ä */
\r
9461 /*
\83L
\81[
\83\8f\81[
\83h
\82Ì
\92\86\82É
\93¯
\82¶
\95¶
\8e\9a\82ª
\82 \82é
\82Æ
\82«
\82Í
\81A
\8cã
\82ë
\82Ì
\95¶
\8e\9a\82Ì
\88Ê
\92u
\82ª
\97D
\90æ
\82³
\82ê
\82é */
\r
9462 skip_array[ *p - min_character ] = keyword_last_pointer - p;
\r
9469 if ( skip_array != NULL ) {
\r
9470 free( skip_array );
\r
9471 skip_array = NULL;
\r
9474 self->SkipArray = skip_array;
\r
9480 /***********************************************************************
\r
9481 <<< (SearchStringByAC_Class) >>>
\r
9482 ************************************************************************/
\r
9483 errnum_t SearchStringByAC_Class_makeFunctionsStep1( SearchStringByAC_Class* self,
\r
9484 const TCHAR** KeywordArray, unsigned KeywordArrayCount );
\r
9485 errnum_t SearchStringByAC_Class_makeFunctionsStep2( SearchStringByAC_Class* self );
\r
9486 errnum_t SearchStringByAC_Class_increaseState( SearchStringByAC_Class* self );
\r
9487 errnum_t SearchStringByAC_Class_addOutputFunction( SearchStringByAC_Class* self,
\r
9488 int State, const TCHAR* Keyword );
\r
9489 errnum_t SearchStringByAC_Class_addOutputFunctions( SearchStringByAC_Class* self,
\r
9490 int TargetState, int SourceState );
\r
9493 /***********************************************************************
\r
9494 <<< [SearchStringByAC_Class_initConst] >>>
\r
9495 ************************************************************************/
\r
9496 void SearchStringByAC_Class_initConst( SearchStringByAC_Class* self )
\r
9498 Set2_initConst( &self->GoToFunction );
\r
9499 self->FailureFunction = NULL;
\r
9500 self->OutputFunction = NULL;
\r
9501 self->OutputCount = NULL;
\r
9505 /***********************************************************************
\r
9506 <<< [SearchStringByAC_Class_initialize] >>>
\r
9507 ************************************************************************/
\r
9508 errnum_t SearchStringByAC_Class_initialize( SearchStringByAC_Class* self,
\r
9509 const TCHAR* TextString, const TCHAR** KeywordArray, size_t KeywordArrayCount )
\r
9511 return SearchStringByAC_Class_initializeFromPart(
\r
9512 self, TextString, _tcslen( TextString ), KeywordArray, KeywordArrayCount );
\r
9516 /***********************************************************************
\r
9517 <<< [SearchStringByAC_Class_initializeFromPart] >>>
\r
9518 ************************************************************************/
\r
9519 errnum_t SearchStringByAC_Class_initializeFromPart( SearchStringByAC_Class* self,
\r
9520 const TCHAR* TextString, size_t TextString_Length,
\r
9521 const TCHAR** KeywordArray, size_t KeywordArrayCount )
\r
9525 self->StateNum = SearchStringByAC_RootState;
\r
9526 self->TextString = TextString;
\r
9527 self->TextStringLength = TextString_Length;
\r
9528 self->TextStringIndex = 0;
\r
9529 self->FoundKeywords = NULL;
\r
9531 e= Set2_init( &self->GoToFunction, 0x1000 ); IF(e){goto fin;}
\r
9532 self->FailureFunction = NULL;
\r
9533 self->OutputFunction = NULL;
\r
9534 self->OutputCount = NULL;
\r
9535 self->StateCount = 0;
\r
9537 /* Make functions */
\r
9538 e= SearchStringByAC_Class_makeFunctionsStep1( self, KeywordArray, KeywordArrayCount );
\r
9540 e= SearchStringByAC_Class_makeFunctionsStep2( self );
\r
9546 SearchStringByAC_Class_finalize( self, e );
\r
9552 /***********************************************************************
\r
9553 <<< [SearchStringByAC_Class_finalize] >>>
\r
9554 ************************************************************************/
\r
9555 errnum_t SearchStringByAC_Class_finalize( SearchStringByAC_Class* self, errnum_t e )
\r
9557 e= Set2_finish( &self->GoToFunction, e );
\r
9559 if ( self->FailureFunction != NULL ) {
\r
9560 free( self->FailureFunction );
\r
9561 self->FailureFunction = NULL;
\r
9563 if ( self->OutputFunction != NULL ) {
\r
9566 for ( i = 0; i < self->StateCount; i += 1 ) {
\r
9567 const TCHAR** keywords = self->OutputFunction[i];
\r
9569 if ( keywords != NULL ) {
\r
9570 free( (void*) keywords );
\r
9573 free( (void*) self->OutputFunction );
\r
9574 self->OutputFunction = NULL;
\r
9576 if ( self->OutputCount != NULL ) {
\r
9577 free( self->OutputCount );
\r
9578 self->OutputCount = NULL;
\r
9584 /***********************************************************************
\r
9585 <<< [SearchStringByAC_Class_search] >>>
\r
9586 - Aho-Corasick
\96@(AC
\96@)
\82Ì
\8c\9f\8dõ
\82ð
\82·
\82é
\8aÖ
\90\94\r
9587 -
\8fî
\95ñ
\8c\9f\8dõ
\83A
\83\8b\83S
\83\8a\83Y
\83\80 p112
\82Ì C
\8c¾
\8cê
\94Å
\82Í
\81A
\96{
\8aÖ
\90\94\82Ì for
\95¶
\88È
\8d~
\r
9588 ************************************************************************/
\r
9589 errnum_t SearchStringByAC_Class_search( SearchStringByAC_Class* self,
\r
9590 int* out_TextStringIndex, TCHAR** out_Keyword )
\r
9592 int state_num = self->StateNum; /* s */
\r
9593 const TCHAR* text_string = self->TextString; /* text */
\r
9594 int text_string_length = self->TextStringLength; /* m */
\r
9595 int text_string_index = self->TextStringIndex; /* i - 1 */
\r
9596 AC_GotoFunctionType goto_function = (AC_GotoFunctionType) self->GoToFunction.First; /* g */
\r
9597 int* failure_function = self->FailureFunction; /* f */
\r
9598 const TCHAR*** output_function = self->OutputFunction; /* output */
\r
9599 int next_state_num;
\r
9600 const TCHAR** found_keywords = self->FoundKeywords;
\r
9604 /*
\91O
\89ñ
\83}
\83b
\83`
\82µ
\82½
\83L
\81[
\83\8f\81[
\83h
\82Ì
\91±
\82«
\82ð
\8fo
\97Í
\82·
\82é */
\r
9605 if ( found_keywords != NULL ) {
\r
9606 int found_keyword_index = self->FoundKeywordIndex + 1;
\r
9607 const TCHAR* keyword;
\r
9609 if ( found_keyword_index < self->FoundKeywordsCount ) {
\r
9610 keyword = found_keywords[ found_keyword_index ];
\r
9612 *out_Keyword = (TCHAR*) keyword;
\r
9613 *out_TextStringIndex = text_string_index + 1 - _tcslen( keyword );
\r
9614 self->FoundKeywordIndex = found_keyword_index;
\r
9617 self->FoundKeywords = NULL;
\r
9618 text_string_index += 1;
\r
9621 /*
\83e
\83L
\83X
\83g
\82Ì
\92\86\82ð
\82P
\95¶
\8e\9a\82¸
\82Â
\92²
\82×
\82é */
\r
9622 for ( /* "text_string_index" is already set */;
\r
9623 text_string_index < text_string_length;
\r
9624 text_string_index += 1 ) {
\r
9627 TCHAR a_character = text_string[ text_string_index ];
\r
9629 /* AC
\96@
\82Ì goto
\8aÖ
\90\94\82ð
\8eg
\82Á
\82Ä
\81A
\8e\9f\82Ì
\8fó
\91Ô
\82É
\91J
\88Ú
\82·
\82é */
\r
9631 ASSERT_R( text_string[ text_string_index ] <= SearchStringByAC_MaxCharacterCode,
\r
9632 e=E_OTHERS; goto fin );
\r
9634 if ( a_character > SearchStringByAC_MaxCharacterCode ) {
\r
9635 a_character = _T('\0');
\r
9638 next_state_num = goto_function[ state_num ][ a_character ];
\r
9640 /* AC
\96@
\82Ì goto
\8aÖ
\90\94\82ª fail
\82µ
\82½
\82ç
\81Afailure
\8aÖ
\90\94\82ð
\8eg
\82Á
\82Ä
\81A */
\r
9641 /*
\8e\9f\82Ì
\8fó
\91Ô
\82É
\91J
\88Ú
\82µ
\82Ä
\81A
\8dÄ
\82Ñ goto
\8aÖ
\90\94\82ð
\8eg
\82¤ */
\r
9642 if ( next_state_num == SearchStringByAC_Fail ) {
\r
9643 if ( state_num == SearchStringByAC_RootState ) {
\r
9644 next_state_num = SearchStringByAC_RootState;
\r
9647 state_num = failure_function[ state_num ];
\r
9652 state_num = next_state_num;
\r
9654 /* AC
\96@
\82Ì output
\8aÖ
\90\94\82ð
\8eg
\82Á
\82Ä
\81A
\83}
\83b
\83`
\82µ
\82½
\83L
\81[
\83\8f\81[
\83h
\82ð
\8fo
\97Í
\82·
\82é */
\r
9655 found_keywords = output_function[ state_num ];
\r
9656 if ( found_keywords != NULL ) {
\r
9657 const int first_keyword_index = 0;
\r
9658 const TCHAR* keyword = found_keywords[ first_keyword_index ];
\r
9660 *out_Keyword = (TCHAR*) keyword;
\r
9661 *out_TextStringIndex = text_string_index + 1 - _tcslen( keyword );
\r
9662 self->FoundKeywords = found_keywords;
\r
9663 self->FoundKeywordsCount = self->OutputCount[ state_num ];
\r
9664 self->FoundKeywordIndex = first_keyword_index;
\r
9665 self->TextStringIndex = text_string_index;
\r
9666 self->StateNum = state_num;
\r
9671 /*
\83e
\83L
\83X
\83g
\82Ì
\8dÅ
\8cã
\82Ü
\82Å
\92²
\82×
\82½
\8cã */
\r
9672 *out_Keyword = NULL;
\r
9673 *out_TextStringIndex = SearchString_NotFound;
\r
9674 self->FoundKeywords = NULL;
\r
9682 /***********************************************************************
\r
9683 <<< [SearchStringByAC_Class_setTextString] >>>
\r
9684 ************************************************************************/
\r
9685 errnum_t SearchStringByAC_Class_setTextString( SearchStringByAC_Class* self,
\r
9686 const TCHAR* TextString )
\r
9688 return SearchStringByAC_Class_setTextStringFromPart( self,
\r
9689 TextString, _tcslen( TextString ) );
\r
9693 /***********************************************************************
\r
9694 <<< [SearchStringByAC_Class_setTextStringFromPart] >>>
\r
9695 ************************************************************************/
\r
9696 errnum_t SearchStringByAC_Class_setTextStringFromPart( SearchStringByAC_Class* self,
\r
9697 const TCHAR* TextString, size_t TextString_Length )
\r
9699 self->StateNum = SearchStringByAC_RootState;
\r
9700 self->TextString = TextString;
\r
9701 self->TextStringLength = TextString_Length;
\r
9702 self->TextStringIndex = 0;
\r
9703 self->FoundKeywords = NULL;
\r
9709 /***********************************************************************
\r
9710 <<< [SearchStringByAC_Class_makeFunctionsStep1] >>>
\r
9711 - Aho-Corasick
\96@(AC
\96@)
\82Ì goto
\8aÖ
\90\94\82Æ output
\8aÖ
\90\94\82ð
\8dì
\90¬
\82·
\82é
\r
9712 -
\8fî
\95ñ
\8c\9f\8dõ
\83A
\83\8b\83S
\83\8a\83Y
\83\80 p117
\82Ì C
\8c¾
\8cê
\94Å
\r
9713 ************************************************************************/
\r
9714 errnum_t SearchStringByAC_Class_makeFunctionsStep1( SearchStringByAC_Class* self,
\r
9715 const TCHAR** KeywordArray, unsigned KeywordArrayCount )
\r
9718 unsigned keyword_num;
\r
9720 AC_GotoFunctionType goto_function; /* g */
\r
9722 e= SearchStringByAC_Class_increaseState( self ); IF(e){goto fin;}
\r
9723 /* newstate = 0; */ /* self->StateCount - 1 */
\r
9724 goto_function = (AC_GotoFunctionType) self->GoToFunction.First; /* g */
\r
9726 for ( keyword_num = 0; keyword_num < KeywordArrayCount; keyword_num += 1 ) {
\r
9727 const TCHAR* keyword = KeywordArray[ keyword_num ];
\r
9728 int keyword_length = _tcslen( keyword ); /* n */
\r
9729 int keyword_index; /* j - 1, p - 1 */
\r
9733 state = SearchStringByAC_RootState;
\r
9734 keyword_index = 0;
\r
9736 /*
\8aù
\82É
\93o
\98^
\82³
\82ê
\82Ä
\82¢
\82é goto
\8aÖ
\90\94\82Í
\90V
\82½
\82É
\92è
\8b`
\82µ
\82È
\82¢ */
\r
9738 ASSERT_R( keyword[ keyword_index ] <= SearchStringByAC_MaxCharacterCode,
\r
9739 e=E_OTHERS; goto fin );
\r
9740 next_state = goto_function[ state ][ keyword[ keyword_index ] ];
\r
9741 if ( next_state != SearchStringByAC_Fail ) {
\r
9742 state = next_state;
\r
9743 keyword_index += 1;
\r
9749 /*
\90V
\82µ
\82¢
\8fó
\91Ô
\82Ö
\91J
\88Ú
\82·
\82é goto
\8aÖ
\90\94\82ð
\92è
\8b`
\82·
\82é */
\r
9750 while ( keyword_index < keyword_length ) {
\r
9751 int16_t new_state = self->StateCount;
\r
9753 e= SearchStringByAC_Class_increaseState( self );
\r
9754 /* newstate += 1; */
\r
9756 goto_function = (AC_GotoFunctionType) self->GoToFunction.First; /* g */
\r
9757 ASSERT_R( keyword[ keyword_index ] <= SearchStringByAC_MaxCharacterCode,
\r
9758 e=E_OTHERS; goto fin );
\r
9759 goto_function[ state ][ keyword[ keyword_index ] ] = new_state;
\r
9760 state = new_state;
\r
9761 keyword_index += 1;
\r
9763 e= SearchStringByAC_Class_addOutputFunction( self, state, keyword );
\r
9773 /***********************************************************************
\r
9774 <<< [SearchStringByAC_Class_makeFunctionsStep2] >>>
\r
9775 - Aho-Corasick
\96@(AC
\96@)
\82Ì failure
\8aÖ
\90\94\82Ì
\8dì
\90¬
\82Æ output
\8aÖ
\90\94\82Ì
\8dX
\90V
\82ð
\82·
\82é
\r
9776 -
\8fî
\95ñ
\8c\9f\8dõ
\83A
\83\8b\83S
\83\8a\83Y
\83\80 p122
\82Ì C
\8c¾
\8cê
\94Å
\r
9777 ************************************************************************/
\r
9778 errnum_t SearchStringByAC_Class_makeFunctionsStep2( SearchStringByAC_Class* self )
\r
9781 uint32_t ch; /* Character(
\95¶
\8e\9a) TCHAR
\8c^
\82É
\82µ
\82È
\82¢
\82Ì
\82Í
\81A
\83\8b\81[
\83v
\82ð
\8fI
\97¹
\82³
\82¹
\82é
\82½
\82ß */
\r
9782 int state; /* s */
\r
9783 int* queue = NULL;
\r
9784 int enqueue_index;
\r
9785 int dequeue_index;
\r
9786 int* failure_function = NULL;
\r
9787 AC_GotoFunctionType goto_function = (AC_GotoFunctionType) self->GoToFunction.First;
\r
9790 /*
\83L
\83\85\81[
\82ð
\8f\89\8aú
\89»
\82·
\82é */
\r
9791 queue = (int*) malloc( sizeof(int) * self->StateCount );
\r
9792 IF( queue == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
9793 enqueue_index = 0;
\r
9794 dequeue_index = 0;
\r
9796 /* failure
\8aÖ
\90\94\82ð
\8f\89\8aú
\89»
\82·
\82é */
\r
9797 failure_function = (int*) malloc( sizeof(int) * self->StateCount );
\r
9798 IF( failure_function == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
9800 /*
\90[
\82³
\82ª
\82P
\82Ì failure
\8aÖ
\90\94\82Ì
\8fo
\97Í
\82ð
\82O
\82É
\82·
\82é */
\r
9801 for ( ch = 0; ch <= SearchStringByAC_MaxCharacterCode; ch += 1 ) {
\r
9802 state = goto_function[ SearchStringByAC_RootState ][ ch ];
\r
9803 if ( state == SearchStringByAC_Fail ) { continue; }
\r
9806 /*
\8fó
\91Ô 0(=SearchStringByAC_RootState)
\82Ì
\91J
\88Ú
\90æ
\82Ì
\8fó
\91Ô
\82ð
\83L
\83\85\81[
\82É
\92Ç
\89Á
\82·
\82é */
\r
9807 queue[ enqueue_index ] = state;
\r
9808 enqueue_index += 1;
\r
9810 failure_function[ state ] = SearchStringByAC_RootState;
\r
9813 while ( enqueue_index > dequeue_index ) {
\r
9814 int back_state; /* r */
\r
9815 int back_new_state; /* state, p */
\r
9816 int new_state; /* q */
\r
9818 /*
\83L
\83\85\81[
\82©
\82ç
\8eæ
\82è
\8fo
\82µ
\82½
\8fó
\91Ô
\82ð
\81A
\82P
\82Â
\90ó
\82¢
\8fó
\91Ô r
\82Æ
\82·
\82é */
\r
9819 back_state = queue[ dequeue_index ];
\r
9820 dequeue_index += 1;
\r
9822 for ( ch = 0; ch <= SearchStringByAC_MaxCharacterCode; ch += 1 ) {
\r
9823 state = goto_function[ back_state ][ ch ];
\r
9824 if ( state == SearchStringByAC_Fail ) { continue; }
\r
9826 /* back_state
\82Ì
\91J
\88Ú
\90æ
\82Ì
\8fó
\91Ô
\82ð
\83L
\83\85\81[
\82É
\92Ç
\89Á
\82·
\82é */
\r
9827 queue[ enqueue_index ] = state;
\r
9828 enqueue_index += 1;
\r
9830 /* 0
\81`state
\82©
\82ç
\82È
\82é
\95¶
\8e\9a\97ñ
\82Ì
\81A
\8dÅ
\92·
\82Ì
\90Ú
\94ö
\8e« 0
\81`new_state
\82ð
\92T
\82· */
\r
9831 back_new_state = failure_function[ back_state ];
\r
9833 new_state = goto_function[ back_new_state ][ ch ];
\r
9834 if ( new_state == SearchStringByAC_Fail ) {
\r
9835 if ( back_new_state == SearchStringByAC_RootState ) {
\r
9836 new_state = SearchStringByAC_RootState;
\r
9839 back_new_state = failure_function[ back_new_state ];
\r
9844 failure_function[ state ] = new_state;
\r
9846 /* output
\8aÖ
\90\94\82ð
\8dX
\90V
\82·
\82é */
\r
9847 e= SearchStringByAC_Class_addOutputFunctions(
\r
9848 self, state, failure_function[ state ] );
\r
9853 self->FailureFunction = failure_function;
\r
9854 failure_function = NULL;
\r
9858 if ( queue != NULL ) { free( queue ); }
\r
9859 if ( failure_function != NULL ) { free( failure_function ); }
\r
9864 /***********************************************************************
\r
9865 <<< [SearchStringByAC_Class_increaseState] >>>
\r
9866 ************************************************************************/
\r
9867 errnum_t SearchStringByAC_Class_increaseState( SearchStringByAC_Class* self )
\r
9870 AC_GotoFunctionType new_goto_function;
\r
9871 const TCHAR*** new_output_function;
\r
9872 int* new_output_count;
\r
9873 int16_t new_state_count = self->StateCount + 1;
\r
9876 /* goto
\8aÖ
\90\94\82É
\91\8a\93\96\82·
\82é
\83\81\83\82\83\8a\81[
\97Ì
\88æ
\82ð
\91\9d\82â
\82· */
\r
9877 e= Set2_allocate( &self->GoToFunction, &new_goto_function ); IF(e){goto fin;}
\r
9879 printf( "goto funcion %d/%d \n",
\r
9880 Set2_getCount( &self->GoToFunction, *new_goto_function ),
\r
9881 Set2_getCountMax( &self->GoToFunction, *new_goto_function ) );
\r
9884 /*
\90V
\82µ
\82¢ state
\82Ì goto
\8aÖ
\90\94\82ð 0(=SearchStringByAC_Fail)
\82Å
\8f\89\8aú
\89»
\82·
\82é */
\r
9885 memset( new_goto_function, 0, sizeof(*new_goto_function) );
\r
9888 /* output
\8aÖ
\90\94\82É
\91\8a\93\96\82·
\82é
\83\81\83\82\83\8a\81[
\97Ì
\88æ
\82ð
\91\9d\82â
\82· */
\r
9889 new_output_function = (const TCHAR***) realloc( (void*) self->OutputFunction,
\r
9890 sizeof(self->OutputFunction[0]) * new_state_count );
\r
9891 IF ( new_output_function == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
9892 new_output_function[ new_state_count - 1 ] = NULL;
\r
9894 new_output_count = (int*) realloc( self->OutputCount,
\r
9895 sizeof(self->OutputCount[0]) * new_state_count );
\r
9896 IF ( new_output_count == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
9897 new_output_count[ new_state_count - 1 ] = 0;
\r
9900 /* Set "self->..." */
\r
9901 self->OutputFunction = new_output_function;
\r
9902 self->OutputCount = new_output_count;
\r
9903 self->StateCount = new_state_count;
\r
9911 /***********************************************************************
\r
9912 <<< [SearchStringByAC_Class_addOutputFunction] >>>
\r
9913 ************************************************************************/
\r
9914 errnum_t SearchStringByAC_Class_addOutputFunction( SearchStringByAC_Class* self,
\r
9915 int State, const TCHAR* Keyword )
\r
9918 const TCHAR** new_keywords = NULL;
\r
9919 int old_count = self->OutputCount[ State ];
\r
9921 new_keywords = (const TCHAR**) realloc( (void*) self->OutputFunction[ State ],
\r
9922 sizeof(const TCHAR*) * (old_count + 1) );
\r
9923 IF ( new_keywords == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
9924 new_keywords[ old_count ] = Keyword;
\r
9926 self->OutputFunction[ State ] = new_keywords;
\r
9927 self->OutputCount[ State ] = old_count + 1;
\r
9935 /***********************************************************************
\r
9936 <<< [SearchStringByAC_Class_addOutputFunctions] >>>
\r
9937 ************************************************************************/
\r
9938 errnum_t SearchStringByAC_Class_addOutputFunctions( SearchStringByAC_Class* self,
\r
9939 int TargetState, int SourceState )
\r
9942 const TCHAR** keywords = self->OutputFunction[ SourceState ];
\r
9944 int count = self->OutputCount[ SourceState ];
\r
9946 for ( i = 0; i < count; i += 1 ) {
\r
9947 e= SearchStringByAC_Class_addOutputFunction( self,
\r
9948 TargetState, keywords[ i ] );
\r
9959 /*=================================================================*/
\r
9960 /* <<< [DebugTools/DebugTools.c] >>> */
\r
9961 /*=================================================================*/
\r
9963 /**************************************************************************
\r
9964 <<< (g_DebugVar) >>>
\r
9965 ***************************************************************************/
\r
9966 int g_DebugVar[10];
\r
9970 /**************************************************************************
\r
9971 <<< (DebugTools) >>>
\r
9972 ***************************************************************************/
\r
9973 #if DEBUGTOOLS_USES
\r
9974 #define DebugTools_get() (&g_DebugTools)
\r
9975 extern DebugTools g_DebugTools;
\r
9978 DebugTools g_DebugTools;
\r
9981 int Debug_setReturnValueOnBreak( int ID )
\r
9983 DebugTools* m = DebugTools_get();
\r
9984 m->m_ReturnValueOnBreak_minus1 = ID - 1;
\r
9988 int Debug_disableBreak( int iExceptID )
\r
9990 DebugTools* m = DebugTools_get();
\r
9991 m->m_DisableBreakExceptID_plus1 = iExceptID + 1;
\r
9995 int Debug_setBreakByFName( const TCHAR* Path )
\r
9997 DebugTools* m = DebugTools_get();
\r
9998 return MallocAndCopyString( &m->m_BreakByFName, Path );
\r
10001 int Debug_onBreakCase( DebugTools* m )
\r
10004 if ( m->m_DisableBreakExceptID_plus1 == 0 || m->m_BreakID == m->m_DisableBreakExceptID_plus1 - 1 ) {
\r
10005 // DebugBreakR();
\r
10006 if ( m->m_ReturnValueOnBreak_minus1 == 0 ) return E_DEBUG_BREAK;
\r
10007 return m->m_ReturnValueOnBreak_minus1 + 1;
\r
10010 _tprintf( _T("[BREAK]\n") );
\r
10016 TCHAR* StrT_refFName( const TCHAR* s );
\r
10018 int Debug_onOpen( const TCHAR* Path )
\r
10020 DebugTools* m = DebugTools_get();
\r
10022 if ( m->m_BreakByFName != NULL &&
\r
10023 _tcsicmp( m->m_BreakByFName, StrT_refFName( Path ) ) == 0 ) {
\r
10024 return Debug_onBreakCase( m );
\r
10032 /***********************************************************************
\r
10033 <<< [HeapLogWatchClass] >>>
\r
10034 ************************************************************************/
\r
10035 typedef struct _HeapLogWatchClass HeapLogWatchClass;
\r
10036 struct _HeapLogWatchClass {
\r
10038 ptrdiff_t Offset;
\r
10039 uint32_t BreakValue;
\r
10043 HeapLogWatchClass g_HeapLogWatch[ 10 ];
\r
10046 /***********************************************************************
\r
10047 <<< (HeapLogClass) >>>
\r
10048 ************************************************************************/
\r
10049 typedef struct _HeapLogClass HeapLogClass;
\r
10050 struct _HeapLogClass {
\r
10051 void** Addresses;
\r
10057 HeapLogClass g_HeapLog;
\r
10060 /***********************************************************************
\r
10061 <<< [HeapLogClass_log] >>>
\r
10062 ************************************************************************/
\r
10063 void HeapLogClass_log( void* in_Address, size_t in_Size )
\r
10068 while ( g_HeapLog.Count >= g_HeapLog.CountMax ) {
\r
10069 void* new_address;
\r
10070 int new_count_max = g_HeapLog.CountMax * 2 + 4;
\r
10072 new_address = realloc_no_redirected( g_HeapLog.Addresses, new_count_max * sizeof( *g_HeapLog.Addresses ) );
\r
10073 if ( new_address == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
10074 g_HeapLog.Addresses = (void**) new_address;
\r
10076 new_address = realloc_no_redirected( g_HeapLog.Sizes, new_count_max * sizeof( *g_HeapLog.Sizes ) );
\r
10077 if ( new_address == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
10078 g_HeapLog.Sizes = (size_t*) new_address;
\r
10080 g_HeapLog.CountMax = new_count_max;
\r
10083 g_HeapLog.Addresses[ g_HeapLog.Count ] = in_Address;
\r
10084 g_HeapLog.Sizes[ g_HeapLog.Count ] = in_Size;
\r
10085 g_HeapLog.Count += 1;
\r
10088 for ( i = 0; i < _countof( g_HeapLogWatch ); i += 1 ) {
\r
10089 HeapLogWatchClass* watch = &g_HeapLogWatch[ i ];
\r
10091 if ( watch->IsEnabled ) {
\r
10092 if ( watch->AllocatedID == g_HeapLog.Count ) {
\r
10093 if ( watch->IsPrintf ) {
\r
10094 printf( "<HeapLogClass_log event=\"Allocated\" index=\"%d\"/>\n",
\r
10106 /***********************************************************************
\r
10107 <<< [HeapLogClass_getID] >>>
\r
10108 ************************************************************************/
\r
10109 int HeapLogClass_getID( const void* in_Address )
\r
10113 for ( i = g_HeapLog.Count - 1; i >= 0; i -= 1 ) {
\r
10114 const void* start = g_HeapLog.Addresses[ i ];
\r
10115 const void* over;
\r
10117 over = g_HeapLog.Addresses[ i ];
\r
10118 PointerType_plus( &over, g_HeapLog.Sizes[ i ] );
\r
10120 if ( start <= in_Address && in_Address < over ) {
\r
10128 /***********************************************************************
\r
10129 <<< [HeapLogClass_printID] >>>
\r
10130 ************************************************************************/
\r
10131 void HeapLogClass_printID( const void* in_Address )
\r
10133 int block_ID = HeapLogClass_getID( in_Address );
\r
10134 ptrdiff_t offset;
\r
10136 if ( block_ID != HeapLogClass_NotAllocatedID ) {
\r
10137 offset = PointerType_diff( in_Address, g_HeapLog.Addresses[ block_ID ] );
\r
10143 printf( "<HeapLogClass_printID allocated_id=\"%d\" offset=\"0x%04X\"/>\n",
\r
10144 block_ID, offset );
\r
10148 /***********************************************************************
\r
10149 <<< [HeapLogClass_addWatch] >>>
\r
10150 ************************************************************************/
\r
10151 void HeapLogClass_addWatch( int in_IndexNum, int in_AllocatedID, ptrdiff_t in_Offset,
\r
10152 uint32_t in_BreakValue, bool in_IsPrintf )
\r
10154 HeapLogWatchClass* watch = &g_HeapLogWatch[ in_IndexNum ];
\r
10156 if ( in_IndexNum >= _countof( g_HeapLogWatch ) ) {
\r
10157 printf( "HeapLogClass_addWatch: Error of IndexNum (%d)\n", in_IndexNum );
\r
10161 if ( in_IsPrintf ) {
\r
10162 printf( "<HeapLogClass_addWatch index=\"%d\" allocated_id=\"%d\" offset=\"0x%04X\"/>\n",
\r
10163 in_IndexNum, in_AllocatedID, in_Offset );
\r
10165 watch->AllocatedID = in_AllocatedID;
\r
10166 watch->Offset = in_Offset;
\r
10167 watch->BreakValue = in_BreakValue;
\r
10168 watch->IsPrintf = in_IsPrintf;
\r
10169 watch->IsEnabled = true;
\r
10173 /***********************************************************************
\r
10174 <<< [HeapLogClass_watch] >>>
\r
10175 ************************************************************************/
\r
10176 void HeapLogClass_watch( int in_IndexNum )
\r
10178 HeapLogWatchClass* watch = &g_HeapLogWatch[ in_IndexNum ];
\r
10183 if ( in_IndexNum >= _countof( g_HeapLogWatch ) ) {
\r
10184 printf( "HeapLogClass_addWatch: Error of IndexNum (%d)\n", in_IndexNum );
\r
10188 if ( watch->IsEnabled && g_HeapLog.Count > watch->AllocatedID ) {
\r
10189 const void* pointer = g_HeapLog.Addresses[ watch->AllocatedID ];
\r
10191 PointerType_plus( &pointer, watch->Offset );
\r
10192 value = *(uint32_t*) pointer;
\r
10194 if ( watch->IsPrintf ) {
\r
10195 printf( "<HeapLogClass_watch index=\"%d\" value=\"%d\" value16=\"0x%08X\"/>\n",
\r
10196 in_IndexNum, value, value );
\r
10198 if ( value == watch->BreakValue ) { DebugBreakR(); }
\r
10204 /***********************************************************************
\r
10205 <<< [HeapLogClass_getWatchingAddress] >>>
\r
10206 ************************************************************************/
\r
10207 void* HeapLogClass_getWatchingAddress( int in_IndexNum )
\r
10209 HeapLogWatchClass* watch = &g_HeapLogWatch[ in_IndexNum ];
\r
10210 void* return_value;
\r
10213 if ( in_IndexNum >= _countof( g_HeapLogWatch ) ) {
\r
10214 printf( "HeapLogClass_addWatch: Error of IndexNum (%d)\n", in_IndexNum );
\r
10219 if ( watch->IsEnabled && g_HeapLog.Count > watch->AllocatedID ) {
\r
10220 return_value = g_HeapLog.Addresses[ watch->AllocatedID ];
\r
10221 PointerType_plus( &return_value, watch->Offset );
\r
10223 return_value = NULL;
\r
10226 return return_value;
\r
10230 /***********************************************************************
\r
10231 <<< [HeapLogClass_finalize] >>>
\r
10232 ************************************************************************/
\r
10233 void HeapLogClass_finalize()
\r
10235 if ( g_HeapLog.Addresses != NULL ) {
\r
10236 free( g_HeapLog.Addresses );
\r
10237 g_HeapLog.Addresses = NULL;
\r
10239 if ( g_HeapLog.Sizes != NULL ) {
\r
10240 free( g_HeapLog.Sizes );
\r
10241 g_HeapLog.Sizes = NULL;
\r
10243 g_HeapLog.Count = 0;
\r
10244 g_HeapLog.CountMax = 0;
\r
10249 /***********************************************************************
\r
10250 <<< [TestableDebugBreak] >>>
\r
10251 ************************************************************************/
\r
10252 typedef struct _TestableDebugBreakClass TestableDebugBreakClass;
\r
10253 struct _TestableDebugBreakClass {
\r
10254 bool IsDisableTestableDebugBreak;
\r
10255 volatile int DebugBreakCount;
\r
10256 CRITICAL_SECTION Critical;
\r
10257 SingletonInitializerClass Initializer;
\r
10259 static TestableDebugBreakClass gs_TestableDebugBreak = { false, 0 };
\r
10262 /*[SetTestableDebugBreak]*/
\r
10263 void SetTestableDebugBreak( bool IsEnableBreak )
\r
10265 TestableDebugBreakClass* self = &gs_TestableDebugBreak;
\r
10266 self->IsDisableTestableDebugBreak = ! IsEnableBreak;
\r
10269 /*[TestableDebugBreak_Sub]*/
\r
10270 int TestableDebugBreak_Sub()
\r
10272 TestableDebugBreakClass* self = &gs_TestableDebugBreak;
\r
10274 if ( ! SingletonInitializerClass_isInitialized( &self->Initializer ) ) {
\r
10275 if ( SingletonInitializerClass_isFirst( &self->Initializer ) ) {
\r
10277 InitializeCriticalSection( &self->Critical );
\r
10279 SingletonInitializerClass_onFinishedInitialize( &self->Initializer, 0 );
\r
10283 EnterCriticalSection( &self->Critical );
\r
10284 self->DebugBreakCount += 1;
\r
10285 LeaveCriticalSection( &self->Critical );
\r
10287 return ! self->IsDisableTestableDebugBreak;
\r
10290 /*[GetDebugBreakCount]*/
\r
10291 int GetDebugBreakCount()
\r
10293 TestableDebugBreakClass* self = &gs_TestableDebugBreak;
\r
10294 return self->DebugBreakCount;
\r
10299 /*=================================================================*/
\r
10300 /* <<< [SetX/SetX.c] >>> */
\r
10301 /*=================================================================*/
\r
10303 /***********************************************************************
\r
10304 <<< [Set2_init] >>>
\r
10305 ************************************************************************/
\r
10306 errnum_t Set2_init( Set2* m, int FirstSize )
\r
10308 m->First = malloc( FirstSize );
\r
10309 if ( m->First == NULL ) return E_FEW_MEMORY;
\r
10310 m->Next = m->First;
\r
10311 m->Over = (char*)m->First + FirstSize;
\r
10314 m->PointerOfDebugArray = NULL;
\r
10320 /***********************************************************************
\r
10321 <<< [Set2_finish] >>>
\r
10322 ************************************************************************/
\r
10323 errnum_t Set2_finish( Set2* m, errnum_t e )
\r
10325 if ( m->First != NULL ) { free( m->First ); m->First = NULL; }
\r
10330 /***********************************************************************
\r
10331 <<< [Set2_ref_imp] >>>
\r
10332 ************************************************************************/
\r
10333 errnum_t Set2_ref_imp( Set2* m, int iElem, void* out_pElem, size_t ElemSize )
\r
10338 IF( iElem < 0 ) goto err_ns;
\r
10339 p = (char*) m->First + ( (unsigned)iElem * ElemSize );
\r
10340 IF( p >= (char*)m->Next ) goto err_ns;
\r
10341 *(char**)out_pElem = p;
\r
10347 err_ns: e = E_NOT_FOUND_SYMBOL; goto fin;
\r
10352 /***********************************************************************
\r
10353 <<< [Set2_getIterator] >>>
\r
10354 ************************************************************************/
\r
10355 errnum_t Set2_getIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )
\r
10357 out_Iterator->Parent = self;
\r
10358 out_Iterator->ElementSize = ElementSize;
\r
10359 out_Iterator->Current = (uint8_t*) self->First - ElementSize;
\r
10365 /***********************************************************************
\r
10366 <<< [Set2_getDescendingIterator] >>>
\r
10367 ************************************************************************/
\r
10368 errnum_t Set2_getDescendingIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )
\r
10370 out_Iterator->Parent = self;
\r
10371 out_Iterator->ElementSize = ElementSize;
\r
10372 out_Iterator->Current = (uint8_t*) self->Next;
\r
10378 /***********************************************************************
\r
10379 <<< [Set2_IteratorClass_getNext] >>>
\r
10380 ************************************************************************/
\r
10381 void* Set2_IteratorClass_getNext( Set2_IteratorClass* self )
\r
10383 uint8_t* next = self->Current + self->ElementSize;
\r
10385 if ( next >= (uint8_t*) self->Parent->Next ) {
\r
10388 self->Current = next;
\r
10395 /***********************************************************************
\r
10396 <<< [Set2_IteratorClass_getPrevious] >>>
\r
10397 ************************************************************************/
\r
10398 void* Set2_IteratorClass_getPrevious( Set2_IteratorClass* self )
\r
10400 uint8_t* previous = self->Current - self->ElementSize;
\r
10402 if ( previous < (uint8_t*) self->Parent->First ) {
\r
10405 self->Current = previous;
\r
10412 /***********************************************************************
\r
10413 <<< [Set2_alloc_imp] >>>
\r
10414 ************************************************************************/
\r
10415 errnum_t Set2_alloc_imp( Set2* m, void* pp, size_t size )
\r
10419 e= Set2_expandIfOverByAddr( m, (char*) m->Next + size ); IF(e)goto fin;
\r
10420 *(void**)pp = m->Next;
\r
10421 m->Next = (char*) m->Next + size;
\r
10423 DISCARD_BYTES( *(void**)pp, size );
\r
10431 /***********************************************************************
\r
10432 <<< [Set2_allocMulti_sub] >>>
\r
10433 ************************************************************************/
\r
10434 errnum_t Set2_allocMulti_sub( Set2* m, void* out_pElem, size_t ElemsSize )
\r
10439 e= Set2_expandIfOverByAddr( m, (char*) m->Next + ElemsSize ); IF(e)goto fin;
\r
10440 p = (char*) m->Next;
\r
10441 m->Next = p + ElemsSize;
\r
10442 *(char**)out_pElem = p;
\r
10451 /***********************************************************************
\r
10452 <<< [Set2_expandIfOverByAddr_imp] >>>
\r
10453 ************************************************************************/
\r
10454 errnum_t Set2_expandIfOverByAddr_imp( Set2* m, void* OverAddrBasedOnNowFirst )
\r
10458 unsigned offset_of_over;
\r
10459 unsigned offset_of_next;
\r
10461 if ( OverAddrBasedOnNowFirst <= m->Over ) { e=E_OTHERS; goto fin; }
\r
10463 offset_of_next = (unsigned)( (char*)OverAddrBasedOnNowFirst - (char*)m->First );
\r
10464 offset_of_over = (unsigned)( ( (char*)m->Over - (char*)m->First ) ) * 2;
\r
10465 IF_D( offset_of_next >= 0x80000000 ) { e=E_OTHERS; goto fin; }
\r
10466 if ( offset_of_over == 0 ) { offset_of_over = 0x100; }
\r
10467 while ( offset_of_over < offset_of_next ) { offset_of_over *= 2; }
\r
10468 IF( offset_of_over >= 0x10000000 ) { e=E_OTHERS; goto fin; }
\r
10470 new_first = realloc( m->First, offset_of_over * 2 );
\r
10471 IF( new_first == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
10473 m->Next = (char*) new_first + ( (char*)m->Next - (char*)m->First );
\r
10474 m->Over = (char*) new_first + offset_of_over * 2;
\r
10475 m->First = new_first;
\r
10478 if ( m->PointerOfDebugArray != NULL )
\r
10479 { *m->PointerOfDebugArray = m->First; }
\r
10489 /***********************************************************************
\r
10490 <<< [Set2_free_imp] >>>
\r
10491 ************************************************************************/
\r
10492 errnum_t Set2_free_imp( Set2* self, void* in_PointerOfPointer, size_t in_Size_ofElement, errnum_t e )
\r
10496 element = *(void**) in_PointerOfPointer;
\r
10498 if ( element != NULL ) {
\r
10499 if ( element != ( (byte_t*) self->Next - in_Size_ofElement ) ) {
\r
10500 if ( e == 0 ) { e=E_OTHERS; }
\r
10504 memset( element, 0xFE, in_Size_ofElement );
\r
10507 self->Next = element;
\r
10509 *(void**) in_PointerOfPointer = NULL;
\r
10517 /***********************************************************************
\r
10518 <<< [Set2_separate] >>>
\r
10519 ************************************************************************/
\r
10520 errnum_t Set2_separate( Set2* m, int NextSize, void** allocate_Array )
\r
10523 void* p = m->First;
\r
10525 if ( NextSize == 0 ) {
\r
10531 e= Set2_init( m, NextSize ); IF(e)goto fin;
\r
10533 *allocate_Array = p;
\r
10542 /***********************************************************************
\r
10543 <<< [Set2_pop_imp] >>>
\r
10544 ************************************************************************/
\r
10545 errnum_t Set2_pop_imp( Set2* m, void* pp, size_t size )
\r
10550 p = (char*) m->Next - size;
\r
10552 IF ( p < m->First ) { e=E_OTHERS; goto fin; }
\r
10564 /***********************************************************************
\r
10565 <<< [Set2_setDebug] >>>
\r
10566 ************************************************************************/
\r
10568 void Set2_setDebug( Set2* m, void* PointerOfDebugArray )
\r
10570 m->PointerOfDebugArray = (void**) PointerOfDebugArray;
\r
10571 *m->PointerOfDebugArray = m->First;
\r
10577 /***********************************************************************
\r
10578 <<< [Set2a_init] >>>
\r
10579 ************************************************************************/
\r
10580 int Set2a_init( Set2a* m, void* ArrInStack, size_t ArrInStack_Size )
\r
10584 /* "m->First" is initialized in "Set2a_initConst" */
\r
10586 m->Next = m->First;
\r
10587 m->Over = (char*)m->First + ArrInStack_Size;
\r
10589 ASSERT_D( m->First == ArrInStack, e=E_OTHERS; goto fin );
\r
10592 m->PointerOfDebugArray = NULL;
\r
10599 UNREFERENCED_VARIABLE( ArrInStack );
\r
10606 /***********************************************************************
\r
10607 <<< [Set2a_alloc_imp] >>>
\r
10608 ************************************************************************/
\r
10609 int Set2a_alloc_imp( Set2a* m, void* ArrInStack, void* out_Pointer, size_t ElemSize )
\r
10613 e= Set2a_expandIfOverByAddr_imp( m, ArrInStack, (char*)m->Next + ElemSize ); IF(e)goto fin;
\r
10614 *(void**)out_Pointer = m->Next;
\r
10615 m->Next = (char*) m->Next + ElemSize;
\r
10625 /***********************************************************************
\r
10626 <<< [Set2a_expandIfOverByAddr_imp] >>>
\r
10627 ************************************************************************/
\r
10628 int Set2a_expandIfOverByAddr_imp( Set2a* m, void* ArrInStack, void* OverAddrBasedOnNowFirst )
\r
10630 void* new_memory;
\r
10633 if ( m->First == ArrInStack ) {
\r
10634 ofs = (char*)m->Over - (char*)m->First;
\r
10635 new_memory = malloc( ofs * 2 );
\r
10636 IF( new_memory == NULL ) return E_FEW_MEMORY;
\r
10638 memcpy( new_memory, m->First, ofs * 2 );
\r
10640 m->First = new_memory;
\r
10641 m->Over = (char*)new_memory + ofs * 2;
\r
10642 m->Next = (char*)new_memory + ofs;
\r
10646 return Set2_expandIfOverByAddr_imp( (Set2*) m, OverAddrBasedOnNowFirst );
\r
10652 /*-------------------------------------------------------------------------*/
\r
10653 /* <<<< ### (Set4) Class >>>> */
\r
10654 /*-------------------------------------------------------------------------*/
\r
10658 /****************************************************************
\r
10659 <<< [Set4_init_imp] >>>
\r
10660 *****************************************************************/
\r
10661 errnum_t Set4_init_imp( Set4* self, size_t in_ElementSize, size_t in_FirstHeapSize )
\r
10663 int element_count;
\r
10665 self->FirstBlock = NULL;
\r
10666 self->CurrentBlockFirst = NULL;
\r
10667 self->u.NextBlock = &self->FirstBlock;
\r
10668 self->CurrentBlockNext = self->u.CurrentBlockOver;
\r
10669 element_count = ( in_FirstHeapSize - sizeof(void*) ) / in_ElementSize;
\r
10670 self->HeapSize = element_count * in_ElementSize + sizeof(void*);
\r
10671 self->ElementSize = in_ElementSize;
\r
10678 /****************************************************************
\r
10679 <<< [Set4_finish2_imp] >>>
\r
10680 *****************************************************************/
\r
10681 errnum_t Set4_finish2_imp( Set4* self, errnum_t e, size_t in_ElementSize, FinalizeFuncType in_Type_Finalize )
\r
10685 ASSERT_D( self->ElementSize == in_ElementSize, e= MergeError( e, E_OTHERS ); goto fin );
\r
10687 for ( Set4_forEach_imp( self, &p, in_ElementSize ) ) {
\r
10688 e= in_Type_Finalize( p.p, e );
\r
10699 /****************************************************************
\r
10700 <<< [Set4_finish2_imp2] >>>
\r
10701 *****************************************************************/
\r
10702 errnum_t Set4_finish2_imp2( Set4* self )
\r
10707 p = self->FirstBlock;
\r
10708 while ( p != NULL ) {
\r
10709 p2 = *(void**)( p + self->HeapSize - sizeof(void*) );
\r
10719 /****************************************************************
\r
10720 <<< [Set4_alloc_imp] >>>
\r
10721 *****************************************************************/
\r
10722 errnum_t Set4_alloc_imp( Set4* self, void* out_ElementPointer, size_t in_ElementSize )
\r
10725 byte_t* new_block;
\r
10728 ASSERT_D( in_ElementSize == self->ElementSize, e=E_OTHERS; goto fin );
\r
10730 /* Add new element */
\r
10731 if ( self->CurrentBlockNext == self->u.CurrentBlockOver ) {
\r
10732 new_block = (byte_t*) malloc( self->HeapSize );
\r
10733 IF ( new_block == NULL ) { e=E_FEW_MEMORY; goto fin; }
\r
10734 element = new_block;
\r
10736 *self->u.NextBlock = new_block;
\r
10737 self->CurrentBlockNext = new_block + in_ElementSize;
\r
10739 self->CurrentBlockFirst = new_block;
\r
10740 self->u.CurrentBlockOver = new_block + self->HeapSize - sizeof(void*);
\r
10741 *self->u.NextBlock = NULL;
\r
10744 /* Add existed element */
\r
10746 ASSERT_D( self->CurrentBlockNext < self->u.CurrentBlockOver, e=E_OTHERS; goto fin );
\r
10747 element = self->CurrentBlockNext;
\r
10748 self->CurrentBlockNext += in_ElementSize;
\r
10751 *(void**) out_ElementPointer = element;
\r
10760 /****************************************************************
\r
10761 <<< [Set4_free_imp] >>>
\r
10762 *****************************************************************/
\r
10763 errnum_t Set4_free_imp( Set4* self, void* in_out_ElementPointer, size_t in_ElementSize, errnum_t e0 )
\r
10766 void* element = *(void**) in_out_ElementPointer;
\r
10768 ASSERT_D( in_ElementSize == self->ElementSize, e=E_OTHERS; goto fin );
\r
10770 if ( element != NULL ) {
\r
10771 if ( self->CurrentBlockNext == self->CurrentBlockFirst ) {
\r
10773 byte_t* previous_block = NULL;
\r
10774 byte_t* previous_element;
\r
10777 block = self->FirstBlock;
\r
10779 block = *(byte_t**)( block + self->HeapSize - sizeof(void*) ) )
\r
10781 if ( block == self->CurrentBlockFirst )
\r
10784 previous_block = block;
\r
10786 ASSERT_R( previous_block != NULL, e=E_OTHERS; goto fin );
\r
10788 previous_element = previous_block + self->HeapSize - sizeof(void*) - in_ElementSize;
\r
10789 ASSERT_R( element == previous_element, e=E_ACCESS_DENIED; goto fin );
\r
10792 self->CurrentBlockFirst = previous_block;
\r
10793 self->CurrentBlockNext = previous_element;
\r
10794 self->u.CurrentBlockOver = previous_element + in_ElementSize;
\r
10795 *self->u.NextBlock = NULL;
\r
10798 byte_t* previous_element = self->CurrentBlockNext - in_ElementSize;
\r
10800 ASSERT_D( element == previous_element, e=E_ACCESS_DENIED; goto fin );
\r
10802 self->CurrentBlockNext = previous_element;
\r
10805 *(void**) in_out_ElementPointer = NULL;
\r
10817 /****************************************************************
\r
10818 <<< [Set4_ref_imp] >>>
\r
10819 *****************************************************************/
\r
10820 void* Set4_ref_imp( Set4* self, int i, int size )
\r
10822 byte_t* p = self->FirstBlock;
\r
10823 size_t offset = i * size;
\r
10824 size_t offset_over = self->HeapSize - sizeof(void*);
\r
10826 if ( i < 0 ) { return NULL; }
\r
10828 if ( p == NULL ) { return NULL; }
\r
10829 while ( offset >= offset_over ) {
\r
10830 p = *(void**)( (char*)p + offset_over );
\r
10831 if ( p == NULL ) { return NULL; }
\r
10832 offset -= offset_over;
\r
10836 if ( p >= self->CurrentBlockNext ) { return NULL; }
\r
10843 /****************************************************************
\r
10844 <<< [Set4_getCount_imp] >>>
\r
10845 *****************************************************************/
\r
10846 int Set4_getCount_imp( Set4* self, int size )
\r
10848 void* p = self->FirstBlock;
\r
10851 int offset_over = self->HeapSize - sizeof(void*);
\r
10853 if ( p == NULL ) { return 0; }
\r
10857 p = *(void**)( (char*)p + offset_over );
\r
10858 if ( p == NULL ) break;
\r
10859 offset += offset_over;
\r
10862 offset += (int)( (char*)self->CurrentBlockNext - (char*)p2 );
\r
10864 return offset / size;
\r
10869 /****************************************************************
\r
10870 <<< [Set4_forEach_imp2] >>>
\r
10871 *****************************************************************/
\r
10872 void Set4_forEach_imp2( Set4* self, Set4Iter* p, int size )
\r
10874 if ( p->p == NULL ) { /* first */
\r
10875 if ( self->FirstBlock == NULL ) return; /* elem count = 0 */
\r
10876 p->Over = &self->FirstBlock;
\r
10878 else { /* The next of array */
\r
10879 p->p = (char*)p->p + size;
\r
10880 if ( p->p < p->Over ) return;
\r
10883 /* The last element */
\r
10884 if ( p->p == self->CurrentBlockNext ) { p->p = NULL; return; }
\r
10886 /* The next element */
\r
10887 p->p = *(void**) p->Over;
\r
10888 p->Over = (char*)p->p + self->HeapSize - sizeof(void*);
\r
10889 if ( *(void**)p->Over == NULL ) p->Over = self->CurrentBlockNext;
\r
10894 /***********************************************************************
\r
10895 <<< (ListClass) >>>
\r
10896 ************************************************************************/
\r
10898 /*[ListClass_initConst]*/
\r
10899 void ListClass_initConst( ListClass* self )
\r
10901 self->Terminator.Data = NULL;
\r
10902 self->Terminator.List = self;
\r
10903 self->Terminator.Next = &self->Terminator;
\r
10904 self->Terminator.Previous = &self->Terminator;
\r
10909 /*[ListClass_addAtIndex]*/
\r
10910 errnum_t ListClass_addAtIndex( ListClass* self, int Index, ListElementClass* Element )
\r
10913 ListElementClass* target;
\r
10915 if ( Index == self->Count ) {
\r
10916 e= ListClass_addLast( self, Element ); IF(e){goto fin;}
\r
10919 e= ListClass_get( self, Index, &target ); IF(e){goto fin;}
\r
10920 e= ListClass_addAt_Sub( Element, target ); IF(e){goto fin;}
\r
10929 /*[ListClass_addAt_Sub]*/
\r
10930 errnum_t ListClass_addAt_Sub( ListElementClass* AddingElement, ListElementClass* Target )
\r
10933 ListElementClass* target_previous = Target->Previous;
\r
10934 ListClass* self = Target->List;
\r
10936 ASSERT_R( AddingElement->List == NULL, e=E_ACCESS_DENIED; goto fin );
\r
10938 AddingElement->Next = Target;
\r
10939 AddingElement->Previous = target_previous;
\r
10940 target_previous->Next = AddingElement;
\r
10941 Target->Previous = AddingElement;
\r
10942 AddingElement->List = self;
\r
10943 self->Count += 1;
\r
10951 /*[ListClass_get]*/
\r
10952 errnum_t ListClass_get( ListClass* self, int Index, ListElementClass** out_Element )
\r
10955 ListElementClass* element = self->Terminator.Next;
\r
10957 ASSERT_R( Index >= 0 && Index < self->Count, e=E_NOT_FOUND_SYMBOL; goto fin );
\r
10959 while ( Index != 0 ) {
\r
10960 element = element->Next;
\r
10964 *out_Element = element;
\r
10972 /*[ListClass_set]*/
\r
10973 errnum_t ListClass_set( ListClass* self, int Index, ListElementClass* Element )
\r
10976 ListElementClass* target;
\r
10978 ASSERT_R( Element->List == NULL, e=E_ACCESS_DENIED; goto fin );
\r
10980 e= ListClass_get( self, Index, &target ); IF(e){goto fin;}
\r
10981 e= ListClass_replace( self, target, Element ); IF(e){goto fin;}
\r
10989 /*[ListClass_replace]*/
\r
10990 errnum_t ListClass_replace( ListClass* self, ListElementClass* RemovingElement,
\r
10991 ListElementClass* AddingElement )
\r
10995 ASSERT_R( RemovingElement->List == self, e=E_NOT_FOUND_SYMBOL; goto fin );
\r
10996 ASSERT_R( AddingElement->List == NULL, e=E_ACCESS_DENIED; goto fin );
\r
10997 ASSERT_R( RemovingElement != &RemovingElement->List->Terminator,
\r
10998 e=E_NOT_FOUND_SYMBOL; goto fin );
\r
11000 RemovingElement->Next->Previous = AddingElement;
\r
11001 RemovingElement->Previous->Next = AddingElement;
\r
11002 AddingElement->Next = RemovingElement->Next;
\r
11003 AddingElement->Previous = RemovingElement->Previous;
\r
11005 AddingElement->List = self;
\r
11007 RemovingElement->List = NULL;
\r
11009 RemovingElement->Next = NULL;
\r
11010 RemovingElement->Previous = NULL;
\r
11019 /*[ListClass_getIndexOfData]*/
\r
11020 int ListClass_getIndexOfData( ListClass* self, void* Data )
\r
11023 ListElementClass* element = self->Terminator.Next;
\r
11024 ListElementClass* tarminator = &self->Terminator;
\r
11026 for ( index = 0; ; index += 1 ) {
\r
11027 if ( element == tarminator )
\r
11028 { return INVALID_ARRAY_INDEX; }
\r
11030 if ( element->Data == Data )
\r
11031 { return index; }
\r
11033 element = element->Next;
\r
11038 /*[ListClass_getIndexOf]*/
\r
11039 int ListClass_getIndexOf( ListClass* self, ListElementClass* Element )
\r
11042 ListElementClass* elem = self->Terminator.Next;
\r
11043 ListElementClass* tarminator = &self->Terminator;
\r
11045 for ( index = 0; ; index += 1 ) {
\r
11046 if ( elem == Element )
\r
11047 { return index; }
\r
11049 if ( elem == tarminator )
\r
11050 { return INVALID_ARRAY_INDEX; }
\r
11052 elem = elem->Next;
\r
11057 /*[ListClass_getLastIndexOfData]*/
\r
11058 int ListClass_getLastIndexOfData( ListClass* self, void* Data )
\r
11061 ListElementClass* element = self->Terminator.Previous;
\r
11062 ListElementClass* tarminator = &self->Terminator;
\r
11064 for ( index = self->Count - 1; ; index -= 1 ) {
\r
11065 if ( element == tarminator )
\r
11066 { return INVALID_ARRAY_INDEX; }
\r
11068 if ( element->Data == Data )
\r
11069 { return index; }
\r
11071 element = element->Previous;
\r
11076 /*[ListClass_getArray]*/
\r
11077 errnum_t ListClass_getArray( ListClass* self, void* DataArray, size_t DataArraySize )
\r
11080 ListIteratorClass iterator;
\r
11082 void** data_pointer;
\r
11084 ASSERT_R( DataArraySize >= self->Count * sizeof(void*), e=E_FEW_ARRAY; goto fin );
\r
11086 e= ListClass_getListIterator( self, &iterator ); IF(e){goto fin;}
\r
11087 for ( data_pointer = (void**) DataArray; ; data_pointer += 1 ) {
\r
11088 data = ListIteratorClass_getNext( &iterator );
\r
11089 if ( data == NULL ) { break; }
\r
11091 *data_pointer = data;
\r
11100 /*[ListClass_removeByIndex]*/
\r
11101 errnum_t ListClass_removeByIndex( ListClass* self, int Index )
\r
11104 ListElementClass* target;
\r
11106 e= ListClass_get( self, Index, &target ); IF(e){goto fin;}
\r
11107 e= ListClass_remove( self, target ); IF(e){goto fin;}
\r
11115 /*[ListClass_remove]*/
\r
11116 errnum_t ListClass_remove( ListClass* self, ListElementClass* Element )
\r
11118 if ( Element->List == self ) {
\r
11119 Element->Previous->Next = Element->Next;
\r
11120 Element->Next->Previous = Element->Previous;
\r
11121 Element->List = NULL;
\r
11123 Element->Next = NULL;
\r
11124 Element->Previous = NULL;
\r
11126 self->Count -= 1;
\r
11132 /*[ListClass_clear]*/
\r
11133 errnum_t ListClass_clear( ListClass* self )
\r
11135 ListElementClass* target = self->Terminator.Next;
\r
11136 ListElementClass* next;
\r
11137 ListElementClass* terminator = &self->Terminator;
\r
11139 while ( target != terminator ) {
\r
11140 target->List = NULL;
\r
11142 next = target->Next;
\r
11144 target->Next = NULL;
\r
11145 target->Previous = NULL;
\r
11150 self->Terminator.Next = terminator;
\r
11151 self->Terminator.Previous = terminator;
\r
11158 /*[ListIteratorClass_getNext]*/
\r
11159 void* ListIteratorClass_getNext( ListIteratorClass* self )
\r
11161 ListElementClass* next = self->Element->Next;
\r
11163 self->Element = next;
\r
11165 if ( next == &next->List->Terminator )
\r
11168 { return next->Data; }
\r
11172 /*[ListIteratorClass_getPrevious]*/
\r
11173 void* ListIteratorClass_getPrevious( ListIteratorClass* self )
\r
11175 ListElementClass* previous = self->Element->Previous;
\r
11177 self->Element = previous;
\r
11179 if ( previous == &previous->List->Terminator )
\r
11182 { return previous->Data; }
\r
11186 /*[ListIteratorClass_replace]*/
\r
11187 errnum_t ListIteratorClass_replace( ListIteratorClass* self, ListElementClass* AddingElement )
\r
11190 ListElementClass* removing_element = self->Element;
\r
11192 e= ListClass_replace( removing_element->List, removing_element, AddingElement );
\r
11194 self->Element = AddingElement;
\r
11202 /*[ListIteratorClass_remove]*/
\r
11203 errnum_t ListIteratorClass_remove( ListIteratorClass* self )
\r
11206 ListElementClass* removing_element = self->Element;
\r
11208 ASSERT_R( removing_element->List != NULL, e=E_NOT_FOUND_SYMBOL; goto fin );
\r
11209 /* Already removed */
\r
11210 ASSERT_R( removing_element != &removing_element->List->Terminator,
\r
11211 e=E_NOT_FOUND_SYMBOL; goto fin ); /* Over next or previous */
\r
11213 self->ModifiedElement.Next = removing_element->Next;
\r
11214 self->ModifiedElement.Previous = removing_element->Previous;
\r
11215 self->Element = &self->ModifiedElement;
\r
11217 e= ListClass_remove( removing_element->List, removing_element ); IF(e){goto fin;}
\r
11226 /***********************************************************************
\r
11227 <<< [ListClass_finalizeWithVTable] >>>
\r
11228 ************************************************************************/
\r
11229 errnum_t ListClass_finalizeWithVTable( ListClass* self, bool IsFreeElements, errnum_t e )
\r
11232 ListIteratorClass iterator;
\r
11233 ClassID_SuperClass* element;
\r
11234 FinalizerVTableClass* v_table;
\r
11236 ee= ListClass_getListIterator( self, &iterator );
\r
11238 if ( e == 0 ) { e = ee; }
\r
11243 element = (ClassID_SuperClass*) ListIteratorClass_getNext( &iterator );
\r
11244 if ( element == NULL ) { break; }
\r
11245 ee= ListIteratorClass_remove( &iterator );
\r
11247 /* Call "Finalize" */
\r
11248 v_table = (FinalizerVTableClass*) ClassID_Class_getVTable(
\r
11249 element->ClassID, &g_FinalizerInterface_ID );
\r
11250 IF ( v_table == NULL ) {
\r
11251 if ( e == 0 ) { e=E_OTHERS; }
\r
11254 e= v_table->Finalize( element, e );
\r
11257 /* Call "HeapMemory_free" */
\r
11258 if ( IsFreeElements ) {
\r
11259 e= HeapMemory_free( &element, e );
\r
11269 /***********************************************************************
\r
11270 <<< [ListClass_printXML] >>>
\r
11271 ************************************************************************/
\r
11272 errnum_t ListClass_printXML( ListClass* self, FILE* OutputStream )
\r
11275 ListIteratorClass iterator;
\r
11276 ClassID_SuperClass* element;
\r
11277 PrintXML_VTableClass* v_table;
\r
11279 e= ListClass_getListIterator( self, &iterator ); IF(e){goto fin;}
\r
11281 element = (ClassID_SuperClass*) ListIteratorClass_getNext( &iterator );
\r
11282 if ( element == NULL ) { break; }
\r
11284 /* Call "PrintXML" */
\r
11285 v_table = (PrintXML_VTableClass*) ClassID_Class_getVTable(
\r
11286 element->ClassID, &g_PrintXML_Interface_ID );
\r
11287 if ( v_table == NULL ) {
\r
11288 _ftprintf_s( OutputStream, _T("<UnknownClass error=\"Not found PrintXML_VTable\"/>\n") );
\r
11291 e= v_table->PrintXML( element, OutputStream ); IF(e){goto fin;}
\r
11302 /***********************************************************************
\r
11303 <<< (VariantListClass) >>>
\r
11304 ************************************************************************/
\r
11306 /*[VariantListClass_initConst]*/
\r
11307 void VariantListClass_initConst( VariantListClass* self )
\r
11309 ListClass_initConst( &self->List );
\r
11313 /*[VariantListClass_finalize]*/
\r
11314 errnum_t VariantListClass_finalize( VariantListClass* self, errnum_t e )
\r
11317 ListIteratorClass iterator;
\r
11318 VariantClass* variant;
\r
11320 ee= ListClass_getListIterator( &self->List, &iterator );
\r
11322 if ( e == 0 ) { e = ee; }
\r
11327 variant = (VariantClass*) ListIteratorClass_getNext( &iterator );
\r
11328 if ( variant == NULL ) { break; }
\r
11329 ee= ListIteratorClass_remove( &iterator );
\r
11331 Variant_SuperClass* object = variant->Object;
\r
11332 FinalizerVTableClass* v_table;
\r
11334 v_table = ClassID_Class_getVTable( object->ClassID, &g_FinalizerInterface_ID );
\r
11335 if ( v_table != NULL ) {
\r
11336 e= v_table->Finalize( object, e );
\r
11338 e= FreeMemory( &object, e );
\r
11339 e= FreeMemory( &variant, e );
\r
11348 /*[VariantListClass_createElement]*/
\r
11349 errnum_t VariantListClass_createElement( VariantListClass* self,
\r
11350 void* /*<Variant_SuperClass**>*/ out_ElementObject,
\r
11351 const ClassID_Class* ClassID, void* Parameter )
\r
11354 VariantClass* variant = NULL;
\r
11355 Variant_SuperClass* object = NULL;
\r
11356 InitializeFuncType initialize;
\r
11357 bool is_initialized = false;
\r
11359 e= MallocMemory( &variant, sizeof( VariantClass ) ); IF(e){goto fin;}
\r
11360 ListElementClass_initConst( &variant->ListElement, variant );
\r
11362 e= MallocMemory( &object, ClassID->Size ); IF(e){goto fin;}
\r
11363 initialize = ClassID->InitializeFunction;
\r
11364 if ( initialize != NULL ) {
\r
11365 e= initialize( object, Parameter ); IF(e){goto fin;}
\r
11367 is_initialized = true;
\r
11369 variant->Object = object;
\r
11370 object->StaticAddress = variant;
\r
11371 e= ListClass_addLast( &self->List, &variant->ListElement ); IF(e){goto fin;}
\r
11373 *(Variant_SuperClass**) out_ElementObject = object;
\r
11378 if ( is_initialized ) {
\r
11379 FinalizerVTableClass* v_table;
\r
11381 v_table = ClassID_Class_getVTable( ClassID, &g_FinalizerInterface_ID );
\r
11382 if ( v_table != NULL ) {
\r
11383 e= v_table->Finalize( object, e );
\r
11386 e= FreeMemory( &object, e );
\r
11387 e= FreeMemory( &variant, e );
\r
11393 /*[VariantListClass_destroyElement]*/
\r
11394 errnum_t VariantListClass_destroyElement( VariantListClass* self,
\r
11395 void* /*<Variant_SuperClass**>*/ in_out_ElementObject, errnum_t e )
\r
11398 FinalizerVTableClass* v_table;
\r
11399 VariantClass* variant;
\r
11400 Variant_SuperClass* object = *(Variant_SuperClass**) in_out_ElementObject;
\r
11402 if ( object != NULL ) {
\r
11403 variant = object->StaticAddress;
\r
11405 ee= ListClass_remove( &self->List, &variant->ListElement );
\r
11406 UNREFERENCED_VARIABLE( ee );
\r
11408 v_table = ClassID_Class_getVTable( object->ClassID, &g_FinalizerInterface_ID );
\r
11409 if ( v_table != NULL ) {
\r
11410 e= v_table->Finalize( object, e );
\r
11412 e= FreeMemory( &object, e );
\r
11413 e= FreeMemory( &variant, e );
\r
11415 *(Variant_SuperClass**) in_out_ElementObject = NULL;
\r
11422 /***********************************************************************
\r
11423 <<< (Variant_SuperClass) >>>
\r
11424 ************************************************************************/
\r
11425 static const ClassID_Class* gs_Variant_SuperClass_SuperClassIDs[] = {
\r
11426 &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID,
\r
11429 /*[g_Variant_SuperClass_ID]*/
\r
11430 const ClassID_Class g_Variant_SuperClass_ID = {
\r
11431 "Variant_SuperClass",
\r
11432 gs_Variant_SuperClass_SuperClassIDs,
\r
11433 _countof( gs_Variant_SuperClass_SuperClassIDs ),
\r
11434 sizeof( Variant_SuperClass ),
\r
11435 Variant_SuperClass_initialize,
\r
11441 /*[Variant_SuperClass_initialize]*/
\r
11442 errnum_t Variant_SuperClass_initialize( Variant_SuperClass* self, void* Parameter )
\r
11444 self->ClassID = &g_Variant_SuperClass_ID;
\r
11445 self->FinalizerVTable = NULL;
\r
11446 self->StaticAddress = NULL;
\r
11447 UNREFERENCED_VARIABLE( Parameter );
\r
11453 /***********************************************************************
\r
11454 <<< (VariantListIteratorClass) >>>
\r
11455 ************************************************************************/
\r
11457 /*[VariantListIteratorClass_getNext]*/
\r
11458 Variant_SuperClass* VariantListIteratorClass_getNext( VariantListIteratorClass* self )
\r
11460 VariantClass* variant;
\r
11462 variant = ListIteratorClass_getNext( &self->Iterator );
\r
11463 if ( variant == NULL ) {
\r
11466 return variant->Object;
\r
11472 /***********************************************************************
\r
11473 <<< [PArray_setFromArray] >>>
\r
11474 ************************************************************************/
\r
11475 int PArray_setFromArray( void* PointerArray, size_t PointerArraySize, void* out_ppRight,
\r
11476 void* SrcArray, size_t SrcArraySize, size_t SrcArrayElemSize )
\r
11484 pp = (char**) PointerArray;
\r
11485 pp_over = (char**)( (char*)PointerArray + PointerArraySize );
\r
11486 s = (char*) SrcArray;
\r
11487 s_over = (char*) SrcArray + SrcArraySize;
\r
11489 IF ( (pp_over - pp) * SrcArraySize < SrcArraySize ) {
\r
11490 s_over = (char*)SrcArray + (pp_over - pp) * SrcArraySize;
\r
11494 while ( s < s_over ) {
\r
11496 pp++; s += SrcArrayElemSize;
\r
11499 if ( out_ppRight != NULL ) *(char***)out_ppRight = pp - 1;
\r
11506 /***********************************************************************
\r
11507 <<< [PArray_doShakerSort] >>>
\r
11508 ************************************************************************/
\r
11509 errnum_t PArray_doShakerSort( const void* PointerArray, size_t PointerArraySize,
\r
11510 const void* ppLeft, const void* ppRight, CompareFuncType Compare, const void* Param )
\r
11513 void** p_left = (void**)ppLeft;
\r
11514 void** p_right = (void**)ppRight;
\r
11521 if ( PointerArraySize == 0 ) { e=0; goto fin; }
\r
11523 IF_D( ppLeft != NULL && ( ppLeft < PointerArray || (char*)ppLeft >= (char*)PointerArray + PointerArraySize ) ) goto err;
\r
11524 IF_D( ppRight != NULL && ( ppRight < PointerArray || (char*)ppRight >= (char*)PointerArray + PointerArraySize ) ) goto err;
\r
11526 if ( p_left == NULL ) p_left = (void**) PointerArray;
\r
11527 if ( p_right == NULL ) p_right = (void**)( (char*) PointerArray + PointerArraySize - sizeof(void*) );
\r
11531 //=== Run to right
\r
11536 while ( p1 < p_right ) {
\r
11537 e= Compare( p1, p2, Param, &cmp ); IF(e)goto fin;
\r
11539 swap = *p1; *p1 = *p2; *p2 = swap;
\r
11544 if ( p_swap == p_left ) break;
\r
11545 p_right = p_swap;
\r
11548 //=== Run to left
\r
11549 p1 = p_right - 1;
\r
11551 p_swap = p_right;
\r
11553 while ( p1 >= p_left ) {
\r
11554 e= Compare( p1, p2, Param, &cmp ); IF(e)goto fin;
\r
11556 swap = *p1; *p1 = *p2; *p2 = swap;
\r
11561 if ( p_swap == p_right ) break;
\r
11569 err: e = E_OTHERS; goto fin;
\r
11574 /***********************************************************************
\r
11575 <<< [PArray_isSorted] >>>
\r
11576 ************************************************************************/
\r
11577 errnum_t PArray_isSorted( const void* PointerArray, size_t PointerArraySize,
\r
11578 CompareFuncType Compare, const void* Param, bool* out_IsSorted )
\r
11582 const void** p_over;
\r
11585 p = PointerArray;
\r
11586 p_over = (const void**)( (uintptr_t) PointerArray + PointerArraySize - sizeof(void*) );
\r
11588 while ( p < p_over ) {
\r
11589 e= Compare( p, p + 1, Param, &result );
\r
11592 IF ( result > 0 ) { *out_IsSorted = false; goto fin; }
\r
11597 *out_IsSorted = true;
\r
11605 /***********************************************************************
\r
11606 <<< [PArray_doBinarySearch] >>>
\r
11607 ************************************************************************/
\r
11608 errnum_t PArray_doBinarySearch( const void* PointerArray, size_t PointerArraySize,
\r
11609 const void* Key, CompareFuncType Compare, const void* Param,
\r
11610 int* out_FoundOrLeftIndex, int* out_CompareResult )
\r
11613 uintptr_t base = (uintptr_t) PointerArray;
\r
11614 uintptr_t left; /* index */
\r
11616 uintptr_t middle;
\r
11620 right = (uintptr_t) PointerArraySize / sizeof(void*);
\r
11628 e= PArray_isSorted( PointerArray, PointerArraySize, Compare, Param, &is_sorted );
\r
11630 IF ( ! is_sorted ) { e=E_NO_NEXT; goto fin; }
\r
11635 while ( right - left >= 2 ) {
\r
11636 middle = ( left + right ) / 2;
\r
11638 e= Compare( &Key, ( (const void**) base + middle ), Param, &result );
\r
11641 if ( result == 0 ) {
\r
11644 } else if ( result < 0 ) {
\r
11651 e= Compare( &Key, ( (const void**) base + left ), Param, &result );
\r
11656 *out_FoundOrLeftIndex = left;
\r
11657 *out_CompareResult = result;
\r
11663 /***********************************************************************
\r
11664 <<< (DictionaryAA_NodeClass:Class) >>>
\r
11665 ************************************************************************/
\r
11667 /*[DictionaryAA_SearchWorkClass]*/
\r
11668 typedef struct _DictionaryAA_SearchWorkClass DictionaryAA_SearchWorkClass;
\r
11669 struct _DictionaryAA_SearchWorkClass {
\r
11670 const TCHAR* SearchKey;
\r
11671 DictionaryAA_NodeClass* FoundNode;
\r
11672 bool IsErrorIfNotFound;
\r
11675 /*[DictionaryAA_TraverseWorkClass]*/
\r
11676 typedef struct _DictionaryAA_TraverseWorkClass DictionaryAA_TraverseWorkClass;
\r
11677 struct _DictionaryAA_TraverseWorkClass {
\r
11678 DictionaryAA_TraverseFuncType Function;
\r
11679 void* UserParameter;
\r
11682 errnum_t DictionaryAA_NodeClass_insert( DictionaryAA_NodeClass* Node,
\r
11683 DictionaryAA_NodeClass** out_ParentNode, DictionaryAA_SearchWorkClass* work );
\r
11684 errnum_t DictionaryAA_NodeClass_search( DictionaryAA_NodeClass* Node,
\r
11685 DictionaryAA_SearchWorkClass* work );
\r
11686 DictionaryAA_NodeClass* DictionaryAA_NodeClass_remove( DictionaryAA_NodeClass* Node,
\r
11687 const TCHAR* Key, DictionaryAA_NodeClass** out_RemovingNode );
\r
11688 DictionaryAA_NodeClass* DictionaryAA_NodeClass_skew( DictionaryAA_NodeClass* Node );
\r
11689 DictionaryAA_NodeClass* DictionaryAA_NodeClass_split( DictionaryAA_NodeClass* Node );
\r
11690 DictionaryAA_NodeClass* DictionaryAA_NodeClass_rotateLeft( DictionaryAA_NodeClass* Node );
\r
11691 DictionaryAA_NodeClass* DictionaryAA_NodeClass_rotateRight( DictionaryAA_NodeClass* Node );
\r
11692 DictionaryAA_NodeClass* DictionaryAA_NodeClass_searchMin( DictionaryAA_NodeClass* Node );
\r
11693 errnum_t DictionaryAA_NodeClass_toEmpty( DictionaryAA_NodeClass* Node, errnum_t e );
\r
11694 errnum_t DictionaryAA_NodeClass_onTraverse( DictionaryAA_NodeClass* Node,
\r
11695 DictionaryAA_TraverseWorkClass* work );
\r
11696 errnum_t DictionaryAA_NodeClass_print( DictionaryAA_NodeClass* Node, int RootHeight,
\r
11697 FILE* OutputStream );
\r
11701 /***********************************************************************
\r
11702 <<< (DictionaryAA_Class) >>>
\r
11703 ************************************************************************/
\r
11705 /*[DictionaryAA_Class_initConst]*/
\r
11706 void DictionaryAA_Class_initConst( DictionaryAA_Class* self )
\r
11708 self->Root = &g_DictionaryAA_NullNode;
\r
11712 /*[DictionaryAA_Class_finalize]*/
\r
11713 errnum_t DictionaryAA_Class_finalize( DictionaryAA_Class* self, errnum_t e )
\r
11715 return DictionaryAA_NodeClass_toEmpty( self->Root, e );
\r
11719 /*[DictionaryAA_Class_insert]*/
\r
11720 errnum_t DictionaryAA_Class_insert( DictionaryAA_Class* self, const TCHAR* Key,
\r
11721 DictionaryAA_NodeClass** out_Node )
\r
11724 DictionaryAA_SearchWorkClass work;
\r
11726 work.SearchKey = Key;
\r
11728 e= DictionaryAA_NodeClass_insert( self->Root, &self->Root, &work );
\r
11730 *out_Node = work.FoundNode;
\r
11736 /*[DictionaryAA_Class_remove]*/
\r
11737 errnum_t DictionaryAA_Class_remove( DictionaryAA_Class* self, const TCHAR* Key )
\r
11740 DictionaryAA_NodeClass* removing_node = NULL;
\r
11742 self->Root = DictionaryAA_NodeClass_remove( self->Root, Key, &removing_node );
\r
11743 if ( removing_node == NULL ) { e = E_NOT_FOUND_SYMBOL; goto fin; }
\r
11747 if ( removing_node != NULL ) {
\r
11748 e= HeapMemory_free( &removing_node->Key, e );
\r
11749 e= HeapMemory_free( &removing_node, e );
\r
11755 /*[DictionaryAA_Class_search]*/
\r
11756 errnum_t DictionaryAA_Class_search( DictionaryAA_Class* self, const TCHAR* Key,
\r
11757 DictionaryAA_NodeClass** out_Node )
\r
11760 DictionaryAA_SearchWorkClass work;
\r
11762 work.SearchKey = Key;
\r
11763 work.IsErrorIfNotFound = true;
\r
11765 e= DictionaryAA_NodeClass_search( self->Root, &work );
\r
11767 *out_Node = work.FoundNode;
\r
11773 /*[DictionaryAA_Class_isExist]*/
\r
11774 bool DictionaryAA_Class_isExist( DictionaryAA_Class* self, const TCHAR* Key )
\r
11776 DictionaryAA_SearchWorkClass work;
\r
11778 work.SearchKey = Key;
\r
11779 work.IsErrorIfNotFound = false;
\r
11781 DictionaryAA_NodeClass_search( self->Root, &work );
\r
11783 return ( work.FoundNode != NULL );
\r
11787 /*[DictionaryAA_Class_freeAllKeysHeap]*/
\r
11789 errnum_t DictionaryAA_Class_freeAllKeysHeap( DictionaryAA_Class* self, errnum_t e )
\r
11792 DictionaryAA_IteratorClass iterator;
\r
11793 DictionaryAA_NodeClass* node;
\r
11795 DictionaryAA_IteratorClass_initConst( &iterator );
\r
11797 ee= DictionaryAA_IteratorClass_initialize( &iterator, self );
\r
11798 IF ( ee != 0 && e==0 ) { e = ee; goto fin; }
\r
11799 for ( DictionaryAA_Class_forEach( &iterator, &node ) ) {
\r
11800 e= HeapMemory_free( &node->Key, e );
\r
11805 e= DictionaryAA_IteratorClass_finalize( &iterator, e );
\r
11811 /*[DictionaryAA_Class_traverse]*/
\r
11812 errnum_t DictionaryAA_Class_traverse( DictionaryAA_Class* self,
\r
11813 DictionaryAA_TraverseFuncType Function,
\r
11814 void* UserParameter )
\r
11816 DictionaryAA_TraverseWorkClass work;
\r
11818 work.Function = Function;
\r
11819 work.UserParameter = UserParameter;
\r
11821 return DictionaryAA_NodeClass_onTraverse( self->Root, &work );
\r
11825 /*[DictionaryAA_Class_toEmpty]*/
\r
11826 errnum_t DictionaryAA_Class_toEmpty( DictionaryAA_Class* self )
\r
11830 e= DictionaryAA_NodeClass_toEmpty( self->Root, 0 ); IF(e){goto fin;}
\r
11834 self->Root = &g_DictionaryAA_NullNode;
\r
11839 /*[DictionaryAA_Class_print]*/
\r
11840 errnum_t DictionaryAA_Class_print( DictionaryAA_Class* self, FILE* OutputStream )
\r
11845 r= _ftprintf_s( OutputStream, _T("DictionaryAA -------------------\n") );
\r
11846 IF(r<0) { e=E_ACCESS_DENIED; goto fin; }
\r
11848 e= DictionaryAA_NodeClass_print( self->Root, self->Root->Height, OutputStream );
\r
11858 /***********************************************************************
\r
11859 <<< [DictionaryAA_Class_finalize2] >>>
\r
11860 ************************************************************************/
\r
11861 errnum_t DictionaryAA_Class_finalize2( DictionaryAA_Class* self, errnum_t e,
\r
11862 bool in_IsFreeItem, FinalizeFuncType in_Type_Finalize )
\r
11866 DictionaryAA_NodeClass* node;
\r
11867 DictionaryAA_IteratorClass iterator;
\r
11869 DictionaryAA_IteratorClass_initConst( &iterator );
\r
11871 ee= DictionaryAA_IteratorClass_initialize( &iterator, self );
\r
11872 IF(ee){e=MergeError(e,ee);goto fin;}
\r
11873 for ( DictionaryAA_Class_forEach( &iterator, &node ) ) {
\r
11874 if ( in_Type_Finalize != NULL ) {
\r
11875 e= in_Type_Finalize( node->Item, e );
\r
11877 if ( in_IsFreeItem ) {
\r
11878 e= HeapMemory_free( &node->Item, e );
\r
11883 e= DictionaryAA_IteratorClass_finalize( &iterator, e );
\r
11884 e= DictionaryAA_Class_finalize( self, e );
\r
11890 /***********************************************************************
\r
11891 <<< [DictionaryAA_Class_getArray] >>>
\r
11892 ************************************************************************/
\r
11893 errnum_t DictionaryAA_Class_getArray( DictionaryAA_Class* self,
\r
11894 TCHAR*** in_out_Strings, int* in_out_StringCount, NewStringsEnum in_HowToAllocate )
\r
11897 int string_count = 0;
\r
11898 int string_count_max;
\r
11900 TCHAR** key_array = NULL;
\r
11901 TCHAR** new_key_array = NULL;
\r
11903 DictionaryAA_NodeClass* node;
\r
11904 DictionaryAA_IteratorClass iterator;
\r
11906 DictionaryAA_IteratorClass_initConst( &iterator );
\r
11909 /* Set "string_count_max", "key_array" */
\r
11910 if ( IsBitSet( in_HowToAllocate, NewStringsEnum_NewPointers ) ) {
\r
11912 string_count_max = 0;
\r
11913 e= DictionaryAA_IteratorClass_initialize( &iterator, self );
\r
11915 for ( DictionaryAA_Class_forEach( &iterator, &node ) ) {
\r
11916 string_count_max += 1;
\r
11918 e= DictionaryAA_IteratorClass_finalize( &iterator, 0 ); IF(e){goto fin;}
\r
11920 e= HeapMemory_allocateArray( &new_key_array, string_count_max );
\r
11922 *in_out_Strings = new_key_array;
\r
11923 key_array = new_key_array;
\r
11926 ASSERT_R( in_out_StringCount != NULL, e=E_OTHERS; goto fin );
\r
11927 string_count_max = *in_out_StringCount;
\r
11928 key_array = *in_out_Strings;
\r
11930 memset( key_array, 0x00, string_count_max * sizeof(TCHAR*) );
\r
11933 /* Set "key_array[ string_count ]" */
\r
11934 e= DictionaryAA_IteratorClass_initialize( &iterator, self );
\r
11936 for ( DictionaryAA_Class_forEach( &iterator, &node ) ) {
\r
11937 const TCHAR* value = node->Key;
\r
11939 if ( IsBitSet( in_HowToAllocate, NewStringsEnum_NewCharacters ) ) {
\r
11940 ASSERT_R( IsBitNotSet( in_HowToAllocate, NewStringsEnum_LinkCharacters ),
\r
11941 e=E_OTHERS; goto fin );
\r
11943 e= MallocAndCopyString( &key_array[ string_count ], value );
\r
11946 else if ( IsBitSet( in_HowToAllocate, NewStringsEnum_LinkCharacters ) ) {
\r
11947 const TCHAR** key_pp = &key_array[ string_count ];
\r
11949 ASSERT_R( *key_pp == NULL, e=E_OTHERS; goto fin );
\r
11953 ASSERT_R( false, e=E_LIMITATION; goto fin );
\r
11955 string_count += 1;
\r
11958 *in_out_StringCount = string_count;
\r
11959 new_key_array = NULL;
\r
11964 if ( IsBitSet( in_HowToAllocate, NewStringsEnum_NewCharacters ) ) {
\r
11965 if ( key_array != NULL ) {
\r
11966 for ( string_count -= 1; string_count >= 0; string_count -= 1 ) {
\r
11967 e= HeapMemory_free( &key_array[ string_count ], e );
\r
11972 e= HeapMemory_free( &new_key_array, e );
\r
11973 e= DictionaryAA_IteratorClass_finalize( &iterator, e );
\r
11979 /***********************************************************************
\r
11980 <<< (DictionaryAA_NodeClass) >>>
\r
11981 ************************************************************************/
\r
11983 /*[g_DictionaryAA_NullNode]*/
\r
11984 DictionaryAA_NodeClass g_DictionaryAA_NullNode = {
\r
11985 /* Key */ _T("(NullNode)"),
\r
11988 /* Left */ &g_DictionaryAA_NullNode,
\r
11989 /* Right */ &g_DictionaryAA_NullNode,
\r
11993 /*[DictionaryAA_NodeClass_insert]*/
\r
11994 errnum_t DictionaryAA_NodeClass_insert( DictionaryAA_NodeClass* in_Node,
\r
11995 DictionaryAA_NodeClass** out_ParentNode, DictionaryAA_SearchWorkClass* work )
\r
11999 if ( in_Node == &g_DictionaryAA_NullNode ) {
\r
12000 e= HeapMemory_allocate( &in_Node ); IF(e){goto fin;}
\r
12001 in_Node->Key = NULL;
\r
12002 e= MallocAndCopyString( &in_Node->Key, work->SearchKey ); IF(e){goto fin;}
\r
12003 in_Node->Item = NULL;
\r
12004 in_Node->Height = 1;
\r
12005 in_Node->Left = &g_DictionaryAA_NullNode;
\r
12006 in_Node->Right = &g_DictionaryAA_NullNode;
\r
12007 *out_ParentNode = in_Node;
\r
12008 work->FoundNode = in_Node;
\r
12011 int compare = _tcscmp( work->SearchKey, in_Node->Key );
\r
12013 if ( compare == 0 ) {
\r
12014 *out_ParentNode = in_Node;
\r
12015 work->FoundNode = in_Node;
\r
12018 if ( compare < 0 ) {
\r
12019 e= DictionaryAA_NodeClass_insert( in_Node->Left, &in_Node->Left, work );
\r
12022 else { /* compare > 0 */
\r
12023 e= DictionaryAA_NodeClass_insert( in_Node->Right, &in_Node->Right, work );
\r
12026 in_Node = DictionaryAA_NodeClass_skew( in_Node );
\r
12027 in_Node = DictionaryAA_NodeClass_split( in_Node );
\r
12028 *out_ParentNode = in_Node;
\r
12038 /*[DictionaryAA_NodeClass_search]*/
\r
12039 errnum_t DictionaryAA_NodeClass_search( DictionaryAA_NodeClass* in_Node,
\r
12040 DictionaryAA_SearchWorkClass* work )
\r
12045 if ( in_Node == &g_DictionaryAA_NullNode ) {
\r
12046 IF ( work->IsErrorIfNotFound ) { e = E_NOT_FOUND_SYMBOL; goto fin; }
\r
12047 work->FoundNode = NULL;
\r
12051 compare = _tcscmp( work->SearchKey, in_Node->Key );
\r
12053 if ( compare == 0 ) {
\r
12054 work->FoundNode = in_Node;
\r
12057 if ( compare < 0 ) {
\r
12058 e= DictionaryAA_NodeClass_search( in_Node->Left, work );
\r
12061 else { /* compare > 0 */
\r
12062 e= DictionaryAA_NodeClass_search( in_Node->Right, work );
\r
12073 /*[DictionaryAA_NodeClass_remove]*/
\r
12074 DictionaryAA_NodeClass* DictionaryAA_NodeClass_remove( DictionaryAA_NodeClass* in_Node,
\r
12075 const TCHAR* Key, DictionaryAA_NodeClass** out_RemovingNode )
\r
12077 if ( in_Node != &g_DictionaryAA_NullNode ) {
\r
12078 int compare = _tcscmp( Key, in_Node->Key );
\r
12080 if ( compare == 0 ) {
\r
12081 if ( in_Node->Left == &g_DictionaryAA_NullNode ) {
\r
12082 *out_RemovingNode = in_Node;
\r
12083 in_Node = in_Node->Right;
\r
12084 } else if ( in_Node->Right == &g_DictionaryAA_NullNode ) {
\r
12085 *out_RemovingNode = in_Node;
\r
12086 in_Node = in_Node->Left;
\r
12088 DictionaryAA_NodeClass* reuse_node = in_Node;
\r
12089 DictionaryAA_NodeClass* sacrifice_node;
\r
12090 DictionaryAA_NodeClass swap;
\r
12092 sacrifice_node = DictionaryAA_NodeClass_searchMin( in_Node->Right );
\r
12093 reuse_node->Right = DictionaryAA_NodeClass_remove(
\r
12094 in_Node->Right, sacrifice_node->Key, &sacrifice_node );
\r
12096 swap.Key = reuse_node->Key;
\r
12097 swap.Item = reuse_node->Item;
\r
12098 reuse_node->Key = sacrifice_node->Key;
\r
12099 reuse_node->Item = sacrifice_node->Item;
\r
12100 sacrifice_node->Key = swap.Key;
\r
12101 sacrifice_node->Item = swap.Item;
\r
12102 *out_RemovingNode = sacrifice_node;
\r
12105 else if ( compare < 0 ) {
\r
12106 in_Node->Left = DictionaryAA_NodeClass_remove( in_Node->Left, Key, out_RemovingNode );
\r
12108 else { /* compare > 0 */
\r
12109 in_Node->Right = DictionaryAA_NodeClass_remove( in_Node->Right, Key, out_RemovingNode );
\r
12112 if ( in_Node->Left->Height < in_Node->Height - 1 ||
\r
12113 in_Node->Right->Height < in_Node->Height - 1 )
\r
12115 in_Node->Height -= 1;
\r
12116 if ( in_Node->Right->Height > in_Node->Height )
\r
12117 { in_Node->Right->Height = in_Node->Height; }
\r
12118 in_Node = DictionaryAA_NodeClass_skew( in_Node );
\r
12119 in_Node->Right = DictionaryAA_NodeClass_skew( in_Node->Right );
\r
12120 in_Node->Right->Right = DictionaryAA_NodeClass_skew( in_Node->Right->Right );
\r
12121 in_Node = DictionaryAA_NodeClass_split( in_Node );
\r
12122 in_Node->Right = DictionaryAA_NodeClass_split( in_Node->Right );
\r
12129 /*[DictionaryAA_NodeClass_skew]*/
\r
12130 DictionaryAA_NodeClass* DictionaryAA_NodeClass_skew( DictionaryAA_NodeClass* in_Node )
\r
12132 if ( in_Node->Left->Height == in_Node->Height ) {
\r
12133 in_Node = DictionaryAA_NodeClass_rotateRight( in_Node );
\r
12140 /*[DictionaryAA_NodeClass_split]*/
\r
12141 DictionaryAA_NodeClass* DictionaryAA_NodeClass_split( DictionaryAA_NodeClass* in_Node )
\r
12143 if ( in_Node->Height == in_Node->Right->Right->Height ) {
\r
12144 in_Node = DictionaryAA_NodeClass_rotateLeft( in_Node );
\r
12145 in_Node->Height += 1;
\r
12152 /*[DictionaryAA_NodeClass_rotateLeft]*/
\r
12153 DictionaryAA_NodeClass* DictionaryAA_NodeClass_rotateLeft( DictionaryAA_NodeClass* in_Node )
\r
12155 DictionaryAA_NodeClass* swap;
\r
12157 swap = in_Node->Right;
\r
12158 in_Node->Right = swap->Left;
\r
12159 swap->Left = in_Node;
\r
12165 /*[DictionaryAA_NodeClass_rotateRight]*/
\r
12166 DictionaryAA_NodeClass* DictionaryAA_NodeClass_rotateRight( DictionaryAA_NodeClass* in_Node )
\r
12168 DictionaryAA_NodeClass* swap;
\r
12170 swap = in_Node->Left;
\r
12171 in_Node->Left = swap->Right;
\r
12172 swap->Right = in_Node;
\r
12178 DictionaryAA_NodeClass* DictionaryAA_NodeClass_searchMin( DictionaryAA_NodeClass* in_Node )
\r
12180 while ( in_Node->Left != &g_DictionaryAA_NullNode )
\r
12181 { in_Node = in_Node->Left; }
\r
12186 /*[DictionaryAA_NodeClass_toEmpty]*/
\r
12187 errnum_t DictionaryAA_NodeClass_toEmpty( DictionaryAA_NodeClass* in_Node, errnum_t e )
\r
12189 if ( in_Node != &g_DictionaryAA_NullNode ) {
\r
12190 e= DictionaryAA_NodeClass_toEmpty( in_Node->Left, e );
\r
12191 e= DictionaryAA_NodeClass_toEmpty( in_Node->Right, e );
\r
12192 e= HeapMemory_free( &in_Node->Key, e );
\r
12193 e= HeapMemory_free( &in_Node, e );
\r
12199 /*[DictionaryAA_NodeClass_onTraverse]*/
\r
12200 errnum_t DictionaryAA_NodeClass_onTraverse( DictionaryAA_NodeClass* in_Node,
\r
12201 DictionaryAA_TraverseWorkClass* work )
\r
12205 if ( in_Node != &g_DictionaryAA_NullNode ) {
\r
12206 e= DictionaryAA_NodeClass_onTraverse( in_Node->Left, work ); IF(e){goto fin;}
\r
12207 e= work->Function( in_Node, work->UserParameter ); IF(e){goto fin;}
\r
12208 e= DictionaryAA_NodeClass_onTraverse( in_Node->Right, work ); IF(e){goto fin;}
\r
12217 /*[DictionaryAA_NodeClass_print]*/
\r
12218 errnum_t DictionaryAA_NodeClass_print( DictionaryAA_NodeClass* in_Node, int RootHeight,
\r
12219 FILE* OutputStream )
\r
12224 if ( in_Node != &g_DictionaryAA_NullNode ) {
\r
12226 e= DictionaryAA_NodeClass_print( in_Node->Left, RootHeight, OutputStream );
\r
12229 r= _ftprintf_s( OutputStream, _T("%*s%s\n"), ( RootHeight - in_Node->Height ) * 4,
\r
12230 _T(""), in_Node->Key ); IF(r<0) { e=E_ACCESS_DENIED; goto fin; }
\r
12232 e= DictionaryAA_NodeClass_print( in_Node->Right, RootHeight, OutputStream );
\r
12243 /***********************************************************************
\r
12244 <<< (DictionaryAA_IteratorClass) >>>
\r
12245 ************************************************************************/
\r
12247 errnum_t DictionaryAA_IteratorClass_initialize_sub( DictionaryAA_NodeClass* in_Node,
\r
12251 /*[DictionaryAA_IteratorClass_initialize]*/
\r
12252 errnum_t DictionaryAA_IteratorClass_initialize( DictionaryAA_IteratorClass* self,
\r
12253 DictionaryAA_Class* Collection )
\r
12257 e= Set2_init( &self->Nodes, 0x100 ); IF(e){goto fin;}
\r
12259 e= DictionaryAA_Class_traverse( Collection, DictionaryAA_IteratorClass_initialize_sub,
\r
12260 &self->Nodes ); IF(e){goto fin;}
\r
12262 self->NextNode = self->Nodes.First;
\r
12270 /*[DictionaryAA_IteratorClass_initialize_sub]*/
\r
12271 errnum_t DictionaryAA_IteratorClass_initialize_sub( DictionaryAA_NodeClass* in_Node,
\r
12275 Set2* array = (Set2*) Array;
\r
12276 DictionaryAA_NodeClass** pp_node;
\r
12278 e= Set2_alloc( array, &pp_node, DictionaryAA_NodeClass* ); IF(e){goto fin;}
\r
12279 *pp_node = in_Node;
\r
12287 /*[DictionaryAA_IteratorClass_getNext]*/
\r
12288 DictionaryAA_NodeClass* DictionaryAA_IteratorClass_getNext(
\r
12289 DictionaryAA_IteratorClass* self )
\r
12291 DictionaryAA_NodeClass* return_value;
\r
12293 if ( self->NextNode < (DictionaryAA_NodeClass**) self->Nodes.Next ) {
\r
12294 return_value = *self->NextNode;
\r
12295 self->NextNode += 1;
\r
12298 return_value = NULL;
\r
12301 return return_value;
\r
12306 /*=================================================================*/
\r
12307 /* <<< [Print/Print2.c] >>> */
\r
12308 /*=================================================================*/
\r
12310 /***********************************************************************
\r
12311 <<< [PrintfCounterClass] >>>
\r
12312 ************************************************************************/
\r
12313 #if USE_PRINTF_COUNTER
\r
12314 PrintfCounterClass g_PrintfCounter;
\r
12319 /***********************************************************************
\r
12320 <<< [printf_to_file] >>>
\r
12321 ************************************************************************/
\r
12323 #if USE_PRINTF_MULTI_THREAD
\r
12324 enum { g_PrintfMultiThreadCountMax = 8 };
\r
12325 DWORD g_printf_file_tid[ g_PrintfMultiThreadCountMax ];
\r
12326 bool g_printf_file_clear;
\r
12329 TCHAR g_printf_file_path[MAX_PATH];
\r
12330 int g_printf_file_indent;
\r
12332 static DWORD gs_locked_thread = 0;
\r
12335 void printf_lock_init_const( PrintfFileWorkClass* out_Work )
\r
12337 out_Work->File = NULL;
\r
12338 #if USE_PRINTF_MULTI_THREAD
\r
12339 out_Work->Mutex = NULL;
\r
12340 out_Work->ThreadIndex = 0;
\r
12344 errnum_t printf_lock( PrintfFileWorkClass* out_Work )
\r
12348 DWORD tid = GetCurrentThreadId();
\r
12349 FILE* file = NULL;
\r
12350 #if USE_PRINTF_MULTI_THREAD
\r
12351 HANDLE mutex = NULL;
\r
12352 int thread_index = 0;
\r
12355 printf_lock_init_const( out_Work );
\r
12357 e= printf_get_path( &path ); IF(e){goto fin;}
\r
12359 #if USE_PRINTF_MULTI_THREAD
\r
12360 mutex = CreateMutex( NULL, TRUE, TEXT("printf_file_mutex") );
\r
12361 IF ( mutex == NULL ) { e=E_GET_LAST_ERROR; goto fin; }
\r
12362 if ( gs_locked_thread == tid )
\r
12363 { DebugBreak(); } /* Re-entrant error */
\r
12364 /* Call "GetLogOptionPath" and "AppKey_newWritable" */
\r
12365 gs_locked_thread = tid;
\r
12367 if ( ! g_printf_file_clear ) {
\r
12368 if ( path != NULL ) _tremove( path );
\r
12369 g_printf_file_clear = true;
\r
12371 for ( thread_index = 0; thread_index < _countof( g_printf_file_tid ); thread_index += 1 ) {
\r
12372 if ( g_printf_file_tid[ thread_index ] == 0 || g_printf_file_tid[ thread_index ] == tid )
\r
12375 g_printf_file_tid[ thread_index ] = tid;
\r
12378 if ( path[0] == _T('\0') )
\r
12379 { file = stdout; }
\r
12383 en= _tfopen_s( &file, path, _T("a") );
\r
12384 if(en){ DebugBreak(); }
\r
12388 out_Work->File = file;
\r
12389 #if USE_PRINTF_MULTI_THREAD
\r
12390 out_Work->Mutex = mutex;
\r
12391 out_Work->ThreadIndex = thread_index;
\r
12394 printf_unlock( out_Work, e );
\r
12400 errnum_t printf_unlock( PrintfFileWorkClass* work, errnum_t e )
\r
12402 FILE* file = work->File;
\r
12403 #if USE_PRINTF_MULTI_THREAD
\r
12404 HANDLE mutex = work->Mutex;
\r
12407 if ( file != stdout && file != NULL )
\r
12408 { fclose( file ); }
\r
12410 #if USE_PRINTF_MULTI_THREAD
\r
12411 if ( mutex != NULL ) {
\r
12412 gs_locked_thread = 0;
\r
12413 ReleaseMutex( mutex );
\r
12414 CloseHandle( mutex );
\r
12418 printf_lock_init_const( work );
\r
12424 void printf_to_file( const char* format, ... )
\r
12426 enum { num_8_tab = 8 };
\r
12431 FILE* file = NULL;
\r
12432 int thread_index = 0;
\r
12434 ErrStackAreaClass err_stack;
\r
12435 PrintfFileWorkClass work;
\r
12437 PushErr( &err_stack );
\r
12439 e= printf_lock( &work ); if(e){goto fin;}
\r
12441 file = work.File;
\r
12442 thread_index = work.ThreadIndex;
\r
12445 #if USE_PRINTF_COUNTER
\r
12446 if ( g_PrintfCounter.Count == 0 ) {
\r
12447 char* process_ID;
\r
12449 #if USE_PRINTF_MULTI_PROCESS
\r
12450 process_ID = "ProcessID:";
\r
12455 fprintf_s( file, "%*s|{%sg_PrintfCounter.BreakIndent:g_PrintfCounter.BreakCount}\n",
\r
12456 thread_index * num_8_tab + g_printf_file_indent, "", process_ID );
\r
12460 #if USE_PRINTF_MULTI_THREAD
\r
12461 fprintf_s( file, "%*s", thread_index * num_8_tab + g_printf_file_indent + 1, "|" );
\r
12464 #if USE_PRINTF_COUNTER
\r
12466 char process_ID[ INT_DECIMAL_LENGTH_MAX + 5 ];
\r
12468 #if USE_PRINTF_MULTI_PROCESS
\r
12469 sprintf_s( process_ID, _countof( process_ID ), "%d:", GetCurrentProcessId() );
\r
12471 process_ID[0] = '\0';
\r
12474 g_PrintfCounter.Count ++;
\r
12475 fprintf_s( file, "{%s%d:%d}", process_ID, thread_index * num_8_tab + g_printf_file_indent,
\r
12476 g_PrintfCounter.Count );
\r
12480 va_start( va, format );
\r
12481 r= vfprintf_s( file, format, va );
\r
12483 IF(r<0){ e=E_ERRNO; goto fin; }
\r
12487 e= printf_unlock( &work, e );
\r
12489 IfErrThenBreak();
\r
12490 PopErr( &err_stack );
\r
12491 #if USE_PRINTF_COUNTER
\r
12492 if ( g_PrintfCounter.BreakCount > 0 &&
\r
12493 g_PrintfCounter.Count >= g_PrintfCounter.BreakCount &&
\r
12494 thread_index * num_8_tab + g_printf_file_indent == g_PrintfCounter.BreakIndent )
\r
12495 { DebugBreakR(); }
\r
12502 //[printf_file_start]
\r
12503 void printf_file_start( bool IsDelete, int IndentWidth )
\r
12505 g_printf_file_indent = IndentWidth;
\r
12507 if ( IsDelete ) {
\r
12511 e= printf_get_path( &path ); IF(e)return;
\r
12512 if ( path != NULL ) _tremove( path );
\r
12514 #if USE_PRINTF_MULTI_THREAD
\r
12515 g_printf_file_clear = true;
\r
12520 // [printf_get_path]
\r
12521 int printf_get_path( TCHAR** out_Path )
\r
12525 TCHAR desktop[MAX_PATH];
\r
12527 if ( g_printf_file_path[0] == '\0' ) {
\r
12528 b= SHGetSpecialFolderPath( NULL, desktop, CSIDL_DESKTOP, FALSE ); IF(!b){goto err_gt;}
\r
12529 e= StrT_getFullPath( g_printf_file_path, sizeof(g_printf_file_path),
\r
12530 _T("DebugOut.txt"), desktop ); IF(e){goto err_gt;}
\r
12532 if ( g_printf_file_path[0] == '*' ) {
\r
12533 *out_Path = _T("");
\r
12536 *out_Path = g_printf_file_path;
\r
12542 err_gt: e= E_GET_LAST_ERROR; goto fin;
\r
12546 // [printf_set_path]
\r
12547 int printf_set_path( const TCHAR* Path )
\r
12551 if ( Path[0] == _T('\0') ) {
\r
12552 g_printf_file_path[0] = _T('*');
\r
12553 g_printf_file_path[1] = _T('\0');
\r
12557 e= StrT_cpy( g_printf_file_path, sizeof(g_printf_file_path), Path );
\r
12566 /***********************************************************************
\r
12567 <<< [GetLogOptionPath] >>>
\r
12568 ************************************************************************/
\r
12569 TCHAR* GetLogOptionPath()
\r
12572 TCHAR* log_path = NULL;
\r
12573 TCHAR log_opt_path[MAX_PATH];
\r
12575 e= GetCommandLineNamed( _T("Log"), false, log_opt_path, sizeof(log_opt_path) );
\r
12576 //[out] log_opt_path
\r
12577 if ( e != E_NOT_FOUND_SYMBOL ) { IF(e)goto fin; }
\r
12580 e= printf_set_path( log_opt_path ); IF(e)goto fin;
\r
12583 e= printf_get_path( &log_path ); IF(e)goto fin;
\r
12587 if ( e ) { // if error, return default path
\r
12588 printf_set_path( _T("") );
\r
12589 printf_get_path( &log_path );
\r
12597 /***********************************************************************
\r
12598 <<< [vsprintf_r] >>>
\r
12599 ************************************************************************/
\r
12600 errnum_t vsprintf_r( char* s, size_t s_size, const char* format, va_list va )
\r
12603 #pragma warning(push)
\r
12604 #pragma warning(disable: 4996)
\r
12607 int r = _vsnprintf( s, s_size, format, va );
\r
12610 #pragma warning(pop)
\r
12613 IF( r == (int) s_size )
\r
12614 { s[s_size-1] = '\0'; return E_FEW_ARRAY; }
\r
12616 { return E_NOT_FOUND_SYMBOL; } /* Bad character code */
\r
12623 /***********************************************************************
\r
12624 <<< [vswprintf_r] >>>
\r
12625 ************************************************************************/
\r
12626 #ifndef __linux__
\r
12627 errnum_t vswprintf_r( wchar_t* s, size_t s_size, const wchar_t* format, va_list va )
\r
12629 size_t tsize = s_size / sizeof(wchar_t);
\r
12632 #pragma warning(push)
\r
12633 #pragma warning(disable: 4996)
\r
12636 int r = _vsnwprintf( s, tsize, format, va );
\r
12639 #pragma warning(pop)
\r
12642 if ( r == (int) tsize || r == -1 ) { s[tsize-1] = '\0'; return E_FEW_ARRAY; }
\r
12649 /***********************************************************************
\r
12650 <<< [stprintf_r] >>>
\r
12651 ************************************************************************/
\r
12652 errnum_t stprintf_r( TCHAR* s, size_t s_size, const TCHAR* format, ... )
\r
12657 va_start( va, format );
\r
12658 e = vstprintf_r( s, s_size, format, va );
\r
12665 /***********************************************************************
\r
12666 <<< [stcpy_part_r] >>>
\r
12667 ************************************************************************/
\r
12668 errnum_t stcpy_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,
\r
12669 const TCHAR* src, const TCHAR* src_over )
\r
12671 size_t s_space = (char*)s + s_size - (char*)s_start;
\r
12674 IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) { return 1; }
\r
12676 if ( src_over == NULL ) { src_over = StrT_chr( src, _T('\0') ); }
\r
12677 IF_D( src > src_over ) { return 1; }
\r
12678 src_size = (char*)src_over - (char*)src;
\r
12679 IF ( src_size >= s_space ) {
\r
12680 s_space -= sizeof(TCHAR);
\r
12681 memcpy( s, src, s_space );
\r
12683 s_start = (TCHAR*)((char*)s_start + s_space );
\r
12686 if ( p_s_last != NULL ) { *p_s_last=s_start; }
\r
12687 return E_FEW_ARRAY;
\r
12690 memcpy( s_start, src, src_size + sizeof(TCHAR) );
\r
12691 s_start = (TCHAR*)((char*)s_start + src_size); *s_start = _T('\0');
\r
12692 if ( p_s_last != NULL ) { *p_s_last = s_start; }
\r
12699 /***********************************************************************
\r
12700 <<< [stprintf_part_r] >>>
\r
12701 ************************************************************************/
\r
12702 errnum_t stprintf_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,
\r
12703 const TCHAR* format, ... )
\r
12707 va_start( va, format );
\r
12709 IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) {return E_OTHERS;}
\r
12711 e = vstprintf_r( s_start, s_size - ( (char*)s_start - (char*)s), format, va );
\r
12712 va_end( va ); if ( p_s_last != NULL ) *p_s_last = StrT_chr( s_start, '\0' );
\r
12718 /***********************************************************************
\r
12719 <<< [ftcopy_part_r] >>>
\r
12720 ************************************************************************/
\r
12721 errnum_t ftcopy_part_r( FILE* OutputStream, const TCHAR* Str, const TCHAR* StrOver )
\r
12727 TCHAR buffer[256];
\r
12729 ASSERT_R( Str <= StrOver, e=E_OTHERS; goto fin );
\r
12733 size = (uint8_t*) StrOver - (uint8_t*) p;
\r
12734 if ( size <= sizeof(buffer) - sizeof(TCHAR) ) {
\r
12738 size = sizeof(buffer) - sizeof(TCHAR);
\r
12742 memcpy( buffer, p, size );
\r
12743 *(TCHAR*)( (uint8_t*) buffer + size ) = _T('\0');
\r
12744 _fputts( buffer, OutputStream ); IF(ferror(OutputStream)){e=E_ERRNO; goto fin;}
\r
12749 p = (const TCHAR*)( (uint8_t*) p + size );
\r
12759 /***********************************************************************
\r
12760 * Function: OpenConsole
\r
12763 * out_IsExistOrNewConsole - NULL is permitted
\r
12764 ************************************************************************/
\r
12765 errnum_t OpenConsole( bool in_OpenIfNoConsole, bool* out_IsExistOrNewConsole )
\r
12770 HANDLE stdout_handle;
\r
12771 int stdout_file_descriptor;
\r
12772 FILE* stdout_stream;
\r
12774 PROCESSENTRY32 current_process;
\r
12776 current_process.dwSize = sizeof( current_process );
\r
12777 e= GetProcessInformation( GetCurrentProcessId(), /*Set*/ ¤t_process ); IF(e){goto fin;}
\r
12780 is_console = (bool) AttachConsole( current_process.th32ParentProcessID );
\r
12782 if ( out_IsExistOrNewConsole != NULL ) {
\r
12783 if ( in_OpenIfNoConsole ) {
\r
12784 *out_IsExistOrNewConsole = ! is_console; /* is new console */
\r
12786 *out_IsExistOrNewConsole = is_console; /* is exist console */
\r
12790 if ( ! is_console ) {
\r
12791 if ( in_OpenIfNoConsole ) {
\r
12793 b= AllocConsole();
\r
12796 { e=0; goto fin; }
\r
12797 IF(!b) { e=E_OTHERS; goto fin; }
\r
12800 stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
\r
12801 IF ( stdout_handle == NULL ) { e=E_OTHERS; goto fin; }
\r
12802 stdout_file_descriptor = _open_osfhandle( (intptr_t) stdout_handle, _O_TEXT );
\r
12803 stdout_stream = _fdopen( stdout_file_descriptor, "w" );
\r
12804 setvbuf( stdout_stream, NULL, _IONBF, 0 );
\r
12806 *stdout = *stdout_stream;
\r
12815 /*=================================================================*/
\r
12816 /* <<< [Lock_1/Lock_1.c] >>> */
\r
12817 /*=================================================================*/
\r
12819 /*-------------------------------------------------------------------------*/
\r
12820 /* <<<< ### (SingletonInitializerClass) implement >>>> */
\r
12821 /*-------------------------------------------------------------------------*/
\r
12824 volatile int g_SingletonInitializerClass_FailSleepTime = SingletonInitializerClass_FailSleepTime;
\r
12827 /*[SingletonInitializerClass_isFirst]*/
\r
12828 bool SingletonInitializerClass_isFirst( SingletonInitializerClass* self )
\r
12831 if ( InterlockedCompareExchange( &self->InitializeStep, 1, 0 ) == 0 ) {
\r
12835 while ( self->InitializeStep == 1 ) {
\r
12836 Sleep( 0 ); /* Wait for initialized by other thread. */
\r
12839 if ( self->InitializeStep == 2 ) {
\r
12843 Sleep( g_SingletonInitializerClass_FailSleepTime );
\r
12844 g_SingletonInitializerClass_FailSleepTime = 0;
\r
12850 /*[SingletonInitializerClass_onFinishedInitialize]*/
\r
12851 void SingletonInitializerClass_onFinishedInitialize( SingletonInitializerClass* self, errnum_t e )
\r
12854 { self->InitializeStep = 2; }
\r
12856 { self->InitializeStep = 0; }
\r
12860 /*[SingletonInitializerClass_isInitialized]*/
\r
12861 bool SingletonInitializerClass_isInitialized( SingletonInitializerClass* self )
\r
12863 return ( self->InitializeStep == 2 );
\r
12867 /*-------------------------------------------------------------------------*/
\r
12868 /* <<< End of Class implement >>> */
\r
12869 /*-------------------------------------------------------------------------*/
\r
12873 /*=================================================================*/
\r
12874 /* <<< [CRT_plus_1/CRT_plus_1.c] >>> */
\r
12875 /*=================================================================*/
\r
12877 /***********************************************************************
\r
12878 <<< [ttoi_ex] >>>
\r
12879 ************************************************************************/
\r
12880 int ttoi_ex( const TCHAR* string, bit_flags_fast32_t options )
\r
12882 int return_value;
\r
12884 UNREFERENCED_VARIABLE( options);
\r
12886 if ( string[0] == _T('0') &&
\r
12887 ( string[1] == _T('x') || string[1] == _T('X') ) )
\r
12889 return_value = (int) _tcstoul( &string[2], NULL, 16 );
\r
12892 return_value = _ttoi( string );
\r
12895 return return_value;
\r
12900 /***********************************************************************
\r
12901 <<< (ClassID_Class) >>>
\r
12902 ************************************************************************/
\r
12904 /*[ClassID_Class_isSuperClass]*/
\r
12905 bool ClassID_Class_isSuperClass( const ClassID_Class* ClassID, const ClassID_Class* SuperClassID )
\r
12907 if ( ClassID == SuperClassID ) {
\r
12913 for ( i = ClassID->SuperClassID_Array_Count - 1; i >= 0; i -= 1 ) {
\r
12914 if ( ClassID->SuperClassID_Array[ i ] == SuperClassID ) {
\r
12923 /*[ClassID_Class_createObject]*/
\r
12924 errnum_t ClassID_Class_createObject( const ClassID_Class* ClassID, void* out_Object, void* Parameter )
\r
12927 ClassID_SuperClass* object = NULL;
\r
12929 e= HeapMemory_allocateBytes( &object, ClassID->Size ); IF(e){goto fin;}
\r
12930 if ( ClassID->InitializeFunction != NULL ) {
\r
12931 e= ClassID->InitializeFunction( object, Parameter ); IF(e){goto fin;}
\r
12934 memset( object, 0, ClassID->Size );
\r
12935 object->ClassID = ClassID;
\r
12937 *(void**) out_Object = object;
\r
12942 if ( object != NULL ) { e= HeapMemory_free( &object, e ); }
\r
12947 /*[ClassID_Class_getVTable]*/
\r
12948 void* ClassID_Class_getVTable( const ClassID_Class* ClassID, const InterfaceID_Class* InterfaceID )
\r
12952 for ( i = ClassID->InterfaceToVTable_Array_Conut - 1; i >= 0; i -= 1 ) {
\r
12953 if ( ClassID->InterfaceToVTable_Array[ i ].InterfaceID == InterfaceID ) {
\r
12954 return (void*) ClassID->InterfaceToVTable_Array[ i ].VTable;
\r
12962 /***********************************************************************
\r
12963 <<< (ClassID_SuperClass) >>>
\r
12964 ************************************************************************/
\r
12966 /*[g_ClassID_SuperClass_ID]*/
\r
12967 const ClassID_Class g_ClassID_SuperClass_ID = {
\r
12968 "ClassID_SuperClass", /* /ClassName */
\r
12969 NULL, /* .SuperClassID_Array */
\r
12970 0, /* .SuperClassID_Array_Count */
\r
12971 sizeof( ClassID_SuperClass ), /* .Size */
\r
12972 NULL, /* .InitializeFunction */
\r
12973 NULL, /* .InterfaceToVTable_Array */
\r
12974 0 /* .InterfaceToVTable_Array_Conut */
\r
12979 /***********************************************************************
\r
12980 <<< (g_FinalizerInterface_ID) >>>
\r
12981 ************************************************************************/
\r
12983 const InterfaceID_Class g_FinalizerInterface_ID = { "FinalizerInterface" };
\r
12987 /***********************************************************************
\r
12988 <<< (g_PrintXML_Interface_ID) >>>
\r
12989 ************************************************************************/
\r
12991 const InterfaceID_Class g_PrintXML_Interface_ID = { "PrintXML_Interface" };
\r
12995 /***********************************************************************
\r
12996 <<< [malloc_redirected] >>>
\r
12997 ************************************************************************/
\r
12999 void* malloc_redirected( size_t in_Size )
\r
13001 void* address = malloc( in_Size );
\r
13004 HeapLogClass_log( address, in_Size ); /*(HeapLogClass_log in malloc_redirected)*/
\r
13005 /*
\8fã
\8bL malloc
\82Æ
\82Í
\95Ê
\82É
\81A
\82±
\82±
\82Ì
\93à
\95\94\82Å realloc
\82·
\82é
\82±
\82Æ
\82ª
\82 \82è
\82Ü
\82·
\81B */
\r
13009 } /*(end_of_malloc_redirected)*/
\r
13010 #define malloc malloc_redirected
\r
13014 /***********************************************************************
\r
13015 <<< [realloc_redirected] >>>
\r
13016 ************************************************************************/
\r
13018 void* realloc_redirected( void* in_Address, size_t in_Size )
\r
13020 void* address = realloc( in_Address, in_Size );
\r
13023 HeapLogClass_log( address, in_Size ); /*(HeapLogClass_log in realloc_redirected)*/
\r
13024 /*
\8fã
\8bL realloc
\82Æ
\82Í
\95Ê
\82É
\81A
\82±
\82±
\82Ì
\93à
\95\94\82Å realloc
\82·
\82é
\82±
\82Æ
\82ª
\82 \82è
\82Ü
\82·
\81B */
\r
13028 } /*(end_of_realloc_redirected)*/
\r
13029 #define realloc realloc_redirected
\r
13033 /***********************************************************************
\r
13034 <<< [calloc_redirected] >>>
\r
13035 ************************************************************************/
\r
13037 void* calloc_redirected( size_t in_Count, size_t in_Size )
\r
13039 void* address = calloc( in_Count, in_Size );
\r
13041 HeapLogClass_log( address, in_Size ); /*(HeapLogClass_log in calloc_redirected)*/
\r
13044 } /*(end_of_calloc_redirected)*/
\r
13045 #define calloc calloc_redirected
\r
13049 /***********************************************************************
\r
13050 <<< [malloc_no_redirected] >>>
\r
13051 ************************************************************************/
\r
13053 void* malloc_no_redirected( size_t in_Size )
\r
13055 return malloc( in_Size );
\r
13057 #define malloc malloc_redirected
\r
13061 /***********************************************************************
\r
13062 <<< [realloc_no_redirected] >>>
\r
13063 ************************************************************************/
\r
13065 void* realloc_no_redirected( void* in_Address, size_t in_Size )
\r
13067 return realloc( in_Address, in_Size );
\r
13069 #define realloc realloc_redirected
\r
13073 /***********************************************************************
\r
13074 <<< [calloc_no_redirected] >>>
\r
13075 ************************************************************************/
\r
13077 void* calloc_no_redirected( size_t in_Count, size_t in_Size )
\r
13079 return calloc( in_Count, in_Size );
\r
13081 #define calloc calloc_redirected
\r