+/* Character Code Encoding: "WHITE SQUARE" is \81 */\r
/* The source file was composed by module mixer */ \r
\r
#include "include_c.h"\r
************************************************************************/\r
int Globals_finalize( int e )\r
{\r
+ HeapLogClass_finalize();\r
e= AppKey_finishGlobal( e ); \r
\r
return e;\r
\r
\r
/***********************************************************************\r
+* Function: GetProcessInformation\r
+************************************************************************/\r
+errnum_t GetProcessInformation( DWORD in_ProcessID, PROCESSENTRY32* out_Info )\r
+{\r
+ errnum_t e;\r
+ BOOL b;\r
+ HANDLE snapshot = (HANDLE) -1;\r
+\r
+ snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );\r
+ IF ( snapshot == (HANDLE) -1 ) { e=E_OTHERS; goto fin; }\r
+ b= Process32First( snapshot, /*Set*/ out_Info );\r
+ IF (!b) { e=E_OTHERS; goto fin; }\r
+ for (;;) {\r
+ if ( out_Info->th32ProcessID == in_ProcessID ) {\r
+ break;\r
+ }\r
+ b= Process32Next( snapshot, /*Set*/ out_Info );\r
+ IF (!b) { e=E_OTHERS; goto fin; }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( snapshot != (HANDLE) -1 ) { CloseHandle( snapshot ); }\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
<<< [env_part] >>> \r
************************************************************************/\r
int env_part( TCHAR* Str, unsigned StrSize, TCHAR* StrStart, TCHAR** out_StrLast,\r
\r
//=== p, o \82ð\8dX\90V\82·\82é\r
p = p2 + 1;\r
- o = _tcschr( o, _T('\0') );\r
+ o = StrT_chr( o, _T('\0') );\r
}\r
}\r
else {\r
/*=================================================================*/\r
\r
/***********************************************************************\r
- <<< [Parse_PP_Directive] >>> \r
+ <<< [g_NaturalDocsKeywords] >>> \r
************************************************************************/\r
-\r
-errnum_t Parse_PP_Directive_Step1( const TCHAR* Text, Set2* DirectivePointerArray );\r
-errnum_t Parse_PP_Directive_ConnectIf( Set2* DirectivePointerArray );\r
-errnum_t Parse_PP_Directive_Parameter( Set2* DirectivePointerArray );\r
+TCHAR* g_NaturalDocsKeywords[] = {\r
+\r
+ /*===========================================================*/\r
+ /* General Topics */\r
+ /* Generic */\r
+ _T("topic"), _T("topics"), _T("about"), _T("list"),\r
+\r
+ /* Section (Ends Scope) */\r
+ _T("section"), _T("title"),\r
+\r
+ /* Group */\r
+ _T("group"),\r
+\r
+ /* File (Always Global) */\r
+ _T("file"), _T("files"), _T("program"), _T("programs"), _T("script"), _T("scripts"),\r
+ _T("document"), _T("documents"), _T("doc"), _T("docs"), _T("header"), _T("headers"),\r
+\r
+ /*===========================================================*/\r
+ /* Code Topics */\r
+ /* Class (Starts Scope) */\r
+ _T("class"), _T("classes"), _T("structure"), _T("structures"), _T("struct"), _T("structs"),\r
+ _T("package"), _T("packages"), _T("namespace"), _T("namespaces"),\r
+\r
+ /* Interface (Starts Scope) */\r
+ _T("interface"), _T("interfaces"),\r
+\r
+ /* Type */\r
+ _T("type"), _T("types"), _T("typedef"), _T("typedefs"),\r
+\r
+ /* Constant */\r
+ _T("constant"), _T("constants"), _T("const"), _T("consts"),\r
+\r
+ /* Enumeration (Topic indexed under Types Members indexed under Constants) */\r
+ _T("enumeration"), _T("enumerations"), _T("enum"), _T("enums"),\r
+\r
+ /* Function (List topics break apart) */\r
+ _T("function"), _T("functions"), _T("func"), _T("funcs"),\r
+ _T("procedure"), _T("procedures"), _T("proc"), _T("procs"),\r
+ _T("routine"), _T("routines"), _T("subroutine"), _T("subroutines"),\r
+ _T("sub"), _T("subs"), _T("method"), _T("methods"),\r
+ _T("callback"), _T("callbacks"), _T("constructor"), _T("constructors"),\r
+ _T("destructor"), _T("destructors"), _T("operator"), _T("operators"),\r
+\r
+ /* Property */\r
+ _T("property"), _T("properties"), _T("prop"), _T("props"),\r
+\r
+ /* Event */\r
+ _T("event"), _T("events"),\r
+\r
+ /* Delegate */\r
+ _T("delegate"), _T("delegates"),\r
+\r
+ /* Macro */\r
+ _T("macro"), _T("macros"),\r
+ _T("define"), _T("defines"), _T("def"), _T("defs"),\r
+\r
+ /* Variable */\r
+ _T("variable"), _T("variables"), _T("var"), _T("vars"),\r
+ _T("integer"), _T("integers"), _T("int"), _T("ints"),\r
+ _T("uint"), _T("uints"), _T("long"), _T("longs"),\r
+ _T("ulong"), _T("ulongs"), _T("short"), _T("shorts"),\r
+ _T("ushort"), _T("ushorts"), _T("byte"), _T("bytes"),\r
+ _T("ubyte"), _T("ubytes"), _T("sbyte"), _T("sbytes"),\r
+ _T("float"), _T("floats"), _T("double"), _T("doubles"),\r
+ _T("real"), _T("reals"), _T("decimal"), _T("decimals"),\r
+ _T("scalar"), _T("scalars"), _T("array"), _T("arrays"),\r
+ _T("arrayref"), _T("arrayrefs"), _T("hash"), _T("hashes"),\r
+ _T("hashref"), _T("hashrefs"), _T("bool"), _T("bools"),\r
+ _T("boolean"), _T("booleans"), _T("flag"), _T("flags"),\r
+ _T("bit"), _T("bits"), _T("bitfield"), _T("bitfields"),\r
+ _T("field"), _T("fields"), _T("pointer"), _T("pointers"),\r
+ _T("ptr"), _T("ptrs"), _T("reference"), _T("references"),\r
+ _T("ref"), _T("refs"), _T("object"), _T("objects"),\r
+ _T("obj"), _T("objs"), _T("character"), _T("characters"),\r
+ _T("wcharacter"), _T("wcharacters"), _T("char"), _T("chars"),\r
+ _T("wchar"), _T("wchars"), _T("string"), _T("strings"),\r
+ _T("wstring"), _T("wstrings"), _T("str"), _T("strs"),\r
+ _T("wstr"), _T("wstrs"), _T("handle"), _T("handles"),\r
+\r
+ /*===========================================================*/\r
+ /* Database Topics */\r
+ /* Database */\r
+ _T("database"), _T("databases"), _T("db"), _T("dbs"),\r
+\r
+ /* Database Table (Starts Scope) */\r
+ _T("table"), _T("tables"),\r
+ _T("database table"), _T("database tables"), _T("db table"), _T("db tables"),\r
+\r
+ /* Database View (Starts Scope) */\r
+ _T("view"), _T("views"),\r
+ _T("database view"), _T("database views"), _T("db view"), _T("db views"),\r
+\r
+ /* Database Cursor */\r
+ _T("cursor"), _T("cursors"),\r
+ _T("database cursor"), _T("database cursors"), _T("db cursor"), _T("db cursors"),\r
+\r
+ /* Database Index */\r
+ _T("index"), _T("indexes"), _T("indices"),\r
+ _T("database index"), _T("database indexes"), _T("database indices"),\r
+ _T("db index"), _T("db indexes"), _T("db indices"),\r
+ _T("key"), _T("keys"),\r
+ _T("database key"), _T("database keys"), _T("db key"), _T("db keys"),\r
+ _T("primary key"), _T("primary keys"),\r
+ _T("database primary key"), _T("database primary keys"),\r
+ _T("db primary key"), _T("db primary keys"),\r
+\r
+ /* Database Trigger */\r
+ _T("trigger"), _T("triggers"),\r
+ _T("database trigger"), _T("database triggers"), _T("db trigger"), _T("db triggers"),\r
+\r
+ /*===========================================================*/\r
+ /* Miscellaneous Topics */\r
+ /* Cookie (Always global) */\r
+ _T("cookie"), _T("cookies"),\r
+\r
+ /* Build Target */\r
+ _T("target"), _T("targets"),\r
+ _T("build target"), _T("build targets"),\r
+};\r
\r
\r
-errnum_t Parse_PP_Directive( const TCHAR* Text,\r
- Set2* /*<PP_DirectiveClass*>*/ DirectivePointerArray )\r
+ \r
+/***********************************************************************\r
+ <<< [NaturalDocsHeaderClass_initConst] >>> \r
+************************************************************************/\r
+void NaturalDocsHeaderClass_initConst( NaturalDocsHeaderClass* self )\r
{\r
- errnum_t e;\r
-\r
- e= Parse_PP_Directive_Step1( Text, DirectivePointerArray ); IF(e){goto fin;}\r
- e= Parse_PP_Directive_ConnectIf( DirectivePointerArray ); IF(e){goto fin;}\r
- e= Parse_PP_Directive_Parameter( DirectivePointerArray ); IF(e){goto fin;}\r
-\r
- e=0;\r
-fin:\r
- return e;\r
+ self->Keyword = NULL;\r
+ self->Name = NULL;\r
+ self->Brief = NULL;\r
+ Set2_initConst( &self->Arguments );\r
+ self->ReturnValue = NULL;\r
+ self->Descriptions = NULL;\r
+ Set2_initConst( &self->DescriptionItems );\r
}\r
\r
\r
-/*[Parse_PP_Directive_Step1]*/\r
-errnum_t Parse_PP_Directive_Step1( const TCHAR* Text, Set2* DirectivePointerArray )\r
+ \r
+/***********************************************************************\r
+ <<< [NaturalDocsHeaderClass_finalize] >>> \r
+************************************************************************/\r
+errnum_t NaturalDocsHeaderClass_finalize( NaturalDocsHeaderClass* self, errnum_t e )\r
{\r
- errnum_t e;\r
- const TCHAR* pos;\r
- const TCHAR* p;\r
- PP_DirectiveClass* directive = NULL;\r
- PP_DirectiveClass directive_0;\r
- PP_DirectiveClass** directive_pp;\r
- ClassID_Class* class_ID;\r
+ Set2_IteratorClass iterator;\r
+ NaturalDocsDefinitionClass* p1;\r
+ NaturalDocsDescriptionClass* p2;\r
\r
- pos = Text;\r
- PP_DirectiveClass_initConst( &directive_0 );\r
\r
- for (;;) {\r
+ e= HeapMemory_free( &self->Keyword, e );\r
+ e= HeapMemory_free( &self->Name, e );\r
+ e= HeapMemory_free( &self->Brief, e );\r
\r
- /* Set "DirectiveName_Start" */\r
- p = _tcschr( pos, _T('#') );\r
- if ( p == NULL )\r
- { break; }\r
- p = StrT_skip( p + 1, _T(" \t") );\r
- ASSERT_R( *p != _T('\0'), e=E_OTHERS; goto fin );\r
- directive_0.DirectiveName_Start = p;\r
+ for ( Set2_forEach2( &self->Arguments, &iterator, &p1 ) ) {\r
+ e= NaturalDocsDefinitionClass_finalize( p1, e );\r
+ }\r
+ e= Set2_finish( &self->Arguments, e );\r
\r
+ e= HeapMemory_free( &self->ReturnValue, e );\r
+ e= HeapMemory_free( &self->Descriptions, e );\r
\r
- /* Set "DirectiveName_Over" */\r
- directive_0.DirectiveName_Over =\r
- StrT_searchOverOfCIdentifier( directive_0.DirectiveName_Start );\r
+ for ( Set2_forEach2( &self->DescriptionItems, &iterator, &p2 ) ) {\r
+ e= NaturalDocsDescriptionClass_finalize( p2, e );\r
+ }\r
+ e= Set2_finish( &self->DescriptionItems, e );\r
\r
+ return e;\r
+}\r
\r
- /* Set "Start" */\r
- p = StrT_rstr( Text, directive_0.DirectiveName_Start, _T("\n"), NULL );\r
- if ( p == NULL ) { p = Text; }\r
- else { p += 1; }\r
- directive_0.Start = p;\r
\r
+ \r
+/***********************************************************************\r
+ <<< [NaturalDocsDefinitionClass_initConst] >>> \r
+************************************************************************/\r
+void NaturalDocsDefinitionClass_initConst( NaturalDocsDefinitionClass* self )\r
+{\r
+ self->Name = NULL;\r
+ self->Brief = NULL;\r
+}\r
\r
- /* Set "Over" */\r
- p = directive_0.DirectiveName_Over;\r
- for (;;) {\r
- const TCHAR* p2 = _tcschr( p, _T('\n') );\r
- if ( p2 == NULL ) {\r
- p = _tcschr( p, _T('\0') );\r
- break;\r
- } else if ( *( p2 - 1 ) == _T('\\') ) {\r
- p = p2 + 1;\r
- continue;\r
- } else {\r
- p = p2 + 1;\r
- break;\r
- }\r
- }\r
- directive_0.Over = p;\r
\r
+ \r
+/***********************************************************************\r
+ <<< [NaturalDocsDefinitionClass_finalize] >>> \r
+************************************************************************/\r
+errnum_t NaturalDocsDefinitionClass_finalize( NaturalDocsDefinitionClass* self, errnum_t e )\r
+{\r
+ e= HeapMemory_free( &self->Name, e );\r
+ e= HeapMemory_free( &self->Brief, e );\r
+ return e;\r
+}\r
\r
- /* Set "directive" */\r
- {\r
- static NameOnlyClass table[] = {\r
- { _T("define"), (void*) &g_PP_SharpDefineClass_ID },\r
- { _T("include"),(void*) &g_PP_SharpIncludeClass_ID },\r
- { _T("if"), (void*) &g_PP_SharpIfClass_ID },\r
- { _T("else"), (void*) &g_PP_SharpElseClass_ID },\r
- { _T("endif"), (void*) &g_PP_SharpEndifClass_ID },\r
- { _T("ifdef"), (void*) &g_PP_SharpIfdefClass_ID },\r
- { _T("ifndef"), (void*) &g_PP_SharpIfndefClass_ID },\r
- };\r
\r
- class_ID = StrT_convPartStrToPointer(\r
- directive_0.DirectiveName_Start,\r
- directive_0.DirectiveName_Over,\r
- table, sizeof(table), (void*) &g_PP_DirectiveClass_ID );\r
- }\r
+ \r
+/***********************************************************************\r
+ <<< [NaturalDocsDescriptionTypeEnum_to_String] >>> \r
+************************************************************************/\r
\r
- e= ClassID_Class_createObject( class_ID, &directive, NULL ); IF(e){goto fin;}\r
+static const TCHAR* gs_NaturalDocsDescriptionTypeEnum_to_String[ NaturalDocsDescriptionType_Count ] = {\r
+ _T("Unknown"), _T("SubTitle"), _T("Paragraph"), _T("Code")\r
+};\r
+static_assert_global( NaturalDocsDescriptionType_Unknown == 0, "" );\r
+static_assert_global( NaturalDocsDescriptionType_SubTitle == 1, "" );\r
+static_assert_global( NaturalDocsDescriptionType_Paragraph == 2, "" );\r
+static_assert_global( NaturalDocsDescriptionType_Code == 3, "" );\r
\r
- directive->DirectiveName_Start = directive_0.DirectiveName_Start;\r
- directive->DirectiveName_Over = directive_0.DirectiveName_Over;\r
- directive->Start = directive_0.Start;\r
- directive->Over = directive_0.Over;\r
+const TCHAR* NaturalDocsDescriptionTypeEnum_to_String( int in, const TCHAR* in_OutOfRange )\r
+{\r
+ const TCHAR* ret;\r
\r
+ if ( in >= NaturalDocsDescriptionType_Unknown && in < NaturalDocsDescriptionType_Count )\r
+ { ret = gs_NaturalDocsDescriptionTypeEnum_to_String[ in - NaturalDocsDescriptionType_Unknown ]; }\r
+ else\r
+ { ret = in_OutOfRange; }\r
\r
- /* Add to "DirectivePointerArray" (1) */\r
- e= Set2_alloc( DirectivePointerArray, &directive_pp, PP_DirectiveClass* );\r
- IF(e){goto fin;}\r
+ return ret;\r
+}\r
\r
\r
- /* Add to "DirectivePointerArray" (2) */\r
- *directive_pp = directive;\r
- directive = NULL;\r
+ \r
+/***********************************************************************\r
+ <<< [NaturalDocsDescriptionClass_initConst] >>> \r
+************************************************************************/\r
+void NaturalDocsDescriptionClass_initConst( NaturalDocsDescriptionClass* self )\r
+{\r
+ self->Type = NaturalDocsDescriptionType_Unknown;\r
+ self->Start = NULL;\r
+ self->Over = NULL;\r
+ self->u.Unknown = NULL;\r
+}\r
\r
\r
- /* Next */\r
- pos = directive_0.Over;\r
- PP_DirectiveClass_initConst( &directive_0 );\r
+ \r
+/***********************************************************************\r
+ <<< [NaturalDocsDescriptionClass_finalize] >>> \r
+************************************************************************/\r
+errnum_t NaturalDocsDescriptionClass_finalize( NaturalDocsDescriptionClass* self, errnum_t e )\r
+{\r
+ if ( self->Type == NaturalDocsDescriptionType_DefinitionList ) {\r
+ if ( self->u.Definition != NULL )\r
+ { e= NaturalDocsDefinitionClass_finalize( self->u.Definition, e ); }\r
+ e= HeapMemory_free( &self->u.Definition, e );\r
}\r
+ self->Type = NaturalDocsDescriptionType_Unknown;\r
\r
- e=0;\r
-fin:\r
- if ( directive != NULL ) { e= HeapMemory_free( &directive, e ); }\r
return e;\r
}\r
\r
\r
-/*[Parse_PP_Directive_ConnectIf]*/\r
-errnum_t Parse_PP_Directive_ConnectIf( Set2* DirectivePointerArray )\r
+ \r
+/***********************************************************************\r
+ <<< [ParseNaturalDocsComment] >>> \r
+- HeapMemory_free( out_NaturalDocsHeader );\r
+************************************************************************/\r
+\r
+void ParseNaturalDocsLine( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,\r
+ const TCHAR** out_LineStart, const TCHAR** out_LineOver );\r
+void ParseNaturalDocsDefinitionList( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,\r
+ const TCHAR** out_NameStart, const TCHAR** out_NameOver,\r
+ const TCHAR** out_BriefStart, const TCHAR** out_BriefOver, bool in_IsSkipFirstLine );\r
+\r
+\r
+errnum_t ParseNaturalDocsComment( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,\r
+ NaturalDocsHeaderClass** out_NaturalDocsHeader, NaturalDocsParserConfigClass* config )\r
{\r
- errnum_t e;\r
- PP_DirectiveClass** pp;\r
- PP_DirectiveClass** pp_over;\r
- PP_DirectiveClass* directive;\r
- PP_SharpIfClass** pp_sh_if; /* pp is pointer of pointer, sh = sharp */\r
- PP_SharpElseClass** pp_sh_else;\r
- Set2 if_stack;\r
- Set2 else_stack;\r
- PP_SharpIfClass* sh_if; /* sh = sharp */\r
- PP_SharpElseClass* sh_else; /* sh = sharp */\r
- PP_SharpEndifClass* sh_endif; /* sh = sharp */\r
- PP_DirectiveClass* sh_if_or_else; /* sh = sharp */\r
+ errnum_t e;\r
+ const TCHAR* p;\r
+ const TCHAR* p_over;\r
+ int step_num;\r
+ bool is_found = false;\r
+ const TCHAR* descriptions = NULL;\r
\r
+ NaturalDocsHeaderClass* header = NULL;\r
+ NaturalDocsDefinitionClass* definition_a = NULL; /* a = for Argument */\r
+ NaturalDocsDefinitionClass* definition_p = NULL; /* p = for in Paragraph */\r
+ NaturalDocsDescriptionClass* description = NULL;\r
\r
- Set2_initConst( &if_stack );\r
- Set2_initConst( &else_stack );\r
- e= Set2_init( &if_stack, 0x10 ); IF(e){goto fin;}\r
- e= Set2_init( &else_stack, 0x10 ); IF(e){goto fin;}\r
- sh_if = NULL;\r
- sh_else = NULL;\r
- sh_endif = NULL;\r
- sh_if_or_else = NULL;\r
+ e= HeapMemory_allocate( &header ); IF(e){goto fin;}\r
+ NaturalDocsHeaderClass_initConst( header );\r
+ e= Set2_init( &header->Arguments, 0x10 ); IF(e){goto fin;}\r
+ e= Set2_init( &header->DescriptionItems, 0x40 ); IF(e){goto fin;}\r
\r
- for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {\r
- directive = *pp;\r
\r
- if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfClass_ID ) ) {\r
+ /* Parse keyword */\r
+ step_num = 0;\r
+ for ( p = in_SourceStart; p < in_SourceOver; p += 1 ) {\r
+ if ( ! StrT_isCIdentifier( *p ) ) { continue; }\r
\r
- /* Start of nest */\r
- if ( sh_if_or_else != NULL ) {\r
- e= Set2_alloc( &if_stack, &pp_sh_if, PP_SharpIfClass* );\r
- IF(e){goto fin;}\r
- *pp_sh_if = sh_if;\r
+ if ( step_num == 0 ) {\r
+ p_over = StrT_searchOverOfIdiom( p );\r
\r
- e= Set2_alloc( &else_stack, &pp_sh_else, PP_SharpElseClass* );\r
- IF(e){goto fin;}\r
- *pp_sh_else = sh_else;\r
+ if ( *p_over != _T(':') ) {\r
+ break; /* This comment is not parsed */\r
+ }\r
+ if ( StrT_searchPartStringIndexI( p, p_over,\r
+ g_NaturalDocsKeywords, _countof(g_NaturalDocsKeywords),\r
+ NOT_FOUND_INDEX )\r
+ == NOT_FOUND_INDEX )\r
+ {\r
+ if ( StrT_searchPartStringIndexI( p, p_over,\r
+ config->AdditionalKeywords, config->AdditionalKeywordsLength,\r
+ NOT_FOUND_INDEX )\r
+ == NOT_FOUND_INDEX )\r
+ {\r
+ break; /* This comment is not parsed */\r
+ }\r
}\r
\r
- /* Set "sh_if" */\r
- sh_if = (PP_SharpIfClass*) directive;\r
- sh_if_or_else = directive;\r
+ e= MallocAndCopyStringByLength( &header->Keyword, p, p_over - p );\r
+ IF(e){goto fin;}\r
+ header->KeywordStart = p;\r
+ header->KeywordOver = p_over;\r
+ p = p_over;\r
}\r
- else if ( directive->ClassID == &g_PP_SharpElseClass_ID ) {\r
- sh_else = (PP_SharpElseClass*) directive;\r
-\r
- IF ( sh_if == NULL ) {\r
- Error4_printf( _T("<ERROR msg=\"Not found #if\"/>") );\r
- e= E_ORIGINAL; goto fin;\r
+ else if ( step_num == 1 ) {\r
+ TCHAR* name = NULL;\r
+\r
+ p_over = StrT_chrs( p, _T("\r\n") );\r
+ ASSERT_R( p_over != NULL, e=E_OTHERS; goto fin );\r
+ if ( p_over >= p + 2 ) {\r
+ if ( p_over[-2] == _T('*') && p_over[-1] == _T('/') )\r
+ { p_over -= 2; }\r
}\r
+ p_over = StrT_rskip( p, p_over - 1, _T(" \t"), NULL );\r
+ ASSERT_R( p_over != NULL, e=E_OTHERS; goto fin );\r
+ p_over += 1;\r
\r
- /* Link #if and #else */\r
- sh_if->NextDirective = directive;\r
- sh_else->StartDirective = sh_if;\r
- sh_if_or_else = directive;\r
+ e= MallocAndCopyStringByLength( &name, p, p_over - p );\r
+ IF(e){goto fin;}\r
+ e= StrT_trim( name, sizeof(TCHAR) * ( _tcslen( name ) + 1 ), name );\r
+ IF(e){goto fin;}\r
+ header->Name = name;\r
+ header->NameStart = p;\r
+ header->NameOver = p_over;\r
+ is_found = true;\r
+ break;\r
}\r
- else if ( directive->ClassID == &g_PP_SharpEndifClass_ID ) {\r
- sh_endif = (PP_SharpEndifClass*) directive;\r
+ step_num += 1;\r
+ }\r
\r
- IF ( sh_if_or_else == NULL ) {\r
- Error4_printf( _T("<ERROR msg=\"Not found #if\"/>") );\r
- e= E_ORIGINAL; goto fin;\r
- }\r
+ if ( header->Keyword != NULL && header->Name == NULL ) {\r
+ e= MallocAndCopyString( &header->Name, _T("") );\r
+ IF(e){goto fin;}\r
+ is_found = true;\r
+ }\r
\r
- /* Link ( #if or #else ) and #endif */\r
- sh_if->EndDirective = sh_endif;\r
- if ( sh_else == NULL )\r
- { sh_if->NextDirective = directive; }\r
- else\r
- { sh_else->EndDirective = sh_endif; }\r
- sh_endif->StartDirective = sh_if;\r
- sh_endif->PreviousDirective = sh_if_or_else;\r
\r
- sh_if = NULL;\r
- sh_else = NULL;\r
- sh_endif = NULL;\r
- sh_if_or_else = NULL;\r
+ /* Parse 2nd line */\r
+ ParseNaturalDocsLine( p, in_SourceOver, &p, &p_over );\r
+ if ( p_over >= in_SourceOver ) {\r
+ p = in_SourceOver;\r
+ }\r
+ else if ( p == NULL ) {\r
+ p = p_over;\r
+ descriptions = p_over;\r
+ }\r
+ else {\r
+ e= MallocAndCopyStringByLength( &header->Brief, p, p_over - p );\r
+ IF(e){goto fin;}\r
+ header->BriefStart = p;\r
+ header->BriefOver = p_over;\r
\r
- /* End of nest */\r
- if ( if_stack.Next > if_stack.First ) {\r
- e= Set2_pop( &if_stack, &pp_sh_if, PP_SharpIfClass* );\r
- IF(e){goto fin;}\r
- sh_if = *pp_sh_if;\r
+ p = StrT_rskip( in_SourceStart, p - 1, _T(" \t"), NULL );\r
+ IF ( p == NULL ) { e=E_OTHERS; goto fin; }\r
+ header->BriefNoIndent = p + 2;\r
\r
- e= Set2_pop( &else_stack, &pp_sh_else, PP_SharpElseClass* );\r
- IF(e){goto fin;}\r
- sh_else = *pp_sh_else;\r
+ p = p_over;\r
\r
- if ( sh_else == NULL ) {\r
- sh_if_or_else = (PP_DirectiveClass*) sh_if;\r
- } else {\r
- sh_if_or_else = (PP_DirectiveClass*) sh_else;\r
- }\r
- }\r
- }\r
+ descriptions = p;\r
}\r
\r
- e=0;\r
-fin:\r
- e= Set2_finish( &if_stack, e );\r
- e= Set2_finish( &else_stack, e );\r
- return e;\r
-}\r
\r
+ /* ... */\r
+ for ( /* p */; p < in_SourceOver; p += 1 ) {\r
+ if ( ! StrT_isCIdentifier( *p ) ) { continue; }\r
\r
-/*[Parse_PP_Directive_Parameter]*/\r
-errnum_t Parse_PP_Directive_Parameter( Set2* DirectivePointerArray )\r
-{\r
- errnum_t e;\r
- TCHAR* p;\r
- PP_DirectiveClass** pp;\r
- PP_DirectiveClass** pp_over;\r
- PP_DirectiveClass* directive;\r
+ p_over = StrT_searchOverOfIdiom( p );\r
\r
- for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {\r
- directive = *pp;\r
+ if ( *p_over != _T(':') ) { continue; }\r
\r
- if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpDefineClass_ID ) ) {\r
- PP_SharpDefineClass* sh_define = (PP_SharpDefineClass*) directive;\r
+ /* Parse Argument Label */\r
+ if ( StrT_cmp_i_part( p, p_over, _T("Arguments") ) == 0 ) {\r
+ const TCHAR* p1;\r
+ const TCHAR* p1_over;\r
+ const TCHAR* p2;\r
+ const TCHAR* p2_over;\r
\r
- p = StrT_skip( sh_define->DirectiveName_Over, _T(" \t") );\r
- IF ( p >= sh_define->Over ) { e=E_OTHERS; goto fin; }\r
- sh_define->Symbol_Start = p;\r
+ header->ArgumentsLabel = p;\r
\r
- p = StrT_searchOverOfCIdentifier( p );\r
- sh_define->Symbol_Over = p;\r
+ for (;;) {\r
+ ParseNaturalDocsDefinitionList( p, in_SourceOver,\r
+ &p1, &p1_over, &p2, &p2_over, true );\r
+ if ( p2 == NULL )\r
+ { break; }\r
+\r
+ e= Set2_allocate( &header->Arguments, &definition_a );\r
+ IF(e){goto fin;}\r
+ NaturalDocsDefinitionClass_initConst( definition_a );\r
+\r
+ e= MallocAndCopyStringByLength( &definition_a->Name, p1, p1_over - p1 );\r
+ IF(e){goto fin;}\r
+ definition_a->NameStart = p1;\r
+ definition_a->NameOver = p1_over;\r
+\r
+ e= MallocAndCopyStringByLength( &definition_a->Brief, p2, p2_over - p2 );\r
+ IF(e){goto fin;}\r
+ definition_a->BriefStart = p2;\r
+ definition_a->BriefOver = p2_over;\r
+\r
+ definition_a = NULL;\r
+\r
+ descriptions = p2_over;\r
+\r
+ p = p2_over;\r
+ }\r
}\r
\r
- if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIncludeClass_ID ) ) {\r
- TCHAR* p;\r
- TCHAR* closers;\r
- PP_SharpIncludeClass* sh_include = (PP_SharpIncludeClass*) directive;\r
+ /* Parse Return Value Label */\r
+ else if ( StrT_cmp_i_part( p, p_over, _T("Return Value") ) == 0 ) {\r
\r
- p = StrT_skip( sh_include->DirectiveName_Over, _T(" \t") );\r
- IF ( p >= sh_include->Over ) { e=E_OTHERS; goto fin; }\r
- switch ( *p ) {\r
- case '<':\r
- sh_include->PathBracket = _T('<');\r
- closers = _T(">");\r
- break;\r
+ header->ReturnValueLabel = p;\r
\r
- case '"':\r
- sh_include->PathBracket = _T('"');\r
- closers = _T("\"");\r
- break;\r
+ ParseNaturalDocsLine( p, in_SourceOver, &p, &p_over );\r
+ if ( p == NULL ) {\r
+ p = in_SourceOver;\r
+ ASSERT_D( p_over != NULL, __noop() );\r
+ }\r
+ else {\r
+ e= MallocAndCopyStringByLength( &header->ReturnValue, p, p_over - p );\r
+ IF(e){goto fin;}\r
+ header->ReturnValueStart = p;\r
+ header->ReturnValueOver = p_over;\r
\r
- default:\r
- sh_include->PathBracket = _T('\0');\r
- closers = _T(" \t\n");\r
- break;\r
+ p = p_over;\r
}\r
+ descriptions = p_over;\r
+ }\r
+ }\r
\r
- sh_include->Path_Start = p + 1;\r
\r
- p = StrT_chrs( p + 1, closers );\r
- IF ( p == NULL ) { e=E_OTHERS; goto fin; }\r
- sh_include->Path_Over = p;\r
+ /* Set "header->Descriptions" */\r
+ if ( descriptions != NULL ) {\r
+ const TCHAR* descriptions_over;\r
+\r
+ descriptions_over = StrT_rstr( in_SourceStart, in_SourceOver, _T("\n"), NULL );\r
+ if ( descriptions_over != NULL ) {\r
+ const TCHAR* over2 = StrT_rstr( in_SourceStart, descriptions_over - 1, _T("\n"), NULL );\r
+ const TCHAR* p2;\r
+\r
+ /* If last line was only "*******" Then "descriptions_over = over2". */\r
+ if ( over2 != NULL ) {\r
+ p2 = StrT_skip( over2 + 1, _T("* /\t") );\r
+ IF ( p2 == NULL ) { e=E_OTHERS; goto fin; }\r
+ if ( p2 >= descriptions_over ) {\r
+ descriptions_over = over2;\r
+ }\r
+ }\r
+ }\r
+ if ( descriptions_over != NULL ) {\r
+ const TCHAR* p2;\r
+\r
+ if ( *( descriptions_over - 1 ) == _T('\r') )\r
+ { descriptions_over -= 1; }\r
+\r
+ /* Set "descriptions_over" to before end of comment */\r
+ p2 = StrT_rskip( descriptions, descriptions_over - 1, _T(" \t"), NULL );\r
+ if ( p2 != NULL ) {\r
+ if ( *p2 == _T('/') && *( p2 - 1 ) == _T('*') ) {\r
+ p2 = StrT_rskip( descriptions, p2 - 2, _T(" \t"), NULL );\r
+ if ( p2 == NULL ) {\r
+ descriptions_over = descriptions;\r
+ } else {\r
+ descriptions_over = p2 + 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Set "header" */\r
+ header->DescriptionsStart = descriptions;\r
+ header->DescriptionsOver = descriptions_over;\r
+ e= MallocAndCopyStringByLength( &header->Descriptions,\r
+ descriptions, descriptions_over - descriptions );\r
+ IF(e){goto fin;}\r
}\r
+ }\r
\r
- if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfdefClass_ID ) ) {\r
- TCHAR* p;\r
- PP_SharpIfdefClass* sh_ifdef; /* sh = sharp */\r
\r
- sh_ifdef = (PP_SharpIfdefClass*) directive;\r
+ /* Set "header->DescriptionItems" */\r
+ if ( descriptions != NULL && header->DescriptionsOver != NULL ) {\r
+ const TCHAR* line;\r
+ const TCHAR* p_last;\r
+ const TCHAR* p_line_feed;\r
+ const TCHAR* descriptions_over = header->DescriptionsOver;\r
+ bool is_definition_list;\r
\r
- p = StrT_skip( sh_ifdef->DirectiveName_Over, _T(" \t") );\r
- IF ( p >= sh_ifdef->Over ) { e=E_OTHERS; goto fin; }\r
- sh_ifdef->Symbol_Start = p;\r
+ for (\r
+ line = _tcschr( descriptions, _T('\n') ) + 1;\r
+ line < descriptions_over;\r
+ line = p_line_feed + 1 )\r
+ {\r
+ p_line_feed = _tcschr( line, _T('\n') );\r
\r
- p = StrT_searchOverOfCIdentifier( p );\r
- sh_ifdef->Symbol_Over = p;\r
+\r
+ /* Set "p" : Skip space or "*" */\r
+ for ( p = line; p < p_line_feed; p += 1 ) {\r
+ TCHAR a_char = *p;\r
+\r
+ if ( a_char == ' ' || a_char == '\t' || a_char == '*' )\r
+ { continue; }\r
+ else\r
+ { break; }\r
+ }\r
+\r
+ /* Set "p_last" */\r
+ for ( p_last = p_line_feed - 1; p_last > p; p_last -= 1 ) {\r
+ TCHAR a_char = *p_last;\r
+\r
+ if ( a_char == ' ' || a_char == '\t' || a_char == '\n' )\r
+ { continue; }\r
+ else\r
+ { break; }\r
+ }\r
+\r
+\r
+ /* Set "is_definition_list", "definition_p" */\r
+ {\r
+ const TCHAR* p1;\r
+ const TCHAR* p1_over;\r
+ const TCHAR* p2;\r
+ const TCHAR* p2_over;\r
+\r
+ is_definition_list = false;\r
+ p1 = _tcschr( p, _T('-') );\r
+ p2 = _tcschr( p, _T('\n') );\r
+\r
+\r
+ if ( p1 != NULL && p1 < p2 ) {\r
+\r
+ for ( p1_over = p2 - 1; p1_over > p1; p1_over -= 1 ) {\r
+ if ( ! _istspace( *p1_over ) )\r
+ { break;}\r
+ }\r
+ if ( p1_over == p1 ) {\r
+ p1 = NULL; /* For next if */\r
+ p2_over = NULL; /* For warning C4701 */\r
+ } else {\r
+ ParseNaturalDocsDefinitionList( p, in_SourceOver,\r
+ &p1, &p1_over, &p2, &p2_over, false );\r
+ }\r
+ if ( p1 != NULL && p2 != NULL ) {\r
+ e= HeapMemory_allocate( &definition_p ); IF(e){goto fin;}\r
+ NaturalDocsDefinitionClass_initConst( definition_p );\r
+\r
+ e= MallocAndCopyStringByLength( &definition_p->Name,\r
+ p1, p1_over - p1 );\r
+ IF(e){goto fin;}\r
+ definition_p->NameStart = p1;\r
+ definition_p->NameOver = p1_over;\r
+\r
+ e= MallocAndCopyStringByLength( &definition_p->Brief,\r
+ p2, p2_over - p2 );\r
+ IF(e){goto fin;}\r
+ definition_p->BriefStart = p2;\r
+ definition_p->BriefOver = p2_over;\r
+ is_definition_list = true;\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /* End of Paragraph */\r
+ if ( description != NULL &&\r
+ description->Type == NaturalDocsDescriptionType_Paragraph &&\r
+ p == p_last )\r
+ {\r
+ description = NULL;\r
+ }\r
+\r
+ /* End of Code */\r
+ if ( description != NULL &&\r
+ description->Type == NaturalDocsDescriptionType_Code &&\r
+ *p != _T('>') )\r
+ {\r
+ description = NULL;\r
+ }\r
+\r
+\r
+ /* Add Code */\r
+ if ( *p == _T('>') ) {\r
+ if ( description == NULL ||\r
+ description->Type != NaturalDocsDescriptionType_Code )\r
+ {\r
+ e= Set2_allocate( &header->DescriptionItems, &description );\r
+ IF(e){goto fin;}\r
+ NaturalDocsDescriptionClass_initConst( description );\r
+\r
+ description->Type = NaturalDocsDescriptionType_Code;\r
+ description->Start = line;\r
+ }\r
+ description->Over = p_line_feed + 1;\r
+ }\r
+\r
+ /* Add SubTitle */\r
+ else if ( *p_last == _T(':') ) {\r
+ e= Set2_allocate( &header->DescriptionItems, &description );\r
+ IF(e){goto fin;}\r
+ NaturalDocsDescriptionClass_initConst( description );\r
+\r
+ description->Type = NaturalDocsDescriptionType_SubTitle;\r
+ description->Start = p;\r
+ description->Over = p_last;\r
+\r
+ description = NULL;\r
+ }\r
+\r
+ /* Add DefinitionList */\r
+ else if ( is_definition_list ) {\r
+ e= Set2_allocate( &header->DescriptionItems, &description );\r
+ IF(e){goto fin;}\r
+ NaturalDocsDescriptionClass_initConst( description );\r
+\r
+ description->Type = NaturalDocsDescriptionType_DefinitionList;\r
+ description->Start = line;\r
+ description->Over = p_line_feed + 1;\r
+ description->u.Definition = definition_p;\r
+\r
+ description = NULL;\r
+ definition_p = NULL;\r
+ }\r
+\r
+ /* Add Paragraph */\r
+ else {\r
+ bool is_exist_content = false;\r
+\r
+ if ( description == NULL ||\r
+ description->Type != NaturalDocsDescriptionType_Paragraph )\r
+ {\r
+ const TCHAR* p;\r
+\r
+ for ( p = line; p < p_line_feed; p += 1 ) {\r
+ switch ( *p ) {\r
+ case ' ': case '\t': case '*':\r
+ break;\r
+ default:\r
+ is_exist_content = true;\r
+ goto exit_for_1;\r
+ }\r
+ }\r
+exit_for_1:;\r
+ }\r
+ if ( is_exist_content ) {\r
+\r
+ e= Set2_allocate( &header->DescriptionItems, &description );\r
+ IF(e){goto fin;}\r
+ NaturalDocsDescriptionClass_initConst( description );\r
+\r
+ description->Type = NaturalDocsDescriptionType_Paragraph;\r
+ description->Start = line;\r
+ }\r
+ if ( description != NULL ) {\r
+ description->Over = p_line_feed + 1;\r
+ }\r
+ }\r
+\r
+\r
+ /* Delete not used data */\r
+ e=0;\r
+ if ( definition_p != NULL )\r
+ { e= NaturalDocsDefinitionClass_finalize( definition_p, e ); }\r
+ e= HeapMemory_free( &definition_p, e );\r
+ IF(e){goto fin;}\r
}\r
}\r
\r
+\r
+ *out_NaturalDocsHeader = header;\r
+ header = NULL;\r
+\r
e=0;\r
fin:\r
+ if ( header != NULL ) {\r
+ e= Set2_free( &header->Arguments, &definition_a, e );\r
+ if ( definition_p != NULL )\r
+ { e= NaturalDocsDefinitionClass_finalize( definition_p, e ); }\r
+ e= HeapMemory_free( &definition_p, e );\r
+ e= Set2_free( &header->DescriptionItems, &description, e );\r
+ }\r
+ if ( ! is_found || e != 0 ) {\r
+ if ( header == NULL )\r
+ { header = *out_NaturalDocsHeader; }\r
+ e= NaturalDocsHeaderClass_finalize( header, e );\r
+ e= HeapMemory_free( &header, e );\r
+ *out_NaturalDocsHeader = NULL;\r
+ }\r
return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [Delete_PP_Directive] >>> \r
+ <<< [ParseNaturalDocsLine] >>> \r
************************************************************************/\r
-errnum_t Delete_PP_Directive( Set2* DirectivePointerArray, errnum_t e )\r
+void ParseNaturalDocsLine( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,\r
+ const TCHAR** out_LineStart, const TCHAR** out_LineOver )\r
{\r
- PP_DirectiveClass** pp;\r
- PP_DirectiveClass** pp_over;\r
- PP_DirectiveClass* directive;\r
- FinalizerVTableClass* finalizer;\r
+ const TCHAR* p;\r
+ const TCHAR* p_over; /* position of over */\r
+ TCHAR a_char; /* char = charcter */\r
\r
- if ( Set2_isInited( DirectivePointerArray ) ) {\r
- for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {\r
- directive = *pp;\r
- finalizer = ClassID_Class_getVTable( directive->ClassID,\r
- &g_FinalizerInterface_ID );\r
- e= finalizer->Finalize( directive, e );\r
- e= HeapMemory_free( &directive, e );\r
+\r
+ *out_LineStart = NULL;\r
+ *out_LineOver = NULL;\r
+\r
+\r
+ /* Move to next line */\r
+ for ( p = in_SourceStart; p < in_SourceOver; p += 1 ) {\r
+ if ( *p == '\n' ) {\r
+ p += 1;\r
+ break;\r
}\r
+ }\r
\r
- e= Set2_finish( DirectivePointerArray, e );\r
+ /* Skip space or "*" */\r
+ for ( /* p */ ; p < in_SourceOver; p += 1 ) {\r
+ a_char = *p;\r
+\r
+ if ( a_char == ' ' || a_char == '\t' || a_char == '*' )\r
+ { continue; }\r
+ else\r
+ { break; }\r
+ }\r
+\r
+ /* Move to right of line */\r
+ for ( p_over = p; p_over < in_SourceOver; p_over += 1 ) {\r
+ a_char = *p_over;\r
+\r
+ if ( a_char == '\n' ) {\r
+ for ( p_over -= 1; /* p_over >= p */; p_over -= 1 ) {\r
+ if ( p_over <= p ) {\r
+ p_over = p;\r
+ break;\r
+ }\r
+\r
+ a_char = *p_over;\r
+\r
+ if ( a_char == ' ' || a_char == '\t' ) {\r
+ continue;\r
+ } else {\r
+ p_over += 1;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if ( p != p_over ) {\r
+ *out_LineStart = p;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ *out_LineOver = p_over;\r
+\r
+ if ( p_over > p + 2 && *( p_over - 2 ) == _T('*') && *( p_over - 1 ) == _T('/') && *out_LineStart == NULL ) {\r
+ for ( p_over -= 3; p_over > p; p_over -= 1 ) {\r
+ a_char = *p_over;\r
+\r
+ if ( a_char == ' ' || a_char == '\t' )\r
+ { continue; }\r
+ else\r
+ { break; }\r
+ }\r
+ \r
+ *out_LineStart = p;\r
+ *out_LineOver = p_over + 1;\r
}\r
- return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< (PP_DirectiveClass) >>> \r
+ <<< [ParseNaturalDocsDefinitionList] >>> \r
************************************************************************/\r
-\r
-/*[PP_DirectiveClass_initConst]*/\r
-void PP_DirectiveClass_initConst( PP_DirectiveClass* self )\r
+void ParseNaturalDocsDefinitionList( const TCHAR* in_SourceStart, const TCHAR* in_SourceOver,\r
+ const TCHAR** out_NameStart, const TCHAR** out_NameOver,\r
+ const TCHAR** out_BriefStart, const TCHAR** out_BriefOver, bool in_IsSkipFirstLine )\r
{\r
- self->ClassID = &g_PP_DirectiveClass_ID;\r
- self->Start = NULL;\r
- self->Over = NULL;\r
- self->DirectiveName_Start = NULL;\r
- self->DirectiveName_Over = NULL;\r
-}\r
+ const TCHAR* p;\r
+ const TCHAR* p_over;\r
+ TCHAR a_char; /* char = charcter */\r
\r
-/*[g_PP_DirectiveClass_ID]*/\r
-static const ClassID_Class* gs_PP_DirectiveClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID\r
-};\r
-static const FinalizerVTableClass gs_PP_DirectiveClass_FinalizerVTable = {\r
- offsetof( PP_DirectiveClass, FinalizerVTable ),\r
- DefaultFunction_Finalize\r
-};\r
-static const InterfaceToVTableClass gs_PP_DirectiveClass_InterfaceToVTables[] = {\r
- { &g_FinalizerInterface_ID, &gs_PP_DirectiveClass_FinalizerVTable }\r
-};\r
-const ClassID_Class g_PP_DirectiveClass_ID = {\r
- "PP_DirectiveClass",\r
- gs_PP_DirectiveClass_SuperClassIDs,\r
- _countof( gs_PP_DirectiveClass_SuperClassIDs ),\r
- sizeof( PP_DirectiveClass ),\r
- NULL,\r
- gs_PP_DirectiveClass_InterfaceToVTables,\r
- _countof( gs_PP_DirectiveClass_InterfaceToVTables )\r
-};\r
\r
+ *out_NameStart = NULL;\r
+ *out_BriefStart = NULL;\r
\r
-/*[g_PP_SharpDefineClass_ID]*/\r
-static const ClassID_Class* gs_PP_SharpDefineClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
- &g_PP_DirectiveClass_ID\r
-};\r
-static const FinalizerVTableClass gs_PP_SharpDefineClass_FinalizerVTable = {\r
- offsetof( PP_SharpDefineClass, FinalizerVTable ),\r
- DefaultFunction_Finalize\r
-};\r
-static const InterfaceToVTableClass gs_PP_SharpDefineClass_InterfaceToVTables[] = {\r
- { &g_FinalizerInterface_ID, &gs_PP_SharpDefineClass_FinalizerVTable }\r
-};\r
-const ClassID_Class g_PP_SharpDefineClass_ID = {\r
- "PP_SharpDefineClass",\r
- gs_PP_SharpDefineClass_SuperClassIDs,\r
- _countof( gs_PP_SharpDefineClass_SuperClassIDs ),\r
- sizeof( PP_SharpDefineClass ),\r
- NULL,\r
- gs_PP_SharpDefineClass_InterfaceToVTables,\r
- _countof( gs_PP_SharpDefineClass_InterfaceToVTables )\r
-};\r
+ if ( in_IsSkipFirstLine ) {\r
+ for ( p = in_SourceStart; p < in_SourceOver; p += 1 ) {\r
+ if ( *p == '\n' ) {\r
+ p += 1;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ p = in_SourceStart;\r
+ }\r
\r
+ for ( /* p */ ; p < in_SourceOver; p += 1 ) {\r
+ a_char = *p;\r
\r
-/*[g_PP_SharpIncludeClass_ID]*/\r
-static const ClassID_Class* gs_PP_SharpIncludeClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
- &g_PP_DirectiveClass_ID\r
-};\r
-static const FinalizerVTableClass gs_PP_SharpIncludeClass_FinalizerVTable = {\r
- offsetof( PP_SharpIncludeClass, FinalizerVTable ),\r
- DefaultFunction_Finalize\r
-};\r
-static const InterfaceToVTableClass gs_PP_SharpIncludeClass_InterfaceToVTables[] = {\r
- { &g_FinalizerInterface_ID, &gs_PP_SharpIncludeClass_FinalizerVTable }\r
-};\r
-const ClassID_Class g_PP_SharpIncludeClass_ID = {\r
- "PP_SharpIncludeClass",\r
- gs_PP_SharpIncludeClass_SuperClassIDs,\r
- _countof( gs_PP_SharpIncludeClass_SuperClassIDs ),\r
- sizeof( PP_SharpIncludeClass ),\r
- NULL,\r
- gs_PP_SharpIncludeClass_InterfaceToVTables,\r
- _countof( gs_PP_SharpIncludeClass_InterfaceToVTables )\r
-};\r
+ if ( a_char == ' ' || a_char == '\t' || a_char == '*' )\r
+ { continue; }\r
+ else\r
+ { break; }\r
+ }\r
+ for ( p_over = p; p_over < in_SourceOver; p_over += 1 ) {\r
+ a_char = *p_over;\r
\r
+ if ( a_char == '-' ) {\r
+ if ( p_over == p ) {\r
+ break; /* Not definition list but normal list */\r
+ }\r
+ else {\r
+ const TCHAR* p2_over;\r
\r
-/*[g_PP_SharpIfClass_ID]*/\r
-static const ClassID_Class* gs_PP_SharpIfClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
- &g_PP_DirectiveClass_ID\r
-};\r
-static const FinalizerVTableClass gs_PP_SharpIfClass_FinalizerVTable = {\r
- offsetof( PP_SharpIfClass, FinalizerVTable ),\r
- DefaultFunction_Finalize\r
-};\r
-static const InterfaceToVTableClass gs_PP_SharpIfClass_InterfaceToVTables[] = {\r
- { &g_FinalizerInterface_ID, &gs_PP_SharpIfClass_FinalizerVTable }\r
-};\r
-const ClassID_Class g_PP_SharpIfClass_ID = {\r
- "PP_SharpIfClass",\r
- gs_PP_SharpIfClass_SuperClassIDs,\r
- _countof( gs_PP_SharpIfClass_SuperClassIDs ),\r
- sizeof( PP_SharpIfClass ),\r
- NULL,\r
- gs_PP_SharpIfClass_InterfaceToVTables,\r
- _countof( gs_PP_SharpIfClass_InterfaceToVTables )\r
-};\r
+ for ( p2_over = p_over - 1; /* p2_over >= p */; p2_over -= 1 ) {\r
+ a_char = *p2_over;\r
+ if ( a_char == ' ' || a_char == '\t' ) {\r
+ continue;\r
+ } else {\r
+ p2_over += 1;\r
+ break;\r
+ }\r
+ }\r
\r
+ *out_NameStart = p;\r
+ *out_NameOver = p2_over;\r
+ }\r
+ break;\r
+ }\r
+ else if ( a_char == '\n' ) {\r
+ goto fin;\r
+ }\r
+ }\r
+ for ( p = p_over + 1; p < in_SourceOver; p += 1 ) {\r
+ a_char = *p;\r
\r
-/*[g_PP_SharpElseClass_ID]*/\r
-static const ClassID_Class* gs_PP_SharpElseClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
- &g_PP_DirectiveClass_ID\r
-};\r
-static const FinalizerVTableClass gs_PP_SharpElseClass_FinalizerVTable = {\r
- offsetof( PP_SharpElseClass, FinalizerVTable ),\r
- DefaultFunction_Finalize\r
-};\r
-static const InterfaceToVTableClass gs_PP_SharpElseClass_InterfaceToVTables[] = {\r
- { &g_FinalizerInterface_ID, &gs_PP_SharpElseClass_FinalizerVTable }\r
-};\r
-const ClassID_Class g_PP_SharpElseClass_ID = {\r
- "PP_SharpElseClass",\r
- gs_PP_SharpElseClass_SuperClassIDs,\r
- _countof( gs_PP_SharpElseClass_SuperClassIDs ),\r
- sizeof( PP_SharpElseClass ),\r
- NULL,\r
- gs_PP_SharpElseClass_InterfaceToVTables,\r
- _countof( gs_PP_SharpElseClass_InterfaceToVTables )\r
-};\r
+ if ( a_char == ' ' || a_char == '\t' || a_char == '*' )\r
+ { continue; }\r
+ else\r
+ { break; }\r
+ }\r
+ for ( p_over = p; p_over < in_SourceOver; p_over += 1 ) {\r
+ a_char = *p_over;\r
\r
+ if ( a_char == '\n' ) {\r
+ for ( p_over -= 1; /* p_over >= p */; p_over -= 1 ) {\r
+ a_char = *p_over;\r
+ if ( a_char == ' ' || a_char == '\t' ) {\r
+ continue;\r
+ } else {\r
+ p_over += 1;\r
+ break;\r
+ }\r
+ }\r
\r
-/*[g_PP_SharpEndifClass_ID]*/\r
-static const ClassID_Class* gs_PP_SharpEndifClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
- &g_PP_DirectiveClass_ID\r
-};\r
-static const FinalizerVTableClass gs_PP_SharpEndifClass_FinalizerVTable = {\r
- offsetof( PP_SharpEndifClass, FinalizerVTable ),\r
- DefaultFunction_Finalize\r
-};\r
-static const InterfaceToVTableClass gs_PP_SharpEndifClass_InterfaceToVTables[] = {\r
- { &g_FinalizerInterface_ID, &gs_PP_SharpEndifClass_FinalizerVTable }\r
-};\r
-const ClassID_Class g_PP_SharpEndifClass_ID = {\r
- "PP_SharpEndifClass",\r
- gs_PP_SharpEndifClass_SuperClassIDs,\r
- _countof( gs_PP_SharpEndifClass_SuperClassIDs ),\r
- sizeof( PP_SharpEndifClass ),\r
- NULL,\r
- gs_PP_SharpEndifClass_InterfaceToVTables,\r
- _countof( gs_PP_SharpEndifClass_InterfaceToVTables )\r
-};\r
+ *out_BriefStart = p;\r
+ *out_BriefOver = p_over;\r
+ break;\r
+ }\r
+ }\r
\r
+fin:\r
+ return;\r
+}\r
\r
-/*[g_PP_SharpIfdefClass_ID]*/\r
-static const ClassID_Class* gs_PP_SharpIfdefClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
- &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID\r
-};\r
-static const FinalizerVTableClass gs_PP_SharpIfdefClass_FinalizerVTable = {\r
- offsetof( PP_SharpIfdefClass, FinalizerVTable ),\r
- DefaultFunction_Finalize\r
-};\r
-static const InterfaceToVTableClass gs_PP_SharpIfdefClass_InterfaceToVTables[] = {\r
- { &g_FinalizerInterface_ID, &gs_PP_SharpIfdefClass_FinalizerVTable }\r
-};\r
-const ClassID_Class g_PP_SharpIfdefClass_ID = {\r
- "PP_SharpIfdefClass",\r
- gs_PP_SharpIfdefClass_SuperClassIDs,\r
- _countof( gs_PP_SharpIfdefClass_SuperClassIDs ),\r
- sizeof( PP_SharpIfdefClass ),\r
- NULL,\r
- gs_PP_SharpIfdefClass_InterfaceToVTables,\r
- _countof( gs_PP_SharpIfdefClass_InterfaceToVTables )\r
-};\r
\r
+ \r
+/***********************************************************************\r
+ <<< (NaturalCommentClass) >>> \r
+************************************************************************/\r
\r
-/*[g_PP_SharpIfndefClass_ID]*/\r
-static const ClassID_Class* gs_PP_SharpIfndefClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
- &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID, &g_PP_SharpIfdefClass_ID\r
+static const FinalizerVTableClass gs_NaturalCommentClass_FinalizerVTable = {\r
+ offsetof( NaturalCommentClass, FinalizerVTable ),\r
+ NaturalCommentClass_finalize,\r
};\r
-static const FinalizerVTableClass gs_PP_SharpIfndefClass_FinalizerVTable = {\r
- offsetof( PP_SharpIfndefClass, FinalizerVTable ),\r
- DefaultFunction_Finalize\r
+static const PrintXML_VTableClass gs_NaturalCommentClass_PrintXML_VTable = {\r
+ offsetof( NaturalCommentClass, PrintXML_VTable ),\r
+ NaturalCommentClass_printXML,\r
};\r
-static const InterfaceToVTableClass gs_PP_SharpIfndefClass_InterfaceToVTables[] = {\r
- { &g_FinalizerInterface_ID, &gs_PP_SharpIfndefClass_FinalizerVTable }\r
+static const InterfaceToVTableClass gs_NaturalCommentClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_NaturalCommentClass_FinalizerVTable },\r
+ { &g_PrintXML_Interface_ID, &gs_NaturalCommentClass_PrintXML_VTable },\r
+};\r
+static const ClassID_Class* gs_NaturalCommentClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_ParsedRangeClass_ID, &g_SyntaxSubNodeClass_ID,\r
+ &g_SyntaxNodeClass_ID, &g_NaturalCommentClass_ID,\r
};\r
\r
-const ClassID_Class g_PP_SharpIfndefClass_ID = {\r
- "PP_SharpIfndefClass",\r
- gs_PP_SharpIfndefClass_SuperClassIDs,\r
- _countof( gs_PP_SharpIfndefClass_SuperClassIDs ),\r
- sizeof( PP_SharpIfndefClass ),\r
+/*[g_NaturalCommentClass_ID]*/\r
+const ClassID_Class g_NaturalCommentClass_ID = {\r
+ "NaturalCommentClass",\r
+ gs_NaturalCommentClass_SuperClassIDs,\r
+ _countof( gs_NaturalCommentClass_SuperClassIDs ),\r
+ sizeof( NaturalCommentClass ),\r
NULL,\r
- gs_PP_SharpIfndefClass_InterfaceToVTables,\r
- _countof( gs_PP_SharpIfndefClass_InterfaceToVTables )\r
+ gs_NaturalCommentClass_InterfaceToVTables,\r
+ _countof( gs_NaturalCommentClass_InterfaceToVTables ),\r
};\r
\r
\r
\r
/***********************************************************************\r
- <<< (ParsedRangeClass) >>> \r
+ <<< [NaturalCommentClass_initConst] >>> \r
************************************************************************/\r
-\r
-/*[ParsedRangeClass_initConst]*/\r
-void ParsedRangeClass_initConst( ParsedRangeClass* self )\r
+void NaturalCommentClass_initConst( NaturalCommentClass* self )\r
{\r
- self->ClassID = &g_ParsedRangeClass_ID;\r
- self->FinalizerVTable = NULL;\r
- self->StaticAddress = NULL;\r
- self->Start = NULL;\r
- self->Over = NULL;\r
+ SyntaxNodeClass_initConst( (SyntaxNodeClass*) self );\r
+ self->ClassID = &g_NaturalCommentClass_ID;\r
+ self->FinalizerVTable = &gs_NaturalCommentClass_FinalizerVTable;\r
+ self->PrintXML_VTable = &gs_NaturalCommentClass_PrintXML_VTable;\r
+ self->NaturalDocsHeader = NULL;\r
}\r
\r
\r
-/*[g_ParsedRangeClass_ID]*/\r
-static const ClassID_Class* gs_ParsedRangeClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID\r
-};\r
-const ClassID_Class g_ParsedRangeClass_ID = {\r
- "ParsedRangeClass",\r
- gs_ParsedRangeClass_SuperClassIDs,\r
- _countof( gs_ParsedRangeClass_SuperClassIDs ),\r
- sizeof( ParsedRangeClass ),\r
- NULL,\r
-};\r
+ \r
+/***********************************************************************\r
+ <<< [NaturalCommentClass_finalize] >>> \r
+************************************************************************/\r
+errnum_t NaturalCommentClass_finalize( NaturalCommentClass* self, errnum_t e )\r
+{\r
+ if ( self->NaturalDocsHeader != NULL ) {\r
+ e= NaturalDocsHeaderClass_finalize( self->NaturalDocsHeader, e );\r
+ e= HeapMemory_free( &self->NaturalDocsHeader, e );\r
+ }\r
+ return e;\r
+}\r
\r
\r
\r
/***********************************************************************\r
- <<< [ParsedRanges_getCut_by_PP_Directive] >>> \r
+ <<< [NaturalCommentClass_printXML] >>> \r
************************************************************************/\r
-errnum_t ParsedRanges_getCut_by_PP_Directive(\r
- Set2* /*<ParsedRangeClass>*/ CutRanges,\r
- Set2* /*<PP_DirectiveClass*>*/ DirectivePointerArray,\r
- const TCHAR* Symbol, bool IsCutDefine )\r
+errnum_t NaturalCommentClass_printXML( NaturalCommentClass* self, FILE* OutputStream )\r
{\r
- errnum_t e;\r
- PP_DirectiveClass** p;\r
- PP_DirectiveClass** p_over;\r
+ errnum_t e;\r
+ int r;\r
+ Set2_IteratorClass iterator;\r
+ NaturalDocsHeaderClass* header;\r
+ NaturalDocsDefinitionClass* definition;\r
+ NaturalDocsDescriptionClass* description;\r
\r
- for ( Set2_forEach( DirectivePointerArray, &p, &p_over, PP_DirectiveClass* ) ) {\r
- PP_DirectiveClass* directive = *p;\r
\r
- if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfdefClass_ID ) ) {\r
- PP_SharpIfdefClass* sh_ifdef = (PP_SharpIfdefClass*) directive; /* sh = sharp */\r
- PP_SharpElseClass* sh_else; /* sh = sharp */\r
- PP_SharpEndifClass* sh_endif; /* sh = sharp */\r
+ r= _ftprintf_s( OutputStream, _T("<NaturalCommentClass") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
\r
- if ( StrT_cmp_part( sh_ifdef->Symbol_Start, sh_ifdef->Symbol_Over, Symbol ) == 0 ) {\r
- ParsedRangeClass* cut;\r
- bool is_ifndef = ( sh_ifdef->ClassID == &g_PP_SharpIfndefClass_ID );\r
+ header = self->NaturalDocsHeader;\r
+ if ( header != NULL ) {\r
+ r= _ftprintf_s( OutputStream, _T(" NaturalDocsKeyword=\"%s\""), header->Keyword );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
\r
+ ASSERT_D( StrT_cmp_part( header->KeywordStart, header->KeywordOver, header->Keyword ) == 0,\r
+ e=E_OTHERS; goto fin );\r
\r
- /* Set "sh_else", "sh_endif" */\r
- if ( ClassID_Class_isSuperClass( sh_ifdef->NextDirective->ClassID,\r
- &g_PP_SharpElseClass_ID ) ) {\r
- sh_else = (PP_SharpElseClass*) sh_ifdef->NextDirective;\r
- sh_endif = sh_ifdef->EndDirective;\r
- } else {\r
- sh_else = NULL;\r
- sh_endif = (PP_SharpEndifClass*) sh_ifdef->NextDirective;\r
- }\r
\r
+ r= _ftprintf_s( OutputStream, _T(" Name=\"%s\""), header->Name );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
\r
- /* Add to "CutRanges" */\r
- e= Set2_alloc( CutRanges, &cut, ParsedRangeClass ); IF(e){goto fin;}\r
- cut->Start = sh_ifdef->Start;\r
- if ( is_ifndef == ! IsCutDefine ) {\r
- if ( sh_else != NULL ) {\r
- cut->Over = sh_else->Over;\r
+ ASSERT_D( StrT_cmp_part( header->NameStart, header->NameOver, header->Name ) == 0,\r
+ e=E_OTHERS; goto fin );\r
+ }\r
+ r= _ftprintf_s( OutputStream, _T(" StartLineNum=\"%d\""), self->StartLineNum );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
\r
- e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );\r
- IF(e){goto fin;}\r
- cut->Start = sh_endif->Start;\r
- }\r
- cut->Over = sh_endif->Over;\r
- }\r
- else {\r
- cut->Over = sh_ifdef->Over;\r
+ r= _ftprintf_s( OutputStream, _T(" LastLineNum=\"%d\""), self->LastLineNum );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
\r
- e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );\r
- IF(e){goto fin;}\r
- if ( sh_else != NULL ) {\r
- cut->Start = sh_else->Start;\r
- } else {\r
- cut->Start = sh_endif->Start;\r
- }\r
- cut->Over = sh_endif->Over;\r
- }\r
- }\r
+ if ( self->ParentComment != NULL ) {\r
+ r= _ftprintf_s( OutputStream, _T(" ParentComment=\"%s\""), self->ParentComment->NaturalDocsHeader->Name );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+ }\r
+ r= _ftprintf_s( OutputStream, _T(">\n") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+\r
+ if ( header != NULL ) {\r
+ if ( header->Brief != NULL ) {\r
+ r= _ftprintf_s( OutputStream, _T("\t<Brief><![CDATA[%s]]></Brief>\n"), header->Brief );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ ASSERT_D( StrT_cmp_part( header->BriefStart, header->BriefOver, header->Brief ) == 0,\r
+ e=E_OTHERS; goto fin );\r
+ ASSERT_D( header->BriefNoIndent > header->NameOver &&\r
+ header->BriefNoIndent < header->BriefStart,\r
+ e=E_OTHERS; goto fin );\r
+ }\r
+\r
+ if ( header->Arguments.First < header->Arguments.Next ) {\r
+ ASSERT_D( StrT_cmp_part( header->ArgumentsLabel, header->ArgumentsLabel + 10,\r
+ _T("Arguments:") ) == 0, e=E_OTHERS; goto fin );\r
+ }\r
+ for ( Set2_forEach2( &header->Arguments, &iterator, &definition ) ) {\r
+ r= _ftprintf_s( OutputStream, _T("\t<Arguments Name=\"%s\"><![CDATA[%s]]></Arguments>\n"),\r
+ definition->Name, definition->Brief );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ ASSERT_D( StrT_cmp_part( definition->NameStart, definition->NameOver, definition->Name )\r
+ == 0, e=E_OTHERS; goto fin );\r
+ ASSERT_D( StrT_cmp_part( definition->BriefStart, definition->BriefOver, definition->Brief )\r
+ == 0, e=E_OTHERS; goto fin );\r
+ }\r
+\r
+ if ( header->ReturnValue != NULL ) {\r
+ r= _ftprintf_s( OutputStream, _T("\t<ReturnValue><![CDATA[%s]]></ReturnValue>\n"), header->ReturnValue );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ ASSERT_D( StrT_cmp_part( header->ReturnValueStart, header->ReturnValueOver,\r
+ header->ReturnValue ) == 0, e=E_OTHERS; goto fin );\r
+ ASSERT_D( StrT_cmp_part( header->ReturnValueLabel, header->ReturnValueLabel + 13,\r
+ _T("Return Value:") ) == 0, e=E_OTHERS; goto fin );\r
+ }\r
+\r
+ if ( ! Set2_isEmpty( &header->DescriptionItems ) ) {\r
+ r= _ftprintf_s( OutputStream, _T("\t<DescriptionItems>\n") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+ }\r
+ for ( Set2_forEach2( &header->DescriptionItems, &iterator, &description ) ) {\r
+ r= _ftprintf_s( OutputStream, _T("\t\t<DescriptionItem type=\"%s\"><![CDATA["),\r
+ NaturalDocsDescriptionTypeEnum_to_String( description->Type, _T("UNKNOWN") ) );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+ e= ftcopy_part_r( OutputStream, description->Start, description->Over );\r
+ r= _ftprintf_s( OutputStream, _T("]]></DescriptionItem>\n") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+ }\r
+ if ( ! Set2_isEmpty( &header->DescriptionItems ) ) {\r
+ r= _ftprintf_s( OutputStream, _T("\t</DescriptionItems>\n") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
}\r
}\r
\r
+\r
+ r= _ftprintf_s( OutputStream, _T("</NaturalCommentClass>\n") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
e=0;\r
fin:\r
return e;\r
\r
\r
/***********************************************************************\r
- <<< [ParsedRangeClass_onInitializedForDebug] >>> \r
+ <<< [MakeNaturalComments_C_Language] >>> \r
************************************************************************/\r
-#if ! defined( NDEBUG )\r
-void ParsedRangeClass_onInitializedForDebug( ParsedRangeClass* self )\r
-{\r
- /* These code can be modified for Debug. */\r
- #if 0 // IS_USED_DEBUG_CHECK_CLASS\r
- TCHAR* text;\r
- ptrdiff_t break_diff = 0x1FA6A;\r
-\r
- START_D( 10 );\r
- text = GET_D( 1, TCHAR* );\r
- PointerType_plus( &text, break_diff );\r
- if ( text == self->Start ) {\r
- if ( self->ClassID == &g_ParsedRangeClass_ID ) {\r
- SET_D( 2, self );\r
- }\r
- }\r
- END_D();\r
- #else\r
- UNREFERENCED_VARIABLE( self );\r
- #endif\r
-}\r
-#endif\r
\r
+errnum_t MakeNaturalComments_C_Language__Sub( C_LanguageTokenClass* StartToken,\r
+ LineNumberIndexClass* LineNumbers,\r
+ NaturalCommentClass** out_NewComment,\r
+ NaturalDocsParserConfigClass* config );\r
\r
- \r
-/***********************************************************************\r
- <<< [ParsedRanges_compareByStart] >>> \r
-************************************************************************/\r
-int ParsedRanges_compareByStart( const void* _a1, const void* _a2 )\r
+errnum_t MakeNaturalComments_C_Language( ListClass* /*<C_LanguageTokenClass*>*/ TokenList,\r
+ LineNumberIndexClass* LineNumbers,\r
+ ListClass* /*<NaturalCommentClass*>*/ TopSyntaxNodeList,\r
+ NaturalDocsParserConfigClass* config )\r
{\r
- ParsedRangeClass* a1 = (ParsedRangeClass*) _a1;\r
- ParsedRangeClass* a2 = (ParsedRangeClass*) _a2;\r
+ errnum_t e;\r
+ const ClassID_Class* class_ID;\r
+ ListIteratorClass iterator;\r
+ C_LanguageTokenClass* token;\r
+ NaturalCommentClass* comment;\r
+ NaturalCommentClass* new_comment;\r
+ NaturalDocsParserConfigClass config_body;\r
\r
- return a1->Start - a2->Start;\r
-}\r
\r
+ if ( config == NULL ) {\r
+ config = &config_body;\r
+ config->Flags = 0;\r
+ }\r
\r
- \r
-/***********************************************************************\r
- <<< [ParsedRanges_write_by_Cut] >>> \r
-************************************************************************/\r
-errnum_t ParsedRanges_write_by_Cut(\r
- Set2* /*<ParsedRangeClass>*/ CutRanges,\r
- const TCHAR* Text, FILE* OutFile )\r
-{\r
- errnum_t e;\r
- const TCHAR* position;\r
- ParsedRangeClass* p;\r
- ParsedRangeClass* p_over;\r
+ if ( IsBitNotSet( config->Flags, NaturalDocsParserConfig_AdditionalKeywords ) ) {\r
+ config->AdditionalKeywords = NULL;\r
+ config->AdditionalKeywordsLength = 0;\r
+ }\r
+ else {\r
+ ASSERT_R( IsBitSet( config->Flags, NaturalDocsParserConfig_AdditionalKeywordsLength ),\r
+ e=E_OTHERS; goto fin );\r
+ }\r
\r
- qsort( CutRanges->First, Set2_getCount( CutRanges, ParsedRangeClass ),\r
- sizeof(ParsedRangeClass), ParsedRanges_compareByStart );\r
+ if ( IsBitSet( config->Flags, NaturalDocsParserConfig_AdditionalKeywordsEndsScopesFirstIndex ) ) {\r
+ if ( IsBitNotSet( config->Flags, NaturalDocsParserConfig_AdditionalKeywordsEndsScopesLength ) ) {\r
+ config->AdditionalKeywordsEndsScopesLength = 1;\r
+ }\r
+ }\r
+ else {\r
+ config->AdditionalKeywordsEndsScopesFirstIndex = 0;\r
+ config->AdditionalKeywordsEndsScopesLength = 0;\r
+ }\r
\r
- position = Text;\r
- for ( Set2_forEach( CutRanges, &p, &p_over, ParsedRangeClass ) ) {\r
- const TCHAR* cut_start_position;\r
- const TCHAR* cut_over_position;\r
\r
- cut_start_position = p->Start;\r
- if ( position < cut_start_position ) {\r
- e= FileT_writePart( OutFile, (TCHAR*)position, (TCHAR*)cut_start_position );\r
- IF(e){goto fin;}\r
+ for ( ListClass_forEach( TokenList, &iterator, &token ) ) {\r
+ class_ID = token->ClassID;\r
+ if ( class_ID == &g_C_LanguageTokenClass_ID ) {\r
+ C_LanguageTokenEnum token_type = token->TokenType;\r
+\r
+ if ( token_type == TwoChar8( '/', '*' ) ) {\r
+ e= MakeNaturalComments_C_Language__Sub( token, LineNumbers, &new_comment, config );\r
+ IF(e){goto fin;}\r
+ if ( new_comment != NULL ) {\r
+ e= ListClass_addLast( TopSyntaxNodeList, &new_comment->ListElement );\r
+ IF(e){goto fin;}\r
+ }\r
+ }\r
}\r
+ }\r
\r
- cut_over_position = p->Over;\r
- if ( position < cut_over_position ) {\r
- position = cut_over_position;\r
+ /* Set "comment->ParentComment" */\r
+ {\r
+ enum {\r
+ starts_scope_start = 19,\r
+ starts_scope_end = 30,\r
+ ends_scope_start = 4, \r
+ ends_scope_end = 5,\r
+ };\r
+\r
+ NaturalCommentClass* parent = NULL;\r
+\r
+\r
+ ASSERT_D( _tcscmp( g_NaturalDocsKeywords[ starts_scope_start ], _T("class") ) == 0, e=E_OTHERS; goto fin );\r
+ ASSERT_D( _tcscmp( g_NaturalDocsKeywords[ starts_scope_end ], _T("interfaces") ) == 0, e=E_OTHERS; goto fin );\r
+ ASSERT_D( _tcscmp( g_NaturalDocsKeywords[ ends_scope_start ], _T("section") ) == 0, e=E_OTHERS; goto fin );\r
+ ASSERT_D( _tcscmp( g_NaturalDocsKeywords[ ends_scope_end ], _T("title") ) == 0, e=E_OTHERS; goto fin );\r
+\r
+\r
+ for ( ListClass_forEach( TopSyntaxNodeList, &iterator, &comment ) ) {\r
+ NaturalDocsHeaderClass* header = comment->NaturalDocsHeader;\r
+ int index;\r
+\r
+ index = StrT_searchPartStringIndexI( header->KeywordStart, header->KeywordOver,\r
+ g_NaturalDocsKeywords, _countof(g_NaturalDocsKeywords),\r
+ NOT_FOUND_INDEX );\r
+\r
+ if ( index == NOT_FOUND_INDEX ) {\r
+ index = StrT_searchPartStringIndexI( header->KeywordStart, header->KeywordOver,\r
+ config->AdditionalKeywords, config->AdditionalKeywordsLength,\r
+ NOT_FOUND_INDEX );\r
+\r
+ if ( index >= config->AdditionalKeywordsEndsScopesFirstIndex &&\r
+ index < config->AdditionalKeywordsEndsScopesFirstIndex +\r
+ config->AdditionalKeywordsEndsScopesLength )\r
+ {\r
+ index = ends_scope_start;\r
+ }\r
+ else {\r
+ index = NOT_FOUND_INDEX;\r
+ }\r
+ }\r
+\r
+ if ( index >= starts_scope_start && index <= starts_scope_end ) {\r
+ parent = comment;\r
+ comment->ParentComment = NULL;\r
+ }\r
+ else if ( index >= ends_scope_start && index <= ends_scope_end ) {\r
+ parent = NULL;\r
+ comment->ParentComment = NULL;\r
+ }\r
+ else {\r
+ comment->ParentComment = parent;\r
+ }\r
}\r
}\r
- _fputts( position, OutFile ); IF(ferror(OutFile)){e=E_ERRNO; goto fin;}\r
\r
e=0;\r
fin:\r
}\r
\r
\r
- \r
-/*=================================================================*/\r
-/* <<< [Locale/Locale.c] >>> */ \r
-/*=================================================================*/\r
- \r
-/***********************************************************************\r
- <<< [g_LocaleSymbol] >>> \r
-************************************************************************/\r
-char* g_LocaleSymbol = "";\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [Locale_init] >>> \r
-************************************************************************/\r
-int Locale_init()\r
+errnum_t MakeNaturalComments_C_Language__Sub( C_LanguageTokenClass* StartToken,\r
+ LineNumberIndexClass* LineNumbers,\r
+ NaturalCommentClass** out_NewComment,\r
+ NaturalDocsParserConfigClass* config )\r
{\r
- g_LocaleSymbol = ".OCP";\r
- setlocale( LC_ALL, ".OCP" );\r
- return 0;\r
-}\r
+ errnum_t e;\r
+ C_LanguageTokenClass* token;\r
+ NaturalCommentClass* new_comment;\r
+ int line_num;\r
\r
+ *out_NewComment = NULL;\r
\r
- \r
-/***********************************************************************\r
- <<< [Locale_isInited] >>> \r
-************************************************************************/\r
-int Locale_isInited()\r
-{\r
- return ( g_LocaleSymbol[0] != '\0' );\r
- // \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
-}\r
+ e= HeapMemory_allocate( &new_comment ); IF(e){goto fin;}\r
+ NaturalCommentClass_initConst( new_comment );\r
\r
\r
- \r
-/*=================================================================*/\r
-/* <<< [FileT/FileT.c] >>> */ \r
-/*=================================================================*/\r
- \r
-/***********************************************************************\r
- <<< [FileT_isExist] >>> \r
-************************************************************************/\r
-bool FileT_isExist( const TCHAR* path )\r
-{\r
- #if ! FileT_isExistWildcard\r
+ /* Set members of "new_comment" */\r
+ new_comment->Start = StartToken->Start;\r
+ e= LineNumberIndexClass_searchLineNumber( LineNumbers, new_comment->Start, &line_num );\r
+ IF(e){goto fin;}\r
+ new_comment->StartLineNum = line_num;\r
\r
- DWORD r;\r
\r
- if ( path[0] == _T('\0') ) return false;\r
- r = GetFileAttributes( path );\r
- return r != (DWORD)-1;\r
+ token = StartToken;\r
+ for (;;) {\r
+ token = (C_LanguageTokenClass*) token->ListElement.Next->Data;\r
+ IF ( token == NULL ) { e=E_OTHERS; goto fin; }\r
+ if ( token->TokenType == TwoChar8( '*', '/' ) )\r
+ { break; }\r
+ }\r
\r
- #else\r
+ new_comment->Over = token->Over;\r
+ e= LineNumberIndexClass_searchLineNumber( LineNumbers, new_comment->Over - 1, &line_num );\r
+ IF(e){goto fin;}\r
+ new_comment->LastLineNum = line_num;\r
\r
- HANDLE find;\r
- WIN32_FIND_DATA data;\r
\r
- find = FindFirstFileEx( path, FindExInfoStandard, &data,\r
- FindExSearchNameMatch, NULL, 0 );\r
+ /* ... */\r
+ e= ParseNaturalDocsComment( new_comment->Start, new_comment->Over,\r
+ &new_comment->NaturalDocsHeader, config ); IF(e){goto fin;}\r
\r
- if ( find == INVALID_HANDLE_VALUE ) {\r
- return false;\r
+\r
+ /* Set "*out_NewComment" */\r
+ if ( new_comment->NaturalDocsHeader != NULL ) {\r
+ *out_NewComment = new_comment;\r
+ new_comment = NULL;\r
}\r
- else {\r
- FindClose( find );\r
- return true;\r
+ e=0;\r
+fin:\r
+ if ( new_comment != NULL ) {\r
+ e= NaturalCommentClass_finalize( new_comment, e );\r
+ HeapMemory_free( &new_comment, e );\r
}\r
\r
- #endif\r
+ return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [FileT_isFile] >>> \r
+ <<< [LexicalAnalize_C_Language] >>> \r
************************************************************************/\r
-bool FileT_isFile( const TCHAR* path )\r
+errnum_t LexicalAnalize_C_Language( const TCHAR* in_Text,\r
+ ListClass* /*<C_LanguageTokenClass>*/ in_TokenList )\r
{\r
- DWORD r = GetFileAttributes( path );\r
- return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == 0;\r
- // 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
-}\r
-\r
+ errnum_t e;\r
+ const TCHAR* p;\r
+ TCHAR c;\r
+ TCHAR c2;\r
+ int next_plus;\r
+ bool is_in_c_comment = false; /* Slash asterisk */\r
+ bool is_in_cpp_comment = false; /* Double slash */\r
\r
- \r
-/***********************************************************************\r
- <<< [FileT_isDir] >>> \r
-************************************************************************/\r
-bool FileT_isDir( const TCHAR* path )\r
-{\r
- DWORD r = GetFileAttributes( path );\r
- return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == FILE_ATTRIBUTE_DIRECTORY;\r
- // 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
-}\r
+ C_LanguageTokenEnum token_type;\r
+ C_LanguageTokenClass* token = NULL;\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [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
-************************************************************************/\r
-typedef struct {\r
- /*--- inherit from FileT_CallByNestFindData */\r
- void* CallerArgument;\r
- TCHAR* FullPath; // abstruct path\r
- TCHAR* StepPath;\r
- TCHAR* FileName;\r
- DWORD FileAttributes;\r
+ p = in_Text;\r
+ c = *p;\r
+ while ( c != '\0' ) {\r
+ next_plus = 1;\r
+\r
+ if ( c >= 'A' && c <= 'Z' ) { token_type = gc_TokenOfCIdentifier; }\r
+ else if ( c >= 'a' && c <= 'z' ) { token_type = gc_TokenOfCIdentifier; }\r
+ else if ( c == '_' ) { token_type = gc_TokenOfCIdentifier; }\r
+ else if ( c >= '0' && c <= '9' ) { token_type = gc_TokenOfNumber; }\r
+ else if ( c == '=' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '=' ) { token_type = TwoChar8( '=', '=' ); next_plus = 2; }\r
+ else { token_type = '='; }\r
+ }\r
+ else if ( c == '+' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '+' ) { token_type = TwoChar8( '+', '+' ); next_plus = 2; }\r
+ else if ( c2 == '=' ) { token_type = TwoChar8( '+', '=' ); next_plus = 2; }\r
+ else { token_type = '+'; }\r
+ }\r
+ else if ( c == '-' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '>' ) { token_type = TwoChar8( '-', '>' ); next_plus = 2; }\r
+ else if ( c2 == '-' ) { token_type = TwoChar8( '-', '-' ); next_plus = 2; }\r
+ else if ( c2 == '=' ) { token_type = TwoChar8( '-', '=' ); next_plus = 2; }\r
+ else { token_type = '-'; }\r
+ }\r
+ else if ( c == '*' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '/' ) { token_type = TwoChar8( '*', '/' ); next_plus = 2; }\r
+ else if ( c2 == '=' ) { token_type = TwoChar8( '*', '=' ); next_plus = 2; }\r
+ else { token_type = '*'; }\r
+\r
+ if ( c2 == '/' ) {\r
+ if ( ! is_in_cpp_comment )\r
+ { is_in_c_comment = false; }\r
+ }\r
+ }\r
+ else if ( c == '/' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '/' ) { token_type = TwoChar8( '/', '/' ); next_plus = 2; }\r
+ else if ( c2 == '*' ) { token_type = TwoChar8( '/', '*' ); next_plus = 2; }\r
+ else if ( c2 == '=' ) { token_type = TwoChar8( '/', '=' ); next_plus = 2; }\r
+ else { token_type = '/'; }\r
+\r
+ if ( ! is_in_c_comment && ! is_in_cpp_comment ) {\r
+ if ( c2 == '/' )\r
+ { is_in_cpp_comment = true; }\r
+ else if ( c2 == '*' )\r
+ { is_in_c_comment = true; }\r
+ }\r
+ }\r
+ else if ( c == '<' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '<' ) { token_type = TwoChar8( '<', '<' ); next_plus = 2; }\r
+ else if ( c2 == '=' ) { token_type = TwoChar8( '<', '=' ); next_plus = 2; }\r
+ else { token_type = '<'; }\r
+ }\r
+ else if ( c == '>' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '>' ) { token_type = TwoChar8( '>', '>' ); next_plus = 2; }\r
+ else if ( c2 == '=' ) { token_type = TwoChar8( '>', '=' ); next_plus = 2; }\r
+ else { token_type = '>'; }\r
+ }\r
+ else if ( c == '!' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '=' ) { token_type = TwoChar8( '!', '=' ); next_plus = 2; }\r
+ else { token_type = '!'; }\r
+ }\r
+ else if ( c == '&' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '&' ) { token_type = TwoChar8( '&', '&' ); next_plus = 2; }\r
+ else if ( c2 == '=' ) { token_type = TwoChar8( '&', '=' ); next_plus = 2; }\r
+ else { token_type = '&'; }\r
+ }\r
+ else if ( c == '|' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '|' ) { token_type = TwoChar8( '|', '|' ); next_plus = 2; }\r
+ else if ( c2 == '=' ) { token_type = TwoChar8( '|', '=' ); next_plus = 2; }\r
+ else { token_type = '|'; }\r
+ }\r
+ else if ( c == '%' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '=' ) { token_type = TwoChar8( '%', '=' ); next_plus = 2; }\r
+ else { token_type = '%'; }\r
+ }\r
+ else if ( c == '^' ) {\r
+ c2 = *( p + 1 );\r
+ if ( c2 == '=' ) { token_type = TwoChar8( '^', '=' ); next_plus = 2; }\r
+ else { token_type = '^'; }\r
+ }\r
+ else {\r
+ switch ( c ) {\r
+ case '(': token_type = c; break;\r
+ case ')': token_type = c; break;\r
+ case '{': token_type = c; break;\r
+ case '}': token_type = c; break;\r
+ case '[': token_type = c; break;\r
+ case ']': token_type = c; break;\r
+ case '"': token_type = gc_TokenOfString; break;\r
+ case '\'': token_type = gc_TokenOfChar; break;\r
+ case '.': token_type = c; break;\r
+ case ',': token_type = c; break;\r
+ case ':': token_type = c; break;\r
+ case ';': token_type = c; break;\r
+ case '\n': token_type = c; is_in_cpp_comment = false; break;\r
+ case '?': token_type = c; break;\r
+ case '~': token_type = c; break;\r
+ default: token_type = gc_TokenOfOther; break;\r
+ }\r
+ }\r
\r
- /*---*/\r
- BitField Flags;\r
- FuncType CallbackFromNestFind;\r
- TCHAR FullPathMem[4096];\r
-} FileT_CallByNestFindDataIn;\r
+ if ( token_type == gc_TokenOfCIdentifier ) {\r
+ bool is_in_identifier;\r
\r
-int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m );\r
+ for (;;) {\r
+ c2 = *( p + next_plus );\r
+ if ( c2 >= 'A' && c2 <= 'Z' ) { is_in_identifier = true; }\r
+ else if ( c2 >= 'a' && c2 <= 'z' ) { is_in_identifier = true; }\r
+ else if ( c2 >= '0' && c2 <= '9' ) { is_in_identifier = true; }\r
+ else if ( c2 == '_' ) { is_in_identifier = true; }\r
+ else { is_in_identifier = false; }\r
\r
+ if ( ! is_in_identifier )\r
+ { break; }\r
\r
-int FileT_callByNestFind( const TCHAR* Path, BitField Flags, void* Argument, FuncType Callback )\r
-{\r
- int e;\r
- FileT_CallByNestFindDataIn data;\r
+ next_plus += 1;\r
+ }\r
+ }\r
+ else if ( ( token_type == gc_TokenOfString || token_type == gc_TokenOfChar ) &&\r
+ ( ! is_in_c_comment && ! is_in_cpp_comment ) )\r
+ {\r
+ bool is_escape = false;\r
\r
- {\r
- TCHAR* p;\r
+ for (;;) {\r
+ c2 = *( p + next_plus );\r
+ if ( ! is_escape ) {\r
+ if ( c2 == c ) {\r
+ next_plus += 1;\r
+ break;\r
+ }\r
+ else if ( c2 == '\\' ) {\r
+ is_escape = true;\r
+ }\r
+ }\r
+ else {\r
+ is_escape = false;\r
+ }\r
\r
- e= StrT_cpy( data.FullPathMem, sizeof(data.FullPathMem), Path ); IF(e)goto fin;\r
+ next_plus += 1;\r
+ }\r
+ }\r
\r
+ if ( token_type != gc_TokenOfOther ) {\r
+ e= HeapMemory_allocate( &token ); IF(e){goto fin;}\r
+ C_LanguageTokenClass_initConst( token );\r
+ token->Start = p;\r
+ token->Over = p + next_plus;\r
+ token->TokenType = token_type;\r
\r
- /* FullPathMem \82Ì\8dÅ\8cã\82É \ \82ª\96³\82¢\82È\82ç\92Ç\89Á\82·\82é */\r
- p = _tcschr( data.FullPathMem, _T('\0') );\r
- p--;\r
- if ( *p != _T('\\') ) {\r
- p++;\r
- IF( p >= data.FullPathMem + (sizeof(data.FullPathMem) / sizeof(TCHAR)) - 1 )goto err_fa;\r
- *p = _T('\\');\r
+ e= ListClass_addLast( in_TokenList, &token->ListElement ); IF(e){goto fin;}\r
+ token = NULL;\r
}\r
\r
-\r
- /* data \82ð\8f\89\8aú\89»\82·\82é */\r
- data.CallerArgument = Argument;\r
- data.FullPath = data.FullPathMem;\r
- data.StepPath = p + 1;\r
- data.FileName = p + 1;\r
- data.Flags = Flags;\r
- data.CallbackFromNestFind = Callback;\r
+ p += next_plus;\r
+ c = *p;\r
}\r
\r
- /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ\8aÖ\90\94\82Ö */\r
- e= FileT_callByNestFind_sub( &data ); IF(e)goto fin;\r
-\r
e=0;\r
fin:\r
+ e= HeapMemory_free( &token, e );\r
return e;\r
-err_fa: e= E_FEW_ARRAY; goto fin;\r
}\r
\r
\r
-int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m )\r
+ \r
+/***********************************************************************\r
+ <<< [CutComment_C_LanguageToken] >>> \r
+************************************************************************/\r
+errnum_t CutComment_C_LanguageToken( ListClass* /*<C_LanguageTokenClass>*/ TokenList )\r
{\r
- int e;\r
- HANDLE find;\r
- WIN32_FIND_DATA data;\r
- TCHAR* p;\r
- int done;\r
-\r
-\r
- /* 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
- if ( m->Flags & FileT_FolderBeforeFiles ) {\r
- *( m->FileName - 1 ) = _T('\0'); // m->FullPath \82Ì\8dÅ\8cã\82Ì \ \82ð\88ê\8e\9e\93I\82É\83J\83b\83g\r
- *( m->FileName ) = _T('\0'); // m->FileName, m->StepPath \82ð "" \82É\82·\82é\r
- m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
+ errnum_t e;\r
+ C_LanguageTokenClass* p;\r
+ C_LanguageTokenEnum token_type;\r
+ bool is_in_c_comment;\r
+ bool is_in_cpp_comment;\r
+ bool is_cut;\r
+ ListIteratorClass iterator;\r
\r
- if ( m->StepPath[0] == _T('\0') ) {\r
- TCHAR* step_path = m->StepPath;\r
- TCHAR* fname = m->FileName;\r
\r
- m->StepPath = _T(".");\r
- m->FileName = StrT_refFName( m->FullPath );\r
- e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
- m->StepPath = step_path;\r
- m->FileName = fname;\r
+ is_in_c_comment = false;\r
+ is_in_cpp_comment = false;\r
+ e= ListClass_getListIterator( TokenList, &iterator ); IF(e){goto fin;}\r
+ for (;;) {\r
+ p = (C_LanguageTokenClass*) ListIteratorClass_getNext( &iterator );\r
+ if ( p == NULL ) { break; }\r
+ ASSERT_D( p->ClassID == &g_C_LanguageTokenClass_ID, e=E_OTHERS; goto fin );\r
+\r
+ token_type = p->TokenType;\r
+ if ( token_type == TwoChar8( '/', '*' ) ) {\r
+ if ( ! is_in_cpp_comment ) {\r
+ is_in_c_comment = true;\r
+ }\r
+ is_cut = true;\r
}\r
- else if ( m->FileName[0] == _T('\0') ) {\r
- TCHAR* fname = m->FileName;\r
-\r
- m->FileName = StrT_refFName( m->FullPath );\r
- e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
- m->FileName = fname;\r
+ else if ( token_type == TwoChar8( '*', '/' ) ) {\r
+ if ( ! is_in_cpp_comment ) {\r
+ is_in_c_comment = false;\r
+ }\r
+ is_cut = true;\r
+ }\r
+ else if ( token_type == TwoChar8( '/', '/' ) ) {\r
+ if ( ! is_in_c_comment ) {\r
+ is_in_cpp_comment = true;\r
+ }\r
+ is_cut = true;\r
+ }\r
+ else if ( token_type == '\n' ){\r
+ is_in_cpp_comment = false;\r
+ is_cut = true;\r
}\r
else {\r
- e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ is_cut = ( is_in_c_comment || is_in_cpp_comment );\r
+ }\r
+\r
+ if ( is_cut ) {\r
+ e= ListIteratorClass_remove( &iterator );\r
+ e= HeapMemory_free( &p, e ); \r
}\r
- *( m->FileName - 1 ) = _T('\\');\r
}\r
\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
- /* * \82ð\92Ç\89Á */\r
- p = m->FileName;\r
- IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
- *p = _T('*'); *(p+1) = _T('\0');\r
\r
+ \r
+/***********************************************************************\r
+* Function: CutCommentC_1\r
+************************************************************************/\r
+errnum_t CutCommentC_1( const TCHAR* in_InputPath, const TCHAR* in_OutputPath )\r
+{\r
+ errnum_t e;\r
+ FILE* file = NULL;\r
+ TCHAR* text = NULL;\r
+ ListClass tokens;\r
\r
- /* \83t\83@\83C\83\8b\82©\83t\83H\83\8b\83_\82ð\97ñ\8b\93\82µ\82Ü\82· */\r
- find = FindFirstFileEx( m->FullPathMem, FindExInfoStandard, &data,\r
- FindExSearchNameMatch, NULL, 0 );\r
- done = ( find == INVALID_HANDLE_VALUE );\r
-\r
- while (!done)\r
- {\r
- if ( _tcscmp( data.cFileName, _T(".") ) == 0 ||\r
- _tcscmp( data.cFileName, _T("..") ) == 0 ) {\r
- done = ! FindNextFile( find, &data );\r
- continue;\r
- }\r
-\r
- StrT_cpy( m->FileName,\r
- sizeof(m->FullPathMem) - ( (char*)m->FileName - (char*)m->FullPathMem ),\r
- data.cFileName );\r
- m->FileAttributes = data.dwFileAttributes;\r
-\r
- if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
- TCHAR* prev_fname = m->FileName;\r
-\r
- p = _tcschr( m->FileName, _T('\0') );\r
-\r
- IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
- *p = _T('\\'); *(p+1) = _T('\0');\r
- m->FileName = p + 1;\r
-\r
- e= FileT_callByNestFind_sub( m ); IF(e)goto fin; /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ */\r
-\r
- m->FileName = prev_fname;\r
- }\r
- else {\r
- e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
- }\r
-\r
- done = ! FindNextFile( find, &data );\r
- }\r
- FindClose( find );\r
-\r
-\r
- /* 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
- if ( m->Flags & FileT_FolderAfterFiles ) {\r
- TCHAR* step_path = m->StepPath;\r
- TCHAR* fname = m->FileName;\r
-\r
- *( m->FileName - 1 ) = _T('\0');\r
- m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
- if ( ( *( m->StepPath - 1 ) == _T('\0') ) && ( m->StepPath > m->FullPath ) ) {\r
- m->StepPath = _T(".");\r
- }\r
- m->FileName = StrT_refFName( m->FullPath );\r
+ ListClass_initConst( &tokens );\r
\r
- e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ e= FileT_openForRead( &file, in_InputPath ); IF(e){goto fin;}\r
+ e= FileT_readAll( file, &text, NULL ); IF(e){goto fin;}\r
+ e= FileT_closeAndNULL( &file, 0 ); IF(e){goto fin;}\r
\r
- m->StepPath = step_path;\r
- m->FileName = fname;\r
- }\r
+ e= LexicalAnalize_C_Language( text, &tokens ); IF(e){goto fin;}\r
+ e= FileT_openForWrite( &file, in_OutputPath, 0 ); IF(e){goto fin;}\r
+ e= CopyWithoutComment_C_Language( &tokens, text, file ); IF(e){goto fin;}\r
+ e= FileT_closeAndNULL( &file, 0 ); IF(e){goto fin;}\r
\r
e=0;\r
fin:\r
+ e= Delete_C_LanguageToken( &tokens, e );\r
+ e= HeapMemory_free( &text, e );\r
+ e= FileT_closeAndNULL( &file, e );\r
return e;\r
-err_fa: e= E_FEW_ARRAY; goto fin;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [FileT_openForRead] >>> \r
+* Function: CopyWithoutComment_C_Language\r
************************************************************************/\r
-int FileT_openForRead( FILE** out_pFile, const TCHAR* Path )\r
+errnum_t CopyWithoutComment_C_Language( ListClass* in_Tokens, TCHAR* in_Text, FILE* in_OutStream )\r
{\r
- errno_t en;\r
-\r
- assert( Locale_isInited() );\r
+ errnum_t e;\r
+ const TCHAR* p;\r
+ TCHAR* source = in_Text;\r
+ TCHAR* comment_start = NULL;\r
+ TCHAR* comment_over = NULL;\r
+ bool is_new_space = false;\r
\r
- #if DEBUGTOOLS_USES\r
- { int e= Debug_onOpen( Path ); if(e) return e; }\r
- #endif\r
+ C_LanguageTokenClass* token;\r
+ ListIteratorClass iterator;\r
+ const ClassID_Class* class_ID;\r
\r
- en = _tfopen_s( out_pFile, Path, _T("r")_T(fopen_ccs) );\r
- if ( en == ENOENT ) {\r
- #ifndef UNDER_CE\r
- {\r
- TCHAR cwd[512];\r
\r
- if ( _tgetcwd( cwd, _countof(cwd) ) == NULL ) {\r
- cwd[0] = _T('\0');\r
- }\r
- Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\" current=\"%s\"/>"),\r
- Path, cwd );\r
- }\r
- #else\r
- Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\"/>"), Path );\r
- #endif\r
+ /* 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
\r
- return E_PATH_NOT_FOUND;\r
- }\r
- if ( en == EACCES ) {\r
- Error4_printf( _T("access denied \"%s\"\n"), Path );\r
- return E_ACCESS_DENIED;\r
- }\r
- IF(en)return E_OTHERS;\r
\r
- return 0;\r
-}\r
+ for ( ListClass_forEach( in_Tokens, &iterator, &token ) ) {\r
+ class_ID = token->ClassID;\r
+ if ( class_ID == &g_C_LanguageTokenClass_ID ) {\r
+ C_LanguageTokenEnum token_type = token->TokenType;\r
\r
+ if ( ( token_type == TwoChar8( '/', '*' ) || token_type == TwoChar8( '/', '/' )\r
+ ) && source <= token->Start && comment_start == NULL ) {\r
+ p = token->Start;\r
+ p = StrT_rskip( in_Text, p - 1, _T(" \t"), NULL );\r
\r
- \r
-/***********************************************************************\r
- <<< [FileT_openForWrite] >>> \r
-************************************************************************/\r
-int FileT_openForWrite( FILE** out_pFile, const TCHAR* Path, int Flags )\r
-{\r
- int e;\r
- errno_t en;\r
- TCHAR* open_type;\r
- BOOL b;\r
- int retry_count;\r
+ if ( p != NULL ) {\r
+ comment_start = (TCHAR*) p + 1;\r
+ } else {\r
+ comment_start = in_Text;\r
+ }\r
+ if ( source > comment_start )\r
+ { comment_start = source; }\r
\r
- IF_D( ! Locale_isInited() ) return E_NOT_INIT_GLOBAL;\r
\r
- #if Uses_AppKey\r
- e= AppKey_addNewWritableFolder( Path ); IF(e)goto fin;\r
- #endif\r
+ if ( token_type == TwoChar8( '/', '/' ) ) {\r
+ p = StrT_chr( comment_start, _T('\n') );\r
+ if ( p != NULL ) {\r
+ if ( comment_start == in_Text || *( comment_start - 1 ) == _T('\n') )\r
+ { p += 1; } /* This line has comment only */\r
+ } else {\r
+ p = StrT_chr( comment_start, _T('\0') );\r
+ }\r
\r
- if ( Flags & F_Append )\r
- open_type = ( Flags & F_Unicode ? _T("a")_T(fopen_ccs) : _T("at") );\r
- else\r
- open_type = ( Flags & F_Unicode ? _T("w")_T(fopen_ccs) : _T("wt") );\r
+ comment_over = (TCHAR*) p;\r
+ }\r
+ }\r
+ else if ( token_type == TwoChar8( '*', '/' ) && comment_start != NULL ) {\r
+ p = token->Over;\r
+ p = StrT_skip( p, _T(" \t") );\r
+ if ( comment_start > in_Text ) {\r
+ if ( *( comment_start - 1 ) == _T('\n') ) {\r
+ if ( *p == _T('\n') )\r
+ { p += 1; }\r
+ }\r
+ else if ( *p != _T('\n') ) {\r
+ /* Keeps spaces */\r
+ TCHAR* p2 = _tcschr( comment_start, _T('/') );\r
\r
- #if DEBUGTOOLS_USES\r
- { int e= Debug_onOpen( Path ); if(e) return e; }\r
- #endif\r
+ if ( p2 != comment_start ) {\r
+ comment_start = p2;\r
+ } else {\r
+ is_new_space = true;\r
+ }\r
+ }\r
+ }\r
\r
- for ( retry_count = 0; ; retry_count ++ ) {\r
- en = _tfopen_s( out_pFile, Path, open_type );\r
- if ( en != EACCES ) break;\r
+ comment_over = (TCHAR*) p;\r
+ }\r
\r
- retry_count += 1;\r
- if ( retry_count == 15 ) break;\r
- Sleep( 1000 );\r
- }\r
- if ( en == 2 ) { // ENOENT\r
- e= FileT_mkdir( Path ); IF(e)goto fin;\r
- b= RemoveDirectory( Path ); IF(!b)goto err_gt;\r
- en = _tfopen_s( out_pFile, Path, open_type );\r
\r
- IF ( en == 2 ) {\r
- _tprintf( _T("cannot open \"%s\"\n"), Path );\r
+ if ( comment_over != NULL ) {\r
+ e= FileT_writePart( in_OutStream, source, comment_start ); IF(e){goto fin;}\r
\r
- #ifndef UNDER_CE\r
- {\r
- TCHAR cwd[512];\r
+ if ( is_new_space ) {\r
+ _TINT rt= _fputtc( _T(' '), in_OutStream );\r
+ IF(rt==_TEOF){e=E_OTHERS; goto fin;}\r
+ is_new_space = false;\r
+ }\r
\r
- if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )\r
- _tprintf( _T("current = \"%s\"\n"), cwd );\r
+ source = comment_over;\r
+ comment_start = NULL;\r
+ comment_over = NULL;\r
}\r
- #endif\r
-\r
- e = E_NOT_FOUND_SYMBOL;\r
- goto fin;\r
}\r
}\r
- IF(en)goto err;\r
+ e= FileT_writePart( in_OutStream, source, StrT_chr( source, _T('\0') ) ); IF(e){goto fin;}\r
\r
e=0;\r
fin:\r
return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
-err_gt: e = SaveWindowsLastError(); goto fin;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [FileT_close] >>> \r
+ <<< [Delete_C_LanguageToken] >>> \r
************************************************************************/\r
-int FileT_close( FILE* File, int e )\r
+errnum_t Delete_C_LanguageToken( ListClass* /*<C_LanguageTokenClass*>*/ TokenList, errnum_t e )\r
{\r
- if ( File != NULL ) {\r
- int r = fclose( File );\r
- IF(r&&!e)e=E_ERRNO;\r
- }\r
- return e;\r
+ return ListClass_finalizeWithVTable( TokenList, true, e );\r
}\r
\r
\r
-\r
\r
/***********************************************************************\r
- <<< [FileT_closeAndNULL] >>> \r
+ <<< (C_LanguageTokenClass) >>> \r
************************************************************************/\r
-errnum_t FileT_closeAndNULL( FILE** in_out_File, errnum_t e )\r
-{\r
- FILE* file = *in_out_File;\r
-\r
- if ( file != NULL ) {\r
- int r = fclose( file );\r
- IF ( r && e == 0 ) { e = E_ERRNO; }\r
- *in_out_File = NULL;\r
- }\r
\r
- return e;\r
-}\r
+static const FinalizerVTableClass gs_C_LanguageTokenClass_FinalizerVTable = {\r
+ offsetof( C_LanguageTokenClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize,\r
+};\r
+static const PrintXML_VTableClass gs_C_LanguageTokenClass_PrintXML_VTable = {\r
+ offsetof( C_LanguageTokenClass, PrintXML_VTable ),\r
+ C_LanguageTokenClass_printXML,\r
+};\r
+static const InterfaceToVTableClass gs_C_LanguageTokenClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_C_LanguageTokenClass_FinalizerVTable },\r
+ { &g_PrintXML_Interface_ID, &gs_C_LanguageTokenClass_PrintXML_VTable },\r
+};\r
+static const ClassID_Class* gs_C_LanguageTokenClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_ParsedRangeClass_ID, &g_SyntaxSubNodeClass_ID,\r
+ &g_C_LanguageTokenClass_ID,\r
+};\r
\r
+/*[g_C_LanguageTokenClass_ID]*/\r
+const ClassID_Class g_C_LanguageTokenClass_ID = {\r
+ "C_LanguageTokenClass",\r
+ gs_C_LanguageTokenClass_SuperClassIDs,\r
+ _countof( gs_C_LanguageTokenClass_SuperClassIDs ),\r
+ sizeof( C_LanguageTokenClass ),\r
+ NULL,\r
+ gs_C_LanguageTokenClass_InterfaceToVTables,\r
+ _countof( gs_C_LanguageTokenClass_InterfaceToVTables ),\r
+};\r
\r
\r
\r
/***********************************************************************\r
- <<< [FileT_readAll] >>> \r
+ <<< [C_LanguageTokenClass_initConst] >>> \r
************************************************************************/\r
-#ifdef IsTest_FileT_readAll\r
- #define _CV(x) CoverageLogClass_output( x, _T("FileT_readAll") )\r
-#else\r
- #define _CV(x)\r
-#endif\r
-\r
-errnum_t FileT_readAll( FILE* File, TCHAR** out_Text, size_t* out_TextLength )\r
+void C_LanguageTokenClass_initConst( C_LanguageTokenClass* self )\r
{\r
-#ifdef IsTest_FileT_readAll\r
- enum { text_max_size_first = 0x10 };\r
-#else\r
- enum { text_max_size_first = 0xFF00 };\r
-#endif\r
- errnum_t e;\r
- TCHAR* text = NULL;\r
- TCHAR* text_over = (TCHAR*) DUMMY_INITIAL_VALUE;\r
- size_t text_max_size = text_max_size_first;\r
- TCHAR* text_max_over;\r
-\r
+ self->ClassID = &g_C_LanguageTokenClass_ID;\r
+ self->FinalizerVTable = &gs_C_LanguageTokenClass_FinalizerVTable;\r
+ self->Start = NULL;\r
+ self->Over = NULL;\r
+ self->PrintXML_VTable = &gs_C_LanguageTokenClass_PrintXML_VTable;\r
+ self->Parent = NULL;\r
+ ListElementClass_initConst( &self->SubNodeListElement, self );\r
+ self->TokenType = gc_TokenOfOther;\r
+ ListElementClass_initConst( &self->ListElement, self );\r
+ self->ParentBlock = NULL;\r
+}\r
\r
- text = (TCHAR*) malloc( text_max_size ); IF( text == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
- text_over = text;\r
- text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );\r
\r
- text[0] = _T('\0'); /* for empty file */\r
+ \r
+/***********************************************************************\r
+ <<< [C_LanguageTokenClass_printXML] >>> \r
+************************************************************************/\r
+errnum_t C_LanguageTokenClass_printXML( C_LanguageTokenClass* self, FILE* OutputStream )\r
+{\r
+ errnum_t e;\r
+ int r;\r
\r
- for (;;) {\r
- _fgetts( text_over, text_max_over - text_over, File );\r
+ r= _ftprintf_s( OutputStream, _T("<C_LanguageTokenClass") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
\r
- if ( *text_over == _T('\0') ) { /* End of file. If space line, *text_over == _T('\n'). */\r
- _CV(1);\r
- ASSERT_R( feof( File ), e=E_OTHERS; goto fin );\r
- break;\r
- }\r
- text_over = _tcschr( text_over, _T('\0') );\r
- if ( feof( File ) ) { break; }\r
+#if 0\r
+ r= _ftprintf_s( OutputStream, _T(" Address=\"0x%08X\""), self );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+#endif\r
\r
- if ( (uint8_t*) text_over - (uint8_t*) text == (int)( text_max_size - sizeof(TCHAR) ) ) {\r
- /* if full in text */\r
- TCHAR* new_text;\r
- size_t old_text_max_size = text_max_size;\r
+ r= _ftprintf_s( OutputStream, _T(" TokenType=\"%s\""),\r
+ C_LanguageTokenEnum_convertToStr( self->TokenType ) );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
\r
- #ifdef IsTest_FileT_readAll\r
- EmptyHeapMemoryEmulation( _T("T_FileT_readAll_FewMemory"), 1 );\r
- #endif\r
+ r= _ftprintf_s( OutputStream, _T(" Token=\"") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+ e= ftcopy_part_r( OutputStream, self->Start, self->Over ); IF(e){goto fin;}\r
+ r= _ftprintf_s( OutputStream, _T("\"") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
\r
- text_max_size *= 4;\r
- new_text = (TCHAR*) realloc( text, text_max_size );\r
- IF( new_text == NULL ) { e=E_FEW_MEMORY; _CV(2); goto fin; }\r
- text = new_text;\r
- text_over = (TCHAR*)( (uint8_t*) new_text + old_text_max_size - sizeof(TCHAR) );\r
- text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );\r
- }\r
- else {\r
- _CV(3);\r
- }\r
- }\r
+ r= _ftprintf_s( OutputStream, _T("/>\n") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
\r
e=0;\r
fin:\r
- if ( e ) {\r
- if ( text != NULL ) { _CV(4); free( text ); }\r
- }\r
- else {\r
- *out_Text = text;\r
- if ( out_TextLength != NULL ) { *out_TextLength = text_over - text; }\r
- }\r
return e;\r
}\r
-#undef _CV\r
\r
\r
\r
/***********************************************************************\r
- <<< [FileT_writePart] >>> \r
+ <<< [C_LanguageTokenEnum_convertToStr] >>> \r
************************************************************************/\r
-errnum_t FileT_writePart( FILE* File, const TCHAR* Start, TCHAR* Over )\r
-{\r
- errnum_t e;\r
- TCHAR back_char;\r
- int r;\r
\r
- back_char = *Over;\r
- *Over = _T('\0');\r
+static const NameAndNumClass C_LanguageTokenEnum_ConvertTable[] = {\r
+ { _T("Other"), gc_TokenOfOther },\r
+ { _T("Number"), gc_TokenOfNumber },\r
+ { _T("CIdentifier"), gc_TokenOfCIdentifier },\r
+ { _T("("), gc_TokenOf_28 },\r
+ { _T(")"), gc_TokenOf_29 },\r
+ { _T("{"), gc_TokenOf_7B },\r
+ { _T("}"), gc_TokenOf_7D },\r
+ { _T("["), gc_TokenOf_5B },\r
+ { _T("]"), gc_TokenOf_5D },\r
+ { _T(":"), gc_TokenOf_3A },\r
+ { _T(";"), gc_TokenOf_3B },\r
+ { _T("*"), gc_TokenOf_2A },\r
+ { _T("\\n"), gc_TokenOf_0A },\r
+ { _T("/*"), gc_TokenOf_2A2F },\r
+ { _T("*/"), gc_TokenOf_2F2A },\r
+ { _T("//"), gc_TokenOf_2F2F },\r
+};\r
\r
- IF ( Start > Over ) { e=E_OTHERS; goto fin; }\r
-\r
- r= _ftprintf_s( File, _T("%s"), Start ); IF(r<0){ e=E_ERRNO; goto fin; }\r
-\r
- e=0;\r
-fin:\r
- *Over = back_char;\r
- return e;\r
-}\r
+TCHAR* C_LanguageTokenEnum_convertToStr( C_LanguageTokenEnum Value )\r
+{\r
+ return StrT_convertNumToStr( Value, C_LanguageTokenEnum_ConvertTable,\r
+ _countof( C_LanguageTokenEnum_ConvertTable ), _T("Unknown") );\r
+}\r
\r
\r
\r
/***********************************************************************\r
- <<< [FileT_mkdir] >>> \r
+ <<< [Parse_PP_Directive] >>> \r
************************************************************************/\r
-int FileT_mkdir( const TCHAR* Path )\r
-{\r
- int e;\r
- DWORD r;\r
- TCHAR* p = (TCHAR*) DUMMY_INITIAL_VALUE;\r
- BOOL b;\r
- int n_folder = 0;\r
- TCHAR path2[MAX_PATH];\r
-\r
-\r
- e= StrT_getFullPath( path2, sizeof(path2), Path, NULL ); IF(e)goto fin;\r
- #if Uses_AppKey\r
- e= AppKey_addNewWritableFolder( path2 ); IF(e)goto fin;\r
- #endif\r
\r
+errnum_t Parse_PP_Directive_Step1( const TCHAR* Text, Set2* DirectivePointerArray );\r
+errnum_t Parse_PP_Directive_ConnectIf( Set2* DirectivePointerArray );\r
+errnum_t Parse_PP_Directive_Parameter( Set2* DirectivePointerArray );\r
\r
- //=== \91¶\8dÝ\82·\82é\83t\83H\83\8b\83_\82ð\92T\82·\r
- for (;;) {\r
- r = GetFileAttributes( path2 );\r
- if ( r != (DWORD)-1 ) break; // "C:" \82à\83t\83H\83\8b\83_\82Æ\94»\92è\82³\82ê\82é\r
-\r
- p = StrT_refFName( path2 ) - 1; // \90â\91Î\83p\83X\82È\82Ì\82Å\95K\82¸ *p=='\\'\r
- *p = _T('\0');\r
- n_folder ++;\r
- }\r
- IF ( ! (r & FILE_ATTRIBUTE_DIRECTORY) ) goto err; // \83t\83@\83C\83\8b\82È\82ç\83G\83\89\81[\r
\r
+errnum_t Parse_PP_Directive( const TCHAR* Text,\r
+ Set2* /*<PP_DirectiveClass*>*/ DirectivePointerArray )\r
+{\r
+ errnum_t e;\r
\r
- //=== \83t\83H\83\8b\83_\82ð\8dì\90¬\82·\82é\r
- for ( ; n_folder > 0; n_folder -- ) {\r
- *p = _T('\\');\r
- b= CreateDirectory( path2, NULL ); IF(!b)goto err;\r
- p = _tcschr( p, _T('\0') );\r
- }\r
+ e= Parse_PP_Directive_Step1( Text, DirectivePointerArray ); IF(e){goto fin;}\r
+ e= Parse_PP_Directive_ConnectIf( DirectivePointerArray ); IF(e){goto fin;}\r
+ e= Parse_PP_Directive_Parameter( DirectivePointerArray ); IF(e){goto fin;}\r
\r
e=0;\r
fin:\r
return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
}\r
\r
\r
-\r
- \r
-/***********************************************************************\r
- <<< [FileT_copy] >>> \r
-************************************************************************/\r
-int FileT_copy_sub( FileT_CallByNestFindData* m );\r
-\r
-int FileT_copy( const TCHAR* SrcPath, const TCHAR* DstPath )\r
+/*[Parse_PP_Directive_Step1]*/\r
+errnum_t Parse_PP_Directive_Step1( const TCHAR* Text, Set2* DirectivePointerArray )\r
{\r
- const TCHAR* p_last;\r
- int e;\r
- BOOL b;\r
- TCHAR path[MAX_PATH*4];\r
-\r
-\r
- #if Uses_AppKey\r
- e= AppKey_addNewWritableFolder( DstPath ); IF(e)goto fin;\r
- #endif\r
+ errnum_t e;\r
+ const TCHAR* pos;\r
+ const TCHAR* p;\r
+ PP_DirectiveClass* directive = NULL;\r
+ PP_DirectiveClass directive_0;\r
+ PP_DirectiveClass** directive_pp;\r
+ ClassID_Class* class_ID;\r
\r
- p_last = _tcschr( SrcPath, _T('\0') );\r
- IF_D( p_last <= SrcPath + 1 )goto err_ni;\r
+ pos = Text;\r
+ PP_DirectiveClass_initConst( &directive_0 );\r
\r
+ for (;;) {\r
\r
- //=== \83t\83H\83\8b\83_\82ð\83R\83s\81[\82·\82é\r
- if ( *(p_last - 1) == _T('*') ) {\r
- IF_D( *(p_last - 2) != _T('\\') ) goto err_ni;\r
+ /* Set "DirectiveName_Start" */\r
+ p = _tcschr( pos, _T('#') );\r
+ if ( p == NULL )\r
+ { break; }\r
+ p = StrT_skip( p + 1, _T(" \t") );\r
+ ASSERT_R( *p != _T('\0'), e=E_OTHERS; goto fin );\r
+ directive_0.DirectiveName_Start = p;\r
\r
- e= StrT_getParentFullPath( path, sizeof(path), SrcPath, NULL ); IF(e)goto fin;\r
- IF_D( ! FileT_isDir( path ) )goto err_nf;\r
\r
- e= FileT_callByNestFind( path, FileT_FolderBeforeFiles, (void*) DstPath, (FuncType) FileT_copy_sub );\r
- IF(e)goto fin;\r
- }\r
+ /* Set "DirectiveName_Over" */\r
+ directive_0.DirectiveName_Over =\r
+ StrT_searchOverOfCIdentifier( directive_0.DirectiveName_Start );\r
\r
\r
- //=== \83t\83@\83C\83\8b\82ð\83R\83s\81[\82·\82é\r
- else {\r
- IF_D( _tcschr( SrcPath, _T('*') ) != NULL )goto err_ni;\r
- IF_D( ! FileT_isFile( SrcPath ) ) goto err_nf;\r
+ /* Set "Start" */\r
+ p = StrT_rstr( Text, directive_0.DirectiveName_Start, _T("\n"), NULL );\r
+ if ( p == NULL ) { p = Text; }\r
+ else { p += 1; }\r
+ directive_0.Start = p;\r
\r
- b= CopyFile( SrcPath, DstPath, FALSE );\r
- if (!b) {\r
- if ( FileT_isDir( DstPath ) ) {\r
- e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
- b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
- }\r
- else {\r
- int ee;\r
\r
- p_last = _tcschr( DstPath, _T('\0') ) - 1;\r
- IF_D( p_last < DstPath )goto err;\r
- if ( *p_last == _T('\\') ) {\r
- ee= FileT_mkdir( DstPath ); IF(ee)goto fin;\r
- e= stprintf_r( path, sizeof(path), _T("%s%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
- b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
- }\r
- else {\r
- e = E_ACCESS_DENIED;\r
- ee= StrT_getParentFullPath( path, sizeof(path), DstPath, NULL ); IF(ee)goto fin;\r
- ee= FileT_mkdir( path ); IF(ee)goto fin;\r
- b= CopyFile( SrcPath, DstPath, FALSE ); IF(!b)goto err_gt;\r
- }\r
+ /* Set "Over" */\r
+ p = directive_0.DirectiveName_Over;\r
+ for (;;) {\r
+ const TCHAR* p2 = _tcschr( p, _T('\n') );\r
+ if ( p2 == NULL ) {\r
+ p = _tcschr( p, _T('\0') );\r
+ break;\r
+ } else if ( *( p2 - 1 ) == _T('\\') ) {\r
+ p = p2 + 1;\r
+ continue;\r
+ } else {\r
+ p = p2 + 1;\r
+ break;\r
}\r
}\r
- }\r
-\r
- e=0;\r
-fin:\r
- return e;\r
-\r
-err_ni: e = E_NOT_IMPLEMENT_YET; goto fin;\r
-err_nf: e = E_PATH_NOT_FOUND; goto fin;\r
-err_gt: e = SaveWindowsLastError(); goto fin;\r
-err: e = E_OTHERS; goto fin;\r
-}\r
-\r
+ directive_0.Over = p;\r
\r
-int FileT_copy_sub( FileT_CallByNestFindData* m )\r
-{\r
- const TCHAR* DstPath = (const TCHAR*) m->CallerArgument;\r
- int e;\r
- BOOL b;\r
- TCHAR path[MAX_PATH*4];\r
\r
- e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, m->StepPath ); IF(e)goto fin;\r
+ /* Set "directive" */\r
+ {\r
+ static NameOnlyClass table[] = {\r
+ { _T("define"), (void*) &g_PP_SharpDefineClass_ID },\r
+ { _T("include"),(void*) &g_PP_SharpIncludeClass_ID },\r
+ { _T("if"), (void*) &g_PP_SharpIfClass_ID },\r
+ { _T("else"), (void*) &g_PP_SharpElseClass_ID },\r
+ { _T("endif"), (void*) &g_PP_SharpEndifClass_ID },\r
+ { _T("ifdef"), (void*) &g_PP_SharpIfdefClass_ID },\r
+ { _T("ifndef"), (void*) &g_PP_SharpIfndefClass_ID },\r
+ };\r
\r
- if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
- if ( ! FileT_isDir( path ) )\r
- { b= CreateDirectory( path, NULL ); IF(!b)goto err_gt; }\r
- }\r
- else {\r
- b= CopyFile( m->FullPath, path, FALSE ); IF(!b)goto err_gt;\r
- }\r
+ class_ID = StrT_convPartStrToPointer(\r
+ directive_0.DirectiveName_Start,\r
+ directive_0.DirectiveName_Over,\r
+ table, sizeof(table), (void*) &g_PP_DirectiveClass_ID );\r
+ }\r
\r
- e=0;\r
-fin:\r
- return e;\r
+ e= ClassID_Class_createObject( class_ID, &directive, NULL ); IF(e){goto fin;}\r
\r
-err_gt: e = SaveWindowsLastError(); goto fin;\r
-}\r
+ directive->DirectiveName_Start = directive_0.DirectiveName_Start;\r
+ directive->DirectiveName_Over = directive_0.DirectiveName_Over;\r
+ directive->Start = directive_0.Start;\r
+ directive->Over = directive_0.Over;\r
\r
\r
+ /* Add to "DirectivePointerArray" (1) */\r
+ e= Set2_alloc( DirectivePointerArray, &directive_pp, PP_DirectiveClass* );\r
+ IF(e){goto fin;}\r
\r
- \r
-/***********************************************************************\r
- <<< [FileT_del] >>> \r
-************************************************************************/\r
-int FileT_del_sub( FileT_CallByNestFindData* m );\r
\r
-int FileT_del( const TCHAR* Path )\r
-{\r
- int e;\r
- DWORD r;\r
- TCHAR abs_path[MAX_PATH];\r
+ /* Add to "DirectivePointerArray" (2) */\r
+ *directive_pp = directive;\r
+ directive = NULL;\r
\r
- e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto fin;\r
- #if Uses_AppKey\r
- e= AppKey_addNewWritableFolder( abs_path ); IF(e)goto fin;\r
- #endif\r
\r
- r= GetFileAttributes( Path );\r
- if ( r != (DWORD)-1 ) {\r
- if ( r & FILE_ATTRIBUTE_DIRECTORY ) {\r
- e= FileT_callByNestFind( Path, FileT_FolderAfterFiles, NULL, (FuncType) FileT_del_sub );\r
- }\r
- else {\r
- BOOL b= DeleteFile( Path ); IF(!b)goto err_gt;\r
- }\r
+ /* Next */\r
+ pos = directive_0.Over;\r
+ PP_DirectiveClass_initConst( &directive_0 );\r
}\r
- IF_D( FileT_isExist( Path ) )goto err_ad;\r
\r
e=0;\r
fin:\r
+ if ( directive != NULL ) { e= HeapMemory_free( &directive, e ); }\r
return e;\r
-\r
-err_gt: e = SaveWindowsLastError(); goto fin;\r
-err_ad: e = E_ACCESS_DENIED; goto fin;\r
}\r
\r
\r
-int FileT_del_sub( FileT_CallByNestFindData* m )\r
+/*[Parse_PP_Directive_ConnectIf]*/\r
+errnum_t Parse_PP_Directive_ConnectIf( Set2* DirectivePointerArray )\r
{\r
- int e;\r
- BOOL b;\r
+ errnum_t e;\r
+ PP_DirectiveClass** pp;\r
+ PP_DirectiveClass** pp_over;\r
+ PP_DirectiveClass* directive;\r
+ PP_SharpIfClass** pp_sh_if; /* pp is pointer of pointer, sh = sharp */\r
+ PP_SharpElseClass** pp_sh_else;\r
+ Set2 if_stack;\r
+ Set2 else_stack;\r
+ PP_SharpIfClass* sh_if; /* sh = sharp */\r
+ PP_SharpElseClass* sh_else; /* sh = sharp */\r
+ PP_SharpEndifClass* sh_endif; /* sh = sharp */\r
+ PP_DirectiveClass* sh_if_or_else; /* sh = sharp */\r
\r
- if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
- b= RemoveDirectory( m->FullPath ); IF(!b)goto err_gt;\r
- }\r
- else {\r
- b= DeleteFile( m->FullPath ); IF(!b)goto err_gt;\r
- }\r
\r
- e=0;\r
-fin:\r
- return e;\r
+ Set2_initConst( &if_stack );\r
+ Set2_initConst( &else_stack );\r
+ e= Set2_init( &if_stack, 0x10 ); IF(e){goto fin;}\r
+ e= Set2_init( &else_stack, 0x10 ); IF(e){goto fin;}\r
+ sh_if = NULL;\r
+ sh_else = NULL;\r
+ sh_endif = NULL;\r
+ sh_if_or_else = NULL;\r
\r
-err_gt: e = SaveWindowsLastError(); goto fin;\r
-}\r
- \r
-/***********************************************************************\r
- <<< [AppKey] >>> \r
-************************************************************************/\r
-static errnum_t AppKey_create( AppKey** out_m );\r
-static bool AppKey_isSame( AppKey* m );\r
-static void Writables_initConst( Writables* m );\r
-static errnum_t Writables_init( Writables* m, AppKey* Key );\r
-static errnum_t Writables_finish( Writables* m, int e );\r
-static bool Writables_isInited( Writables* m );\r
-static errnum_t Writables_clearPaths( Writables* m );\r
-static errnum_t Writables_create( Writables** out_m, AppKey* Key );\r
-static errnum_t Writables_copyToConst( Writables* To, Writables* From );\r
+ for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {\r
+ directive = *pp;\r
\r
+ if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfClass_ID ) ) {\r
\r
-typedef struct _CurrentWritables CurrentWritables;\r
-struct _CurrentWritables {\r
- Writables m_CurrentWritables;\r
- TCHAR* m_ProgramFiles; size_t m_ProgramFiles_Len;\r
- TCHAR* m_windir; size_t m_windir_Len;\r
- TCHAR* m_APPDATA; size_t m_APPDATA_Len;\r
- TCHAR* m_LOCALAPPDATA; size_t m_LOCALAPPDATA_Len;\r
-};\r
-static void CurrentWritables_initConst( CurrentWritables* m );\r
-static errnum_t CurrentWritables_init( CurrentWritables* m );\r
-static errnum_t CurrentWritables_finish( CurrentWritables* m, int e );\r
-static errnum_t CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath );\r
+ /* Start of nest */\r
+ if ( sh_if_or_else != NULL ) {\r
+ e= Set2_alloc( &if_stack, &pp_sh_if, PP_SharpIfClass* );\r
+ IF(e){goto fin;}\r
+ *pp_sh_if = sh_if;\r
\r
+ e= Set2_alloc( &else_stack, &pp_sh_else, PP_SharpElseClass* );\r
+ IF(e){goto fin;}\r
+ *pp_sh_else = sh_else;\r
+ }\r
\r
-//////////////////////////////\r
+ /* Set "sh_if" */\r
+ sh_if = (PP_SharpIfClass*) directive;\r
+ sh_if_or_else = directive;\r
+ }\r
+ else if ( directive->ClassID == &g_PP_SharpElseClass_ID ) {\r
+ sh_else = (PP_SharpElseClass*) directive;\r
\r
-static AppKey g_AppKey;\r
-static AppKey* g_AppKeyPrivate;\r
+ IF ( sh_if == NULL ) {\r
+ Error4_printf( _T("<ERROR msg=\"Not found #if\"/>") );\r
+ e= E_ORIGINAL; goto fin;\r
+ }\r
\r
-// under g_AppKey\r
-Writables g_DefaultWritables;\r
-Writables g_CurrentWritables; // public\r
-static CurrentWritables g_CurrentWritablesPrivate;\r
+ /* Link #if and #else */\r
+ sh_if->NextDirective = directive;\r
+ sh_else->StartDirective = sh_if;\r
+ sh_if_or_else = directive;\r
+ }\r
+ else if ( directive->ClassID == &g_PP_SharpEndifClass_ID ) {\r
+ sh_endif = (PP_SharpEndifClass*) directive;\r
\r
+ IF ( sh_if_or_else == NULL ) {\r
+ Error4_printf( _T("<ERROR msg=\"Not found #if\"/>") );\r
+ e= E_ORIGINAL; goto fin;\r
+ }\r
\r
-static errnum_t AppKey_create( AppKey** out_m )\r
-{\r
- errnum_t e;\r
+ /* Link ( #if or #else ) and #endif */\r
+ sh_if->EndDirective = sh_endif;\r
+ if ( sh_else == NULL )\r
+ { sh_if->NextDirective = directive; }\r
+ else\r
+ { sh_else->EndDirective = sh_endif; }\r
+ sh_endif->StartDirective = sh_if;\r
+ sh_endif->PreviousDirective = sh_if_or_else;\r
\r
- IF( g_AppKeyPrivate != NULL ) { e=1; goto fin; }\r
- // 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
+ sh_if = NULL;\r
+ sh_else = NULL;\r
+ sh_endif = NULL;\r
+ sh_if_or_else = NULL;\r
\r
- Writables_initConst( &g_DefaultWritables );\r
- CurrentWritables_initConst( &g_CurrentWritablesPrivate );\r
+ /* End of nest */\r
+ if ( if_stack.Next > if_stack.First ) {\r
+ e= Set2_pop( &if_stack, &pp_sh_if, PP_SharpIfClass* );\r
+ IF(e){goto fin;}\r
+ sh_if = *pp_sh_if;\r
\r
- e= CurrentWritables_init( &g_CurrentWritablesPrivate ); IF(e)goto fin;\r
- e= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(e)goto fin;\r
+ e= Set2_pop( &else_stack, &pp_sh_else, PP_SharpElseClass* );\r
+ IF(e){goto fin;}\r
+ sh_else = *pp_sh_else;\r
\r
- *out_m = &g_AppKey;\r
- g_AppKeyPrivate = &g_AppKey;\r
+ if ( sh_else == NULL ) {\r
+ sh_if_or_else = (PP_DirectiveClass*) sh_if;\r
+ } else {\r
+ sh_if_or_else = (PP_DirectiveClass*) sh_else;\r
+ }\r
+ }\r
+ }\r
+ }\r
\r
e=0;\r
fin:\r
+ e= Set2_finish( &if_stack, e );\r
+ e= Set2_finish( &else_stack, e );\r
return e;\r
}\r
\r
\r
-static bool AppKey_isSame( AppKey* m )\r
+/*[Parse_PP_Directive_Parameter]*/\r
+errnum_t Parse_PP_Directive_Parameter( Set2* DirectivePointerArray )\r
{\r
- return ( m == g_AppKeyPrivate );\r
-}\r
+ errnum_t e;\r
+ TCHAR* p;\r
+ PP_DirectiveClass** pp;\r
+ PP_DirectiveClass** pp_over;\r
+ PP_DirectiveClass* directive;\r
+\r
+ for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {\r
+ directive = *pp;\r
\r
+ if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpDefineClass_ID ) ) {\r
+ PP_SharpDefineClass* sh_define = (PP_SharpDefineClass*) directive;\r
\r
-void AppKey_initGlobal_const()\r
-{\r
- Writables_initConst( &g_DefaultWritables );\r
+ p = StrT_skip( sh_define->DirectiveName_Over, _T(" \t") );\r
+ IF ( p >= sh_define->Over ) { e=E_OTHERS; goto fin; }\r
+ sh_define->Symbol_Start = p;\r
+\r
+ p = StrT_searchOverOfCIdentifier( p );\r
+ sh_define->Symbol_Over = p;\r
+ }\r
+\r
+ if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIncludeClass_ID ) ) {\r
+ TCHAR* p;\r
+ TCHAR* closers;\r
+ PP_SharpIncludeClass* sh_include = (PP_SharpIncludeClass*) directive;\r
+\r
+ p = StrT_skip( sh_include->DirectiveName_Over, _T(" \t") );\r
+ IF ( p >= sh_include->Over ) { e=E_OTHERS; goto fin; }\r
+ switch ( *p ) {\r
+ case '<':\r
+ sh_include->PathBracket = _T('<');\r
+ closers = _T(">");\r
+ break;\r
+\r
+ case '"':\r
+ sh_include->PathBracket = _T('"');\r
+ closers = _T("\"");\r
+ break;\r
+\r
+ default:\r
+ sh_include->PathBracket = _T('\0');\r
+ closers = _T(" \t\n");\r
+ break;\r
+ }\r
+\r
+ sh_include->Path_Start = p + 1;\r
+\r
+ p = StrT_chrs( p + 1, closers );\r
+ IF ( p == NULL ) { e=E_OTHERS; goto fin; }\r
+ sh_include->Path_Over = p;\r
+ }\r
+\r
+ if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfdefClass_ID ) ) {\r
+ TCHAR* p;\r
+ PP_SharpIfdefClass* sh_ifdef; /* sh = sharp */\r
+\r
+ sh_ifdef = (PP_SharpIfdefClass*) directive;\r
+\r
+ p = StrT_skip( sh_ifdef->DirectiveName_Over, _T(" \t") );\r
+ IF ( p >= sh_ifdef->Over ) { e=E_OTHERS; goto fin; }\r
+ sh_ifdef->Symbol_Start = p;\r
+\r
+ p = StrT_searchOverOfCIdentifier( p );\r
+ sh_ifdef->Symbol_Over = p;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
\r
\r
-errnum_t AppKey_finishGlobal( errnum_t e )\r
+ \r
+/***********************************************************************\r
+ <<< [Delete_PP_Directive] >>> \r
+************************************************************************/\r
+errnum_t Delete_PP_Directive( Set2* DirectivePointerArray, errnum_t e )\r
{\r
- errnum_t ee;\r
+ PP_DirectiveClass** pp;\r
+ PP_DirectiveClass** pp_over;\r
+ PP_DirectiveClass* directive;\r
+ FinalizerVTableClass* finalizer;\r
\r
- e= Writables_finish( &g_DefaultWritables, e );\r
- e= CurrentWritables_finish( &g_CurrentWritablesPrivate, e );\r
- ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
+ if ( Set2_isInited( DirectivePointerArray ) ) {\r
+ for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {\r
+ directive = *pp;\r
+ finalizer = ClassID_Class_getVTable( directive->ClassID,\r
+ &g_FinalizerInterface_ID );\r
+ e= finalizer->Finalize( directive, e );\r
+ e= HeapMemory_free( &directive, e );\r
+ }\r
\r
+ e= Set2_finish( DirectivePointerArray, e );\r
+ }\r
return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [AppKey_newWritable] >>> \r
+ <<< [CutPreprocessorDirectives_from_C_LanguageToken] >>> \r
************************************************************************/\r
-errnum_t AppKey_newWritable( AppKey** in_out_m, Writables** out_Writable, ... )\r
+errnum_t CutPreprocessorDirectives_from_C_LanguageToken(\r
+ ListClass* /*<C_LanguageTokenClass*>*/ TokenList,\r
+ Set2* /*<PP_DirectiveClass*>*/ Directives )\r
{\r
- errnum_t e;\r
- AppKey* m = NULL;\r
- Writables* wr = NULL;\r
- #if Uses_OutMallocIDTool\r
- bool is_prev_out_malloc;\r
+ errnum_t e;\r
+ C_LanguageTokenClass* token;\r
+ ListIteratorClass iterator;\r
+ PP_DirectiveClass** pp_directive = Directives->First;\r
+ PP_DirectiveClass** pp_directive_over = Directives->Next;\r
+ PP_DirectiveClass* directive = *pp_directive;\r
\r
- is_prev_out_malloc = OutMallocID_setEnable( false );\r
- #endif\r
\r
+ if ( pp_directive == pp_directive_over )\r
+ { e=0; goto fin; }\r
\r
- //=== AppKey* m \82ð\97L\8cø\82É\82·\82é\r
- if ( in_out_m == NULL ) { // \8d¡\89ñ\82Ì\8aÖ\90\94\82Ì\92\86\82¾\82¯\82Å\8eQ\8fÆ\82·\82é\r
- e= AppKey_create( &m ); IF(e)goto resume;\r
- }\r
- 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
- e= AppKey_create( &m ); IF(e)goto resume;\r
- *in_out_m = m;\r
- }\r
- 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
- m = *in_out_m;\r
+ e= ListClass_getListIterator( TokenList, &iterator ); IF(e){goto fin;}\r
+ for (;;) {\r
+ token = (C_LanguageTokenClass*) ListIteratorClass_getNext( &iterator );\r
+ if ( token == NULL ) { break; }\r
+ ASSERT_D( token->ClassID == &g_C_LanguageTokenClass_ID, e=E_OTHERS; goto fin );\r
+\r
+ if ( token->Start >= directive->Start ) {\r
+ if ( token->Over <= directive->Over ) {\r
+ e= ListIteratorClass_remove( &iterator );\r
+ e= HeapMemory_free( &token, 0 ); IF(e){goto fin;}\r
+ }\r
+ else {\r
+ while ( token->Start > directive->Over ) {\r
+ pp_directive += 1;\r
+ if ( pp_directive >= pp_directive_over )\r
+ { break; }\r
+ directive = *pp_directive;\r
+ }\r
+ }\r
+ }\r
}\r
\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
- //=== \90³\8bK\82Ì AppKey \82©\83`\83F\83b\83N\82·\82é\r
- IF( ! AppKey_isSame( m ) )goto err;\r
\r
+ \r
+/***********************************************************************\r
+ <<< (PP_DirectiveClass) >>> \r
+************************************************************************/\r
\r
- //=== Writable \82ð\90¶\90¬\82·\82é\r
- if ( out_Writable == NULL ) {\r
- wr = &g_DefaultWritables;\r
- e= Writables_finish( wr, 0 ); IF(e)goto resume;\r
- e= Writables_init( wr, m ); IF(e)goto resume;\r
+/*[PP_DirectiveClass_initConst]*/\r
+void PP_DirectiveClass_initConst( PP_DirectiveClass* self )\r
+{\r
+ self->ClassID = &g_PP_DirectiveClass_ID;\r
+ self->Start = NULL;\r
+ self->Over = NULL;\r
+ self->DirectiveName_Start = NULL;\r
+ self->DirectiveName_Over = NULL;\r
+}\r
+\r
+/*[g_PP_DirectiveClass_ID]*/\r
+static const ClassID_Class* gs_PP_DirectiveClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_DirectiveClass_FinalizerVTable = {\r
+ offsetof( PP_DirectiveClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_DirectiveClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_DirectiveClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_DirectiveClass_ID = {\r
+ "PP_DirectiveClass",\r
+ gs_PP_DirectiveClass_SuperClassIDs,\r
+ _countof( gs_PP_DirectiveClass_SuperClassIDs ),\r
+ sizeof( PP_DirectiveClass ),\r
+ NULL,\r
+ gs_PP_DirectiveClass_InterfaceToVTables,\r
+ _countof( gs_PP_DirectiveClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpDefineClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpDefineClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpDefineClass_FinalizerVTable = {\r
+ offsetof( PP_SharpDefineClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpDefineClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpDefineClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpDefineClass_ID = {\r
+ "PP_SharpDefineClass",\r
+ gs_PP_SharpDefineClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpDefineClass_SuperClassIDs ),\r
+ sizeof( PP_SharpDefineClass ),\r
+ NULL,\r
+ gs_PP_SharpDefineClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpDefineClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpIncludeClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpIncludeClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpIncludeClass_FinalizerVTable = {\r
+ offsetof( PP_SharpIncludeClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpIncludeClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpIncludeClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpIncludeClass_ID = {\r
+ "PP_SharpIncludeClass",\r
+ gs_PP_SharpIncludeClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpIncludeClass_SuperClassIDs ),\r
+ sizeof( PP_SharpIncludeClass ),\r
+ NULL,\r
+ gs_PP_SharpIncludeClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpIncludeClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpIfClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpIfClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpIfClass_FinalizerVTable = {\r
+ offsetof( PP_SharpIfClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpIfClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpIfClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpIfClass_ID = {\r
+ "PP_SharpIfClass",\r
+ gs_PP_SharpIfClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpIfClass_SuperClassIDs ),\r
+ sizeof( PP_SharpIfClass ),\r
+ NULL,\r
+ gs_PP_SharpIfClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpIfClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpElseClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpElseClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpElseClass_FinalizerVTable = {\r
+ offsetof( PP_SharpElseClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpElseClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpElseClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpElseClass_ID = {\r
+ "PP_SharpElseClass",\r
+ gs_PP_SharpElseClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpElseClass_SuperClassIDs ),\r
+ sizeof( PP_SharpElseClass ),\r
+ NULL,\r
+ gs_PP_SharpElseClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpElseClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpEndifClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpEndifClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpEndifClass_FinalizerVTable = {\r
+ offsetof( PP_SharpEndifClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpEndifClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpEndifClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpEndifClass_ID = {\r
+ "PP_SharpEndifClass",\r
+ gs_PP_SharpEndifClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpEndifClass_SuperClassIDs ),\r
+ sizeof( PP_SharpEndifClass ),\r
+ NULL,\r
+ gs_PP_SharpEndifClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpEndifClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpIfdefClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpIfdefClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpIfdefClass_FinalizerVTable = {\r
+ offsetof( PP_SharpIfdefClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpIfdefClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpIfdefClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpIfdefClass_ID = {\r
+ "PP_SharpIfdefClass",\r
+ gs_PP_SharpIfdefClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpIfdefClass_SuperClassIDs ),\r
+ sizeof( PP_SharpIfdefClass ),\r
+ NULL,\r
+ gs_PP_SharpIfdefClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpIfdefClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpIfndefClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpIfndefClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID, &g_PP_SharpIfdefClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpIfndefClass_FinalizerVTable = {\r
+ offsetof( PP_SharpIfndefClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpIfndefClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpIfndefClass_FinalizerVTable }\r
+};\r
+\r
+const ClassID_Class g_PP_SharpIfndefClass_ID = {\r
+ "PP_SharpIfndefClass",\r
+ gs_PP_SharpIfndefClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpIfndefClass_SuperClassIDs ),\r
+ sizeof( PP_SharpIfndefClass ),\r
+ NULL,\r
+ gs_PP_SharpIfndefClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpIfndefClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (SyntaxSubNodeClass) >>> \r
+************************************************************************/\r
+\r
+/*[g_SyntaxSubNodeClass_ID]*/\r
+const ClassID_Class g_SyntaxSubNodeClass_ID = {\r
+ "SyntaxSubNodeClass",\r
+ NULL,\r
+ 0,\r
+ sizeof( SyntaxSubNodeClass ),\r
+ NULL,\r
+ NULL,\r
+ 0,\r
+};\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Delete_SyntaxNodeList] >>> \r
+************************************************************************/\r
+errnum_t Delete_SyntaxNodeList( ListClass* /*<SyntaxNodeClass*>*/ NodeList, errnum_t e )\r
+{\r
+ return ListClass_finalizeWithVTable( NodeList, true, e );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (SyntaxNodeClass) >>> \r
+************************************************************************/\r
+\r
+static const FinalizerVTableClass gs_SyntaxNodeClass_FinalizerVTable = {\r
+ offsetof( SyntaxNodeClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize,\r
+};\r
+static const PrintXML_VTableClass gs_SyntaxNodeClass_PrintXML_VTable = {\r
+ offsetof( SyntaxNodeClass, PrintXML_VTable ),\r
+ SyntaxNodeClass_printXML,\r
+};\r
+static const InterfaceToVTableClass gs_SyntaxNodeClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_SyntaxNodeClass_FinalizerVTable },\r
+ { &g_PrintXML_Interface_ID, &gs_SyntaxNodeClass_PrintXML_VTable },\r
+};\r
+static const ClassID_Class* gs_SyntaxNodeClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_ParsedRangeClass_ID, &g_SyntaxSubNodeClass_ID,\r
+ &g_SyntaxNodeClass_ID,\r
+};\r
+\r
+/*[g_SyntaxNodeClass_ID]*/\r
+const ClassID_Class g_SyntaxNodeClass_ID = {\r
+ "SyntaxNodeClass",\r
+ gs_SyntaxNodeClass_SuperClassIDs,\r
+ _countof( gs_SyntaxNodeClass_SuperClassIDs ),\r
+ sizeof( SyntaxNodeClass ),\r
+ NULL,\r
+ gs_SyntaxNodeClass_InterfaceToVTables,\r
+ _countof( gs_SyntaxNodeClass_InterfaceToVTables ),\r
+};\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [SyntaxNodeClass_initConst] >>> \r
+************************************************************************/\r
+void SyntaxNodeClass_initConst( SyntaxNodeClass* self )\r
+{\r
+ self->ClassID = &g_SyntaxNodeClass_ID;\r
+ self->FinalizerVTable = &gs_SyntaxNodeClass_FinalizerVTable;\r
+ self->Start = NULL;\r
+ self->Over = NULL;\r
+ self->PrintXML_VTable = &gs_SyntaxNodeClass_PrintXML_VTable;\r
+ self->Parent = NULL;\r
+ ListElementClass_initConst( &self->SubNodeListElement, self );\r
+ ListClass_initConst( &self->SubNodeList );\r
+ ListElementClass_initConst( &self->ListElement, self );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [SyntaxNodeClass_printXML] >>> \r
+************************************************************************/\r
+errnum_t SyntaxNodeClass_printXML( SyntaxNodeClass* self, FILE* OutputStream )\r
+{\r
+ errnum_t e;\r
+ int r;\r
+\r
+ r= _ftprintf_s( OutputStream, _T("<SyntaxNodeClass") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ r= _ftprintf_s( OutputStream, _T(" Address=\"0x%08X\""), self );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ r= _ftprintf_s( OutputStream, _T("/>\n") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [SyntaxNodeClass_addSubNode] >>> \r
+************************************************************************/\r
+errnum_t SyntaxNodeClass_addSubNode( SyntaxNodeClass* self, SyntaxSubNodeClass* SubNode )\r
+{\r
+ errnum_t e;\r
+\r
+ ASSERT_D( ClassID_Class_isSuperClass( self->ClassID, &g_SyntaxNodeClass_ID ), e=E_OTHERS; goto fin );\r
+ ASSERT_D( ClassID_Class_isSuperClass( SubNode->ClassID, &g_SyntaxSubNodeClass_ID ), e=E_OTHERS; goto fin );\r
+ ASSERT_R( SubNode->Parent == NULL, e=E_OTHERS; goto fin );\r
+\r
+ e= ListClass_addLast( &self->SubNodeList, &SubNode->SubNodeListElement ); IF(e){goto fin;}\r
+ SubNode->Parent = self;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [LineNumberIndexClass_compare_sub] >>> \r
+************************************************************************/\r
+int LineNumberIndexClass_compare_sub( const void* ppLeft, const void* ppRight, const void* Param,\r
+ int* out_Result )\r
+{\r
+ UNREFERENCED_VARIABLE( Param );\r
+ *out_Result = (const uint8_t*) *(TCHAR**) ppLeft - (const uint8_t*) *(TCHAR**) ppRight;\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (LineNumberIndexClass) >>> \r
+************************************************************************/\r
+\r
+/*[LineNumberIndexClass_initConst]*/\r
+void LineNumberIndexClass_initConst( LineNumberIndexClass* self )\r
+{\r
+ Set2_initConst( &self->LeftsOfLine );\r
+}\r
+\r
+\r
+/*[LineNumberIndexClass_finalize]*/\r
+errnum_t LineNumberIndexClass_finalize( LineNumberIndexClass* self, errnum_t e )\r
+{\r
+ return Set2_finish( &self->LeftsOfLine, e );\r
+}\r
+\r
+\r
+/*[LineNumberIndexClass_initialize]*/\r
+errnum_t LineNumberIndexClass_initialize( LineNumberIndexClass* self, const TCHAR* Text )\r
+{\r
+ errnum_t e;\r
+ const TCHAR* p;\r
+ const TCHAR* line_feed;\r
+ const TCHAR** pp_left;\r
+\r
+ e= Set2_init( &self->LeftsOfLine, 1000 * sizeof(TCHAR*) ); IF(e){goto fin;}\r
+\r
+ p = Text;\r
+ for (;;) {\r
+ e= Set2_alloc( &self->LeftsOfLine, &pp_left, const TCHAR* ); IF(e){goto fin;}\r
+ *pp_left = p;\r
+\r
+ line_feed = _tcschr( p, _T('\n') );\r
+ if ( line_feed == NULL )\r
+ { break; }\r
+\r
+ p = line_feed + 1;\r
+ }\r
+\r
+#if 0 //[TODO]\r
+ p = _tcschr( p, _T('\0') );\r
+ e= Set2_alloc( &self->LeftsOfLine, &pp_left, const TCHAR* ); IF(e){goto fin;}\r
+ *pp_left = p + 1;\r
+#else\r
+ if ( *p != _T('\0') ) {\r
+ p = _tcschr( p, _T('\0') );\r
+ e= Set2_alloc( &self->LeftsOfLine, &pp_left, const TCHAR* ); IF(e){goto fin;}\r
+ *pp_left = p + 1;\r
+#endif\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+/*[LineNumberIndexClass_searchLineNumber]*/\r
+errnum_t LineNumberIndexClass_searchLineNumber( LineNumberIndexClass* self, const TCHAR* Position,\r
+ int* out_LineNumber )\r
+{\r
+ errnum_t e;\r
+ int found_index;\r
+ int result;\r
+\r
+ e= PArray_doBinarySearch( self->LeftsOfLine.First,\r
+ (uint8_t*) self->LeftsOfLine.Next - (uint8_t*) self->LeftsOfLine.First,\r
+ Position, LineNumberIndexClass_compare_sub, NULL,\r
+ &found_index, &result );\r
+ IF(e){goto fin;}\r
+\r
+ *out_LineNumber = found_index + 1;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+/*[LineNumberIndexClass_getCountOfLines]*/\r
+int LineNumberIndexClass_getCountOfLines( LineNumberIndexClass* self )\r
+{\r
+ return Set2_getCount( &self->LeftsOfLine, const TCHAR* ) - 1;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (ParsedRangeClass) >>> \r
+************************************************************************/\r
+\r
+/*[ParsedRangeClass_initConst]*/\r
+void ParsedRangeClass_initConst( ParsedRangeClass* self )\r
+{\r
+ self->ClassID = &g_ParsedRangeClass_ID;\r
+ self->FinalizerVTable = NULL;\r
+ self->StaticAddress = NULL;\r
+ self->Start = NULL;\r
+ self->Over = NULL;\r
+}\r
+\r
+\r
+/*[g_ParsedRangeClass_ID]*/\r
+static const ClassID_Class* gs_ParsedRangeClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID\r
+};\r
+const ClassID_Class g_ParsedRangeClass_ID = {\r
+ "ParsedRangeClass",\r
+ gs_ParsedRangeClass_SuperClassIDs,\r
+ _countof( gs_ParsedRangeClass_SuperClassIDs ),\r
+ sizeof( ParsedRangeClass ),\r
+ NULL,\r
+};\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParsedRanges_getCut_by_PP_Directive] >>> \r
+************************************************************************/\r
+errnum_t ParsedRanges_getCut_by_PP_Directive(\r
+ Set2* /*<ParsedRangeClass>*/ CutRanges,\r
+ Set2* /*<PP_DirectiveClass*>*/ DirectivePointerArray,\r
+ const TCHAR* Symbol, bool IsCutDefine )\r
+{\r
+ errnum_t e;\r
+ PP_DirectiveClass** p;\r
+ PP_DirectiveClass** p_over;\r
+\r
+ for ( Set2_forEach( DirectivePointerArray, &p, &p_over, PP_DirectiveClass* ) ) {\r
+ PP_DirectiveClass* directive = *p;\r
+ PP_SharpIfClass* sh_if = NULL; /* sh = sharp */\r
+ bool is_not_condition = false;\r
+\r
+ if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfdefClass_ID ) ) {\r
+ PP_SharpIfdefClass* sh_ifdef = (PP_SharpIfdefClass*) directive; /* sh = sharp */\r
+\r
+ if ( StrT_cmp_part( sh_ifdef->Symbol_Start, sh_ifdef->Symbol_Over, Symbol ) == 0 ) {\r
+ sh_if = (PP_SharpIfClass*) sh_ifdef;\r
+ is_not_condition = ( sh_ifdef->ClassID == &g_PP_SharpIfndefClass_ID );\r
+ }\r
+ }\r
+ else if ( directive->ClassID == &g_PP_SharpIfClass_ID ) {\r
+ const TCHAR* condition_start;\r
+ const TCHAR* condition_over;\r
+\r
+ sh_if = (PP_SharpIfClass*) directive; /* sh = sharp */\r
+ condition_start = sh_if->DirectiveName_Over;\r
+ condition_over = sh_if->Over;\r
+\r
+ while ( condition_start < condition_over ) {\r
+ if ( _istspace( *condition_start ) ) {\r
+ condition_start += 1;\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+ while ( condition_start < condition_over ) {\r
+ if ( _istspace( *( condition_over - 1 ) ) ) {\r
+ condition_over -= 1;\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+ if ( ! StrT_cmp_part( condition_start, condition_over, Symbol ) == 0 ) {\r
+ sh_if = NULL;\r
+ }\r
+ }\r
+\r
+ if ( sh_if != NULL ) {\r
+ PP_SharpElseClass* sh_else; /* sh = sharp */\r
+ PP_SharpEndifClass* sh_endif; /* sh = sharp */\r
+ ParsedRangeClass* cut;\r
+\r
+\r
+ /* Set "sh_else", "sh_endif" */\r
+ if ( ClassID_Class_isSuperClass( sh_if->NextDirective->ClassID,\r
+ &g_PP_SharpElseClass_ID ) ) {\r
+ sh_else = (PP_SharpElseClass*) sh_if->NextDirective;\r
+ sh_endif = sh_if->EndDirective;\r
+ } else {\r
+ sh_else = NULL;\r
+ sh_endif = (PP_SharpEndifClass*) sh_if->NextDirective;\r
+ }\r
+\r
+\r
+ /* Add to "CutRanges" */\r
+ e= Set2_alloc( CutRanges, &cut, ParsedRangeClass ); IF(e){goto fin;}\r
+ cut->Start = sh_if->Start;\r
+ if ( is_not_condition == ! IsCutDefine ) {\r
+ if ( sh_else != NULL ) {\r
+ cut->Over = sh_else->Over;\r
+\r
+ e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );\r
+ IF(e){goto fin;}\r
+ cut->Start = sh_endif->Start;\r
+ }\r
+ cut->Over = sh_endif->Over;\r
+ }\r
+ else {\r
+ cut->Over = sh_if->Over;\r
+\r
+ e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );\r
+ IF(e){goto fin;}\r
+ if ( sh_else != NULL ) {\r
+ cut->Start = sh_else->Start;\r
+ } else {\r
+ cut->Start = sh_endif->Start;\r
+ }\r
+ cut->Over = sh_endif->Over;\r
+ }\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParsedRangeClass_onInitializedForDebug] >>> \r
+************************************************************************/\r
+#if ! defined( NDEBUG )\r
+void ParsedRangeClass_onInitializedForDebug( ParsedRangeClass* self )\r
+{\r
+ /* These code can be modified for Debug. */\r
+ #if 0 // IS_USED_DEBUG_CHECK_CLASS\r
+ TCHAR* text;\r
+ ptrdiff_t break_diff = 0x1FA6A;\r
+\r
+ START_D( 10 );\r
+ text = GET_D( 1, TCHAR* );\r
+ PointerType_plus( &text, break_diff );\r
+ if ( text == self->Start ) {\r
+ if ( self->ClassID == &g_ParsedRangeClass_ID ) {\r
+ SET_D( 2, self );\r
+ }\r
+ }\r
+ END_D();\r
+ #else\r
+ UNREFERENCED_VARIABLE( self );\r
+ #endif\r
+}\r
+#endif\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParsedRanges_compareByStart] >>> \r
+************************************************************************/\r
+int ParsedRanges_compareByStart( const void* _a1, const void* _a2 )\r
+{\r
+ ParsedRangeClass* a1 = (ParsedRangeClass*) _a1;\r
+ ParsedRangeClass* a2 = (ParsedRangeClass*) _a2;\r
+\r
+ return a1->Start - a2->Start;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParsedRanges_write_by_Cut] >>> \r
+************************************************************************/\r
+errnum_t ParsedRanges_write_by_Cut(\r
+ Set2* /*<ParsedRangeClass>*/ CutRanges,\r
+ const TCHAR* Text, FILE* OutFile )\r
+{\r
+ errnum_t e;\r
+ const TCHAR* position;\r
+ ParsedRangeClass* p;\r
+ ParsedRangeClass* p_over;\r
+\r
+ qsort( CutRanges->First, Set2_getCount( CutRanges, ParsedRangeClass ),\r
+ sizeof(ParsedRangeClass), ParsedRanges_compareByStart );\r
+\r
+ position = Text;\r
+ for ( Set2_forEach( CutRanges, &p, &p_over, ParsedRangeClass ) ) {\r
+ const TCHAR* cut_start_position;\r
+ const TCHAR* cut_over_position;\r
+\r
+ cut_start_position = p->Start;\r
+ if ( position < cut_start_position ) {\r
+ e= FileT_writePart( OutFile, (TCHAR*)position, (TCHAR*)cut_start_position );\r
+ IF(e){goto fin;}\r
+ }\r
+\r
+ cut_over_position = p->Over;\r
+ if ( position < cut_over_position ) {\r
+ position = cut_over_position;\r
+ }\r
+ }\r
+ _fputts( position, OutFile ); IF(ferror(OutFile)){e=E_ERRNO; goto fin;}\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [Locale/Locale.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [g_LocaleSymbol] >>> \r
+************************************************************************/\r
+char* g_LocaleSymbol = "";\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Locale_init] >>> \r
+************************************************************************/\r
+int Locale_init()\r
+{\r
+ g_LocaleSymbol = ".OCP";\r
+ setlocale( LC_ALL, ".OCP" );\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Locale_isInited] >>> \r
+************************************************************************/\r
+int Locale_isInited()\r
+{\r
+ return ( g_LocaleSymbol[0] != '\0' );\r
+ // \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
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [IniFile2/IniFile2.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [IniStr_isLeft] >>> \r
+************************************************************************/\r
+bool IniStr_isLeft( const TCHAR* line, const TCHAR* symbol )\r
+{\r
+ const TCHAR* p;\r
+ size_t symbol_len = _tcslen( symbol );\r
+\r
+ /* Skip spaces at the top of line */\r
+ for ( p = line; *p == _T(' ') || *p == _T('\t'); p++ );\r
+\r
+ /* Compare symbol */\r
+ if ( _tcsnicmp( p, symbol, symbol_len ) != 0 ) return false;\r
+\r
+ switch ( *(p + symbol_len) ) {\r
+ case _T(' '): case _T('\t'): case _T('='): return true;\r
+ default: return false;\r
+ }\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [IniStr_refRight] >>> \r
+************************************************************************/\r
+TCHAR* IniStr_refRight( const TCHAR* line, bool bTrimRight )\r
+{\r
+ const TCHAR* p;\r
+\r
+ for ( p = line; *p != _T('\0') && *p != _T('='); p++ );\r
+ if ( *p == _T('=') ) {\r
+\r
+ //=== Skip spaces at the right of equal. Trim the left of value\r
+ for ( p++ ; *p == _T(' ') || *p == _T('\t'); p++ );\r
+\r
+ //=== Trim the right of value\r
+ if ( bTrimRight ) {\r
+ const TCHAR* t;\r
+ TCHAR c;\r
+\r
+ t = StrT_chr( p, _T('\0') );\r
+ if ( t != p ) {\r
+ for ( t--; ; t-- ) {\r
+ if ( t < p )\r
+ { p = StrT_chr( p, _T('\0') ); break; }\r
+\r
+ c = *t;\r
+ if ( c != ' ' && c != '\t' && c != '\n' && c != '\r' )\r
+ { *(TCHAR*)(t+1) = _T('\0'); break; }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return (TCHAR*) p;\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [FileT/FileT.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_isExist] >>> \r
+************************************************************************/\r
+bool FileT_isExist( const TCHAR* path )\r
+{\r
+ #if ! FileT_isExistWildcard\r
+\r
+ DWORD r;\r
+\r
+ if ( path[0] == _T('\0') ) return false;\r
+ r = GetFileAttributes( path );\r
+ return r != (DWORD)-1;\r
+\r
+ #else\r
+\r
+ HANDLE find;\r
+ WIN32_FIND_DATA data;\r
+\r
+ find = FindFirstFileEx( path, FindExInfoStandard, &data,\r
+ FindExSearchNameMatch, NULL, 0 );\r
+\r
+ if ( find == INVALID_HANDLE_VALUE ) {\r
+ return false;\r
+ }\r
+ else {\r
+ FindClose( find );\r
+ return true;\r
+ }\r
+\r
+ #endif\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_isFile] >>> \r
+************************************************************************/\r
+bool FileT_isFile( const TCHAR* path )\r
+{\r
+ DWORD r = GetFileAttributes( path );\r
+ return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == 0;\r
+ // 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
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_isDir] >>> \r
+************************************************************************/\r
+bool FileT_isDir( const TCHAR* path )\r
+{\r
+ DWORD r = GetFileAttributes( path );\r
+ return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == FILE_ATTRIBUTE_DIRECTORY;\r
+ // 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
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [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
+************************************************************************/\r
+typedef struct {\r
+ /*--- inherit from FileT_CallByNestFindData */\r
+ void* CallerArgument;\r
+ TCHAR* FullPath; // abstruct path\r
+ TCHAR* StepPath;\r
+ TCHAR* FileName;\r
+ DWORD FileAttributes;\r
+\r
+ /*---*/\r
+ BitField Flags;\r
+ FuncType CallbackFromNestFind;\r
+ TCHAR FullPathMem[4096];\r
+} FileT_CallByNestFindDataIn;\r
+\r
+int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m );\r
+\r
+\r
+int FileT_callByNestFind( const TCHAR* Path, BitField Flags, void* Argument, FuncType Callback )\r
+{\r
+ int e;\r
+ FileT_CallByNestFindDataIn data;\r
+\r
+ {\r
+ TCHAR* p;\r
+\r
+ e= StrT_cpy( data.FullPathMem, sizeof(data.FullPathMem), Path ); IF(e)goto fin;\r
+\r
+\r
+ /* FullPathMem \82Ì\8dÅ\8cã\82É \ \82ª\96³\82¢\82È\82ç\92Ç\89Á\82·\82é */\r
+ p = StrT_chr( data.FullPathMem, _T('\0') );\r
+ p--;\r
+ if ( *p != _T('\\') ) {\r
+ p++;\r
+ IF( p >= data.FullPathMem + (sizeof(data.FullPathMem) / sizeof(TCHAR)) - 1 )goto err_fa;\r
+ *p = _T('\\');\r
+ }\r
+\r
+\r
+ /* data \82ð\8f\89\8aú\89»\82·\82é */\r
+ data.CallerArgument = Argument;\r
+ data.FullPath = data.FullPathMem;\r
+ data.StepPath = p + 1;\r
+ data.FileName = p + 1;\r
+ data.Flags = Flags;\r
+ data.CallbackFromNestFind = Callback;\r
+ }\r
+\r
+ /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ\8aÖ\90\94\82Ö */\r
+ e= FileT_callByNestFind_sub( &data ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+err_fa: e= E_FEW_ARRAY; goto fin;\r
+}\r
+\r
+\r
+int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m )\r
+{\r
+ int e;\r
+ HANDLE find;\r
+ WIN32_FIND_DATA data;\r
+ TCHAR* p;\r
+ int done;\r
+\r
+\r
+ /* 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
+ if ( m->Flags & FileT_FolderBeforeFiles ) {\r
+ *( m->FileName - 1 ) = _T('\0'); // m->FullPath \82Ì\8dÅ\8cã\82Ì \ \82ð\88ê\8e\9e\93I\82É\83J\83b\83g\r
+ *( m->FileName ) = _T('\0'); // m->FileName, m->StepPath \82ð "" \82É\82·\82é\r
+ m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
+\r
+ if ( m->StepPath[0] == _T('\0') ) {\r
+ TCHAR* step_path = m->StepPath;\r
+ TCHAR* fname = m->FileName;\r
+\r
+ m->StepPath = _T(".");\r
+ m->FileName = StrT_refFName( m->FullPath );\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ m->StepPath = step_path;\r
+ m->FileName = fname;\r
+ }\r
+ else if ( m->FileName[0] == _T('\0') ) {\r
+ TCHAR* fname = m->FileName;\r
+\r
+ m->FileName = StrT_refFName( m->FullPath );\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ m->FileName = fname;\r
+ }\r
+ else {\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ }\r
+ *( m->FileName - 1 ) = _T('\\');\r
+ }\r
+\r
+\r
+ /* * \82ð\92Ç\89Á */\r
+ p = m->FileName;\r
+ IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
+ *p = _T('*'); *(p+1) = _T('\0');\r
+\r
+\r
+ /* \83t\83@\83C\83\8b\82©\83t\83H\83\8b\83_\82ð\97ñ\8b\93\82µ\82Ü\82· */\r
+ find = FindFirstFileEx( m->FullPathMem, FindExInfoStandard, &data,\r
+ FindExSearchNameMatch, NULL, 0 );\r
+ done = ( find == INVALID_HANDLE_VALUE );\r
+\r
+ while (!done)\r
+ {\r
+ if ( _tcscmp( data.cFileName, _T(".") ) == 0 ||\r
+ _tcscmp( data.cFileName, _T("..") ) == 0 ) {\r
+ done = ! FindNextFile( find, &data );\r
+ continue;\r
+ }\r
+\r
+ StrT_cpy( m->FileName,\r
+ sizeof(m->FullPathMem) - ( (char*)m->FileName - (char*)m->FullPathMem ),\r
+ data.cFileName );\r
+ m->FileAttributes = data.dwFileAttributes;\r
+\r
+ if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
+ TCHAR* prev_fname = m->FileName;\r
+\r
+ p = StrT_chr( m->FileName, _T('\0') );\r
+\r
+ IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
+ *p = _T('\\'); *(p+1) = _T('\0');\r
+ m->FileName = p + 1;\r
+\r
+ e= FileT_callByNestFind_sub( m ); IF(e)goto fin; /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ */\r
+\r
+ m->FileName = prev_fname;\r
+ }\r
+ else {\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ }\r
+\r
+ done = ! FindNextFile( find, &data );\r
+ }\r
+ FindClose( find );\r
+\r
+\r
+ /* 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
+ if ( m->Flags & FileT_FolderAfterFiles ) {\r
+ TCHAR* step_path = m->StepPath;\r
+ TCHAR* fname = m->FileName;\r
+\r
+ *( m->FileName - 1 ) = _T('\0');\r
+ m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
+ if ( ( *( m->StepPath - 1 ) == _T('\0') ) && ( m->StepPath > m->FullPath ) ) {\r
+ m->StepPath = _T(".");\r
+ }\r
+ m->FileName = StrT_refFName( m->FullPath );\r
+\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+\r
+ m->StepPath = step_path;\r
+ m->FileName = fname;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+err_fa: e= E_FEW_ARRAY; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_openForRead] >>> \r
+************************************************************************/\r
+int FileT_openForRead( FILE** out_pFile, const TCHAR* Path )\r
+{\r
+ errno_t en;\r
+\r
+ assert( Locale_isInited() );\r
+\r
+ #if DEBUGTOOLS_USES\r
+ { int e= Debug_onOpen( Path ); if(e) return e; }\r
+ #endif\r
+\r
+ en = _tfopen_s( out_pFile, Path, _T("r")_T(fopen_ccs) );\r
+ if ( en == ENOENT ) {\r
+ #ifndef UNDER_CE\r
+ {\r
+ TCHAR cwd[512];\r
+\r
+ if ( _tgetcwd( cwd, _countof(cwd) ) == NULL ) {\r
+ cwd[0] = _T('\0');\r
+ }\r
+ Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\" current=\"%s\"/>"),\r
+ Path, cwd );\r
+ }\r
+ #else\r
+ Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\"/>"), Path );\r
+ #endif\r
+\r
+ return E_PATH_NOT_FOUND;\r
+ }\r
+ if ( en == EACCES ) {\r
+ Error4_printf( _T("access denied \"%s\"\n"), Path );\r
+ return E_ACCESS_DENIED;\r
+ }\r
+ IF(en)return E_OTHERS;\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_openForWrite] >>> \r
+************************************************************************/\r
+int FileT_openForWrite( FILE** out_pFile, const TCHAR* Path, bit_flags_fast32_t Flags )\r
+{\r
+ int e;\r
+ errno_t en;\r
+ TCHAR* open_type;\r
+ BOOL b;\r
+ int retry_count;\r
+\r
+ IF_D( ! Locale_isInited() ) return E_NOT_INIT_GLOBAL;\r
+\r
+ #if Uses_AppKey\r
+ e= AppKey_addNewWritableFolder( Path ); IF(e)goto fin;\r
+ #endif\r
+\r
+ if ( Flags & F_Append )\r
+ open_type = ( Flags & F_Unicode ? _T("a")_T(fopen_ccs) : _T("at") );\r
+ else\r
+ open_type = ( Flags & F_Unicode ? _T("w")_T(fopen_ccs) : _T("wt") );\r
+\r
+ #if DEBUGTOOLS_USES\r
+ { int e= Debug_onOpen( Path ); if(e) return e; }\r
+ #endif\r
+\r
+ for ( retry_count = 0; ; retry_count ++ ) {\r
+ en = _tfopen_s( out_pFile, Path, open_type );\r
+ if ( en != EACCES ) break;\r
+ IF ( GetFileAttributes( Path ) == FILE_ATTRIBUTE_DIRECTORY ) { goto err_gt; }\r
+\r
+ retry_count += 1;\r
+ if ( retry_count == 15 ) break;\r
+ Sleep( 1000 );\r
+ }\r
+ if ( en == 2 ) { // ENOENT\r
+ e= FileT_mkdir( Path ); IF(e)goto fin;\r
+ b= RemoveDirectory( Path ); IF(!b)goto err_gt;\r
+ en = _tfopen_s( out_pFile, Path, open_type );\r
+\r
+ IF ( en == 2 ) {\r
+ _tprintf( _T("cannot open \"%s\"\n"), Path );\r
+\r
+ #ifndef UNDER_CE\r
+ {\r
+ TCHAR cwd[512];\r
+\r
+ if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )\r
+ _tprintf( _T("current = \"%s\"\n"), cwd );\r
+ }\r
+ #endif\r
+\r
+ e = E_NOT_FOUND_SYMBOL;\r
+ goto fin;\r
+ }\r
+ }\r
+ IF(en)goto err;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_close] >>> \r
+************************************************************************/\r
+int FileT_close( FILE* File, int e )\r
+{\r
+ if ( File != NULL ) {\r
+ int r = fclose( File );\r
+ IF(r&&!e)e=E_ERRNO;\r
+ }\r
+ return e;\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_closeAndNULL] >>> \r
+************************************************************************/\r
+errnum_t FileT_closeAndNULL( FILE** in_out_File, errnum_t e )\r
+{\r
+ FILE* file = *in_out_File;\r
+\r
+ if ( file != NULL ) {\r
+ int r = fclose( file );\r
+ IF ( r && e == 0 ) { e = E_ERRNO; }\r
+ *in_out_File = NULL;\r
+ }\r
+\r
+ return e;\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_readAll] >>> \r
+************************************************************************/\r
+#ifdef IsTest_FileT_readAll\r
+ #define _CV(x) CoverageLogClass_output( x, _T("FileT_readAll") )\r
+#else\r
+ #define _CV(x)\r
+#endif\r
+\r
+errnum_t FileT_readAll( FILE* File, TCHAR** out_Text, size_t* out_TextLength )\r
+{\r
+#ifdef IsTest_FileT_readAll\r
+ enum { text_max_size_first = 0x10 };\r
+#else\r
+ enum { text_max_size_first = 0xFF00 };\r
+#endif\r
+ errnum_t e;\r
+ TCHAR* text = NULL;\r
+ TCHAR* text_over = (TCHAR*) DUMMY_INITIAL_VALUE;\r
+ size_t text_max_size = text_max_size_first;\r
+ TCHAR* text_max_over;\r
+\r
+\r
+ text = (TCHAR*) malloc( text_max_size ); IF( text == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ text_over = text;\r
+ text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );\r
+\r
+ text[0] = _T('\0'); /* for empty file */\r
+\r
+ for (;;) {\r
+ _fgetts( text_over, text_max_over - text_over, File );\r
+\r
+ if ( *text_over == _T('\0') ) { /* End of file. If space line, *text_over == _T('\n'). */\r
+ _CV(1);\r
+ ASSERT_R( feof( File ), e=E_OTHERS; goto fin );\r
+ break;\r
+ }\r
+ text_over = StrT_chr( text_over, _T('\0') );\r
+ if ( feof( File ) ) { break; }\r
+\r
+ if ( (uint8_t*) text_over - (uint8_t*) text == (int)( text_max_size - sizeof(TCHAR) ) ) {\r
+ /* if full in text */\r
+ TCHAR* new_text;\r
+ size_t old_text_max_size = text_max_size;\r
+\r
+ #ifdef IsTest_FileT_readAll\r
+ EmptyHeapMemoryEmulation( _T("T_FileT_readAll_FewMemory"), 1 );\r
+ #endif\r
+\r
+ text_max_size *= 4;\r
+ new_text = (TCHAR*) realloc( text, text_max_size );\r
+ IF( new_text == NULL ) { e=E_FEW_MEMORY; _CV(2); goto fin; }\r
+ text = new_text;\r
+ text_over = (TCHAR*)( (uint8_t*) new_text + old_text_max_size - sizeof(TCHAR) );\r
+ text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );\r
+ }\r
+ else {\r
+ _CV(3);\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( e ) {\r
+ if ( text != NULL ) { _CV(4); free( text ); }\r
+ }\r
+ else {\r
+ *out_Text = text;\r
+ if ( out_TextLength != NULL ) { *out_TextLength = text_over - text; }\r
+ }\r
+ return e;\r
+}\r
+#undef _CV\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_writePart] >>> \r
+************************************************************************/\r
+errnum_t FileT_writePart( FILE* File, const TCHAR* Start, TCHAR* Over )\r
+{\r
+ errnum_t e;\r
+ TCHAR back_char;\r
+ int r;\r
+\r
+ back_char = *Over;\r
+\r
+ IF ( Start > Over ) { e=E_OTHERS; goto fin; }\r
+\r
+ *Over = _T('\0');\r
+ r= _ftprintf_s( File, _T("%s"), Start ); IF(r<0){ e=E_ERRNO; goto fin; }\r
+\r
+ e=0;\r
+fin:\r
+ *Over = back_char;\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_mkdir] >>> \r
+************************************************************************/\r
+int FileT_mkdir( const TCHAR* Path )\r
+{\r
+ int e;\r
+ DWORD r;\r
+ TCHAR* p = (TCHAR*) DUMMY_INITIAL_VALUE;\r
+ BOOL b;\r
+ int n_folder = 0;\r
+ TCHAR path2[MAX_PATH];\r
+\r
+\r
+ e= StrT_getFullPath( path2, sizeof(path2), Path, NULL ); IF(e)goto fin;\r
+ #if Uses_AppKey\r
+ e= AppKey_addNewWritableFolder( path2 ); IF(e)goto fin;\r
+ #endif\r
+\r
+\r
+ //=== \91¶\8dÝ\82·\82é\83t\83H\83\8b\83_\82ð\92T\82·\r
+ for (;;) {\r
+ r = GetFileAttributes( path2 );\r
+ if ( r != (DWORD)-1 ) break; // "C:" \82à\83t\83H\83\8b\83_\82Æ\94»\92è\82³\82ê\82é\r
+\r
+ p = StrT_refFName( path2 ) - 1; // \90â\91Î\83p\83X\82È\82Ì\82Å\95K\82¸ *p=='\\'\r
+ *p = _T('\0');\r
+ n_folder ++;\r
+ }\r
+ IF ( ! (r & FILE_ATTRIBUTE_DIRECTORY) ) goto err; // \83t\83@\83C\83\8b\82È\82ç\83G\83\89\81[\r
+\r
+\r
+ //=== \83t\83H\83\8b\83_\82ð\8dì\90¬\82·\82é\r
+ for ( ; n_folder > 0; n_folder -- ) {\r
+ *p = _T('\\');\r
+ b= CreateDirectory( path2, NULL ); IF(!b)goto err;\r
+ p = StrT_chr( p, _T('\0') );\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_copy] >>> \r
+************************************************************************/\r
+int FileT_copy_sub( FileT_CallByNestFindData* m );\r
+\r
+int FileT_copy( const TCHAR* SrcPath, const TCHAR* DstPath )\r
+{\r
+ const TCHAR* p_last;\r
+ int e;\r
+ BOOL b;\r
+ TCHAR path[MAX_PATH*4];\r
+\r
+\r
+ #if Uses_AppKey\r
+ e= AppKey_addNewWritableFolder( DstPath ); IF(e)goto fin;\r
+ #endif\r
+\r
+ p_last = StrT_chr( SrcPath, _T('\0') );\r
+ IF_D( p_last <= SrcPath + 1 )goto err_ni;\r
+\r
+\r
+ //=== \83t\83H\83\8b\83_\82ð\83R\83s\81[\82·\82é\r
+ if ( *(p_last - 1) == _T('*') ) {\r
+ IF_D( *(p_last - 2) != _T('\\') ) goto err_ni;\r
+\r
+ e= StrT_getParentFullPath( path, sizeof(path), SrcPath, NULL ); IF(e)goto fin;\r
+ IF_D( ! FileT_isDir( path ) )goto err_nf;\r
+\r
+ e= FileT_callByNestFind( path, FileT_FolderBeforeFiles, (void*) DstPath, (FuncType) FileT_copy_sub );\r
+ IF(e)goto fin;\r
+ }\r
+\r
+\r
+ //=== \83t\83@\83C\83\8b\82ð\83R\83s\81[\82·\82é\r
+ else {\r
+ IF_D( _tcschr( SrcPath, _T('*') ) != NULL )goto err_ni;\r
+ IF_D( ! FileT_isFile( SrcPath ) ) goto err_nf;\r
+\r
+ b= CopyFile( SrcPath, DstPath, FALSE );\r
+ if (!b) {\r
+ if ( FileT_isDir( DstPath ) ) {\r
+ e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
+ b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
+ }\r
+ else {\r
+ int ee;\r
+\r
+ p_last = StrT_chr( DstPath, _T('\0') ) - 1;\r
+ IF_D( p_last < DstPath )goto err;\r
+ if ( *p_last == _T('\\') ) {\r
+ ee= FileT_mkdir( DstPath ); IF(ee)goto fin;\r
+ e= stprintf_r( path, sizeof(path), _T("%s%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
+ b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
+ }\r
+ else {\r
+ e = E_ACCESS_DENIED;\r
+ ee= StrT_getParentFullPath( path, sizeof(path), DstPath, NULL ); IF(ee)goto fin;\r
+ ee= FileT_mkdir( path ); IF(ee)goto fin;\r
+ b= CopyFile( SrcPath, DstPath, FALSE ); IF(!b)goto err_gt;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_ni: e = E_NOT_IMPLEMENT_YET; goto fin;\r
+err_nf: e = E_PATH_NOT_FOUND; goto fin;\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+\r
+int FileT_copy_sub( FileT_CallByNestFindData* m )\r
+{\r
+ const TCHAR* DstPath = (const TCHAR*) m->CallerArgument;\r
+ int e;\r
+ BOOL b;\r
+ TCHAR path[MAX_PATH*4];\r
+\r
+ e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, m->StepPath ); IF(e)goto fin;\r
+\r
+ if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
+ if ( ! FileT_isDir( path ) )\r
+ { b= CreateDirectory( path, NULL ); IF(!b)goto err_gt; }\r
+ }\r
+ else {\r
+ b= CopyFile( m->FullPath, path, FALSE ); IF(!b)goto err_gt;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_del] >>> \r
+************************************************************************/\r
+int FileT_del_sub( FileT_CallByNestFindData* m );\r
+\r
+int FileT_del( const TCHAR* Path )\r
+{\r
+ int e;\r
+ DWORD r;\r
+ TCHAR abs_path[MAX_PATH];\r
+\r
+ e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto fin;\r
+ #if Uses_AppKey\r
+ e= AppKey_addNewWritableFolder( abs_path ); IF(e)goto fin;\r
+ #endif\r
+\r
+ r= GetFileAttributes( Path );\r
+ if ( r != (DWORD)-1 ) {\r
+ if ( r & FILE_ATTRIBUTE_DIRECTORY ) {\r
+ e= FileT_callByNestFind( Path, FileT_FolderAfterFiles, NULL, (FuncType) FileT_del_sub );\r
+ }\r
+ else {\r
+ BOOL b= DeleteFile( Path ); IF(!b)goto err_gt;\r
+ }\r
+ }\r
+ IF_D( FileT_isExist( Path ) )goto err_ad;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+err_ad: e = E_ACCESS_DENIED; goto fin;\r
+}\r
+\r
+\r
+int FileT_del_sub( FileT_CallByNestFindData* m )\r
+{\r
+ int e;\r
+ BOOL b;\r
+\r
+ if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
+ b= RemoveDirectory( m->FullPath ); IF(!b)goto err_gt;\r
+ }\r
+ else {\r
+ b= DeleteFile( m->FullPath ); IF(!b)goto err_gt;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+}\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_writeSizedStruct_WinAPI] >>> \r
+************************************************************************/\r
+int FileT_writeSizedStruct_WinAPI( HANDLE* Stream, SizedStruct* OutputSizedStruct )\r
+{\r
+ DWORD wrote_size;\r
+ BOOL r;\r
+ int e;\r
+\r
+ r= WriteFile( Stream, &OutputSizedStruct->ThisStructSize,\r
+ sizeof(OutputSizedStruct->ThisStructSize), &wrote_size, NULL );\r
+ IF(!r) goto err_gt;\r
+\r
+ r= WriteFile( Stream, &OutputSizedStruct->OthersData,\r
+ OutputSizedStruct->ThisStructSize - sizeof(OutputSizedStruct->ThisStructSize),\r
+ &wrote_size, NULL );\r
+ IF(!r) goto err_gt;\r
+ e=0;\r
+fin:\r
+ return 0;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_readSizedStruct_WinAPI] >>> \r
+************************************************************************/\r
+int FileT_readSizedStruct_WinAPI( HANDLE* Stream, void** out_SizedStruct )\r
+{\r
+ int e;\r
+ DWORD read_size;\r
+ DWORD data_size;\r
+ void* out = NULL;\r
+ BOOL b;\r
+\r
+ b= ReadFile( Stream, &data_size, sizeof(data_size), &read_size, NULL ); IF(!b) goto err_gt;\r
+ IF( data_size & 0xC0000000 ) goto err_fm;\r
+\r
+ out = malloc( data_size ); IF( out == NULL ) goto err_fm;\r
+ *(size_t*) out = data_size;\r
+\r
+ b= ReadFile( Stream, (size_t*) out + 1, data_size - sizeof(size_t), &read_size, NULL ); IF(!b) goto err_gt;\r
+\r
+ *out_SizedStruct = out;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto rollback;\r
+err_fm: e = E_FEW_MEMORY; goto rollback;\r
+rollback:\r
+ if ( out != NULL ) free( out );\r
+ goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+* Implement: FileT_readUnicodeFileBOM\r
+************************************************************************/\r
+errnum_t FileT_readUnicodeFileBOM( const TCHAR* Path, FileFormatEnum* out_Format )\r
+{\r
+ errnum_t e;\r
+ HANDLE file = INVALID_HANDLE_VALUE;\r
+ unsigned char data[4];\r
+ DWORD read_size;\r
+ BOOL b;\r
+\r
+ if ( ! FileT_isExist( Path ) ) {\r
+ *out_Format = FILE_FORMAT_NOT_EXIST;\r
+ }\r
+ else {\r
+ file = CreateFile( Path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
+ FILE_ATTRIBUTE_NORMAL, 0 );\r
+ IF( file == INVALID_HANDLE_VALUE ) goto err_gt;\r
+\r
+ data[0] = '\0';\r
+ b= ReadFile( file, data, 3, &read_size, NULL ); IF(!b)goto err;\r
+ if ( read_size < 2 ) {\r
+ *out_Format = FILE_FORMAT_NO_BOM;\r
+ }\r
+ else if ( ( data[0] == 0xFF ) && ( data[1] == 0xFE ) ) {\r
+ *out_Format = FILE_FORMAT_UNICODE;\r
+ }\r
+ else if ( ( read_size >= 3 ) &&\r
+ ( data[0] == 0xEF ) && ( data[1] == 0xBB ) && ( data[2] == 0xBF ) ) {\r
+\r
+ *out_Format = FILE_FORMAT_UTF_8;\r
+ }\r
+ else {\r
+ *out_Format = FILE_FORMAT_NO_BOM;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( file != INVALID_HANDLE_VALUE ) { b= CloseHandle( file ); IF(!b&&!e) e = E_OTHERS; }\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+* Implement: FileT_cutFFFE\r
+************************************************************************/\r
+errnum_t FileT_cutFFFE( const TCHAR* in_InputPath, const TCHAR* in_OutputPath, bool in_IsAppend )\r
+{\r
+ errnum_t e;\r
+ HANDLE reading_file = INVALID_HANDLE_VALUE;\r
+ HANDLE writing_file = INVALID_HANDLE_VALUE;\r
+ wchar_t buffer[4096];\r
+ uint8_t* buffer8 = (uint8_t*) buffer;\r
+ wchar_t a_character;\r
+ uint8_t a_character8;\r
+ int index_of_BOM;\r
+ DWORD read_size;\r
+ DWORD writing_size;\r
+ DWORD wrote_size;\r
+ DWORD reading_index;\r
+ DWORD reading_index_over;\r
+ DWORD writing_index;\r
+ DWORD creation;\r
+ BOOL b;\r
+\r
+ FileFormatEnum format;\r
+\r
+ e= FileT_readUnicodeFileBOM( in_InputPath, /*Set*/ &format ); IF(e){goto fin;}\r
+\r
+ if ( ! in_IsAppend ) {\r
+ creation = CREATE_ALWAYS;\r
+ } else {\r
+ creation = OPEN_ALWAYS;\r
+ }\r
+\r
+ reading_file = CreateFile( in_InputPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
+ FILE_ATTRIBUTE_NORMAL, 0 );\r
+ IF( reading_file == INVALID_HANDLE_VALUE ) { e=E_GET_LAST_ERROR; goto fin; }\r
+\r
+ writing_file = CreateFile( in_OutputPath, GENERIC_WRITE, 0, NULL, creation,\r
+ FILE_ATTRIBUTE_NORMAL, 0 );\r
+ IF ( writing_file == INVALID_HANDLE_VALUE ) { e=E_GET_LAST_ERROR; goto fin; }\r
+\r
+ if ( in_IsAppend ) {\r
+ SetFilePointer( writing_file, 0, NULL, FILE_END );\r
+ }\r
+\r
+\r
+ for (;;) {\r
+\r
+ b= ReadFile( reading_file, buffer, sizeof( buffer ), &read_size, NULL );\r
+ IF(!b){ e=SaveWindowsLastError(); goto fin; }\r
+ if ( read_size == 0 )\r
+ { break; }\r
+\r
+ if ( format == FILE_FORMAT_UNICODE ) {\r
+ writing_index = 0;\r
+ reading_index_over = read_size / sizeof( buffer[0] );\r
+ for ( reading_index = 0; reading_index < reading_index_over; reading_index += 1 ) {\r
+\r
+ a_character = buffer[ reading_index ];\r
+\r
+ if ( a_character != 0xFEFF ) { /* FEFF = BOM character */\r
+\r
+ buffer[ writing_index ] = a_character;\r
+ writing_index += 1;\r
+ }\r
+ }\r
+ writing_size = writing_index * sizeof( buffer[0] );\r
+ }\r
+ else if ( format == FILE_FORMAT_UTF_8 ) {\r
+ writing_index = 0;\r
+ index_of_BOM = 0;\r
+ reading_index_over = read_size / sizeof( buffer8[0] );\r
+ for ( reading_index = 0; reading_index < reading_index_over; reading_index += 1 ) {\r
+\r
+ a_character8 = buffer8[ reading_index ];\r
+\r
+ if ( a_character8 == 0xEF ) {\r
+ if ( index_of_BOM >= 1 ) {\r
+ buffer8[ writing_index ] = 0xEF;\r
+ writing_index += 1;\r
+ if ( index_of_BOM >= 2 ) {\r
+ buffer8[ writing_index ] = 0xBB;\r
+ writing_index += 1;\r
+ }\r
+ }\r
+ index_of_BOM = 1;\r
+ }\r
+ else if ( a_character8 == 0xBB && index_of_BOM == 1 ) {\r
+ index_of_BOM = 2;\r
+ }\r
+ else if ( a_character8 == 0xBF && index_of_BOM == 2 ) {\r
+\r
+ /* Skip BOM */\r
+ index_of_BOM = 0;\r
+ }\r
+ else {\r
+ if ( index_of_BOM >= 1 ) {\r
+ buffer8[ writing_index ] = 0xEF;\r
+ writing_index += 1;\r
+ if ( index_of_BOM >= 2 ) {\r
+ buffer8[ writing_index ] = 0xBB;\r
+ writing_index += 1;\r
+ }\r
+ }\r
+\r
+ buffer8[ writing_index ] = a_character8;\r
+ writing_index += 1;\r
+\r
+ index_of_BOM = 0;\r
+ }\r
+ }\r
+ writing_size = writing_index * sizeof( buffer8[0] );\r
+ }\r
+ else {\r
+ writing_size = read_size;\r
+ }\r
+\r
+ b= WriteFile( writing_file, buffer, writing_size, &wrote_size, NULL );\r
+ IF(!b) { e=E_GET_LAST_ERROR; goto fin; }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ e= CloseHandleInFin( writing_file, e );\r
+ e= CloseHandleInFin( reading_file, e );\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParseXML2_StatusClass_getAttribute] >>>\r
+************************************************************************/\r
+errnum_t ParseXML2_StatusClass_getAttribute( ParseXML2_StatusClass* self,\r
+ const TCHAR* AttributeName, TCHAR** out_AttribyteValue )\r
+{\r
+ TCHAR** attr;\r
+\r
+ for ( attr = (TCHAR**) self->u.OnStartElement.Attributes; *attr != NULL; attr += 2 ) {\r
+ if ( _tcsicmp( *attr, AttributeName ) == 0 ) {\r
+ *out_AttribyteValue = *( attr + 1 );\r
+ return 0;\r
+ }\r
+ }\r
+ *out_AttribyteValue = NULL;\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParseXML2_StatusClass_mallocCopyText] >>>\r
+************************************************************************/\r
+errnum_t ParseXML2_StatusClass_mallocCopyText( ParseXML2_StatusClass* self,\r
+ TCHAR** out_Text )\r
+{\r
+ return MallocAndCopyStringByLength( out_Text,\r
+ self->u.OnText.Text, self->u.OnText.TextLength );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParseXML2] >>>\r
+************************************************************************/\r
+\r
+/*[ParseXML2_WorkClass]*/\r
+typedef struct _ParseXML2_WorkClass ParseXML2_WorkClass;\r
+struct _ParseXML2_WorkClass {\r
+ ParseXML2_StatusClass Status;\r
+ ParseXML2_CallbackType OnStartElement;\r
+ ParseXML2_CallbackType OnEndElement;\r
+ ParseXML2_CallbackType OnText;\r
+ Set2 XPath; /* Array of TCHAR */\r
+ Set2 XPathLengths; /* Array of int. Element is TCHAR count. Array count is Status.Depth */\r
+ StrFile TextBuffer;\r
+ int TextStartLineNum; /* 0 = no text */\r
+ errnum_t e;\r
+};\r
+\r
+/*[BOM]*/\r
+enum { BOM = 0xFEFF };\r
+\r
+\r
+static errnum_t ParseXML2_makeXML_Declare_Sub( XML_Parser parser, ParseXML2_WorkClass* work,\r
+ const TCHAR* XML_Path, TCHAR* line, bool* is_xml_declare );\r
+static void Expat_printfToError4( XML_Parser parser, const TCHAR* XML_Path );\r
+static void ParseXML2_onStartElement( void* UserData, const XML_Char* Name, const XML_Char** Atts );\r
+static void ParseXML2_onEndElement( void* UserData, const XML_Char* name );\r
+static void ParseXML2_onText( void* UserData, const XML_Char* Text, int TextLength );\r
+static void ParseXML2_callOnText( ParseXML2_WorkClass* work );\r
+\r
+\r
+errnum_t ParseXML2( const TCHAR* XML_Path, ParseXML2_ConfigClass* in_out_Config )\r
+{\r
+ errnum_t e;\r
+ FILE* file = NULL;\r
+ XML_Parser parser = (XML_Parser) DUMMY_INITIAL_VALUE;\r
+ bool is_parser = false;\r
+ int is_EOF;\r
+ wchar_t bom[1] = { BOM };\r
+ bool is_xml_declare = false; /* <?xml ... ?> */\r
+ enum XML_Status xs;\r
+ ParseXML2_ConfigClass* config = in_out_Config;\r
+ ParseXML2_ConfigClass default_config;\r
+ ParseXML2_WorkClass work_x;\r
+ ParseXML2_WorkClass* work = &work_x;\r
+ TCHAR line[4096];\r
+\r
+ Set2_initConst( &work->XPath );\r
+ Set2_initConst( &work->XPathLengths );\r
+ StrFile_initConst( &work->TextBuffer );\r
+\r
+\r
+ /* Set "config" */\r
+ if ( config == NULL ) { config = &default_config; }\r
+ if ( ! ( config->Flags & F_ParseXML2_Delegate ) ) { config->Delegate = NULL; }\r
+ if ( ! ( config->Flags & F_ParseXML2_OnStartElement ) ) { config->OnStartElement = DefaultFunction; }\r
+ if ( ! ( config->Flags & F_ParseXML2_OnEndElement ) ) { config->OnEndElement = DefaultFunction; }\r
+ if ( ! ( config->Flags & F_ParseXML2_OnText ) ) { config->OnText = DefaultFunction; }\r
+\r
+ /* Set "work" */\r
+ work->Status.Delegate = config->Delegate;\r
+ work->Status.LineNum = 0;\r
+ work->Status.Depth = -1;\r
+ work->Status.PreviousCallbackType = 0;\r
+ work->Status.TagName = NULL;\r
+ work->Status.u.OnStartElement.Attributes = NULL;\r
+ work->OnStartElement = config->OnStartElement;\r
+ work->OnEndElement = config->OnEndElement;\r
+ work->OnText = config->OnText;\r
+ work->e = 0;\r
+\r
+ /* Set "work->XPath", "work->XPathLengths" */\r
+ {\r
+ TCHAR* xpath;\r
+\r
+ e= Set2_init( &work->XPath, MAX_PATH * sizeof(TCHAR) ); IF(e)goto fin;\r
+ e= Set2_init( &work->XPathLengths, 10 * sizeof(int) ); IF(e)goto fin;\r
+ xpath = (TCHAR*) work->XPath.First;\r
+\r
+ xpath[0] = _T('/');\r
+ xpath[1] = _T('\0');\r
+ }\r
+\r
+ /* Set "work->TextBuffer" */\r
+ e= StrFile_init_toHeap( &work->TextBuffer, 0 );\r
+ work->TextStartLineNum = 0;\r
+\r
+ /* Set "parser" */\r
+ parser = XML_ParserCreate( NULL );\r
+ is_parser = true;\r
+ XML_SetUserData( parser, work );\r
+ XML_SetElementHandler( parser, ParseXML2_onStartElement, ParseXML2_onEndElement );\r
+ XML_SetCharacterDataHandler( parser, ParseXML2_onText );\r
+\r
+ /* Parse BOM */\r
+ xs= XML_Parse( parser, (char*)bom, sizeof(bom), 0 );\r
+ IF( xs == XML_STATUS_ERROR ) goto err_ex;\r
+\r
+\r
+ /* Loop of lines of XML file */\r
+ e= FileT_openForRead( &file, XML_Path ); IF(e)goto fin;\r
+ for (;;) {\r
+ line[0] = _T('\0');\r
+ _fgetts( line, _countof(line), file );\r
+ is_EOF = feof( file );\r
+ work->Status.LineNum += 1;\r
+\r
+ /* _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
+ /* <?xml encoding="UTF-16" ?> \82É\95Ï\8dX\82·\82é */\r
+ if ( ! is_xml_declare ) {\r
+ e= ParseXML2_makeXML_Declare_Sub( parser, work, XML_Path, line, &is_xml_declare );\r
+ IF(e)goto fin;\r
+ }\r
+\r
+ /* Parse XML */\r
+ xs= XML_Parse( parser, (char*)line, _tcslen( line ) * sizeof(TCHAR), is_EOF );\r
+ IF( xs == XML_STATUS_ERROR ) goto err_ex;\r
+ IF( work->e != 0 ) { e = work->e; goto fin; }\r
+ if ( is_EOF ) { break; }\r
+ }\r
+ e=0;\r
+fin:\r
+ if ( is_parser ) { XML_ParserFree( parser ); }\r
+ e= FileT_close( file, e );\r
+ e= StrFile_finish( &work->TextBuffer, e );\r
+ e= Set2_finish( &work->XPath, e );\r
+ e= Set2_finish( &work->XPathLengths, e );\r
+ return e;\r
+\r
+err_ex: Expat_printfToError4( parser, XML_Path ); e= E_XML_PARSER; goto fin;\r
+}\r
+\r
+\r
+/*[ParseXML2_makeXML_Declare_Sub]*/\r
+static errnum_t ParseXML2_makeXML_Declare_Sub( XML_Parser parser, ParseXML2_WorkClass* work,\r
+ const TCHAR* XML_Path, TCHAR* line, bool* is_xml_declare )\r
+{\r
+ errnum_t e;\r
+ TCHAR* p;\r
+ TCHAR* str = NULL;\r
+ enum XML_Status xs;\r
+\r
+ UNREFERENCED_VARIABLE( work );\r
+\r
+ if ( _tcschr( line, _T('<') ) > 0 ) {\r
+ if ( _tcsstr( line, _T("<?") ) > 0 ) {\r
+ bool is_replaced = false;\r
+\r
+ {\r
+ static const TCHAR* enc_sjis = _T("encoding=\"Shift_JIS\"");\r
+ static const TCHAR* enc_sjis_utf16 = _T("encoding=\"UTF-16\" ");\r
+\r
+ p = _tcsstr( line, enc_sjis );\r
+ if ( p != NULL ) {\r
+ memcpy( p, enc_sjis_utf16, _tcslen( enc_sjis_utf16 ) * sizeof(TCHAR) );\r
+ is_replaced = true;\r
+ }\r
+ }\r
+ if ( ! is_replaced ) {\r
+ static const TCHAR* enc_utf8 = _T("encoding=\"UTF-8\"");\r
+ static const TCHAR* enc_utf8_utf16 = _T("encoding=\"UTF-16\"");\r
+ size_t str_size;\r
+\r
+ p = _tcsstr( line, enc_utf8 );\r
+ if ( p != NULL ) {\r
+ str_size = ( _tcslen( line ) + 2 ) * sizeof(TCHAR);\r
+ str = (TCHAR*) malloc( str_size ); IF(str==NULL) goto err_fm;\r
+\r
+ e= StrT_replace( str, str_size, line, enc_utf8, enc_utf8_utf16, 0 );\r
+ IF(e)goto fin;\r
+\r
+ xs= XML_Parse( parser, (char*)str, _tcslen( str ) * sizeof(TCHAR), 0 );\r
+ IF( xs == XML_STATUS_ERROR ) goto err_ex;\r
+\r
+ line[0] = _T('\0');\r
+ *is_xml_declare = true;\r
+ e=0;\r
+ goto fin;\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ static const TCHAR* xml_declare = _T("<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n");\r
+\r
+ XML_Parse( parser, (char*)xml_declare, _tcslen( xml_declare ) * sizeof(TCHAR), 0 );\r
+ *is_xml_declare = true;\r
+ e=0;\r
+ goto fin;\r
+ }\r
+ }\r
+ if ( _tcsstr( line, _T("?>") ) != NULL ) {\r
+ *is_xml_declare = true;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( str != NULL ) { free( str ); }\r
+ return e;\r
+\r
+err_fm: e = E_FEW_MEMORY; goto fin;\r
+err_ex: Expat_printfToError4( parser, XML_Path ); e= E_XML_PARSER; goto fin;\r
+}\r
+\r
+\r
+/*[Expat_printfToError4]*/\r
+static void Expat_printfToError4( XML_Parser parser, const TCHAR* XML_Path )\r
+{\r
+ Error4_printf( _T("<ERROR msg=\"%s\" file=\"%s(%lu)\"/>\n"),\r
+ XML_ErrorString( XML_GetErrorCode( parser ) ),\r
+ XML_Path,\r
+ XML_GetCurrentLineNumber(parser) );\r
+}\r
+\r
+\r
+/*[ParseXML2_onStartElement]*/\r
+static void ParseXML2_onStartElement( void* UserData, const XML_Char* Name, const XML_Char** Atts )\r
+{\r
+ ParseXML2_WorkClass* work = (ParseXML2_WorkClass*) UserData;\r
+ TCHAR* xpath = (TCHAR*) DUMMY_INITIAL_VALUE;\r
+ int* xpath_lengths;\r
+ int old_depth = work->Status.Depth;\r
+ int new_depth = work->Status.Depth + 1;\r
+\r
+ if ( work->e != 0 ) return;\r
+\r
+\r
+ /* Call "work->OnText" */\r
+ if ( work->OnText != DefaultFunction )\r
+ { ParseXML2_callOnText( work ); }\r
+\r
+\r
+ /* Set "work->XPath" : Add "Name" */\r
+ {\r
+ errnum_t e;\r
+ int old_xpath_length;\r
+ int name_length = _tcslen( Name );\r
+\r
+\r
+ /* Set "old_xpath_length" */\r
+ xpath_lengths = (int*) work->XPathLengths.First;\r
+ if ( old_depth >= 0 )\r
+ { old_xpath_length = xpath_lengths[ old_depth ]; }\r
+ else\r
+ { old_xpath_length = 0; } /* Length("/") == 1, But 0 for next operation */\r
+\r
+ /* Add "Name" to "work->XPath" */\r
+ e= Set2_expandIfOverByOffset( &work->XPath,\r
+ ( old_xpath_length + name_length + 2 ) * sizeof(TCHAR) );\r
+ IF(e)goto fin2;\r
+ xpath = (TCHAR*) work->XPath.First;\r
+ xpath[ old_xpath_length ] = _T('/');\r
+ memcpy( &xpath[ old_xpath_length + 1 ], Name, name_length * sizeof(TCHAR) );\r
+ xpath[ old_xpath_length + 1 + name_length ] = _T('\0');\r
+\r
+ /* "work->XPathLengths[]" = new XPath length */\r
+ e= Set2_expandIfOverByOffset( &work->XPathLengths, ( new_depth + 1 ) * sizeof(int) );\r
+ IF(e)goto fin2;\r
+ xpath_lengths = (int*) work->XPathLengths.First;\r
+ xpath_lengths[ new_depth ] = old_xpath_length + 1 + name_length;\r
+\r
+ e=0;\r
+ fin2:\r
+ if (e) {\r
+ work->e = e;\r
+ return;\r
+ }\r
+ }\r
+\r
+\r
+ /* Call "work->OnStartElement" */\r
+ work->Status.XPath = xpath;\r
+ if ( old_depth >= 0 )\r
+ { work->Status.TagName = &xpath[ xpath_lengths[ old_depth ] + 1 ]; }\r
+ else\r
+ { work->Status.TagName = &xpath[ 1 ]; }\r
+ work->Status.u.OnStartElement.Attributes = Atts;\r
+ work->Status.Depth += 1;\r
+\r
+ work->e = work->OnStartElement( &work->Status );\r
+\r
+ work->Status.u.OnStartElement.Attributes = NULL;\r
+\r
+ work->Status.PreviousCallbackType = F_ParseXML2_OnStartElement;\r
+}\r
+\r
+\r
+/*[ParseXML2_onEndElement]*/\r
+static void ParseXML2_onEndElement( void* UserData, const XML_Char* Name )\r
+{\r
+ ParseXML2_WorkClass* work = (ParseXML2_WorkClass*) UserData;\r
+ TCHAR* xpath = (TCHAR*) work->XPath.First;\r
+ int* xpath_lengths = (int*) work->XPathLengths.First;\r
+ int new_depth = work->Status.Depth - 1;\r
+\r
+ UNREFERENCED_VARIABLE( Name );\r
+\r
+ if ( work->e != 0 ) return;\r
+\r
+ if ( new_depth >= 0 )\r
+ { work->Status.TagName = &xpath[ xpath_lengths[ new_depth ] + 1 ]; }\r
+ else\r
+ { work->Status.TagName = &xpath[ 1 ]; }\r
+\r
+\r
+ /* Call "work->OnText" */\r
+ if ( work->OnText != DefaultFunction )\r
+ { ParseXML2_callOnText( work ); }\r
+\r
+\r
+ /* Call "work->OnEndElement" */\r
+ work->e = work->OnEndElement( &work->Status );\r
+ work->Status.Depth -= 1;\r
+\r
+\r
+ /* Set "work->XPath" : Remove "Name" */\r
+ if ( new_depth >= 0 ) {\r
+ xpath[ xpath_lengths[ new_depth ] ] = _T('\0');\r
+ if ( new_depth - 1 >= 0 )\r
+ { work->Status.TagName = &xpath[ xpath_lengths[ new_depth - 1 ] + 1 ]; }\r
+ else\r
+ { work->Status.TagName = &xpath[ 1 ]; }\r
+ }\r
+ else {\r
+ xpath[ 1 ] = _T('\0'); /* xpath = "/" */\r
+ work->Status.TagName = &xpath[ 0 ];\r
+ }\r
+\r
+ work->Status.PreviousCallbackType = F_ParseXML2_OnEndElement;\r
+}\r
+\r
+\r
+/*[ParseXML2_onText]*/\r
+static void ParseXML2_onText( void* UserData, const XML_Char* Text, int TextLength )\r
+{\r
+ ParseXML2_WorkClass* work = (ParseXML2_WorkClass*) UserData;\r
+\r
+ if ( work->e != 0 ) return;\r
+\r
+ if ( work->OnText != DefaultFunction ) {\r
+\r
+ #if 1\r
+ work->e = StrFile_writeBinary( &work->TextBuffer, Text, TextLength * sizeof(TCHAR) );\r
+\r
+ if ( work->TextStartLineNum == 0 )\r
+ { work->TextStartLineNum = work->Status.LineNum; }\r
+ #else\r
+ work->Status.u.OnText.Text = Text;\r
+ work->Status.u.OnText.TextLength = TextLength;\r
+\r
+ work->e = work->OnText( &work->Status );\r
+\r
+ work->Status.u.OnText.Text = NULL;\r
+ work->Status.u.OnText.TextLength = 0;\r
+\r
+ work->Status.PreviousCallbackType = F_ParseXML2_OnText;\r
+ #endif\r
+ }\r
+}\r
+\r
+\r
+/*[ParseXML2_callOnText]*/\r
+static void ParseXML2_callOnText( ParseXML2_WorkClass* work )\r
+{\r
+ if ( work->TextStartLineNum != 0 ) {\r
+ int line_num_back_up = work->Status.LineNum;\r
+\r
+ work->Status.u.OnText.Text = work->TextBuffer.Buffer;\r
+ work->Status.u.OnText.TextLength = (TCHAR*) work->TextBuffer.Pointer -\r
+ (TCHAR*) work->TextBuffer.Buffer;\r
+ work->Status.LineNum = work->TextStartLineNum;\r
+\r
+ work->e = work->OnText( &work->Status );\r
+\r
+ if ( work->e == 0 ) {\r
+ work->e = StrFile_setPointer( &work->TextBuffer, 0 );\r
+ IF( work->e ) __noop();\r
+ }\r
+ work->Status.LineNum = line_num_back_up;\r
+ work->TextStartLineNum = 0;\r
+ work->Status.PreviousCallbackType = F_ParseXML2_OnText;\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey] >>> \r
+************************************************************************/\r
+static errnum_t AppKey_create( AppKey** out_m );\r
+static bool AppKey_isSame( AppKey* m );\r
+static void Writables_initConst( Writables* m );\r
+static errnum_t Writables_init( Writables* m, AppKey* Key );\r
+static errnum_t Writables_finish( Writables* m, int e );\r
+static bool Writables_isInited( Writables* m );\r
+static errnum_t Writables_clearPaths( Writables* m );\r
+static errnum_t Writables_create( Writables** out_m, AppKey* Key );\r
+static errnum_t Writables_copyToConst( Writables* To, Writables* From );\r
+\r
+\r
+typedef struct _CurrentWritables CurrentWritables;\r
+struct _CurrentWritables {\r
+ Writables m_CurrentWritables;\r
+ TCHAR* m_ProgramFiles; size_t m_ProgramFiles_Len;\r
+ TCHAR* m_windir; size_t m_windir_Len;\r
+ TCHAR* m_APPDATA; size_t m_APPDATA_Len;\r
+ TCHAR* m_LOCALAPPDATA; size_t m_LOCALAPPDATA_Len;\r
+};\r
+static void CurrentWritables_initConst( CurrentWritables* m );\r
+static errnum_t CurrentWritables_init( CurrentWritables* m );\r
+static errnum_t CurrentWritables_finish( CurrentWritables* m, int e );\r
+static errnum_t CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath );\r
+\r
+\r
+//////////////////////////////\r
+\r
+static AppKey g_AppKey;\r
+static AppKey* g_AppKeyPrivate;\r
+\r
+// under g_AppKey\r
+Writables g_DefaultWritables;\r
+Writables g_CurrentWritables; // public\r
+static CurrentWritables g_CurrentWritablesPrivate;\r
+\r
+\r
+static errnum_t AppKey_create( AppKey** out_m )\r
+{\r
+ errnum_t e;\r
+\r
+ IF( g_AppKeyPrivate != NULL ) { e=1; goto fin; }\r
+ // 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
+\r
+ Writables_initConst( &g_DefaultWritables );\r
+ CurrentWritables_initConst( &g_CurrentWritablesPrivate );\r
+\r
+ e= CurrentWritables_init( &g_CurrentWritablesPrivate ); IF(e)goto fin;\r
+ e= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(e)goto fin;\r
+\r
+ *out_m = &g_AppKey;\r
+ g_AppKeyPrivate = &g_AppKey;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+static bool AppKey_isSame( AppKey* m )\r
+{\r
+ return ( m == g_AppKeyPrivate );\r
+}\r
+\r
+\r
+void AppKey_initGlobal_const()\r
+{\r
+ Writables_initConst( &g_DefaultWritables );\r
+}\r
+\r
+\r
+errnum_t AppKey_finishGlobal( errnum_t e )\r
+{\r
+ errnum_t ee;\r
+\r
+ e= Writables_finish( &g_DefaultWritables, e );\r
+ e= CurrentWritables_finish( &g_CurrentWritablesPrivate, e );\r
+ ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
+\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_newWritable_Sub] >>> \r
+************************************************************************/\r
+errnum_t AppKey_newWritable_Sub( AppKey** in_out_m, Writables** out_Writable,\r
+ va_list va,\r
+ TCHAR** in_Paths, int in_PathCount )\r
+{\r
+ errnum_t e;\r
+ AppKey* m = NULL;\r
+ Writables* wr = NULL;\r
+#if Uses_OutMallocIDTool\r
+ bool is_prev_out_malloc;\r
+\r
+ is_prev_out_malloc = OutMallocID_setEnable( false );\r
+#endif\r
+\r
+\r
+ //=== AppKey* m \82ð\97L\8cø\82É\82·\82é\r
+ if ( in_out_m == NULL ) { // \8d¡\89ñ\82Ì\8aÖ\90\94\82Ì\92\86\82¾\82¯\82Å\8eQ\8fÆ\82·\82é\r
+ e= AppKey_create( &m ); IF(e)goto resume;\r
+ }\r
+ 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
+ e= AppKey_create( &m ); IF(e)goto resume;\r
+ *in_out_m = m;\r
+ }\r
+ 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
+ m = *in_out_m;\r
+ }\r
+\r
+\r
+ //=== \90³\8bK\82Ì AppKey \82©\83`\83F\83b\83N\82·\82é\r
+ IF( ! AppKey_isSame( m ) )goto err;\r
+\r
+\r
+ //=== Writable \82ð\90¶\90¬\82·\82é\r
+ if ( out_Writable == NULL ) {\r
+ wr = &g_DefaultWritables;\r
+ e= Writables_finish( wr, 0 ); IF(e)goto resume;\r
+ e= Writables_init( wr, m ); IF(e)goto resume;\r
+ }\r
+ else {\r
+ e= Writables_create( &wr, m ); IF(e)goto resume;\r
+ *out_Writable = wr;\r
+ }\r
+\r
+\r
+ //=== Writable \82É\83p\83X\82ð\93o\98^\82·\82é\r
+ if ( in_Paths == NULL ) {\r
+ TCHAR* path;\r
+ int i;\r
+\r
+ for ( i=0; ; i++ ) {\r
+ path = va_arg( va, TCHAR* );\r
+ if ( path == NULL ) break;\r
+ IF( i == 5 ) goto err; // \8dÅ\8cã\82Ì NULL \96Y\82ê\91Î\8dô\r
+\r
+ e= Writables_add( wr, m, path ); IF(e)goto resume;\r
+ }\r
+ }\r
+ else {\r
+ int i;\r
+\r
+ for ( i = 0; i < in_PathCount; i += 1 ) {\r
+ e= Writables_add( wr, m, in_Paths[i] ); IF(e){goto fin;}\r
+ }\r
+ }\r
+\r
+ #if defined(TempFile_get)\r
+ {\r
+ TempFile* temp;\r
+\r
+ e= TempFile_get( &temp ); IF(e)goto resume;\r
+ e= Writables_add( wr, m, temp->TempPath ); IF(e)goto resume;\r
+ }\r
+ #endif\r
+\r
+\r
+ //=== \82·\82®\82É Writable \82ð\97L\8cø\82É\82·\82é\r
+ if ( out_Writable == NULL ) {\r
+ e= Writables_enable( wr ); IF(e)goto resume;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ #if Uses_OutMallocIDTool\r
+ OutMallocID_setEnable( is_prev_out_malloc );\r
+ #endif\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto resume;\r
+resume:\r
+ if ( wr != NULL ) {\r
+ if ( out_Writable == NULL )\r
+ e= Writables_finish( wr, e ); // g_DefaultWritables\r
+ else\r
+ e= Writables_delete( wr, e );\r
+ }\r
+ goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_newWritable] >>> \r
+************************************************************************/\r
+errnum_t AppKey_newWritable( AppKey** in_out_m, Writables** out_Writable, ... )\r
+{\r
+ errnum_t e;\r
+ va_list va;\r
+\r
+ va_start( va, out_Writable );\r
+ e = AppKey_newWritable_Sub( in_out_m, out_Writable, va, NULL, 0 );\r
+ va_end( va );\r
+\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_newWritable_byArray] >>> \r
+************************************************************************/\r
+errnum_t AppKey_newWritable_byArray( AppKey** in_out_m, Writables** out_Writable,\r
+ TCHAR** in_Paths, int in_PathCount )\r
+{\r
+ IF ( in_Paths == NULL ) {\r
+ return E_OTHERS;\r
+ } else {\r
+ return AppKey_newWritable_Sub( in_out_m, out_Writable, NULL,\r
+ in_Paths, in_PathCount );\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_addNewWritableFolder] \83`\83F\83b\83N\82·\82é\81A\82Ü\82½\82Í\92Ç\89Á\82·\82é >>> \r
+************************************************************************/\r
+errnum_t AppKey_addNewWritableFolder_Sub( const TCHAR* Path, bool* out_IsWritable );\r
+\r
+errnum_t AppKey_addNewWritableFolder( const TCHAR* Path )\r
+{\r
+ errnum_t e;\r
+ bool is_writable;\r
+\r
+ e= AppKey_addNewWritableFolder_Sub( Path, &is_writable ); IF(e){goto fin;}\r
+ IF ( ! is_writable ) { e=E_OUT_OF_WRITABLE; goto fin; }\r
+ // Path (abs_path) \82Í\81AAppKey_newWritable \82Å\8b\96\89Â\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\81B\r
+ // \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
+ // \8b\96\89Â\82³\82ê\82Ä\82¢\82é\83p\83X\82ð\8am\94F\82µ\82Ä\82\82¾\82³\82¢\81B\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+errnum_t AppKey_addNewWritableFolder_Sub( const TCHAR* Path, bool* out_IsWritable )\r
+{\r
+ errnum_t e;\r
+ TCHAR** pp;\r
+ TCHAR** pp_over;\r
+ Writables* wr = &g_CurrentWritablesPrivate.m_CurrentWritables;\r
+ size_t path_len;\r
+ TCHAR abs_path[MAX_PATH];\r
+\r
+ *out_IsWritable = true;\r
+\r
+ if ( g_AppKeyPrivate == NULL ) {\r
+ e= AppKey_newWritable( NULL, NULL, ".", NULL ); IF(e){goto fin;}\r
+ }\r
+\r
+ e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e){goto fin;}\r
+\r
+ pp_over = wr->m_Paths + wr->m_nPath;\r
+ for ( pp = wr->m_Paths; ; pp++ ) {\r
+ if ( pp >= pp_over ) {\r
+ *out_IsWritable = false;\r
+ break;\r
+ }\r
+ path_len = _tcslen( *pp );\r
+ if ( _tcsnicmp( *pp, abs_path, path_len ) == 0 &&\r
+ ( abs_path[ path_len ] == _T('\\') || abs_path[ path_len ] == _T('\0') ) )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_addWritableFolder] \83`\83F\83b\83N\82µ\82È\82¢\82Å\81A\92Ç\89Á\82·\82é >>> \r
+************************************************************************/\r
+errnum_t AppKey_addWritableFolder( AppKey* m, const TCHAR* Path )\r
+{\r
+ errnum_t e;\r
+ Writables* wr = &g_CurrentWritablesPrivate.m_CurrentWritables;\r
+ bool is_writable;\r
+\r
+ e= AppKey_addNewWritableFolder_Sub( Path, &is_writable ); IF(e){goto fin;}\r
+ if ( ! is_writable ) {\r
+ e= Writables_add( wr, m, Path ); IF(e){goto fin;}\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_checkWritable] >>> \r
+************************************************************************/\r
+errnum_t AppKey_checkWritable( const TCHAR* Path )\r
+{\r
+ return AppKey_addNewWritableFolder( Path );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Writables_init] >>> \r
+************************************************************************/\r
+static void Writables_initConst( Writables* m )\r
+{\r
+ m->m_Paths = NULL;\r
+ m->m_nPath = -1;\r
+}\r
+\r
+\r
+static errnum_t Writables_init( Writables* m, AppKey* Key )\r
+{\r
+ IF( ! AppKey_isSame( Key ) ) return E_OTHERS;\r
+\r
+ m->m_Paths = NULL;\r
+ m->m_nPath = 0;\r
+ return 0;\r
+}\r
+\r
+\r
+static errnum_t Writables_finish( Writables* m, int e )\r
+{\r
+ errnum_t ee;\r
+\r
+ ee= Writables_clearPaths( m ); IF(ee&&!e) e=ee;\r
+ m->m_nPath = -1;\r
+ return e;\r
+}\r
+\r
+\r
+static bool Writables_isInited( Writables* m )\r
+{\r
+ return ( m->m_nPath != -1 );\r
+}\r
+\r
+\r
+static errnum_t Writables_clearPaths( Writables* m )\r
+{\r
+ TCHAR** p;\r
+ TCHAR** p_over;\r
+\r
+ if ( m->m_Paths != NULL ) {\r
+ p_over = m->m_Paths + m->m_nPath;\r
+ for ( p = m->m_Paths; p < p_over; p++ ) {\r
+ free( *p );\r
+ }\r
+ free( m->m_Paths ); m->m_Paths = NULL;\r
+ }\r
+ m->m_nPath = 0;\r
+ return 0;\r
+}\r
+\r
+\r
+static errnum_t Writables_create( Writables** out_m, AppKey* Key )\r
+{\r
+ errnum_t e;\r
+ Writables* m;\r
+\r
+ m = (Writables*) malloc( sizeof(*m) ); IF(m==NULL)return E_FEW_MEMORY;\r
+ Writables_initConst( m );\r
+ e= Writables_init( m, Key ); IF(e)goto resume;\r
+ *out_m = m;\r
+ return 0;\r
+resume: Writables_delete( m, 0 ); free(m); return e;\r
+}\r
+\r
+\r
+errnum_t Writables_delete( Writables* m, errnum_t e )\r
+{\r
+ if ( m == NULL ) goto fin;\r
+ e= Writables_finish( m, e );\r
+ free( m );\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Writables_add] >>> \r
+************************************************************************/\r
+int Writables_add( Writables* m, AppKey* Key, const TCHAR* Path )\r
+{\r
+ int e;\r
+ TCHAR** pp;\r
+ TCHAR* p = NULL;\r
+ size_t path_size;\r
+ TCHAR abs_path[MAX_PATH];\r
+\r
+ IF( ! AppKey_isSame( Key ) )goto err;\r
+ if ( Path[0] == _T('\0') ) return 0;\r
+\r
+ e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto resume;\r
+\r
+ e= CurrentWritables_askFileAccess( &g_CurrentWritablesPrivate, abs_path ); IF(e)goto resume;\r
+\r
+ pp = (TCHAR**) realloc( m->m_Paths, (m->m_nPath + 1) * sizeof(TCHAR*) );\r
+ IF( pp == NULL ) goto err;\r
+ m->m_Paths = pp;\r
+\r
+ path_size = (_tcslen( abs_path ) + 1) * sizeof(TCHAR);\r
+ p = (TCHAR*) malloc( path_size );\r
+ m->m_Paths[ m->m_nPath ] = p;\r
+ IF( p == NULL )goto err;\r
+\r
+ memcpy( p, abs_path, path_size );\r
+ if ( p[ path_size/sizeof(TCHAR) - 2 ] == _T('\\') )\r
+ p[ path_size/sizeof(TCHAR) - 2 ] = _T('\0');\r
+ m->m_nPath ++;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto resume;\r
+resume:\r
+ if ( p != NULL ) free( p );\r
+ goto fin;\r
+}\r
+\r
+\r
+int Writables_remove( Writables* m, const TCHAR* Path )\r
+{\r
+ TCHAR** pp;\r
+ TCHAR** pp_over;\r
+\r
+ pp_over = m->m_Paths + m->m_nPath;\r
+ for ( pp = m->m_Paths; ; pp++ ) {\r
+ if ( pp >= pp_over ) return 0;\r
+ if ( _tcscmp( *pp, Path ) == 0 ) break;\r
+ }\r
+ free( *pp );\r
+ memmove( pp, pp+1, (char*)pp - (char*)pp_over - sizeof(TCHAR) );\r
+ m->m_nPath --;\r
+\r
+ #if _DEBUG\r
+ *( pp_over - 1 ) = NULL;\r
+ #endif\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Writables_enable] >>> \r
+************************************************************************/\r
+int Writables_enable( Writables* m )\r
+{\r
+ int e;\r
+\r
+ e= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, m ); IF(e)goto fin;\r
+ e= Writables_copyToConst( &g_CurrentWritables, &g_CurrentWritablesPrivate.m_CurrentWritables ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+int Writables_disable( Writables* m, int e )\r
+{\r
+ int ee;\r
+\r
+ UNREFERENCED_VARIABLE( m );\r
+\r
+ ee= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
+ ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+static int Writables_copyToConst( Writables* To, Writables* From )\r
+{\r
+ int e;\r
+ TCHAR** pp;\r
+ TCHAR** pp_over;\r
+ TCHAR* p2;\r
+ TCHAR** pp2;\r
+ size_t path_size;\r
+\r
+ if ( To->m_Paths != NULL ) {\r
+ free( To->m_Paths );\r
+ To->m_Paths = NULL;\r
+ To->m_nPath = 0;\r
+ }\r
+\r
+ if ( From != NULL && From->m_nPath > 0 ) {\r
+\r
+ path_size = 0;\r
+ pp_over = From->m_Paths + From->m_nPath;\r
+ for ( pp = From->m_Paths; pp < pp_over; pp++ ) {\r
+ path_size += _tcslen( *pp ) + 1;\r
+ }\r
+\r
+ path_size = From->m_nPath * sizeof(TCHAR*) + path_size * sizeof(TCHAR);\r
+ To->m_Paths = (TCHAR**) malloc( path_size );\r
+ IF( To->m_Paths == NULL ) goto err;\r
+\r
+ p2 = (TCHAR*)( (char*)To->m_Paths + From->m_nPath * sizeof(TCHAR*) );\r
+ pp2 = To->m_Paths;\r
+ for ( pp = From->m_Paths; pp < pp_over; pp++ ) {\r
+ *pp2 = p2;\r
+ path_size = (_tcslen( *pp ) + 1) * sizeof(TCHAR);\r
+ memcpy( p2, *pp, path_size );\r
+ p2 = (TCHAR*)( (char*)p2 + path_size );\r
+ pp2 ++;\r
+ }\r
+ To->m_nPath = From->m_nPath;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [CurrentWritables] >>> \r
+************************************************************************/\r
+static void CurrentWritables_initConst( CurrentWritables* m )\r
+{\r
+ Writables_initConst( &m->m_CurrentWritables );\r
+ m->m_ProgramFiles = NULL;\r
+ m->m_windir = NULL;\r
+ m->m_APPDATA = NULL;\r
+ m->m_LOCALAPPDATA = NULL;\r
+}\r
+\r
+\r
+static int CurrentWritables_init( CurrentWritables* m )\r
+{\r
+ int e;\r
+ #if Uses_OutMallocIDTool\r
+ bool is_prev_out_malloc;\r
+\r
+ is_prev_out_malloc = OutMallocID_setEnable( false );\r
+ #endif\r
+\r
+ e= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(e)goto fin;\r
+\r
+ e= env_malloc( &m->m_ProgramFiles, &m->m_ProgramFiles_Len, _T("ProgramFiles") ); IF(e)goto fin;\r
+ e= env_malloc( &m->m_windir, &m->m_windir_Len, _T("windir") ); IF(e)goto fin;\r
+ e= env_malloc( &m->m_APPDATA, &m->m_APPDATA_Len, _T("APPDATA") ); IF(e)goto fin;\r
+ // e= env_malloc( &m->m_LOCALAPPDATA, &m->m_LOCALAPPDATA_Len, _T("LOCALAPPDATA") ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ #if Uses_OutMallocIDTool\r
+ OutMallocID_setEnable( is_prev_out_malloc );\r
+ #endif\r
+ return e;\r
+}\r
+\r
+\r
+static int CurrentWritables_finish( CurrentWritables* m, int e )\r
+{\r
+ int ee;\r
+\r
+ ee= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
+\r
+ if ( m->m_ProgramFiles != NULL ) free( m->m_ProgramFiles );\r
+ if ( m->m_windir != NULL ) free( m->m_windir );\r
+ if ( m->m_APPDATA != NULL ) free( m->m_APPDATA );\r
+ if ( m->m_LOCALAPPDATA != NULL ) free( m->m_LOCALAPPDATA );\r
+\r
+ m->m_ProgramFiles = NULL;\r
+ m->m_windir = NULL;\r
+ m->m_APPDATA = NULL;\r
+ m->m_LOCALAPPDATA = NULL;\r
+\r
+ return e;\r
+}\r
+\r
+\r
+static int CurrentWritables_askFileAccess_sub(\r
+ const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* FullPath, size_t FullPath_Len );\r
+\r
+static int CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath )\r
+{\r
+ int e;\r
+ size_t abs_len;\r
+\r
+ abs_len = _tcslen( FullPath );\r
+ e= CurrentWritables_askFileAccess_sub( m->m_ProgramFiles, m->m_ProgramFiles_Len, FullPath, abs_len ); IF(e)goto fin;\r
+ e= CurrentWritables_askFileAccess_sub( m->m_windir, m->m_windir_Len, FullPath, abs_len ); IF(e)goto fin;\r
+ e= CurrentWritables_askFileAccess_sub( m->m_APPDATA, m->m_APPDATA_Len, FullPath, abs_len ); IF(e)goto fin;\r
+ e= CurrentWritables_askFileAccess_sub( m->m_LOCALAPPDATA, m->m_LOCALAPPDATA_Len, FullPath, abs_len ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+static int CurrentWritables_askFileAccess_sub(\r
+ const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* FullPath, size_t FullPath_Len )\r
+{\r
+ if ( SystemPath == NULL ) return 0;\r
+\r
+ IF ( _tcsncmp( SystemPath, FullPath, SystemPath_Len ) == 0 )\r
+ 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
+\r
+ IF ( _tcsncmp( SystemPath, FullPath, FullPath_Len ) == 0 )\r
+ 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
+\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [Error4/Error4.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [Get_Error4_Variables] >>> \r
+************************************************************************/\r
+static Error4_VariablesClass gs;\r
+#ifdef _DEBUG\r
+ extern Error4_VariablesClass* g_Error4_Variables = &gs;\r
+#endif\r
+\r
+Error4_VariablesClass* Get_Error4_Variables()\r
+{\r
+ return &gs;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (SetBreakErrorID) >>> \r
+************************************************************************/\r
+\r
+/*[DebugBreakR]*/\r
+void DebugBreakR()\r
+{\r
+ 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
+ DebugBreak();\r
+ // 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
+ // \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
+}\r
+\r
+\r
+#if ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
+\r
+\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+ dll_global_g_DebugBreakCount ErrorClass g_Error; /* \8f\89\8aú\92l\82Í\82·\82×\82Ä\83[\83\8d */\r
+#else\r
+ dll_global_g_DebugBreakCount GlobalErrorClass g_GlobalError;\r
+\r
+ static errnum_t ErrorClass_initializeIfNot_Sub( ErrorClass** out_Error );\r
+ static errnum_t ErrorClass_initializeIfNot_Sub2(void);\r
+#endif\r
+\r
+\r
+#define IF_ if /* Error check for in "IF" macro */\r
+\r
+\r
+/*[SetBreakErrorID]*/\r
+void SetBreakErrorID( int ErrorID )\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+ bool is_print;\r
+\r
+ is_print = ( err->BreakErrorID != ErrorID );\r
+\r
+ err->BreakErrorID = ErrorID;\r
+ /* printf \82Ì\92\86\82Å\94\90¶\82·\82é\83G\83\89\81[\82Å\8e~\82ß\82é\82½\82ß */\r
+\r
+ if ( is_print )\r
+ { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
+\r
+#else\r
+\r
+ GlobalErrorClass* err_global = &g_GlobalError;\r
+\r
+ if ( err_global->BreakGlobalErrorID != ErrorID )\r
+ { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
+ err_global->BreakGlobalErrorID = ErrorID;\r
+\r
+#endif\r
+}\r
+\r
+\r
+\r
+bool OnRaisingError_Sub( const char* FilePath, int LineNum )\r
+ // \96{\8aÖ\90\94\82Í\81AIF \83}\83N\83\8d\82Ì\92\86\82©\82ç\8cÄ\82Î\82ê\82Ü\82·\r
+ // \95Ô\82è\92l\82Í\81A\83u\83\8c\81[\83N\82·\82é\82©\82Ç\82¤\82©\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+ bool is_break;\r
+\r
+ /* \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
+ if ( err->IsError ) {\r
+ return false;\r
+ }\r
+\r
+ /* \83G\83\89\81[\82ª\94\90¶\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
+ err->ErrorID += 1;\r
+ err->IsError = true;\r
+ err->FilePath = FilePath;\r
+ err->LineNum = LineNum;\r
+\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
+ err->ErrorID, (int) err );\r
+ #endif\r
+\r
+ is_break = ( err->ErrorID == err->BreakErrorID );\r
+\r
+ if ( is_break ) {\r
+ printf( "Break in (%d) %s\n", LineNum, FilePath );\r
+ }\r
+ return ( err->ErrorID == err->BreakErrorID );\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ bool is_break = false;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err ); IF_(e){goto fin;}\r
+\r
+\r
+ /* \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
+ if ( err->IsError ) {\r
+ return false;\r
+ }\r
+\r
+ /* \83G\83\89\81[\82ª\94\90¶\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
+ else {\r
+ GlobalErrorClass* err_global = &g_GlobalError;\r
+\r
+ EnterCriticalSection( &err_global->CriticalSection );\r
+\r
+\r
+ err_global->ErrorThreadCount += 1;\r
+ err_global->RaisedGlobalErrorID += 1;\r
+ err->GlobalErrorID = err_global->RaisedGlobalErrorID;\r
+\r
+ err->ErrorID += 1;\r
+ err->IsError = true;\r
+ err->FilePath = FilePath;\r
+ err->LineNum = LineNum;\r
+\r
+ is_break = ( err->ErrorID == err->BreakErrorID ) ||\r
+ ( err->GlobalErrorID == err_global->BreakGlobalErrorID );\r
+\r
+\r
+ /* \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
+ /* \8fã\8bL\82Ì if ( err->IsError ) \82Å\81A\82·\82®\96ß\82é\82½\82ß */\r
+\r
+\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
+ err->GlobalErrorID, (int) err );\r
+ #endif\r
+\r
+\r
+ if ( err->ErrorID == 1 ) {\r
+ FinalizerClass_initConst( &err->Finalizer, err, ErrorClass_finalize );\r
+ e= AddThreadLocalFinalizer( &err->Finalizer );\r
+ }\r
+ else {\r
+ e = 0;\r
+ }\r
+ LeaveCriticalSection( &err_global->CriticalSection );\r
+ IF(e){goto fin;}\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( is_break ) {\r
+ printf( "Break in (%d) %s\n", LineNum, FilePath );\r
+ }\r
+ return is_break;\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+\r
+//[ClearError]\r
+void ClearError()\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ if ( err->IsError ) {\r
+ printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
+ err->ErrorID, (int) err );\r
+ }\r
+ #endif\r
+\r
+ err->IsError = false;\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err );\r
+ if ( e == 0 ) {\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ if ( err->IsError )\r
+ printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
+ err->GlobalErrorID, (int) err );\r
+ #endif\r
+\r
+ if ( err->IsError ) {\r
+ GlobalErrorClass* err_global = &g_GlobalError;\r
+\r
+ EnterCriticalSection( &err_global->CriticalSection );\r
+ err_global->ErrorThreadCount -= 1;\r
+ LeaveCriticalSection( &err_global->CriticalSection );\r
+\r
+ err->IsError = false;\r
+ }\r
+ }\r
+ else {\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"clear_miss\"/>\n" );\r
+ #endif\r
+ }\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+\r
+//[IfErrThenBreak]\r
+void IfErrThenBreak()\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+\r
+ if ( err->IsError &&\r
+ ( err->ErrorID != err->BreakErrorID || err->BreakErrorID == 0 )\r
+ ) {\r
+ printf( "in IfErrThenBreak\n" );\r
+ DebugBreakR();\r
+\r
+ // \83E\83H\83b\83`\82Å\81Aerr->ErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
+ // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82\82¾\82³\82¢\81B\r
+ // \83G\83\89\81[\82ª\94\90¶\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
+ // \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
+ // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
+ err->ErrorID, err->BreakErrorID );\r
+ #endif\r
+\r
+ {\r
+ char str[512];\r
+ sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
+ err->FilePath, err->LineNum );\r
+ OutputDebugStringA( str );\r
+ }\r
+ }\r
+ ClearError();\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ GlobalErrorClass* err_global = &g_GlobalError;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err );\r
+ if ( e ) { DebugBreakR(); ClearError(); return; } /* \93à\95\94\83G\83\89\81[ */\r
+\r
+ if ( err_global->ErrorThreadCount != 0 &&\r
+ ( err->GlobalErrorID != err_global->BreakGlobalErrorID || err_global->BreakGlobalErrorID == 0 )\r
+ ) {\r
+ printf( "in IfErrThenBreak\n" );\r
+ DebugBreakR();\r
+\r
+ // \83E\83H\83b\83`\82Å\81Aerr->GlobalErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
+ // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82\82¾\82³\82¢\81B\r
+ // \83G\83\89\81[\82ª\94\90¶\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
+ // \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
+ // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
+ err->ErrorID, err->BreakErrorID );\r
+ #endif\r
+\r
+ {\r
+ char str[512];\r
+ sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
+ err->FilePath, err->LineNum );\r
+ OutputDebugStringA( str );\r
+ }\r
+ }\r
+ ClearError();\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+\r
+//[PushErr]\r
+void PushErr( ErrStackAreaClass* ErrStackArea )\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+\r
+ ErrStackArea->ErrorID = err->ErrorID;\r
+ ErrStackArea->IsError = err->IsError;\r
+ err->IsError = false;\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err );\r
+ if ( e == 0 ) {\r
+ ErrStackArea->ErrorID = err->ErrorID;\r
+ ErrStackArea->IsError = err->IsError;\r
+ err->IsError = false;\r
+ }\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+//[PopErr]\r
+void PopErr( ErrStackAreaClass* ErrStackArea )\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+\r
+ if ( ErrStackArea->IsError )\r
+ { err->IsError = true; }\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err );\r
+ if ( e == 0 ) {\r
+ if ( ErrStackArea->IsError )\r
+ { err->IsError = true; }\r
+ }\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+\r
+ \r
+/*[SetBreakErrorID:2]*/\r
+#undef IF_\r
+\r
+\r
+#endif // ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
+\r
+\r
+//[MergeError]\r
+errnum_t MergeError( errnum_t e, errnum_t ee )\r
+{\r
+ if ( e == 0 ) { return ee; }\r
+ else { /* ErrorLog_add( ee ); */ return e; }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [g_Error4_String] >>> \r
+************************************************************************/\r
+TCHAR g_Error4_String[4096];\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Error4_printf] >>> \r
+************************************************************************/\r
+void Error4_printf( const TCHAR* format, ... )\r
+{\r
+ va_list va;\r
+ va_start( va, format );\r
+ vstprintf_r( g_Error4_String, sizeof(g_Error4_String), format, va );\r
+ va_end( va );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Error4_getErrStr] >>> \r
+************************************************************************/\r
+void Error4_getErrStr( int ErrNum, TCHAR* out_ErrStr, size_t ErrStrSize )\r
+{\r
+ switch ( ErrNum ) {\r
+\r
+ case 0:\r
+ stprintf_r( out_ErrStr, ErrStrSize, _T("no error") );\r
+ break;\r
+\r
+ case E_FEW_ARRAY:\r
+ stprintf_r( out_ErrStr, ErrStrSize,\r
+ _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
+ break;\r
+\r
+ case E_FEW_MEMORY:\r
+ stprintf_r( out_ErrStr, ErrStrSize,\r
+ _T("<ERROR msg=\"\83q\81[\83v\81E\83\81\83\82\83\8a\81[\82ª\95s\91«\82µ\82Ü\82µ\82½\81B\"/>") );\r
+ break;\r
+\r
+ #ifndef __linux__\r
+ case E_GET_LAST_ERROR: {\r
+ DWORD err_win;\r
+ TCHAR* str_pointer;\r
+\r
+ err_win = gs.WindowsLastError;\r
+ if ( err_win == 0 ) { err_win = GetLastError(); }\r
+\r
+ stprintf_part_r( out_ErrStr, ErrStrSize, out_ErrStr, &str_pointer,\r
+ _T("<ERROR GetLastError=\"0x%08X\" GetLastErrorStr=\""), err_win );\r
+ FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,\r
+ NULL, err_win, LANG_USER_DEFAULT,\r
+ str_pointer, (TCHAR*)( (char*)out_ErrStr + ErrStrSize ) - str_pointer, NULL );\r
+ str_pointer = StrT_chr( str_pointer, _T('\0') );\r
+ if ( *( str_pointer - 2 ) == _T('\r') && *( str_pointer - 1 ) == _T('\n') )\r
+ str_pointer -= 2;\r
+ stcpy_part_r( out_ErrStr, ErrStrSize, str_pointer, NULL, _T("\"/>"), NULL );\r
+ break;\r
+ }\r
+ #endif\r
+\r
+ default:\r
+ if ( g_Error4_String[0] != '\0' )\r
+ stprintf_r( out_ErrStr, ErrStrSize, _T("%s"), g_Error4_String );\r
+ else\r
+ stprintf_r( out_ErrStr, ErrStrSize, _T("<ERROR errnum=\"%d\"/>"), ErrNum );\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [SaveWindowsLastError] >>> \r
+************************************************************************/\r
+errnum_t SaveWindowsLastError()\r
+{\r
+ gs.WindowsLastError = GetLastError();\r
+ return E_GET_LAST_ERROR;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Error4_showToStdErr] >>> \r
+************************************************************************/\r
+void Error4_showToStdErr( int err_num )\r
+{\r
+ Error4_showToStdIO( stderr, err_num );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Error4_showToStdIO] >>> \r
+************************************************************************/\r
+void Error4_showToStdIO( FILE* out, int err_num )\r
+{\r
+ TCHAR msg[1024];\r
+ #if _UNICODE\r
+ char msg2[1024];\r
+ #endif\r
+\r
+ if ( err_num != 0 ) {\r
+ Error4_getErrStr( err_num, msg, sizeof(msg) );\r
+ #if _UNICODE\r
+ setlocale( LC_ALL, ".OCP" );\r
+ sprintf_s( msg2, sizeof(msg2), "%S", msg );\r
+ fprintf( out, "%s\n", msg2 ); // _ftprintf_s \82Å\82Í\93ú\96{\8cê\82ª\8fo\82Ü\82¹\82ñ\r
+ #else\r
+ fprintf( out, "%s\n", msg );\r
+ #endif\r
+\r
+ #if ERR2_ENABLE_ERROR_BREAK\r
+ 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
+ g_Err2.ErrID );\r
+ #else\r
+#if 0\r
+ if ( err_num == E_FEW_MEMORY || gs.WindowsLastError == ERROR_NOT_ENOUGH_MEMORY ) {\r
+ /* Not show the message for developper */\r
+ }\r
+ else {\r
+ 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
+ }\r
+#endif\r
+ #endif\r
+ }\r
+ IfErrThenBreak();\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [CRT_plus_2/CRT_plus_2.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/**************************************************************************\r
+ <<< [Interface] >>> \r
+***************************************************************************/\r
+\r
+/*[DefaultFunction]*/\r
+errnum_t DefaultFunction( void* self )\r
+{\r
+ UNREFERENCED_VARIABLE( self );\r
+ return 0;\r
+}\r
+\r
+/*[DefaultFunction_NotImplementYet]*/\r
+errnum_t DefaultFunction_NotImplementYet( void* self )\r
+{\r
+ UNREFERENCED_VARIABLE( self );\r
+ return E_NOT_IMPLEMENT_YET;\r
+}\r
+\r
+/*[DefaultFunction_Finalize]*/\r
+errnum_t DefaultFunction_Finalize( void* self, errnum_t e )\r
+{\r
+ UNREFERENCED_VARIABLE( self );\r
+ return e;\r
+}\r
+\r
+/*[VTableDefine_overwrite]*/\r
+errnum_t VTableDefine_overwrite( VTableDefine* aVTable, size_t aVTable_ByteSize, int iMethod, void* Func )\r
+{\r
+ VTableDefine* p = aVTable;\r
+ VTableDefine* p_over = (VTableDefine*)( (char*)aVTable + aVTable_ByteSize );\r
+\r
+ for ( ; p < p_over; p++ ) {\r
+ if ( p->m_IMethod == iMethod ) {\r
+ p->m_method = Func;\r
+ return 0;\r
+ }\r
+ }\r
+ return E_NOT_FOUND_SYMBOL;\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [StrT/StrT.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cpy] >>> \r
+- _tcscpy is raising exception, if E_FEW_ARRAY\r
+************************************************************************/\r
+errnum_t StrT_cpy( TCHAR* Dst, size_t DstSize, const TCHAR* Src )\r
+{\r
+ size_t size;\r
+\r
+ size = ( _tcslen( Src ) + 1 ) * sizeof(TCHAR);\r
+ if ( size <= DstSize ) {\r
+ memcpy( Dst, Src, size );\r
+ return 0;\r
+ }\r
+ else {\r
+ memcpy( Dst, Src, DstSize - sizeof(TCHAR) );\r
+ *(TCHAR*)( (char*) Dst + DstSize ) = _T('\0');\r
+ return E_FEW_ARRAY;\r
+ }\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_chr] >>> \r
+************************************************************************/\r
+TCHAR* StrT_chr( const TCHAR* String, TCHAR Key )\r
+{\r
+ const TCHAR* return_value = _tcschr( String, Key );\r
+\r
+ if ( return_value == NULL && Key == _T('\0') ) {\r
+ return_value = String + _tcslen( String );\r
+ }\r
+\r
+ return (TCHAR*) return_value;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_chrNext] >>> \r
+************************************************************************/\r
+TCHAR* StrT_chrNext( const TCHAR* in_Start, TCHAR in_KeyCharactor )\r
+{\r
+ const TCHAR* p = _tcschr( in_Start, in_KeyCharactor );\r
+\r
+ if ( p != NULL )\r
+ { p += 1; }\r
+\r
+ return (TCHAR*) p;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [CharPointerArray_free] >>> \r
+************************************************************************/\r
+errnum_t CharPointerArray_free( TCHAR*** in_out_Strings, int in_StringCount,\r
+ bool in_IsFreePointers, errnum_t e )\r
+{\r
+ TCHAR** strings = *in_out_Strings;\r
+ int i;\r
+\r
+ for ( i = 0; i < in_StringCount; i += 1 ) {\r
+ e= HeapMemory_free( &strings[i], e );\r
+ }\r
+\r
+ if ( in_IsFreePointers ) {\r
+ e= HeapMemory_free( in_out_Strings, e );\r
+ }\r
+\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [MallocAndCopyString] >>> \r
+************************************************************************/\r
+errnum_t MallocAndCopyString( const TCHAR** out_NewString, const TCHAR* SourceString )\r
+{\r
+ TCHAR* str;\r
+ size_t size = ( _tcslen( SourceString ) + 1 ) * sizeof(TCHAR);\r
+\r
+ ASSERT_D( *out_NewString == NULL, __noop() );\r
+\r
+ str = (TCHAR*) malloc( size );\r
+ if ( str == NULL ) { return E_FEW_MEMORY; }\r
+\r
+ memcpy( str, SourceString, size );\r
+\r
+ *out_NewString = str;\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [MallocAndCopyString_char] >>> \r
+************************************************************************/\r
+#ifdef _UNICODE\r
+errnum_t MallocAndCopyString_char( const TCHAR** out_NewString, const char* SourceString )\r
+{\r
+ TCHAR* str;\r
+ size_t size = ( strlen( SourceString ) + 1 ) * sizeof(TCHAR);\r
+ int r;\r
+\r
+ str = (TCHAR*) malloc( size );\r
+ if ( str == NULL ) { return E_FEW_MEMORY; }\r
+\r
+ r = MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED, SourceString, -1, str, size / sizeof(TCHAR) );\r
+ IF ( r == 0 ) {\r
+ free( str );\r
+ return E_GET_LAST_ERROR;\r
+ }\r
+ *out_NewString = str;\r
+ return 0;\r
+}\r
+#endif\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [MallocAndCopyStringByLength] >>> \r
+************************************************************************/\r
+errnum_t MallocAndCopyStringByLength( const TCHAR** out_NewString, const TCHAR* SourceString,\r
+ unsigned CountOfCharacter )\r
+{\r
+ TCHAR* str;\r
+ size_t size = ( CountOfCharacter + 1 ) * sizeof(TCHAR);\r
+\r
+ ASSERT_D( *out_NewString == NULL, __noop() );\r
+ ASSERT_D( CountOfCharacter < 0x7FFFFFFF, __noop() );\r
+\r
+ str = (TCHAR*) malloc( size );\r
+ if ( str == NULL ) { return E_FEW_MEMORY; }\r
+\r
+ memcpy( str, SourceString, size - sizeof(TCHAR) );\r
+ str[ CountOfCharacter ] = _T('\0');\r
+\r
+ *out_NewString = str;\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_chrs] >>> \r
+************************************************************************/\r
+TCHAR* StrT_chrs( const TCHAR* s, const TCHAR* keys )\r
+{\r
+ if ( *keys == _T('\0') ) return NULL;\r
+\r
+ for ( ; *s != _T('\0'); s++ ) {\r
+ if ( _tcschr( keys, *s ) != NULL )\r
+ return (TCHAR*) s;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_rstr] >>> \r
+************************************************************************/\r
+TCHAR* StrT_rstr( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keyword,\r
+ void* NullConfig )\r
+{\r
+ const TCHAR* p;\r
+ int keyword_length = _tcslen( Keyword );\r
+ TCHAR keyword_first = Keyword[0];\r
+\r
+ UNREFERENCED_VARIABLE( NullConfig );\r
+\r
+ p = SearchStart;\r
+ while ( p >= String ) {\r
+ if ( *p == keyword_first ) {\r
+ if ( _tcsncmp( p, Keyword, keyword_length ) == 0 ) {\r
+ return (TCHAR*) p;\r
+ }\r
+ }\r
+ p -= 1;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_skip] >>> \r
+************************************************************************/\r
+TCHAR* StrT_skip( const TCHAR* String, const TCHAR* Keys )\r
+{\r
+ if ( *Keys == _T('\0') ) { return (TCHAR*) String; }\r
+\r
+ for ( ; *String != _T('\0'); String += 1 ) {\r
+ if ( _tcschr( Keys, *String ) == NULL )\r
+ break;\r
+ }\r
+ return (TCHAR*) String;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_rskip] >>> \r
+************************************************************************/\r
+TCHAR* StrT_rskip( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keys,\r
+ void* NullConfig )\r
+{\r
+ const TCHAR* pointer;\r
+\r
+ UNREFERENCED_VARIABLE( NullConfig );\r
+\r
+ if ( *Keys == _T('\0') ) { return (TCHAR*) SearchStart; }\r
+\r
+ for ( pointer = SearchStart; pointer >= String; pointer -= 1 ) {\r
+ if ( _tcschr( Keys, *pointer ) == NULL )\r
+ { return (TCHAR*) pointer; }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_isCIdentifier] >>> \r
+************************************************************************/\r
+bool StrT_isCIdentifier( TCHAR Character )\r
+{\r
+ const TCHAR c = Character;\r
+\r
+ return (\r
+ ( c >= _T('A') && c <= _T('Z') ) ||\r
+ ( c >= _T('a') && c <= _T('z') ) ||\r
+ ( c >= _T('0') && c <= _T('9') ) ||\r
+ c == _T('_') );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_searchOverOfCIdentifier] >>> \r
+************************************************************************/\r
+TCHAR* StrT_searchOverOfCIdentifier( const TCHAR* Text )\r
+{\r
+ const TCHAR* p;\r
+\r
+ for ( p = Text;\r
+ StrT_isCIdentifier( *p );\r
+ p += 1 )\r
+ {\r
+ }\r
+ return (TCHAR*) p;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_searchOverOfIdiom] >>> \r
+************************************************************************/\r
+TCHAR* StrT_searchOverOfIdiom( const TCHAR* Text )\r
+{\r
+ const TCHAR* p;\r
+\r
+ p = Text;\r
+ for ( p = Text;\r
+ StrT_isCIdentifier( *p ) || *p == _T(' ');\r
+ p += 1 )\r
+ {\r
+ }\r
+\r
+ for ( p -= 1;\r
+ *p == _T(' ') && p >= Text;\r
+ p -= 1 )\r
+ {\r
+ }\r
+\r
+ return (TCHAR*) p + 1;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_convPartStrToPointer] >>> \r
+************************************************************************/\r
+void* StrT_convPartStrToPointer( const TCHAR* StringStart, const TCHAR* StringOver,\r
+ const NameOnlyClass* Table, size_t TableSize, void* Default )\r
+{\r
+ const NameOnlyClass* p = Table;\r
+ const NameOnlyClass* p_over = (const NameOnlyClass*)( (uint8_t*) Table + TableSize );\r
+\r
+ while ( p < p_over ) {\r
+ if ( StrT_cmp_part( StringStart, StringOver, p->Name ) == 0 ) {\r
+ return (void*) p->Delegate;\r
+ }\r
+ p += 1;\r
+ }\r
+ return Default;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_convertNumToStr] >>> \r
+************************************************************************/\r
+TCHAR* StrT_convertNumToStr( int Number, const NameAndNumClass* Table, int TableCount,\r
+ const TCHAR* DefaultStr )\r
+{\r
+ const NameAndNumClass* p;\r
+ const NameAndNumClass* p_over = Table + TableCount;\r
+\r
+ for ( p = Table; p < p_over; p += 1 ) {\r
+ if ( p->Number == Number ) {\r
+ return p->Name;\r
+ }\r
+ }\r
+ return (TCHAR*) DefaultStr;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cmp_part] >>> \r
+************************************************************************/\r
+int StrT_cmp_part( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,\r
+ const TCHAR* in_StringB )\r
+{\r
+ const TCHAR* a;\r
+ const TCHAR* b;\r
+ TCHAR aa;\r
+ TCHAR bb;\r
+\r
+ a = in_StringA_Start;\r
+ b = in_StringB;\r
+\r
+ for (;;) {\r
+ if ( a >= in_StringA_Over ) {\r
+ bb = *b;\r
+ if ( bb == _T('\0') )\r
+ { return 0; }\r
+ else\r
+ { return -bb; }\r
+ }\r
+\r
+ aa = *a;\r
+ bb = *b;\r
+\r
+ if ( bb == _T('\0') )\r
+ { return aa; }\r
+\r
+ if ( aa != bb )\r
+ { return aa - bb; }\r
+\r
+ a += 1;\r
+ b += 1;\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cmp_i_part] >>> \r
+************************************************************************/\r
+int StrT_cmp_i_part( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,\r
+ const TCHAR* in_StringB )\r
+{\r
+ const TCHAR* a;\r
+ const TCHAR* b;\r
+ TCHAR aa;\r
+ TCHAR bb;\r
+\r
+ a = in_StringA_Start;\r
+ b = in_StringB;\r
+\r
+ for (;;) {\r
+ if ( a >= in_StringA_Over ) {\r
+ bb = *b;\r
+ if ( bb == _T('\0') )\r
+ { return 0; }\r
+ else\r
+ { return -bb; }\r
+ }\r
+\r
+ aa = *a;\r
+ bb = *b;\r
+\r
+ if ( bb == _T('\0') )\r
+ { return aa; }\r
+\r
+ if ( aa != bb ) {\r
+ if ( _totlower( aa ) != _totlower( bb ) )\r
+ { return aa - bb; }\r
+ }\r
+\r
+ a += 1;\r
+ b += 1;\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cmp_part2] >>> \r
+************************************************************************/\r
+int StrT_cmp_part2( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,\r
+ const TCHAR* in_StringB_Start, const TCHAR* in_StringB_Over )\r
+{\r
+ int length_A = in_StringA_Over - in_StringA_Start;\r
+ int length_B = in_StringB_Over - in_StringB_Start;\r
+\r
+ if ( length_A != length_B ) {\r
+ return length_A - length_B;\r
+ }\r
+ else {\r
+ return _tcsncmp( in_StringA_Start, in_StringB_Start, length_A );\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_refFName] >>> \r
+************************************************************************/\r
+TCHAR* StrT_refFName( const TCHAR* s )\r
+{\r
+ const TCHAR* p;\r
+ TCHAR c;\r
+\r
+ p = StrT_chr( s, _T('\0') );\r
+\r
+ if ( p == s ) return (TCHAR*) s;\r
+\r
+ for ( p--; p>s; p-- ) {\r
+ c = *p;\r
+ if ( c == _T('\\') || c == _T('/') ) return (TCHAR*) p+1;\r
+ }\r
+ if ( *p == _T('\\') || *p == _T('/') ) return (TCHAR*) p+1;\r
+\r
+ return (TCHAR*) s;\r
+}\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_refExt] >>> \r
+************************************************************************/\r
+TCHAR* StrT_refExt( const TCHAR* s )\r
+{\r
+ const TCHAR* p;\r
+\r
+ p = StrT_chr( s, _T('\0') );\r
+\r
+ if ( p == s ) { return (TCHAR*) s; }\r
+\r
+ for ( p--; p>s; p-- ) {\r
+ if ( *p == _T('.') ) return (TCHAR*) p+1;\r
+ if ( *p == _T('/') || *p == _T('\\') )\r
+ { return (TCHAR*) StrT_chr( p, _T('\0') ); }\r
+ }\r
+ if ( *p == _T('.') ) return (TCHAR*) p+1;\r
+\r
+ return (TCHAR*) StrT_chr( s, _T('\0') );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+* Function: StrT_cutFragmentInPath\r
+************************************************************************/\r
+void StrT_cutFragmentInPath( TCHAR* in_out_Path )\r
+{\r
+ TCHAR* p;\r
+\r
+ p = _tcschr( in_out_Path, _T('#') );\r
+ if ( p != NULL ) {\r
+ *p = _T('\0');\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_searchPartStringIndex] >>> \r
+************************************************************************/\r
+int StrT_searchPartStringIndex( const TCHAR* in_String, const TCHAR* in_StringOver,\r
+ const TCHAR** in_StringsArray, uint_fast32_t in_StringsArrayLength,\r
+ int in_DefaultIndex )\r
+{\r
+ const TCHAR** p;\r
+ const TCHAR** p_over = in_StringsArray + in_StringsArrayLength;\r
+ size_t size = (byte_t*) in_StringOver - (byte_t*) in_String;\r
+\r
+ for ( p = in_StringsArray; p < p_over; p += 1 ) {\r
+ if ( memcmp( *p, in_String, size ) == 0 ) {\r
+ return p - in_StringsArray;\r
+ }\r
+ }\r
+ return in_DefaultIndex;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_searchPartStringIndexI] >>> \r
+ - This ignores case sensitive.\r
+************************************************************************/\r
+int StrT_searchPartStringIndexI( const TCHAR* in_String, const TCHAR* in_StringOver,\r
+ const TCHAR** in_StringsArray, uint_fast32_t in_StringsArrayLength,\r
+ int in_DefaultIndex )\r
+{\r
+ const TCHAR** p;\r
+ const TCHAR** p_over = in_StringsArray + in_StringsArrayLength;\r
+ size_t count = (TCHAR*) in_StringOver - (TCHAR*) in_String;\r
+\r
+ for ( p = in_StringsArray; p < p_over; p += 1 ) {\r
+ if ( _tcsnicmp( *p, in_String, count ) == 0 ) {\r
+ return p - in_StringsArray;\r
+ }\r
+ }\r
+ return in_DefaultIndex;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_convStrToId] >>> \r
+************************************************************************/\r
+int StrT_convStrToId( const TCHAR* str, const TCHAR** strs, const int* ids,\r
+ int n, int default_id )\r
+{\r
+ const TCHAR** p;\r
+ const TCHAR** p_over = strs + n;\r
+\r
+ for ( p = strs; p < p_over; p++ ) {\r
+ if ( _tcsicmp( *p, str ) == 0 ) return ids[p - strs];\r
+ }\r
+ return default_id;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_convStrLeftToId] >>> \r
+************************************************************************/\r
+int StrT_convStrLeftToId( const TCHAR* Str, const TCHAR** Strs, const size_t* Lens, const int* Ids,\r
+ int CountOfStrs, TCHAR* Separeters, int DefaultId, TCHAR** out_PosOfLastOfStr )\r
+{\r
+ const TCHAR** pp;\r
+ const TCHAR** pp_over = Strs + CountOfStrs;\r
+ const size_t* p_len;\r
+ const int* p_id;\r
+ const TCHAR* p_last_of_str;\r
+ TCHAR c;\r
+\r
+ p_len = Lens;\r
+ p_id = Ids;\r
+ for ( pp = Strs; pp < pp_over; pp += 1 ) {\r
+\r
+ ASSERT_D( _tcslen( *pp ) == *p_len, goto err );\r
+\r
+ if ( _tcsncmp( Str, *pp, *p_len ) == 0 ) {\r
+ p_last_of_str = Str + *p_len;\r
+ c = *p_last_of_str;\r
+ if ( c == _T('\0') || _tcschr( Separeters, c ) != NULL ) {\r
+ *out_PosOfLastOfStr = (TCHAR*) p_last_of_str;\r
+ return *p_id;\r
+ }\r
+ }\r
+ p_len += 1;\r
+ p_id += 1;\r
+ }\r
+ return DefaultId;\r
+\r
+#if ! NDEBUG\r
+ err: return DefaultId;\r
+#endif\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_replace] >>> \r
+************************************************************************/\r
+errnum_t StrT_replace( TCHAR* Out, size_t OutSize, const TCHAR* In,\r
+ const TCHAR* FromStr, const TCHAR* ToStr, unsigned Opt )\r
+{\r
+ errnum_t e;\r
+ unsigned from_size = _tcslen( FromStr ) * sizeof(TCHAR);\r
+ unsigned to_size = _tcslen( ToStr ) * sizeof(TCHAR);\r
+ const TCHAR* p_in = In;\r
+ TCHAR* p_out = Out;\r
+ const TCHAR* p_in_from;\r
+ size_t copy_size;\r
+ int out_size = OutSize - 1;\r
+\r
+\r
+ /* \92u\8a·\82µ\82Ä\8f¬\82³\82\82È\82é\82Æ\82«\82Í\81A\8d¶\82©\82ç\89E\82Ö\91\96\8d¸\82·\82é */\r
+ if ( to_size <= from_size ) {\r
+\r
+ for (;;) {\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82Ì\90æ\93ª\88Ê\92u\82ð p_in_from \82Ö */\r
+ p_in_from = _tcsstr( p_in, FromStr );\r
+ if ( p_in_from == NULL ) break;\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82Ì\91O\82Ü\82Å In \82©\82ç Out \82Ö\83R\83s\81[\82·\82é */\r
+ copy_size = (char*)p_in_from - (char*)p_in;\r
+ out_size -= copy_size + to_size;\r
+ IF( out_size < 0 ) goto err_fa;\r
+\r
+ if ( p_out != p_in )\r
+ memcpy( p_out, p_in, copy_size );\r
+ p_in = (TCHAR*)( (char*)p_in + copy_size );\r
+ p_out = (TCHAR*)( (char*)p_out + copy_size );\r
+\r
+ /* FromStr \82ð ToStr \82É\92u\82«\8a·\82¦\82é */\r
+ memcpy( p_out, ToStr, to_size );\r
+ p_in = (TCHAR*)( (char*)p_in + from_size );\r
+ p_out = (TCHAR*)( (char*)p_out + to_size );\r
+\r
+ /* "STR_1TIME" */\r
+ if ( Opt & STR_1TIME )\r
+ { break; }\r
+ }\r
+\r
+ /* \8ec\82è\82ð In \82©\82ç Out \82Ö\83R\83s\81[\82·\82é */\r
+ #pragma warning(push)\r
+ #pragma warning(disable:4996)\r
+ if ( p_out != p_in )\r
+ _tcscpy( p_out, p_in );\r
+ p_out = NULL;\r
+ #pragma warning(pop)\r
+ }\r
+\r
+\r
+ /* \92u\8a·\82µ\82Ä\91å\82«\82\82È\82é\82Æ\82«\82Í\81A\89E\82©\82ç\8d¶\82Ö\91\96\8d¸\82·\82é */\r
+ else {\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82ª\96³\82¢\82Æ\82«\82Í\91S\95\94\83R\83s\81[\82·\82é */\r
+ p_in_from = _tcsstr( p_in, FromStr );\r
+ if ( p_in_from == NULL ) {\r
+ if ( p_out != p_in )\r
+ StrT_cpy( Out, OutSize, In );\r
+ p_out = NULL;\r
+ }\r
+ else {\r
+ Set2a froms;\r
+ TCHAR* froms_X[10];\r
+ const TCHAR** pp_froms;\r
+ size_t plus_from_to;\r
+\r
+ Set2a_initConst( &froms, froms_X );\r
+ e= Set2a_init( &froms, froms_X, sizeof(froms_X) ); IF(e)goto fin2;\r
+\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82Ì\91O\82Ü\82Å\83R\83s\81[\82·\82é */\r
+ copy_size = (char*)p_in_from - (char*)p_in;\r
+ out_size -= copy_size;\r
+ IF( out_size < 0 ) goto err_fa2;\r
+\r
+ memcpy( p_out, p_in, copy_size );\r
+ // p_in = (TCHAR*)( (char*)p_in + copy_size ); // \8cã\82Å\8eg\82í\82ê\82È\82¢\r
+ p_out = (TCHAR*)( (char*)p_out + copy_size );\r
+\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82Ì\88Ê\92u\82ð froms \82Ö\8fW\82ß\82é */\r
+ for (;;) {\r
+\r
+ e= Set2a_expandIfOverByAddr( &froms, froms_X, (TCHAR**)froms.Next + 1 ); IF(e)goto fin2;\r
+ pp_froms = (const TCHAR**)froms.Next; froms.Next = (void*)( pp_froms + 1 );\r
+\r
+ *pp_froms = p_in_from;\r
+\r
+ if ( Opt & STR_1TIME )\r
+ { break; }\r
+\r
+ p_in = (const TCHAR*)( (char*)p_in_from + from_size );\r
+ p_in_from = _tcsstr( p_in, FromStr );\r
+ if ( p_in_from == NULL ) break;\r
+ }\r
+\r
+ plus_from_to = ( (TCHAR**)froms.Next - (TCHAR**)froms.First ) * (to_size - from_size);\r
+\r
+\r
+ /* In \82Ì\96\96\94ö\82Ì '\0' \82Ì\88Ê\92u\82à froms \82Ö */\r
+ e= Set2a_expandIfOverByAddr( &froms, froms_X, (TCHAR**)froms.Next + 1 ); IF(e)goto fin2;\r
+ pp_froms = (const TCHAR**)froms.Next; froms.Next = (void*)( pp_froms + 1 );\r
+ p_in = StrT_chr( p_in, _T('\0') );\r
+ *pp_froms = p_in;\r
+\r
+ copy_size = ( (char*)p_in - (char*)In ) + plus_from_to;\r
+ IF( copy_size >= OutSize ) goto err_fa2;\r
+ p_out = (TCHAR*)( (char*)Out + copy_size );\r
+ plus_from_to -= to_size - from_size;\r
+\r
+\r
+ /* \89E\82©\82ç\8d¶\82Ö\91\96\8d¸\82·\82é */\r
+ for ( pp_froms = (TCHAR**)froms.Next - 1;\r
+ pp_froms > (TCHAR**)froms.First;\r
+ pp_froms -- ) {\r
+\r
+ const TCHAR* p_in_from = *(pp_froms - 1);\r
+ const TCHAR* p_in_other = (const TCHAR*)( (char*)p_in_from + from_size );\r
+ const TCHAR* p_in_other_over = *pp_froms;\r
+ TCHAR* p_out_to = (TCHAR*)( (char*)Out + ( (char*)p_in_from - (char*)In ) + plus_from_to );\r
+ TCHAR* p_out_other = (TCHAR*)( (char*)p_out_to + to_size );\r
+\r
+ memmove( p_out_other, p_in_other, (char*)p_in_other_over - (char*)p_in_other );\r
+ memcpy( p_out_to, ToStr, to_size );\r
+\r
+ plus_from_to -= to_size - from_size;\r
+ }\r
+\r
+ goto fin2;\r
+ err_fa2: e = E_FEW_ARRAY; goto fin2;\r
+ fin2:\r
+ e= Set2a_finish( &froms, froms_X, e );\r
+ if ( e ) goto fin;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( p_out != NULL ) *p_out = _T('\0');\r
+ return e;\r
+\r
+err_fa: e = E_FEW_ARRAY; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_replace1] >>> \r
+************************************************************************/\r
+errnum_t StrT_replace1( TCHAR* in_out_String, TCHAR FromCharacter, TCHAR ToCharacter,\r
+ unsigned Opt )\r
+{\r
+ TCHAR* p;\r
+\r
+ UNREFERENCED_VARIABLE( Opt );\r
+\r
+ IF ( FromCharacter == _T('\0') ) { return E_OTHERS; }\r
+\r
+ p = in_out_String;\r
+ for (;;) {\r
+ p = _tcschr( p, FromCharacter );\r
+ if ( p == NULL ) { break; }\r
+ *p = ToCharacter;\r
+ p += 1;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_trim] >>> \r
+************************************************************************/\r
+errnum_t StrT_trim( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str )\r
+{\r
+ const TCHAR* p1;\r
+ const TCHAR* p2;\r
+ TCHAR c;\r
+\r
+ p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;\r
+ for ( p2 = StrT_chr( p1, _T('\0') ) - 1; p2 >= p1; p2-- ) {\r
+ c = *p2;\r
+ if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
+ break;\r
+ }\r
+ return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cutPart] >>> \r
+************************************************************************/\r
+errnum_t StrT_cutPart( TCHAR* in_out_String, TCHAR* in_StartOfCut, TCHAR* in_OverOfCut )\r
+{\r
+ errnum_t e;\r
+ TCHAR* over_of_cut = StrT_chr( in_StartOfCut, _T('\0') );\r
+\r
+#ifndef NDEBUG\r
+ TCHAR* over_of_string = StrT_chr( in_out_String, _T('\0') );\r
+\r
+ ASSERT_D( over_of_cut == over_of_string, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_StartOfCut >= in_out_String, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_StartOfCut <= over_of_string, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_OverOfCut >= in_out_String, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_OverOfCut <= over_of_string, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_StartOfCut <= in_OverOfCut, e=E_OTHERS; goto fin );\r
+#endif\r
+ UNREFERENCED_VARIABLE( in_out_String );\r
+\r
+ memmove( in_StartOfCut, in_OverOfCut,\r
+ PointerType_diff( over_of_cut + 1, in_OverOfCut ) );\r
+\r
+ e=0;\r
+#ifndef NDEBUG\r
+fin:\r
+#endif\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cutLastOf] >>> \r
+************************************************************************/\r
+errnum_t StrT_cutLastOf( TCHAR* in_out_Str, TCHAR Charactor )\r
+{\r
+ TCHAR* last = StrT_chr( in_out_Str, _T('\0') );\r
+\r
+ if ( last > in_out_Str ) {\r
+ if ( *( last - 1 ) == Charactor )\r
+ { *( last - 1 ) = _T('\0'); }\r
+ }\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cutLineComment] >>> \r
+************************************************************************/\r
+errnum_t StrT_cutLineComment( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str, const TCHAR* CommentSign )\r
+{\r
+ const TCHAR* p1;\r
+ const TCHAR* p2;\r
+ TCHAR c;\r
+\r
+ p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;\r
+\r
+ p2 = _tcsstr( p1, CommentSign );\r
+ if ( p2 == NULL ) p2 = StrT_chr( p1, _T('\0') );\r
+\r
+ for ( p2 = p2 - 1; p2 >= p1; p2-- ) {\r
+ c = *p2;\r
+ if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
+ break;\r
+ }\r
+ return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_insert] >>> \r
+************************************************************************/\r
+errnum_t StrT_insert( TCHAR* in_out_WholeString, size_t in_MaxSize_of_WholeString,\r
+ TCHAR* in_out_Target_in_WholeString, TCHAR** out_NextTarget_in_WholeString,\r
+ const TCHAR* in_InsertString )\r
+{\r
+ errnum_t e;\r
+ TCHAR* over_of_whole_string = StrT_chr( in_out_WholeString, _T('\0') );\r
+ size_t insert_length = _tcslen( in_InsertString );\r
+\r
+ ASSERT_D( in_out_Target_in_WholeString >= in_out_WholeString, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_out_Target_in_WholeString <= over_of_whole_string, e=E_OTHERS; goto fin );\r
+\r
+ ASSERT_R( PointerType_diff( over_of_whole_string + 1, in_out_WholeString ) + ( insert_length * sizeof(TCHAR) )\r
+ <= in_MaxSize_of_WholeString, e=E_FEW_ARRAY; goto fin );\r
+\r
+ memmove( in_out_Target_in_WholeString + insert_length, in_out_Target_in_WholeString,\r
+ PointerType_diff( over_of_whole_string + 1, in_out_Target_in_WholeString ) );\r
+\r
+ memcpy( in_out_Target_in_WholeString, in_InsertString, insert_length * sizeof(TCHAR) );\r
+\r
+ if ( out_NextTarget_in_WholeString != NULL ) {\r
+ *out_NextTarget_in_WholeString = in_out_Target_in_WholeString + insert_length;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_insert] >>> \r
+************************************************************************/\r
+errnum_t StrHS_insert( TCHAR** in_out_WholeString,\r
+ int in_TargetIndexInWholeString, int* out_NextWholeInWholeString,\r
+ const TCHAR* in_InsertString )\r
+{\r
+ errnum_t e;\r
+ TCHAR* string = *in_out_WholeString;\r
+ size_t target_length = _tcslen( string );\r
+ size_t insert_length = _tcslen( in_InsertString );\r
+ size_t max_size = _msize( string ) / sizeof( TCHAR );\r
+ size_t new_max_size = target_length + insert_length + 1;\r
+ TCHAR* next_target;\r
+\r
+\r
+ if ( max_size < new_max_size ) {\r
+ TCHAR* new_string = (TCHAR*) realloc( string, new_max_size * sizeof( TCHAR ) );\r
+\r
+ IF ( new_string == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ max_size = new_max_size;\r
+ string = new_string;\r
+ }\r
+\r
+ e= StrT_insert( string, max_size * sizeof( TCHAR ),\r
+ string + in_TargetIndexInWholeString, &next_target,\r
+ in_InsertString ); IF(e){goto fin;}\r
+\r
+ if ( out_NextWholeInWholeString != NULL ) {\r
+ *out_NextWholeInWholeString = next_target - string;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ *in_out_WholeString = string;\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_printfPartV] >>> \r
+************************************************************************/\r
+errnum_t StrHS_printfPartV( TCHAR** in_out_String,\r
+ int in_IndexInString, int* out_NextIndexInString,\r
+ const TCHAR* in_Format, va_list in_VaList )\r
+{\r
+ enum { first_max_size = 40 };\r
+ enum { size_times = 4 };\r
+\r
+ errnum_t e;\r
+ size_t max_size;\r
+ TCHAR* string = *in_out_String;\r
+\r
+\r
+ if ( string == NULL ) {\r
+ max_size = 0;\r
+\r
+ ASSERT_R( in_IndexInString == 0, e=E_OTHERS; goto fin );\r
+ }\r
+ else {\r
+ max_size = _msize( string ) / sizeof( TCHAR );\r
+\r
+ ASSERT_R( in_IndexInString >= 0 && (size_t) in_IndexInString < max_size,\r
+ e=E_OTHERS; goto fin );\r
+ ASSERT_D( (size_t) in_IndexInString <= _tcslen( string ), __noop() );\r
+ }\r
+\r
+\r
+ if ( string == NULL ) {\r
+ string = (TCHAR*) malloc( first_max_size * sizeof( TCHAR ) );\r
+ max_size = first_max_size;\r
+ }\r
+\r
+\r
+ for (;;) {\r
+\r
+ #if _MSC_VER\r
+ #pragma warning(push)\r
+ #pragma warning(disable: 4996)\r
+ #endif\r
+\r
+ #ifdef _UNICODE\r
+ int r = _vsnwprintf( string + in_IndexInString, max_size - in_IndexInString,\r
+ in_Format, in_VaList );\r
+ #else\r
+ int r = _vsnprintf( string + in_IndexInString, max_size - in_IndexInString,\r
+ in_Format, in_VaList );\r
+ #endif\r
+\r
+ #if _MSC_VER\r
+ #pragma warning(pop)\r
+ #endif\r
+\r
+ if ( r >= 0 ) {\r
+ if ( out_NextIndexInString != NULL ) {\r
+ *out_NextIndexInString = in_IndexInString + r;\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ {\r
+ size_t new_max_size = max_size * size_times + first_max_size;\r
+ TCHAR* new_string = (TCHAR*) realloc( string, new_max_size * sizeof( TCHAR ) );\r
+\r
+ IF ( new_string == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ max_size = new_max_size;\r
+ string = new_string;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ *in_out_String = string;\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_printfPart] >>> \r
+************************************************************************/\r
+errnum_t StrHS_printfPart( TCHAR** in_out_String,\r
+ int in_IndexInString, int* out_NextIndexInString,\r
+ const TCHAR* in_Format, ... )\r
+{\r
+ errnum_t e;\r
+ va_list va;\r
+ va_start( va, in_Format );\r
+\r
+ e = StrHS_printfPartV( in_out_String, in_IndexInString, out_NextIndexInString, in_Format, va );\r
+\r
+ va_end( va );\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_printfV] >>> \r
+************************************************************************/\r
+errnum_t StrHS_printfV( TCHAR** in_out_String,\r
+ const TCHAR* in_Format, va_list in_VaList )\r
+{\r
+ return StrHS_printfPartV( in_out_String, 0, NULL, in_Format, in_VaList );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_printf] >>> \r
+************************************************************************/\r
+errnum_t StrHS_printf( TCHAR** in_out_String,\r
+ const TCHAR* in_Format, ... )\r
+{\r
+ errnum_t e;\r
+ va_list va;\r
+ va_start( va, in_Format );\r
+\r
+ e = StrHS_printfPartV( in_out_String, 0, NULL, in_Format, va );\r
+\r
+ va_end( va );\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_meltCSV] >>> \r
+*************************************************************************/\r
+errnum_t StrT_meltCSV( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pCSV )\r
+{\r
+ errnum_t e = 0;\r
+ TCHAR* t;\r
+ TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
+ const TCHAR* s;\r
+ TCHAR dummy[2];\r
+ TCHAR c;\r
+\r
+ t = out_Str;\r
+ s = *pCSV;\r
+ if ( out_Str_Size <= 1 ) { t = dummy; t_last = dummy; }\r
+\r
+ if ( s == NULL ) { *t = _T('\0'); return 0; }\r
+\r
+\r
+ /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82 */\r
+ while ( *s == _T(' ') || *s == _T('\t') ) s++;\r
+\r
+ switch ( *s ) {\r
+\r
+ /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
+ case _T('"'):\r
+ s++;\r
+ c = *s;\r
+ while ( c != _T('"') || *(s+1) == _T('"') ) { /* " \95¶\8e\9a\82Ü\82Å */\r
+ if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }\r
+ if ( c == *(s+1) && c == _T('"') ) s++; /* " \95¶\8e\9a\8e©\91Ì */\r
+ if ( c == _T('\0') ) break;\r
+ *t = c; t++; s++; c = *s;\r
+ }\r
+ *t = _T('\0');\r
+\r
+ s++;\r
+ for (;;) {\r
+ if ( *s == _T(',') ) { s = s+1; break; }\r
+ if ( *s == _T('\0') ) { s = NULL; break; }\r
+ s++;\r
+ }\r
+ *pCSV = s;\r
+ return e;\r
+\r
+ /* \8bó\82Ì\8d\80\96Ú\82Ì\8fê\8d\87 */\r
+ case ',':\r
+ *t = _T('\0');\r
+ *pCSV = s+1;\r
+ return 0;\r
+\r
+ case '\0':\r
+ *t = _T('\0');\r
+ *pCSV = NULL;\r
+ return 0;\r
+\r
+ /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
+ default: {\r
+ TCHAR* sp = NULL; /* \8dÅ\8cã\82Ì\98A\91±\82µ\82½\8bó\94\92\82Ì\90æ\93ª */\r
+\r
+ c = *s;\r
+ while ( c != _T(',') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /* , \95¶\8e\9a\82Ü\82Å */\r
+\r
+ /* sp \82ð\90Ý\92è\82·\82é */\r
+ if ( c == ' ' ) {\r
+ if ( sp == NULL ) sp = t;\r
+ }\r
+ else sp = NULL;\r
+\r
+ if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }\r
+\r
+ /* \83R\83s\81[\82·\82é */\r
+ *t = c; t++; s++; c = *s;\r
+ }\r
+\r
+ /* \95Ô\82è\92l\82ð\8c\88\92è\82·\82é */\r
+ if ( c == _T(',') ) s = s + 1;\r
+ else s = NULL;\r
+\r
+ /* \96\96\94ö\82Ì\8bó\94\92\82ð\8eæ\82è\8f\9c\82 */\r
+ if ( sp != NULL ) *sp = '\0';\r
+ else *t = _T('\0');\r
+\r
+ *pCSV = s;\r
+ return e;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_parseCSV_f] >>> \r
+************************************************************************/\r
+errnum_t StrT_parseCSV_f( const TCHAR* StringOfCSV, bit_flags32_t* out_ReadFlags, const TCHAR* Types, ... )\r
+{\r
+ errnum_t e;\r
+ TCHAR type;\r
+ int types_index;\r
+ va_list va;\r
+ bool is_next_omittable;\r
+ bool is_next_omit;\r
+ const TCHAR* column_pointer;\r
+ TCHAR a_char;\r
+ TCHAR column[ 32 ];\r
+ bit_flags32_t read_flags;\r
+ bit_flags32_t next_read_flag;\r
+ TCHAR* out_str;\r
+ size_t str_size = SIZE_MAX; /* SIZE_MAX = Avoid warning */\r
+\r
+\r
+ va_start( va, Types );\r
+ types_index = 0;\r
+ is_next_omittable = false;\r
+ column_pointer = StringOfCSV;\r
+ read_flags = 0;\r
+ next_read_flag = 1;\r
+ while ( column_pointer != NULL ) {\r
+ out_str = NULL;\r
+\r
+ type = Types[ types_index ];\r
+ switch ( type ) {\r
+ case _T('\0'):\r
+ goto exit_for;\r
+\r
+ case _T('+'):\r
+ is_next_omittable = true;\r
+ break;\r
+\r
+ case _T('s'):\r
+ out_str = va_arg( va, TCHAR* );\r
+ str_size = va_arg( va, size_t );\r
+ ASSERT_D( str_size >= 1, e=E_OTHERS; goto fin );\r
+ break;\r
+\r
+ default:\r
+ out_str = column;\r
+ str_size = sizeof( column );\r
+ break;\r
+ }\r
+\r
+ if ( out_str != NULL ) {\r
+\r
+ // Set "out_str" : Column string in CSV\r
+ column_pointer = StrT_skip( column_pointer, _T(" \t") );\r
+ a_char = *column_pointer;\r
+ if ( is_next_omittable && ( a_char == _T('\0') || a_char == _T(',') ) ) {\r
+ column_pointer = StrT_chrs( column_pointer, _T(",") );\r
+ if ( column_pointer != NULL ) { column_pointer += 1; }\r
+ is_next_omit = true;\r
+ } else {\r
+ e= StrT_meltCSV( out_str, str_size, &column_pointer ); IF(e){goto fin;}\r
+\r
+ is_next_omit = false;\r
+ read_flags |= next_read_flag;\r
+ }\r
+\r
+ switch ( type ) {\r
+ case _T('s'):\r
+ /* "va_arg" was already called */\r
+ break;\r
+\r
+ case _T('i'): {\r
+ int* pointer_of_int = va_arg( va, int* );\r
+\r
+ if ( ! is_next_omit ) {\r
+ *pointer_of_int = ttoi_ex( column, 0 );\r
+ }\r
+ break;\r
+ }\r
+ case _T('f'): {\r
+ double* pointer_of_double = va_arg( va, double* );\r
+\r
+ if ( ! is_next_omit ) {\r
+ *pointer_of_double = _tstof( column );\r
+ }\r
+ break;\r
+ }\r
+ case _T('b'): {\r
+ bool* pointer_of_bool = va_arg( va, bool* );\r
+ int strings_index;\r
+ static const TCHAR* strings[] = {\r
+ _T("1"), _T("true"), _T("yes"),\r
+ };\r
+\r
+ if ( ! is_next_omit ) {\r
+ *pointer_of_bool = false;\r
+ for ( strings_index = 0;\r
+ strings_index < _countof( strings );\r
+ strings_index += 1 )\r
+ {\r
+ if ( _tcsicmp( column, strings[ strings_index ] ) == 0 ) {\r
+ *pointer_of_bool = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ case _T('t'): {\r
+ SYSTEMTIME* pointer_of_time = va_arg( va, SYSTEMTIME* );\r
+ int* pointer_of_bias = va_arg( va, int* );\r
+\r
+ if ( ! is_next_omit ) {\r
+ e= W3CDTF_toSYSTEMTIME( column, pointer_of_time, pointer_of_bias );\r
+ IF(e){goto fin;}\r
+ }\r
+ break;\r
+ }\r
+\r
+ default:\r
+ ASSERT_R( false, e=E_OTHERS; goto fin );\r
+ }\r
+\r
+ is_next_omittable = false;\r
+ next_read_flag <<= 1;\r
+ }\r
+\r
+ types_index += 1;\r
+ }\r
+exit_for:\r
+ if ( out_ReadFlags != NULL ) {\r
+ *out_ReadFlags = read_flags;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ va_end( va );\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_changeToXML_Attribute] >>> \r
+*************************************************************************/\r
+errnum_t StrT_changeToXML_Attribute( TCHAR* out_Str, size_t Str_Size, const TCHAR* InputStr )\r
+{\r
+ errnum_t e;\r
+\r
+ e= StrT_replace( out_Str, Str_Size, InputStr, _T("&"), _T("&"), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("\""), _T("""), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("<"), _T("<"), 0 ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_resumeFromXML_Attribute] >>> \r
+*************************************************************************/\r
+errnum_t StrT_resumeFromXML_Attribute( TCHAR* out_Str, size_t Str_Size, const TCHAR* XML_Attr )\r
+{\r
+ errnum_t e;\r
+\r
+ e= StrT_replace( out_Str, Str_Size, XML_Attr, _T("""), _T("\""), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("<"), _T("<"), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("&"), _T("&"), 0 ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_changeToXML_Text] >>> \r
+*************************************************************************/\r
+errnum_t StrT_changeToXML_Text( TCHAR* out_Str, size_t Str_Size, const TCHAR* InputStr )\r
+{\r
+ errnum_t e;\r
+\r
+ e= StrT_replace( out_Str, Str_Size, InputStr, _T("&"), _T("&"), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("<"), _T("<"), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T(">"), _T(">"), 0 ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_getExistSymbols] >>> \r
+************************************************************************/\r
+errnum_t StrT_getExistSymbols( unsigned* out, bool bCase, const TCHAR* Str, const TCHAR* Symbols, ... )\r
+{\r
+ errnum_t e;\r
+ int i;\r
+ bool* syms_exists = NULL;\r
+ bool b_nosym = false;\r
+ TCHAR* sym = NULL;\r
+ size_t sym_size = ( _tcslen( Symbols ) + 1 ) * sizeof(TCHAR);\r
+ int n_sym = 0;\r
+ const TCHAR** syms = NULL;\r
+ const TCHAR* p;\r
+\r
+ UNREFERENCED_VARIABLE( bCase );\r
+\r
+ sym = (TCHAR*) malloc( sym_size ); IF(sym==NULL)goto err_fm;\r
+\r
+\r
+ //=== Get Symbols\r
+ p = Symbols;\r
+ do {\r
+ e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
+ if ( sym[0] != _T('\0') ) n_sym ++;\r
+ } while ( p != NULL );\r
+\r
+ syms = (const TCHAR**) malloc( n_sym * sizeof(TCHAR*) ); IF(syms==NULL)goto err_fm;\r
+ memset( (TCHAR**) syms, 0, n_sym * sizeof(TCHAR*) );\r
+ syms_exists = (bool*) malloc( n_sym * sizeof(bool) ); IF(syms_exists==NULL)goto err_fm;\r
+ memset( syms_exists, 0, n_sym * sizeof(bool) );\r
+\r
+ p = Symbols; i = 0;\r
+ do {\r
+ e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
+ if ( sym[0] != _T('\0') ) {\r
+ e= MallocAndCopyString( &syms[i], sym ); IF(e)goto fin;\r
+ i++;\r
+ }\r
+ } while ( p != NULL );\r
+\r
+\r
+ //=== Check Str whether having Symbols\r
+ p = Str;\r
+ do {\r
+ e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
+ if ( sym[0] != _T('\0') ) {\r
+ for ( i = 0; i < n_sym; i++ ) {\r
+ if ( _tcscmp( sym, syms[i] ) == 0 ) { syms_exists[i] = true; break; }\r
+ }\r
+ if ( i == n_sym ) b_nosym = true;\r
+ }\r
+ } while ( p != NULL );\r
+\r
+\r
+ //=== Sum numbers\r
+ {\r
+ va_list va;\r
+ unsigned num;\r
+\r
+ va_start( va, Symbols );\r
+ *out = 0;\r
+ for ( i = 0; i < n_sym; i++ ) {\r
+ num = va_arg( va, unsigned );\r
+ if ( syms_exists[i] ) *out |= num;\r
+ }\r
+ va_end( va );\r
+ }\r
+\r
+ e = ( b_nosym ? E_NOT_FOUND_SYMBOL : 0 );\r
+fin:\r
+ if ( syms != NULL ) {\r
+ for ( i = 0; i < n_sym; i++ ) {\r
+ e= HeapMemory_free( &syms[i], e );\r
+ }\r
+ free( (TCHAR**) syms );\r
+ }\r
+ e= HeapMemory_free( &syms_exists, e );\r
+ e= HeapMemory_free( &sym, e );\r
+ return e;\r
+err_fm: e= E_FEW_MEMORY; goto fin;\r
+}\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_meltCmdLine] >>> \r
+*************************************************************************/\r
+errnum_t StrT_meltCmdLine( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pLine )\r
+{\r
+ errnum_t e = 0;\r
+ TCHAR* t;\r
+ TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
+ const TCHAR* s;\r
+ TCHAR dummy;\r
+ TCHAR c;\r
+\r
+ t = out_Str;\r
+ s = *pLine;\r
+ if ( out_Str_Size <= 1 ) { t = &dummy; t_last = &dummy; }\r
+\r
+ if ( s == NULL ) { *t = _T('\0'); return 0; }\r
+\r
+\r
+ /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82 */\r
+ while ( *s == _T(' ') || *s == _T('\t') ) s++;\r
+\r
+ switch ( *s ) {\r
+\r
+ /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
+ case _T('"'):\r
+ s++;\r
+ c = *s;\r
+ while ( c != _T('"') || *(s+1) == _T('"') ) { /* " \95¶\8e\9a\82Ü\82Å */\r
+ if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }\r
+ if ( c == *(s+1) && c == _T('"') ) s++; /* " \95¶\8e\9a\8e©\91Ì */\r
+ if ( c == _T('\0') ) break;\r
+ *t = c; t++; s++; c = *s;\r
+ }\r
+ *t = _T('\0');\r
+\r
+ s++;\r
+ for (;;) {\r
+ if ( *s == _T(' ') ) { s = s+1; break; }\r
+ if ( *s == _T('\0') ) { s = NULL; break; }\r
+ s++;\r
+ }\r
+ *pLine = s;\r
+ return e;\r
+\r
+ case '\0':\r
+ *t = _T('\0');\r
+ *pLine = NULL;\r
+ return 0;\r
+\r
+ /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
+ default: {\r
+ c = *s;\r
+ while ( c != _T(' ') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /* \8bó\94\92\95¶\8e\9a\82Ü\82Å */\r
+\r
+ if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }\r
+\r
+ /* \83R\83s\81[\82·\82é */\r
+ *t = c; t++; s++; c = *s;\r
+ }\r
+\r
+ /* *pLine\82ð\8c\88\92è\82·\82é */\r
+ while ( *s == _T(' ') ) s = s + 1;\r
+ if ( *s == _T('\0') ) s = NULL;\r
+\r
+ /* \96\96\94ö */\r
+ *t = _T('\0');\r
+\r
+ *pLine = s;\r
+ return e;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [W3CDTF_fromSYSTEMTIME] >>> \r
+************************************************************************/\r
+errnum_t W3CDTF_fromSYSTEMTIME( TCHAR* out_W3CDTF, size_t W3CDTF_ByteSize,\r
+ const SYSTEMTIME* Time, int TimeZoneMinute )\r
+{\r
+ errnum_t e;\r
+ TCHAR* char_pointer = out_W3CDTF;\r
+\r
+ e= stprintf_part_r( out_W3CDTF, W3CDTF_ByteSize, char_pointer, &char_pointer,\r
+ _T("%04d-%02d-%02dT%02d:%02d:%02d.%03d"),\r
+ Time->wYear, Time->wMonth, Time->wDay,\r
+ Time->wHour, Time->wMinute, Time->wSecond, Time->wMilliseconds );\r
+ IF(e){goto fin;}\r
+\r
+ e= W3CDTF_getTimeZoneDesignator( char_pointer,\r
+ GetStringSizeFromPointer( out_W3CDTF, W3CDTF_ByteSize, char_pointer ),\r
+ TimeZoneMinute ); IF(e){goto fin;}\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [W3CDTF_toSYSTEMTIME] >>> \r
+************************************************************************/\r
+errnum_t W3CDTF_toSYSTEMTIME( const TCHAR* String, SYSTEMTIME* out_Time, int* out_BiasMinute )\r
+{\r
+ errnum_t e;\r
+ size_t string_length = _tcslen( String );\r
+\r
+ /* 01234567890123456789012345678 */\r
+ /*"yyyy-mm-ddThh:mm:ss.sss+00:00"*/\r
+ /*"0000-00-00T00:00+00:00"*/\r
+\r
+ IF_D( out_BiasMinute == NULL ) { e=E_OTHERS; goto fin; }\r
+\r
+ /* With time */\r
+ if ( string_length >= 11 ) {\r
+ TCHAR a_char;\r
+ const TCHAR* time_zone;\r
+ int number;\r
+\r
+ IF ( String[10] != _T('T') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( String[4] != _T('-') || String[7] != _T('-') )\r
+ { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ IF ( string_length < 16 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( String[13] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ out_Time->wYear = (WORD) _ttoi( &String[0] );\r
+ out_Time->wMonth = (WORD) _ttoi( &String[5] );\r
+ out_Time->wDayOfWeek = 0;\r
+ out_Time->wDay = (WORD) _ttoi( &String[8] );\r
+ out_Time->wHour = (WORD) _ttoi( &String[11] );\r
+ out_Time->wMinute = (WORD) _ttoi( &String[14] );\r
+\r
+ a_char = String[16];\r
+ if ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) {\r
+ time_zone = &String[16];\r
+ out_Time->wSecond = 0;\r
+ out_Time->wMilliseconds = 0;\r
+ } else {\r
+ /* Second */\r
+ IF ( string_length < 19 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( a_char != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ out_Time->wSecond = (WORD) _ttoi( &String[17] );\r
+\r
+\r
+ /* \8f¬\90\94\93_ */\r
+ a_char = String[19];\r
+ if ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) {\r
+ time_zone = &String[19];\r
+ out_Time->wMilliseconds = 0;\r
+ }\r
+ else {\r
+ IF ( a_char != _T('.') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ out_Time->wMilliseconds = 0;\r
+\r
+ number = String[20] - _T('0');\r
+ if ( number < 0 || number > 9 ) {\r
+ time_zone = &String[20];\r
+ } else {\r
+ out_Time->wMilliseconds += (WORD)( number * 100 );\r
+\r
+ number = String[21] - _T('0');\r
+ if ( number < 0 || number > 9 ) {\r
+ time_zone = &String[21];\r
+ } else {\r
+ out_Time->wMilliseconds += (WORD)( number * 10 );\r
+\r
+ number = String[22] - _T('0');\r
+ if ( number < 0 || number > 9 ) {\r
+ time_zone = &String[22];\r
+ } else {\r
+ const TCHAR* pointer = &String[23];\r
+\r
+ out_Time->wMilliseconds += (WORD)( number * 1 );\r
+\r
+ for (;;) {\r
+ number = *pointer - _T('0');\r
+ if ( number < 0 || number > 9 )\r
+ { break; }\r
+\r
+ pointer += 1;\r
+ }\r
+ time_zone = pointer;\r
+ }\r
+ }\r
+ }\r
+\r
+ a_char = *time_zone;\r
+ IF ( ! ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) )\r
+ { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ }\r
+ }\r
+\r
+ /* Time zone */\r
+ if ( a_char == _T('Z') ) {\r
+ *out_BiasMinute = 0;\r
+ }\r
+ else {\r
+ size_t time_zone_length = string_length - ( time_zone - String );\r
+ int bias_minute;\r
+\r
+ IF ( time_zone_length < 6 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( time_zone[3] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ bias_minute = _ttoi( &time_zone[1] ) * 60 + _ttoi( &time_zone[4] );\r
+ if ( a_char == _T('-') ) { bias_minute = -bias_minute; }\r
+ *out_BiasMinute = bias_minute;\r
+ }\r
+ }\r
+\r
+ /* Without time */\r
+ else {\r
+ out_Time->wDayOfWeek = 0;\r
+ out_Time->wHour = 0;\r
+ out_Time->wMinute = 0;\r
+ out_Time->wSecond = 0;\r
+ out_Time->wMilliseconds = 0;\r
+ *out_BiasMinute = 0;\r
+\r
+ IF ( string_length < 4 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ /* Year */\r
+ out_Time->wYear = (WORD) _ttoi( &String[0] );\r
+\r
+ /* Month */\r
+ if ( string_length > 4 ) {\r
+ IF ( string_length < 7 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( String[4] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ out_Time->wMonth = (WORD) _ttoi( &String[5] );\r
+ } else {\r
+ out_Time->wMonth = 1;\r
+ }\r
+\r
+ /* Day */\r
+ if ( string_length > 7 ) {\r
+ IF ( string_length < 10 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( String[7] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ out_Time->wDay = (WORD) _ttoi( &String[8] );\r
+ } else {\r
+ out_Time->wDay = 1;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [W3CDTF_getTimeZoneDesignator] >>> \r
+************************************************************************/\r
+errnum_t W3CDTF_getTimeZoneDesignator( TCHAR* out_TZD, size_t TZD_ByteSize,\r
+ int BiasMinute )\r
+{\r
+ errnum_t e;\r
+ TCHAR sign;\r
+ TIME_ZONE_INFORMATION time_zone;\r
+\r
+\r
+ /* Set "BiasMinute" */\r
+ if ( BiasMinute == W3CDTF_CURRENT_TIME_ZONE ) {\r
+ GetTimeZoneInformation( &time_zone );\r
+ BiasMinute = -time_zone.Bias;\r
+ }\r
+ else {\r
+ enum { minute_1day = 1440 };\r
+\r
+ IF_D ( BiasMinute < -minute_1day || BiasMinute > minute_1day )\r
+ { e=E_OTHERS; goto fin; }\r
+ }\r
+\r
+\r
+ /* Set "sign" */\r
+ if ( BiasMinute >= 0 ) {\r
+ sign = _T('+');\r
+ } else {\r
+ sign = _T('-');\r
+ BiasMinute = -BiasMinute;\r
+ }\r
+\r
+\r
+ /* Set "out_TZD" */\r
+ _stprintf_s( out_TZD, TZD_ByteSize / sizeof(TCHAR), _T("%c%02d:%02d"),\r
+ sign, BiasMinute / 60, BiasMinute % 60 );\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_isFullPath] >>> \r
+************************************************************************/\r
+bool StrT_isFullPath( const TCHAR* path )\r
+{\r
+ bool ret;\r
+\r
+ if ( path[0] == _T('\\') && path[1] == _T('\\') ) {\r
+ ret = true;\r
+ } else {\r
+ const TCHAR* back_slash = _tcschr( path, _T('\\') );\r
+ const TCHAR* slash = _tcschr( path, _T('/') );\r
+ const TCHAR* colon = _tcschr( path, _T(':') );\r
+\r
+ if ( colon != NULL ) {\r
+ const TCHAR* p;\r
+\r
+ for ( p = path; p < colon; p += 1 ) {\r
+ if ( ! _istalnum( *p ) ) {\r
+ colon = NULL;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ ret = ( colon != NULL ) &&\r
+ ( back_slash == colon + 1 || slash == colon + 1 );\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_getFullPath_part] >>> \r
+*************************************************************************/\r
+errnum_t StrT_getFullPath_part( TCHAR* out_FullPath, size_t FullPathSize, TCHAR* OutStart,\r
+ TCHAR** out_OutLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
+{\r
+ errnum_t e;\r
+ TCHAR separator = (TCHAR) DUMMY_INITIAL_VALUE_TCHAR;\r
+ const TCHAR* separator_path;\r
+ TCHAR* out_full_path_over = (TCHAR*)( (uint8_t*) out_FullPath + FullPathSize );\r
+ TCHAR* null_position = NULL;\r
+\r
+ #if CHECK_ARG\r
+ /* "BasePath" must be out of "out_FullPath" */\r
+ ASSERT_R( BasePath < out_FullPath ||\r
+ (uint8_t*) BasePath >= (uint8_t*) out_FullPath + FullPathSize,\r
+ goto err );\r
+ #endif\r
+\r
+\r
+ /* If "StepPath" == "", out_FullPath = "" */\r
+ if ( StepPath[0] == _T('\0') ) {\r
+ ASSERT_R( FullPathSize >= sizeof(TCHAR), goto err_fm );\r
+ out_FullPath[0] = _T('\0');\r
+ e=0; goto fin;\r
+ }\r
+\r
+\r
+ /* Set "OutStart" */\r
+ if ( OutStart == NULL )\r
+ { OutStart = out_FullPath; }\r
+\r
+\r
+ /* Set "separator" : \ or / from "BasePath" */\r
+ if ( StrT_isFullPath( StepPath ) ) {\r
+ separator_path = StepPath;\r
+ }\r
+ else if ( BasePath == NULL ) {\r
+ separator = _T('\\');\r
+ separator_path = NULL;\r
+ }\r
+ else {\r
+ separator_path = BasePath;\r
+ }\r
+ if ( separator_path != NULL ) {\r
+ const TCHAR* p;\r
+ const TCHAR* p2;\r
+\r
+ p = _tcschr( separator_path, _T('\\') );\r
+ p2 = _tcschr( separator_path, _T('/') );\r
+ if ( p == NULL ) {\r
+ if ( p2 == NULL )\r
+ { separator = _T('\\'); }\r
+ else\r
+ { separator = _T('/'); }\r
+ } else {\r
+ if ( p2 == NULL )\r
+ { separator = _T('\\'); }\r
+ else {\r
+ if ( p < p2 )\r
+ { separator = _T('\\'); }\r
+ else\r
+ { separator = _T('/'); }\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /* Set "OutStart" : "BasePath" + / + "StepPath" */\r
+ if ( StrT_isFullPath( StepPath ) ) {\r
+ size_t step_path_length = _tcslen( StepPath );\r
+\r
+ IF( OutStart + step_path_length >= out_full_path_over ) goto err_fa;\r
+ memmove( OutStart, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );\r
+\r
+ /* Set "null_position" */\r
+ null_position = OutStart + step_path_length;\r
+ }\r
+ else {\r
+ TCHAR c;\r
+ TCHAR* p;\r
+ size_t base_path_length;\r
+ size_t step_path_length = _tcslen( StepPath );\r
+\r
+ if ( BasePath == NULL ) {\r
+ base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
+ }\r
+ else {\r
+ base_path_length = _tcslen( BasePath );\r
+ c = BasePath[ base_path_length - 1 ];\r
+ if ( c == _T('\\') || c == _T('/') )\r
+ { base_path_length -= 1; }\r
+ }\r
+\r
+ p = OutStart + base_path_length + 1;\r
+ IF( p + step_path_length >= out_full_path_over ) goto err_fa;\r
+ memmove( p, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );\r
+ /* memmove is for "out_FullPath" == "StepPath" */\r
+\r
+ if ( BasePath == NULL ) {\r
+ GetCurrentDirectory( base_path_length + 1, OutStart );\r
+ if ( OutStart[ base_path_length - 1 ] == _T('\\') )\r
+ { base_path_length -= 1; }\r
+ } else {\r
+ memcpy( OutStart, BasePath, base_path_length * sizeof(TCHAR) );\r
+ }\r
+ OutStart[ base_path_length ] = separator;\r
+\r
+\r
+ /* Set "null_position" */\r
+ null_position = p + step_path_length;\r
+ }\r
+\r
+\r
+ /* Replace \ and / to "separator" in "OutStart" */\r
+ {\r
+ TCHAR other_separator;\r
+\r
+ if ( separator == _T('/') )\r
+ { other_separator = _T('\\'); }\r
+ else\r
+ { other_separator = _T('/'); }\r
+\r
+ e= StrT_replace1( OutStart, other_separator, separator, 0 ); IF(e)goto fin;\r
+ }\r
+\r
+\r
+ /* Replace \*\..\ to \ */\r
+ {\r
+ enum { length = 4 };\r
+ TCHAR parent[ length + 1 ]; /* \..\ or /../ */\r
+ TCHAR* parent_position;\r
+ TCHAR* p;\r
+\r
+ parent[0] = separator;\r
+ parent[1] = _T('.');\r
+ parent[2] = _T('.');\r
+ parent[3] = separator;\r
+ parent[4] = _T('\0');\r
+\r
+ for (;;) {\r
+ parent_position = _tcsstr( OutStart, parent );\r
+ if ( parent_position == NULL ) { break; }\r
+\r
+ p = parent_position - 1;\r
+ for (;;) {\r
+ IF( p < OutStart ) {goto err;} /* "../" are too many */\r
+ if ( *p == separator ) { break; }\r
+ p -= 1;\r
+ }\r
+\r
+ memmove( p + 1,\r
+ parent_position + length,\r
+ ( null_position - ( parent_position + length ) + 1 ) * sizeof(TCHAR) );\r
+\r
+ null_position -= ( parent_position + length ) - ( p + 1 );\r
+ }\r
+ }\r
+\r
+\r
+ /* Cut last \*\.. */\r
+ {\r
+ enum { length = 3 };\r
+ TCHAR* p;\r
+\r
+ while ( null_position - length >= OutStart ) {\r
+ if ( *( null_position - 3 ) != separator ||\r
+ *( null_position - 2 ) != _T('.') ||\r
+ *( null_position - 1 ) != _T('.') )\r
+ { break; }\r
+\r
+ p = null_position - 4;\r
+ for (;;) {\r
+ IF( p < OutStart ) {goto err;} /* "../" are too many */\r
+ if ( *p == separator ) { break; }\r
+ p -= 1;\r
+ }\r
+\r
+ *p = _T('\0');\r
+\r
+ null_position = p;\r
+ }\r
+ }\r
+\r
+\r
+ /* Replace \.\ to \ */\r
+ {\r
+ enum { length = 3 };\r
+ TCHAR current[ length + 1 ]; /* \.\ or /./ */\r
+ TCHAR* current_position;\r
+\r
+ current[0] = separator;\r
+ current[1] = _T('.');\r
+ current[2] = separator;\r
+ current[3] = _T('\0');\r
+\r
+ for (;;) {\r
+ current_position = _tcsstr( OutStart, current );\r
+ if ( current_position == NULL ) { break; }\r
+\r
+ memmove( current_position + 1,\r
+ current_position + length,\r
+ ( null_position - ( current_position + length ) + 1 ) * sizeof(TCHAR) );\r
+\r
+ null_position -= length - 1;\r
+ }\r
+ }\r
+\r
+\r
+ /* Cut last \. */\r
+ {\r
+ TCHAR* over = StrT_chr( OutStart, _T('\0') );\r
+\r
+ while ( over - 2 >= OutStart &&\r
+ *( over - 1 ) == _T('.') && *( over - 2 ) == separator ) {\r
+ over -= 2;\r
+ *over = _T('\0');\r
+ }\r
+ }\r
+\r
+\r
+ /* Add root / */\r
+ if ( null_position - 1 >= OutStart ) {\r
+ if ( *( null_position - 1 ) == _T(':') ) {\r
+ IF( null_position + 1 >= out_full_path_over ) goto err_fa;\r
+\r
+ *( null_position + 0 ) = separator;\r
+ *( null_position + 1 ) = _T('\0');\r
+ null_position += 1;\r
+ }\r
+ }\r
+\r
+\r
+ /* Set "*out_OutLast" */\r
+ if ( out_OutLast != NULL )\r
+ { *out_OutLast = null_position; }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+err_fa: e = E_FEW_ARRAY; goto fin;\r
+err_fm: e = E_FEW_MEMORY; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_allocateFullPath] >>> \r
+************************************************************************/\r
+errnum_t StrT_allocateFullPath( TCHAR** out_FullPath, const TCHAR* StepPath, TCHAR* BasePath )\r
+{\r
+ errnum_t e;\r
+ int step_path_length = _tcslen( StepPath );\r
+ int base_path_length;\r
+ int full_path_size;\r
+\r
+ if ( BasePath == NULL ) {\r
+ base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
+ } else {\r
+ base_path_length = _tcslen( BasePath );\r
+ }\r
+\r
+ full_path_size = ( step_path_length + 1 + base_path_length + 1 ) * sizeof(TCHAR);\r
+\r
+ e= HeapMemory_allocateBytes( out_FullPath, full_path_size ); IF(e){goto fin;}\r
+ e= StrT_getFullPath( *out_FullPath, full_path_size, StepPath, BasePath ); IF(e){goto fin;}\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_getParentFullPath_part] >>> \r
+************************************************************************/\r
+errnum_t StrT_getParentFullPath_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
+ TCHAR** out_StrLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
+{\r
+ errnum_t e;\r
+ TCHAR* p;\r
+\r
+ IF_D( StrStart < Str || (char*) StrStart >= (char*)Str + StrSize ){goto err;}\r
+\r
+ if ( StepPath[0] == _T('\0') ) {\r
+ *StrStart = _T('\0');\r
+ return 0;\r
+ }\r
+\r
+ /* \90â\91Î\83p\83X\82É\82·\82é */\r
+ e= StrT_getFullPath( StrStart,\r
+ StrSize - ( (char*)StrStart - (char*)Str ),\r
+ StepPath, BasePath ); IF(e)goto fin;\r
+\r
+\r
+ /* Cut last \ */\r
+ p = StrT_chr( StrStart, _T('\0') );\r
+ if ( p > StrStart ) {\r
+ TCHAR c = *( p - 1 );\r
+ if ( c == _T('\\') || c == _T('/') )\r
+ { *( p - 1 ) = _T('\0'); }\r
+ }\r
+\r
+\r
+ /* \90e\82Ö */\r
+ p = StrT_refFName( StrStart );\r
+ if ( p > StrStart ) p--;\r
+ *p = _T('\0');\r
+\r
+\r
+ /* \83\8b\81[\83g\82È\82ç \ \82ð\95t\82¯\82é */\r
+ if ( p == StrStart + 2 ) {\r
+ *p = _T('\\'); p++; *p = _T('\0');\r
+ }\r
+\r
+ if ( out_StrLast != NULL ) *out_StrLast = p;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_isOverOfFileName] >>> \r
+- "" or "\" or "/"\r
+************************************************************************/\r
+inline bool StrT_isOverOfFileName( const TCHAR* PointerInPath )\r
+{\r
+ return PointerInPath == NULL ||\r
+ *PointerInPath == _T('\0') ||\r
+ ( ( *PointerInPath == _T('\\') || *PointerInPath == _T('/') ) &&\r
+ *(PointerInPath + 1) == _T('\0') );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_getStepPath] >>> \r
+************************************************************************/\r
+errnum_t StrT_getStepPath( TCHAR* out_StepPath, size_t StepPathSize,\r
+ const TCHAR* FullPath, const TCHAR* BasePath )\r
+{\r
+ errnum_t e;\r
+ const TCHAR* abs_pointer;\r
+ const TCHAR* base_pointer;\r
+ TCHAR abs_char;\r
+ TCHAR base_char;\r
+ TCHAR separator;\r
+ const TCHAR* abs_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
+ const TCHAR* base_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
+ TCHAR* step_pointer;\r
+ TCHAR parent_symbol[4] = { _T('.'), _T('.'), _T('\\'), _T('\0') };\r
+ TCHAR base_path_2[ MAX_PATH ];\r
+\r
+\r
+ ASSERT_D( out_StepPath != FullPath, goto err );\r
+\r
+ abs_pointer = FullPath;\r
+\r
+\r
+ /* Set "base_pointer" */\r
+ if ( BasePath == NULL ) {\r
+ base_pointer = _tgetcwd( base_path_2, _countof(base_path_2) );\r
+ IF( base_pointer == NULL ) {goto err;}\r
+ }\r
+ else {\r
+ base_pointer = BasePath;\r
+ }\r
+\r
+\r
+ /* Set "abs_separator_pointer", "base_separator_pointer" : after same parent folder path */\r
+ separator = 0;\r
+ for (;;) { /* while abs_char == base_char */\r
+ abs_char = *abs_pointer;\r
+ base_char = *base_pointer;\r
+\r
+ abs_char = (TCHAR) _totlower( abs_char );\r
+ base_char = (TCHAR) _totlower( base_char );\r
+\r
+ if ( abs_char == _T('\0') ) {\r
+\r
+ /* out_StepPath = ".", if FullPath == BasePath */\r
+ if ( base_char == _T('\0') ) {\r
+ e= StrT_cpy( out_StepPath, StepPathSize, _T(".") ); IF(e)goto fin;\r
+ e=0; goto fin;\r
+ }\r
+ break;\r
+ }\r
+ if ( base_char == _T('\0') ) { break; }\r
+\r
+ if ( abs_char != base_char ) {\r
+ if ( ( abs_char == _T('/') || abs_char == _T('\\') ) &&\r
+ ( base_char == _T('/') || base_char == _T('\\') ) )\r
+ { /* Do nothing */ }\r
+ else\r
+ { break; }\r
+ }\r
+\r
+ /* Set "separator", "abs_separator_pointer", "base_separator_pointer" */\r
+ if ( base_char == _T('/') || base_char == _T('\\') ) {\r
+ if ( separator == 0 )\r
+ { separator = base_char; }\r
+\r
+ abs_separator_pointer = abs_pointer;\r
+ base_separator_pointer = base_pointer;\r
+ }\r
+\r
+ abs_pointer += 1;\r
+ base_pointer += 1;\r
+ }\r
+\r
+\r
+ /* 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
+ if ( ( ( abs_char == _T('/') || abs_char == _T('\\') ) && base_char == _T('\0') ) ||\r
+ ( base_char == _T('/') || base_char == _T('\\') ) && abs_char == _T('\0') ) {\r
+\r
+ if ( separator == 0 )\r
+ { separator = abs_char; }\r
+\r
+ abs_separator_pointer = abs_pointer;\r
+ base_separator_pointer = base_pointer;\r
+ }\r
+\r
+\r
+ /* out_StepPath = FullPath, if there is not same folder */\r
+ if ( separator == 0 ) {\r
+ e= StrT_cpy( out_StepPath, StepPathSize, FullPath ); IF(e)goto fin;\r
+ e=0; goto fin;\r
+ }\r
+\r
+\r
+ /* Add "..\" to "out_StepPath" */\r
+ parent_symbol[2] = separator;\r
+ step_pointer = out_StepPath;\r
+ for (;;) {\r
+ const TCHAR* p1;\r
+ const TCHAR* p2;\r
+\r
+ if ( StrT_isOverOfFileName( base_separator_pointer ) )\r
+ { break; }\r
+\r
+\r
+ /* Set "base_separator_pointer" : next separator */\r
+ p1 = _tcschr( base_separator_pointer + 1, _T('/') );\r
+ p2 = _tcschr( base_separator_pointer + 1, _T('\\') );\r
+\r
+ if ( p1 == NULL ) {\r
+ if ( p2 == NULL )\r
+ { base_separator_pointer = NULL; }\r
+ else\r
+ { base_separator_pointer = p2; }\r
+ }\r
+ else {\r
+ if ( p2 == NULL ) {\r
+ base_separator_pointer = p1;\r
+ } else {\r
+ if ( p1 < p2 )\r
+ { base_separator_pointer = p1; }\r
+ else\r
+ { base_separator_pointer = p2; }\r
+ }\r
+ }\r
+\r
+\r
+ /* Add "..\" to "out_StepPath" */\r
+ e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, &step_pointer,\r
+ parent_symbol, NULL ); IF(e)goto fin;\r
+ }\r
+\r
+\r
+ /* Copy a part of "FullPath" to "out_StepPath" */\r
+ if ( StrT_isOverOfFileName( abs_separator_pointer ) ) {\r
+ ASSERT_D( step_pointer > out_StepPath, goto err );\r
+ *( step_pointer - 1 ) = _T('\0');\r
}\r
else {\r
- e= Writables_create( &wr, m ); IF(e)goto resume;\r
- *out_Writable = wr;\r
+ e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, NULL,\r
+ abs_separator_pointer + 1, NULL ); IF(e)goto fin;\r
}\r
\r
+ e=0;\r
+fin:\r
+ return e;\r
\r
- //=== Writable \82É\83p\83X\82ð\93o\98^\82·\82é\r
- {\r
- va_list va;\r
- TCHAR* path;\r
- int i;\r
+err: e = E_OTHERS; goto fin;\r
+}\r
\r
- va_start( va, out_Writable );\r
- for ( i=0; ; i++ ) {\r
- path = va_arg( va, TCHAR* );\r
- if ( path == NULL ) break;\r
- IF( i == 5 ) goto err; // \8dÅ\8cã\82Ì NULL \96Y\82ê\91Î\8dô\r
\r
- e= Writables_add( wr, m, path ); IF(e)goto resume;\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_getBaseName_part] >>> \r
+************************************************************************/\r
+errnum_t StrT_getBaseName_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
+ TCHAR** out_StrLast, const TCHAR* SrcPath )\r
+{\r
+ const TCHAR* p1;\r
+ const TCHAR* p2;\r
+ const TCHAR* p3;\r
+ const TCHAR* ps;\r
+\r
+ p1 = StrT_refFName( SrcPath );\r
+\r
+\r
+ //=== # \82ª\96³\82¢\82Æ\82«\81A\8dÅ\8cã\82Ì\83s\83\8a\83I\83h\82Ì\91O\82Ü\82Å\82ª\81ABaseName\r
+ ps = _tcschr( p1, _T('#') );\r
+ if ( ps == NULL ) {\r
+ p2 = _tcsrchr( p1, _T('.') );\r
+ if ( p2 == NULL ) p2 = _tcsrchr( p1, _T('\0') );\r
+ }\r
+\r
+ //=== # \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
+ else {\r
+ p2 = ps;\r
+\r
+ p3 = p1;\r
+ for (;;) {\r
+ p3 = _tcschr( p3, _T('.') );\r
+ if ( p3 == NULL || p3 > ps ) break;\r
+ p2 = p3;\r
+ p3 ++;\r
}\r
- va_end( va );\r
}\r
- #if defined(TempFile_get)\r
- {\r
- TempFile* temp;\r
\r
- e= TempFile_get( &temp ); IF(e)goto resume;\r
- e= Writables_add( wr, m, temp->TempPath ); IF(e)goto resume;\r
+ return stcpy_part_r( Str, StrSize, StrStart, out_StrLast, p1, p2 );\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_addLastOfFileName] >>> \r
+************************************************************************/\r
+errnum_t StrT_addLastOfFileName( TCHAR* out_Path, size_t PathSize,\r
+ const TCHAR* BasePath, const TCHAR* AddName )\r
+{\r
+ TCHAR c;\r
+ size_t copy_size;\r
+ size_t free_size;\r
+ char* out_pos;\r
+ const TCHAR* last_pos_in_base = StrT_chr( BasePath, _T('\0') );\r
+ const TCHAR* term_pos_in_base;\r
+ const TCHAR* add_pos_in_base;\r
+ const TCHAR* period_pos_in_base = _tcsrchr( BasePath, _T('.') ); // > term_pos_in_base\r
+ const TCHAR* last_pos_in_add = StrT_chr( AddName, _T('\0') );\r
+ const TCHAR* term_pos_in_add;\r
+ const TCHAR* period_pos_in_add = _tcsrchr( AddName, _T('.') ); // > term_pos_in_add\r
+\r
+\r
+ DISCARD_BYTES( out_Path, PathSize );\r
+\r
+\r
+ //=== term_pos_in_base\r
+ for ( term_pos_in_base = last_pos_in_base; term_pos_in_base >= BasePath; term_pos_in_base -- ) {\r
+ c = *term_pos_in_base;\r
+ if ( c == _T('/') || c == _T('\\') ) break;\r
}\r
- #endif\r
\r
\r
- //=== \82·\82®\82É Writable \82ð\97L\8cø\82É\82·\82é\r
- if ( out_Writable == NULL ) {\r
- e= Writables_enable( wr ); IF(e)goto resume;\r
+ //=== term_pos_in_add\r
+ for ( term_pos_in_add = last_pos_in_add; term_pos_in_add >= AddName; term_pos_in_add -- ) {\r
+ c = *term_pos_in_add;\r
+ if ( c == _T('/') || c == _T('\\') ) break;\r
+ }\r
+\r
+\r
+ //=== add_pos_in_base\r
+ if ( term_pos_in_base < period_pos_in_base ) {\r
+ add_pos_in_base = period_pos_in_base;\r
+ }\r
+ else {\r
+ if ( term_pos_in_base < BasePath )\r
+ add_pos_in_base = StrT_chr( BasePath, _T('\0') );\r
+ else\r
+ add_pos_in_base = StrT_chr( term_pos_in_base, _T('\0') );\r
+ }\r
+\r
+\r
+ //=== setup output parameters\r
+ out_pos = (char*) out_Path;\r
+ free_size = PathSize;\r
+\r
+\r
+ //=== copy BasePath .. add_pos_in_base\r
+ copy_size = (char*)add_pos_in_base - (char*)BasePath;\r
+ if ( copy_size > free_size ) goto err_fa;\r
+ memcpy( out_pos, BasePath, copy_size );\r
+ out_pos += copy_size;\r
+ free_size -= copy_size;\r
+\r
+\r
+ //=== copy AddName .. last_pos_in_add\r
+ copy_size = (char*)last_pos_in_add - (char*)AddName;\r
+ if ( copy_size > free_size ) goto err_fa;\r
+ memcpy( out_pos, AddName, copy_size );\r
+ out_pos += copy_size;\r
+ free_size -= copy_size;\r
+\r
+\r
+ //=== add name and not change extension\r
+ if ( period_pos_in_add == NULL ) {\r
+\r
+ //=== copy period_pos_in_base .. last_pos_in_base\r
+ if ( period_pos_in_base > term_pos_in_base ) {\r
+ copy_size = (char*)last_pos_in_base - (char*)period_pos_in_base + sizeof(TCHAR);\r
+ if ( copy_size > free_size ) goto err_fa;\r
+ memcpy( out_pos, period_pos_in_base, copy_size );\r
+ }\r
+ else {\r
+ *(TCHAR*)out_pos = _T('\0');\r
+ }\r
+ }\r
+\r
+\r
+ //=== add name and change extension\r
+ else {\r
+\r
+ if ( *(period_pos_in_add + 1) == _T('\0') )\r
+ *( (TCHAR*)out_pos - 1 ) = _T('\0');\r
+ else\r
+ *(TCHAR*)out_pos = _T('\0');\r
+ }\r
+\r
+ return 0;\r
+\r
+err_fa:\r
+ return E_FEW_ARRAY;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_encodeToValidPath] >>> \r
+************************************************************************/\r
+errnum_t StrT_encodeToValidPath( TCHAR* out_Path, size_t in_OutPathSize, const TCHAR* in_Path, bool in_IsName )\r
+{\r
+ errnum_t e;\r
+\r
+ int i_in; /* index of "in_Path" */\r
+ int i_out = 0; /* index of "out_Path" */\r
+ int i_out_over = (int)( in_OutPathSize / sizeof(TCHAR) );\r
+ bool is_colon = in_IsName;\r
+\r
+ ASSERT_R( in_Path != out_Path, e=E_OTHERS; goto fin );\r
+\r
+ for ( i_in = 0; ; i_in += 1 ) {\r
+ bool is_percent;\r
+ int chara = in_Path[ i_in ]; /* a character */\r
+\r
+ if ( chara == _T('\0') )\r
+ { break; }\r
+\r
+\r
+ /* Set "is_percent" */\r
+ switch ( chara ) {\r
+ case _T(','): case _T(';'): case _T('*'): case _T('?'): case _T('"'):\r
+ case _T('<'): case _T('>'): case _T('|'): case _T('%'):\r
+ is_percent = true;\r
+ break;\r
+ case _T(':'):\r
+ is_percent = is_colon;\r
+ is_colon = true;\r
+ break;\r
+ case _T('\\'): case _T('/'):\r
+ is_percent = in_IsName;\r
+ is_colon = true;\r
+ break;\r
+ default:\r
+ is_percent = false;\r
+ break;\r
+ }\r
+\r
+\r
+ /* Set "out_Path[ i_out ]" */\r
+ if ( is_percent ) {\r
+ int high = chara / 0x10;\r
+ int low = chara & 0xF;\r
+\r
+ if ( high <= 9 ) {\r
+ high += _T('0');\r
+ } else {\r
+ high = ( high - 0xA ) + _T('a');\r
+ }\r
+\r
+ if ( low <= 9 ) {\r
+ low += _T('0');\r
+ } else {\r
+ low = ( low - 0xA ) + _T('a');\r
+ }\r
+\r
+ ASSERT_R( i_out + 3 < i_out_over, e=E_FEW_ARRAY; goto fin );\r
+\r
+ out_Path[ i_out + 0 ] = _T('%');\r
+ out_Path[ i_out + 1 ] = (TCHAR) high;\r
+ out_Path[ i_out + 2 ] = (TCHAR) low;\r
+ i_out += 3;\r
+ }\r
+ else {\r
+ ASSERT_R( i_out + 1 < i_out_over, e=E_FEW_ARRAY; goto fin );\r
+\r
+ out_Path[ i_out ] = (TCHAR) chara;\r
+ i_out += 1;\r
+ }\r
}\r
\r
e=0;\r
fin:\r
- #if Uses_OutMallocIDTool\r
- OutMallocID_setEnable( is_prev_out_malloc );\r
- #endif\r
+ out_Path[ i_out ] = _T('\0');\r
+\r
return e;\r
+}\r
\r
-err: e = E_OTHERS; goto resume;\r
-resume:\r
- if ( wr != NULL ) {\r
- if ( out_Writable == NULL )\r
- e= Writables_finish( wr, e ); // g_DefaultWritables\r
- else\r
- e= Writables_delete( wr, e );\r
- }\r
- goto fin;\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Strs_init] >>> \r
+************************************************************************/\r
+enum { Strs_FirstSize = 0x0F00 };\r
+\r
+errnum_t Strs_init( Strs* self )\r
+{\r
+ byte_t* p;\r
+\r
+ self->MemoryAddress = NULL;\r
+\r
+ p = (byte_t*) malloc( Strs_FirstSize );\r
+ IF( p == NULL ) return E_FEW_MEMORY;\r
+\r
+ self->MemoryAddress = p;\r
+ self->MemoryOver = p + Strs_FirstSize;\r
+ self->NextElem = p + sizeof(TCHAR*);\r
+ self->PointerToNextStrInPrevElem = (TCHAR**) p;\r
+ self->Prev_PointerToNextStrInPrevElem = NULL;\r
+ *(TCHAR**) p = NULL;\r
+\r
+ self->FirstOfStrs = self;\r
+ self->NextStrs = NULL;\r
+\r
+ return 0;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [AppKey_addNewWritableFolder] \83`\83F\83b\83N\82·\82é\81A\82Ü\82½\82Í\92Ç\89Á\82·\82é >>> \r
-\81i\92Ç\89Á\82Í\96¢\91Î\89\9e\81j\r
+ <<< [Strs_finish] >>> \r
************************************************************************/\r
-errnum_t AppKey_addNewWritableFolder( const TCHAR* Path )\r
+errnum_t Strs_finish( Strs* self, errnum_t e )\r
{\r
- errnum_t e;\r
- TCHAR** pp;\r
- TCHAR** pp_over;\r
- Writables* wr = &g_CurrentWritablesPrivate.m_CurrentWritables;\r
- size_t path_len;\r
- TCHAR abs_path[MAX_PATH];\r
-\r
- if ( g_AppKeyPrivate == NULL ) {\r
- e= AppKey_newWritable( NULL, NULL, ".", NULL ); IF(e){goto fin;}\r
- }\r
+ Strs* mp;\r
+ Strs* next_mp;\r
\r
- e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e){goto fin;}\r
+ if ( self->MemoryAddress == NULL ) return 0;\r
\r
- pp_over = wr->m_Paths + wr->m_nPath;\r
- for ( pp = wr->m_Paths; ; pp++ ) {\r
- IF ( pp >= pp_over ) { e=E_OUT_OF_WRITABLE; goto fin; }\r
- // Path (abs_path) \82Í\81AAppKey_newWritable \82Å\8b\96\89Â\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\81B\r
- // \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
- // \8b\96\89Â\82³\82ê\82Ä\82¢\82é\83p\83X\82ð\8am\94F\82µ\82Ä\82\82¾\82³\82¢\81B\r
+ mp = self->FirstOfStrs;\r
+ for (;;) {\r
+ free( mp->MemoryAddress );\r
+ if ( mp == self ) break;\r
\r
- path_len = _tcslen( *pp );\r
- if ( _tcsnicmp( *pp, abs_path, path_len ) == 0 &&\r
- ( abs_path[ path_len ] == _T('\\') || abs_path[ path_len ] == _T('\0') ) ) break;\r
+ next_mp = mp->NextStrs;\r
+ free( mp );\r
+ mp = next_mp;\r
}\r
+ self->MemoryAddress = NULL;\r
\r
- e=0;\r
-fin:\r
return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [AppKey_checkWritable] >>> \r
+ <<< [Strs_toEmpty] >>> \r
************************************************************************/\r
-errnum_t AppKey_checkWritable( const TCHAR* Path )\r
+errnum_t Strs_toEmpty( Strs* self )\r
{\r
- return AppKey_addNewWritableFolder( Path );\r
+ Strs_finish( self, 0 );\r
+ return Strs_init( self );\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [Writables_init] >>> \r
+ <<< [Strs_add] >>> \r
************************************************************************/\r
-static void Writables_initConst( Writables* m )\r
-{\r
- m->m_Paths = NULL;\r
- m->m_nPath = -1;\r
-}\r
-\r
-\r
-static errnum_t Writables_init( Writables* m, AppKey* Key )\r
+errnum_t Strs_add( Strs* self, const TCHAR* Str, const TCHAR** out_AllocStr )\r
{\r
- IF( ! AppKey_isSame( Key ) ) return E_OTHERS;\r
-\r
- m->m_Paths = NULL;\r
- m->m_nPath = 0;\r
- return 0;\r
+ return Strs_addBinary( self, Str, StrT_chr( Str, _T('\0') ) + 1, out_AllocStr );\r
}\r
\r
\r
-static errnum_t Writables_finish( Writables* m, int e )\r
+errnum_t Strs_addBinary( Strs* self, const TCHAR* Str, const TCHAR* StrOver, const TCHAR** out_AllocStr )\r
{\r
- errnum_t ee;\r
-\r
- ee= Writables_clearPaths( m ); IF(ee&&!e) e=ee;\r
- m->m_nPath = -1;\r
- return e;\r
-}\r
-\r
+ errnum_t e;\r
+ size_t str_size;\r
+ size_t elem_size;\r
\r
-static bool Writables_isInited( Writables* m )\r
-{\r
- return ( m->m_nPath != -1 );\r
-}\r
+ str_size = ( (byte_t*) StrOver - (byte_t*) Str );\r
+ elem_size = ( sizeof(TCHAR*) + str_size + ( sizeof(void*) - 1 ) ) & ~(sizeof(void*) - 1);\r
\r
+ if ( self->NextElem + elem_size > self->MemoryOver )\r
+ { e= Strs_expandSize( self, str_size ); IF(e)goto fin; }\r
\r
-static errnum_t Writables_clearPaths( Writables* m )\r
-{\r
- TCHAR** p;\r
- TCHAR** p_over;\r
\r
- if ( m->m_Paths != NULL ) {\r
- p_over = m->m_Paths + m->m_nPath;\r
- for ( p = m->m_Paths; p < p_over; p++ ) {\r
- free( *p );\r
- }\r
- free( m->m_Paths ); m->m_Paths = NULL;\r
- }\r
- m->m_nPath = 0;\r
- return 0;\r
-}\r
+ // [ NULL | ... ]\r
+ // [ FirstStr | NULL | TCHAR[] | ... ]\r
+ // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]\r
+ // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
\r
+ if ( out_AllocStr != NULL ) *out_AllocStr = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
\r
-static errnum_t Writables_create( Writables** out_m, AppKey* Key )\r
-{\r
- errnum_t e;\r
- Writables* m;\r
+ //=== fill elem\r
+ *(TCHAR**) self->NextElem = NULL;\r
+ memcpy( self->NextElem + sizeof(TCHAR*), Str, str_size );\r
\r
- m = (Writables*) malloc( sizeof(*m) ); IF(m==NULL)return E_FEW_MEMORY;\r
- Writables_initConst( m );\r
- e= Writables_init( m, Key ); IF(e)goto resume;\r
- *out_m = m;\r
- return 0;\r
-resume: Writables_delete( m, 0 ); free(m); return e;\r
-}\r
+ //=== link to elem from previous elem\r
+ *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
\r
+ //=== update self\r
+ self->Prev_PointerToNextStrInPrevElem = self->PointerToNextStrInPrevElem;\r
+ self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
+ self->NextElem = self->NextElem + elem_size;\r
\r
-errnum_t Writables_delete( Writables* m, errnum_t e )\r
-{\r
- if ( m == NULL ) goto fin;\r
- e= Writables_finish( m, e );\r
- free( m );\r
+ e=0;\r
fin:\r
return e;\r
}\r
\r
\r
/***********************************************************************\r
- <<< [Writables_add] >>> \r
+ <<< [Strs_freeLast] >>> \r
************************************************************************/\r
-int Writables_add( Writables* m, AppKey* Key, TCHAR* Path )\r
+errnum_t Strs_freeLast( Strs* self, TCHAR* AllocStr )\r
{\r
- int e;\r
- TCHAR** pp;\r
- TCHAR* p = NULL;\r
- size_t path_size;\r
- TCHAR abs_path[MAX_PATH];\r
-\r
- IF( ! AppKey_isSame( Key ) )goto err;\r
- if ( Path[0] == _T('\0') ) return 0;\r
-\r
- e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto resume;\r
+ errnum_t e;\r
+ TCHAR* str;\r
+ TCHAR* last_str;\r
+ TCHAR* prev_of_last_str;\r
+ Strs* mp;\r
+ Strs* prev_of_last_mp;\r
\r
- e= CurrentWritables_askFileAccess( &g_CurrentWritablesPrivate, abs_path ); IF(e)goto resume;\r
+ if ( self->Prev_PointerToNextStrInPrevElem == NULL ) {\r
+ prev_of_last_str = NULL;\r
+ last_str = NULL;\r
+ for ( Strs_forEach( self, &str ) ) {\r
+ prev_of_last_str = last_str;\r
+ last_str = str;\r
+ }\r
+ }\r
+ else {\r
+ prev_of_last_str = (TCHAR*)( self->Prev_PointerToNextStrInPrevElem + 1 );\r
+ last_str = (TCHAR*)( self->PointerToNextStrInPrevElem + 1 );\r
+ }\r
\r
- pp = (TCHAR**) realloc( m->m_Paths, (m->m_nPath + 1) * sizeof(TCHAR*) );\r
- IF( pp == NULL ) goto err;\r
- m->m_Paths = pp;\r
+ // [ NULL | ... ]\r
+ IF( last_str != AllocStr ) {goto err;}\r
\r
- path_size = (_tcslen( abs_path ) + 1) * sizeof(TCHAR);\r
- p = (TCHAR*) malloc( path_size );\r
- m->m_Paths[ m->m_nPath ] = p;\r
- IF( p == NULL )goto err;\r
+ // [ FirstStr | NULL | TCHAR[] | ... ]\r
+ if ( prev_of_last_str == NULL ) {\r
+ self->NextElem = self->MemoryAddress + sizeof(TCHAR*);\r
+ self->PointerToNextStrInPrevElem = (TCHAR**) self->MemoryAddress;\r
+ }\r
\r
- memcpy( p, abs_path, path_size );\r
- if ( p[ path_size/sizeof(TCHAR) - 2 ] == _T('\\') )\r
- p[ path_size/sizeof(TCHAR) - 2 ] = _T('\0');\r
- m->m_nPath ++;\r
+ // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]\r
+ else if ( (byte_t*) prev_of_last_str >= self->MemoryAddress &&\r
+ (byte_t*) prev_of_last_str < self->MemoryOver ) {\r
+ self->NextElem = (byte_t*)last_str - sizeof(TCHAR*);\r
+ self->PointerToNextStrInPrevElem = (TCHAR**)( (byte_t*)prev_of_last_str - sizeof(TCHAR*) );\r
+ }\r
\r
- e=0;\r
-fin:\r
- return e;\r
+ // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
+ else {\r
+ prev_of_last_mp = NULL;\r
+ for ( mp = self->FirstOfStrs; mp->NextStrs != self; mp = mp->NextStrs ) {\r
+ prev_of_last_mp = mp;\r
+ }\r
\r
-err: e = E_OTHERS; goto resume;\r
-resume:\r
- if ( p != NULL ) free( p );\r
- goto fin;\r
-}\r
+ free( self->MemoryAddress );\r
\r
+ *self = *mp;\r
\r
-int Writables_remove( Writables* m, TCHAR* Path )\r
-{\r
- TCHAR** pp;\r
- TCHAR** pp_over;\r
+ if ( prev_of_last_mp == NULL ) {\r
+ self->FirstOfStrs = self;\r
+ self->NextStrs = NULL;\r
+ }\r
+ else {\r
+ prev_of_last_mp->NextStrs = self;\r
+ }\r
\r
- pp_over = m->m_Paths + m->m_nPath;\r
- for ( pp = m->m_Paths; ; pp++ ) {\r
- if ( pp >= pp_over ) return 0;\r
- if ( _tcscmp( *pp, Path ) == 0 ) break;\r
+ free( mp );\r
}\r
- free( *pp );\r
- memmove( pp, pp+1, (char*)pp - (char*)pp_over - sizeof(TCHAR) );\r
- m->m_nPath --;\r
+ *self->PointerToNextStrInPrevElem = NULL;\r
+ self->Prev_PointerToNextStrInPrevElem = NULL;\r
\r
- #if _DEBUG\r
- *( pp_over - 1 ) = NULL;\r
- #endif\r
+ e=0;\r
+fin:\r
+ return e;\r
\r
- return 0;\r
+err: e = E_OTHERS; goto fin;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [Writables_enable] >>> \r
+ <<< [Strs_expandSize] >>> \r
************************************************************************/\r
-int Writables_enable( Writables* m )\r
+errnum_t Strs_expandSize( Strs* self, size_t FreeSize )\r
{\r
- int e;\r
+ Strs* mp;\r
+ Strs* mp2;\r
+ size_t elem_size = ( sizeof(TCHAR*) + FreeSize + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
+ size_t memory_size;\r
+ byte_t* new_memory;\r
\r
- e= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, m ); IF(e)goto fin;\r
- e= Writables_copyToConst( &g_CurrentWritables, &g_CurrentWritablesPrivate.m_CurrentWritables ); IF(e)goto fin;\r
+ // [ NULL | ... ]\r
+ // [ FirstStr | NULL | TCHAR[] | ... ]\r
+ // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]\r
+ // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
+\r
+ while ( self->NextElem + elem_size > self->MemoryOver ) {\r
+\r
+ //=== alloc\r
+ mp = (Strs*) malloc( sizeof(Strs) ); IF(mp==NULL) goto err_fm;\r
+ memory_size = ( self->MemoryOver - self->MemoryAddress ) * 2;\r
+ new_memory = (byte_t*) malloc( memory_size );\r
+ IF( new_memory == NULL ) { free( mp ); goto err_fm; }\r
+\r
+ //=== move old memory\r
+ if ( self->FirstOfStrs == self ) {\r
+ self->FirstOfStrs = mp;\r
+ }\r
+ else {\r
+ for ( mp2 = self->FirstOfStrs; mp2->NextStrs != self; mp2 = mp2->NextStrs );\r
+ mp2->NextStrs = mp;\r
+ }\r
+ *mp = *self;\r
+ mp->NextStrs = self;\r
+\r
+ //=== setup new memory\r
+ self->MemoryAddress = new_memory;\r
+ self->MemoryOver = new_memory + memory_size;\r
+ self->NextElem = new_memory;\r
+ // self->PointerToNextStrInPrevElem is same value\r
+ // self->FirstOfStrs is same value\r
+ // self->NextStrs is always NULL\r
+ }\r
+ return 0;\r
\r
- e=0;\r
-fin:\r
- return e;\r
+err_fm: return E_FEW_ARRAY;\r
}\r
\r
\r
-int Writables_disable( Writables* m, int e )\r
+/***********************************************************************\r
+ <<< [Strs_commit] >>>\r
+************************************************************************/\r
+errnum_t Strs_commit( Strs* self, TCHAR* StrOver )\r
{\r
- int ee;\r
+ size_t elem_size;\r
\r
- UNREFERENCED_VARIABLE( m );\r
+ if ( StrOver == NULL )\r
+ { StrOver = StrT_chr( (TCHAR*)( self->NextElem + sizeof(TCHAR*) ), _T('\0') ) + 1; }\r
+ elem_size = ( ( (byte_t*)StrOver - self->NextElem ) + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
\r
- ee= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
- ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
+ //=== fill elem\r
+ *(TCHAR**) self->NextElem = NULL;\r
\r
- e=0;\r
-fin:\r
- return e;\r
+ //=== link to elem from previous elem\r
+ *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
+\r
+ //=== update self\r
+ self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
+ self->NextElem = self->NextElem + elem_size;\r
+\r
+ return 0;\r
}\r
\r
\r
-static int Writables_copyToConst( Writables* To, Writables* From )\r
+ \r
+/***********************************************************************\r
+ <<< [Strs_allocateArray] >>> \r
+************************************************************************/\r
+errnum_t Strs_allocateArray( Strs* self, TCHAR*** out_PointerArray, int* out_Count )\r
{\r
- int e;\r
- TCHAR** pp;\r
- TCHAR** pp_over;\r
- TCHAR* p2;\r
- TCHAR** pp2;\r
- size_t path_size;\r
+ errnum_t e;\r
+ TCHAR* p;\r
+ TCHAR** pp;\r
+ int count;\r
\r
- if ( To->m_Paths != NULL ) {\r
- free( To->m_Paths );\r
- To->m_Paths = NULL;\r
- To->m_nPath = 0;\r
+ count = 0;\r
+ for ( Strs_forEach( self, &p ) ) {\r
+ count += 1;\r
}\r
\r
- if ( From != NULL && From->m_nPath > 0 ) {\r
-\r
- path_size = 0;\r
- pp_over = From->m_Paths + From->m_nPath;\r
- for ( pp = From->m_Paths; pp < pp_over; pp++ ) {\r
- path_size += _tcslen( *pp ) + 1;\r
- }\r
-\r
- path_size = From->m_nPath * sizeof(TCHAR*) + path_size * sizeof(TCHAR);\r
- To->m_Paths = (TCHAR**) malloc( path_size );\r
- IF( To->m_Paths == NULL ) goto err;\r
+ e= HeapMemory_allocateArray( &pp, count ); IF(e){goto fin;}\r
\r
- p2 = (TCHAR*)( (char*)To->m_Paths + From->m_nPath * sizeof(TCHAR*) );\r
- pp2 = To->m_Paths;\r
- for ( pp = From->m_Paths; pp < pp_over; pp++ ) {\r
- *pp2 = p2;\r
- path_size = (_tcslen( *pp ) + 1) * sizeof(TCHAR);\r
- memcpy( p2, *pp, path_size );\r
- p2 = (TCHAR*)( (char*)p2 + path_size );\r
- pp2 ++;\r
- }\r
- To->m_nPath = From->m_nPath;\r
+ count = 0;\r
+ for ( Strs_forEach( self, &p ) ) {\r
+ pp[ count ] = p;\r
+ count += 1;\r
}\r
\r
+ *out_PointerArray = pp;\r
+ *out_Count = count;\r
+\r
e=0;\r
fin:\r
return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
}\r
\r
+\r
\r
/***********************************************************************\r
- <<< [CurrentWritables] >>> \r
+ <<< [StrArr] >>> \r
************************************************************************/\r
-static void CurrentWritables_initConst( CurrentWritables* m )\r
+\r
+/*[StrArr_init]*/\r
+errnum_t StrArr_init( StrArr* self )\r
{\r
- Writables_initConst( &m->m_CurrentWritables );\r
- m->m_ProgramFiles = NULL;\r
- m->m_windir = NULL;\r
- m->m_APPDATA = NULL;\r
- m->m_LOCALAPPDATA = NULL;\r
+ errnum_t e;\r
+\r
+ Set2_initConst( &self->Array );\r
+ Strs_initConst( &self->Chars );\r
+\r
+ e= Set2_init( &self->Array, 0x100 ); IF(e)goto cancel;\r
+ e= Strs_init( &self->Chars ); IF(e)goto cancel;\r
+ return 0;\r
+\r
+cancel: StrArr_finish( self, e ); return e;\r
}\r
\r
\r
-static int CurrentWritables_init( CurrentWritables* m )\r
+/*[StrArr_finish]*/\r
+errnum_t StrArr_finish( StrArr* self, errnum_t e )\r
{\r
- int e;\r
- #if Uses_OutMallocIDTool\r
- bool is_prev_out_malloc;\r
+ if ( ! Set2_isInited( &self->Array ) ) return e;\r
\r
- is_prev_out_malloc = OutMallocID_setEnable( false );\r
- #endif\r
+ e= Set2_finish( &self->Array, e );\r
+ e= Strs_finish( &self->Chars, e );\r
+ return e;\r
+}\r
\r
- e= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(e)goto fin;\r
\r
- e= env_malloc( &m->m_ProgramFiles, &m->m_ProgramFiles_Len, _T("ProgramFiles") ); IF(e)goto fin;\r
- e= env_malloc( &m->m_windir, &m->m_windir_Len, _T("windir") ); IF(e)goto fin;\r
- e= env_malloc( &m->m_APPDATA, &m->m_APPDATA_Len, _T("APPDATA") ); IF(e)goto fin;\r
- // e= env_malloc( &m->m_LOCALAPPDATA, &m->m_LOCALAPPDATA_Len, _T("LOCALAPPDATA") ); IF(e)goto fin;\r
+/*[StrArr_add]*/\r
+errnum_t StrArr_add( StrArr* self, const TCHAR* Str, int* out_I )\r
+{\r
+ errnum_t e;\r
+\r
+ e= StrArr_expandCount( self, _tcslen( Str ) ); IF(e)goto fin;\r
+ _tcscpy_s( StrArr_getFreeAddr( self ), StrArr_getFreeCount( self ), Str );\r
+ e= StrArr_commit( self ); IF(e)goto fin;\r
+ if ( out_I != NULL ) *out_I = Set2_getCount( &self->Array, TCHAR* ) - 1;\r
\r
e=0;\r
fin:\r
- #if Uses_OutMallocIDTool\r
- OutMallocID_setEnable( is_prev_out_malloc );\r
- #endif\r
return e;\r
}\r
\r
\r
-static int CurrentWritables_finish( CurrentWritables* m, int e )\r
+/*[StrArr_commit]*/\r
+errnum_t StrArr_commit( StrArr* self )\r
{\r
- int ee;\r
-\r
- ee= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
-\r
- if ( m->m_ProgramFiles != NULL ) free( m->m_ProgramFiles );\r
- if ( m->m_windir != NULL ) free( m->m_windir );\r
- if ( m->m_APPDATA != NULL ) free( m->m_APPDATA );\r
- if ( m->m_LOCALAPPDATA != NULL ) free( m->m_LOCALAPPDATA );\r
+ errnum_t e;\r
+ TCHAR* p;\r
+ TCHAR** pp = NULL;\r
+ Set2* arr = &self->Array;\r
+ Strs* ss = &self->Chars;\r
\r
- m->m_ProgramFiles = NULL;\r
- m->m_windir = NULL;\r
- m->m_APPDATA = NULL;\r
- m->m_LOCALAPPDATA = NULL;\r
+ p = Strs_getFreeAddr( ss );\r
+ e= Set2_alloc( arr, &pp, TCHAR* ); IF(e)goto fin;\r
+ e= Strs_commit( ss, NULL ); IF(e)goto fin;\r
+ *pp = p;\r
\r
+ e=0;\r
+fin:\r
+ if ( e && pp != NULL ) e= Set2_freeLast( arr, pp, TCHAR*, e );\r
return e;\r
}\r
\r
\r
-static int CurrentWritables_askFileAccess_sub(\r
- const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* FullPath, size_t FullPath_Len );\r
-\r
-static int CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath )\r
+/*[StrArr_fillTo]*/\r
+errnum_t StrArr_fillTo( StrArr* self, int n, const TCHAR* Str )\r
{\r
- int e;\r
- size_t abs_len;\r
+ errnum_t e;\r
+ const TCHAR* p;\r
+ const TCHAR** pp;\r
+ const TCHAR** pp_over;\r
\r
- abs_len = _tcslen( FullPath );\r
- e= CurrentWritables_askFileAccess_sub( m->m_ProgramFiles, m->m_ProgramFiles_Len, FullPath, abs_len ); IF(e)goto fin;\r
- e= CurrentWritables_askFileAccess_sub( m->m_windir, m->m_windir_Len, FullPath, abs_len ); IF(e)goto fin;\r
- e= CurrentWritables_askFileAccess_sub( m->m_APPDATA, m->m_APPDATA_Len, FullPath, abs_len ); IF(e)goto fin;\r
- e= CurrentWritables_askFileAccess_sub( m->m_LOCALAPPDATA, m->m_LOCALAPPDATA_Len, FullPath, abs_len ); IF(e)goto fin;\r
+ n -= Set2_getCount( &self->Array, TCHAR* );\r
+ if ( n <= 0 ) return 0;\r
+\r
+ if ( Str == NULL ) {\r
+ p = NULL;\r
+ }\r
+ else {\r
+ e= Strs_add( &self->Chars, Str, &p ); IF(e)goto fin;\r
+ }\r
+\r
+ e= Set2_allocMulti( &self->Array, &pp, TCHAR*, n ); IF(e)goto fin;\r
+ pp_over = pp + n;\r
+ for ( ; pp < pp_over; pp++ )\r
+ *pp = p;\r
\r
e=0;\r
fin:\r
}\r
\r
\r
-static int CurrentWritables_askFileAccess_sub(\r
- const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* FullPath, size_t FullPath_Len )\r
+/*[StrArr_toEmpty]*/\r
+errnum_t StrArr_toEmpty( StrArr* self )\r
{\r
- if ( SystemPath == NULL ) return 0;\r
-\r
- IF ( _tcsncmp( SystemPath, FullPath, SystemPath_Len ) == 0 )\r
- 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
-\r
- IF ( _tcsncmp( SystemPath, FullPath, FullPath_Len ) == 0 )\r
- 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
+ errnum_t e, ee;\r
\r
- return 0;\r
+ e=0;\r
+ ee= Set2_toEmpty( &self->Array ); IF(ee&&!e)e=ee;\r
+ ee= Strs_toEmpty( &self->Chars ); IF(ee&&!e)e=ee;\r
+ return e;\r
}\r
\r
\r
\r
-/*=================================================================*/\r
-/* <<< [Error4/Error4.c] >>> */ \r
-/*=================================================================*/\r
- \r
/***********************************************************************\r
- <<< [Get_Error4_Variables] >>> \r
+ <<< [StrArr_parseCSV] >>> \r
************************************************************************/\r
-static Error4_VariablesClass gs;\r
-#ifdef _DEBUG\r
- extern Error4_VariablesClass* g_Error4_Variables = &gs;\r
-#endif\r
-\r
-Error4_VariablesClass* Get_Error4_Variables()\r
+errnum_t StrArr_parseCSV( StrArr* self, const TCHAR* CSVLine )\r
{\r
- return &gs;\r
-}\r
+ errnum_t e;\r
+ const TCHAR* p = CSVLine;\r
\r
+ e= StrArr_toEmpty( self ); IF(e)goto fin;\r
\r
- \r
-/***********************************************************************\r
- <<< (SetBreakErrorID) >>> \r
-************************************************************************/\r
+ do {\r
+ e= StrT_meltCSV( StrArr_getFreeAddr( self ), StrArr_getFreeSize( self ), &p );\r
+ if ( e == E_FEW_ARRAY ) {\r
+ e= StrArr_expandSize( self, StrArr_getFreeSize( self ) * 2 ); IF(e)goto fin;\r
+ continue;\r
+ }\r
+ IF(e)goto fin;\r
\r
-/*[DebugBreakR]*/\r
-void DebugBreakR()\r
-{\r
- 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
- DebugBreak();\r
- // 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
- // \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
+ e = StrArr_commit( self ); IF(e)goto fin;\r
+ } while ( p != NULL );\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
\r
\r
-#if ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
+ \r
+/*-------------------------------------------------------------------------*/\r
+/* <<<< ### (StrFile) Read Class implement >>>> */ \r
+/*-------------------------------------------------------------------------*/\r
\r
+errnum_t StrFile_init_sub( StrFile* self, void* Buffer, size_t BufferSize, int Flags );\r
\r
-#if ! IS_MULTI_THREAD_ERROR_CLASS\r
- dll_global_g_DebugBreakCount ErrorClass g_Error; /* \8f\89\8aú\92l\82Í\82·\82×\82Ä\83[\83\8d */\r
-#else\r
- dll_global_g_DebugBreakCount GlobalErrorClass g_GlobalError;\r
+/*[StrFile_init_fromStr]*/\r
+errnum_t StrFile_init_fromStr( StrFile* self, TCHAR* LinkStr )\r
+{\r
+ self->IsBufferInHeap = false;\r
+ #if _UNICODE\r
+ StrFile_init_sub( self, LinkStr,\r
+ (char*)StrT_chr( LinkStr, _T('\0') ) - (char*)LinkStr, STR_FILE_WCHAR );\r
+ #else\r
+ StrFile_init_sub( self, LinkStr,\r
+ (char*)StrT_chr( LinkStr, _T('\0') ) - (char*)LinkStr, 0 );\r
+ #endif\r
\r
- static errnum_t ErrorClass_initializeIfNot_Sub( ErrorClass** out_Error );\r
- static errnum_t ErrorClass_initializeIfNot_Sub2(void);\r
-#endif\r
+ return 0;\r
+}\r
\r
\r
-#define IF_ if /* Error check for in "IF" macro */\r
+/*[StrFile_initConst]*/\r
+void StrFile_initConst( StrFile* self )\r
+{\r
+ self->Buffer = NULL;\r
+}\r
\r
\r
-/*[SetBreakErrorID]*/\r
-void SetBreakErrorID( int ErrorID )\r
+/*[StrFile_init_withBuf]*/\r
+errnum_t StrFile_init_withBuf( StrFile* self, void* LinkBuffer, size_t LinkBufferSize, int Flags )\r
{\r
-#if ! IS_MULTI_THREAD_ERROR_CLASS\r
-\r
- ErrorClass* err = &g_Error;\r
- bool is_print;\r
+ self->IsBufferInHeap = false;\r
+ StrFile_init_sub( self, LinkBuffer, LinkBufferSize, Flags );\r
+ return 0;\r
+}\r
\r
- is_print = ( err->BreakErrorID != ErrorID );\r
\r
- err->BreakErrorID = ErrorID;\r
- /* printf \82Ì\92\86\82Å\94\90¶\82·\82é\83G\83\89\81[\82Å\8e~\82ß\82é\82½\82ß */\r
+/*[StrFile_init_sub]*/\r
+errnum_t StrFile_init_sub( StrFile* self, void* Buffer, size_t BufferSize, int Flags )\r
+{\r
+ unsigned char* top = (unsigned char*) Buffer;\r
\r
- if ( is_print )\r
- { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
+ if ( Flags & STR_FILE_WCHAR ) {\r
+ self->CharSize = 2;\r
+ self->Pointer = top;\r
+ }\r
+ else {\r
+ // UTF-16 BOM= { FF, FE }, UTF-8 BOM = { EF, BB, BF }\r
+ if ( BufferSize >= 2 && top[0] == 0xFF && top[1] == 0xFE ) {\r
+ self->CharSize = 2;\r
+ self->Pointer = top + 2;\r
+ if ( BufferSize % 2 == 1 ) BufferSize --;\r
+ }\r
+ else if ( BufferSize >= 3 && top[0] == 0xEF && top[1] == 0xBB && top[2] == 0xBF ) {\r
+ self->CharSize = 1;\r
+ self->Pointer = top + 3;\r
+ }\r
+ else {\r
+ self->CharSize = 1;\r
+ self->Pointer = top;\r
+ }\r
+ }\r
\r
-#else\r
+ self->Buffer = Buffer;\r
+ self->BufferSize = BufferSize;\r
+ // self->IsBufferInHeap // not init in this function\r
\r
- GlobalErrorClass* err_global = &g_GlobalError;\r
+ return 0;\r
+}\r
\r
- if ( err_global->BreakGlobalErrorID != ErrorID )\r
- { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
- err_global->BreakGlobalErrorID = ErrorID;\r
\r
-#endif\r
-}\r
+/*[StrFile_init_fromSizedStructInStream]*/\r
+errnum_t StrFile_init_fromSizedStructInStream( StrFile* self, HANDLE* Stream )\r
+{\r
+ errnum_t e;\r
\r
+ self->IsBufferInHeap = false;\r
\r
+ e= FileT_readSizedStruct_WinAPI( Stream, &self->Buffer ); IF(e)goto rollback;\r
+ self->IsBufferInHeap = true;\r
+ self->OffsetToHeapBlockFirst = - (int) sizeof(size_t);\r
+ e= StrFile_init_sub( self, (size_t*)self->Buffer + 1,\r
+ *(size_t*)self->Buffer - sizeof(size_t), STR_FILE_READ ); IF(e)goto rollback;\r
+ return 0;\r
\r
-bool OnRaisingError_Sub( const char* FilePath, int LineNum )\r
- // \96{\8aÖ\90\94\82Í\81AIF \83}\83N\83\8d\82Ì\92\86\82©\82ç\8cÄ\82Î\82ê\82Ü\82·\r
- // \95Ô\82è\92l\82Í\81A\83u\83\8c\81[\83N\82·\82é\82©\82Ç\82¤\82©\r
-{\r
-#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+rollback: StrFile_finish( self, e ); return e;\r
+}\r
\r
- ErrorClass* err = &g_Error;\r
- bool is_break;\r
\r
- /* \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
- if ( err->IsError ) {\r
- return false;\r
+/*[StrFile_finish]*/\r
+errnum_t StrFile_finish( StrFile* self, errnum_t e )\r
+{\r
+ if ( self->Buffer == NULL ) return e;\r
+ if ( self->IsBufferInHeap ) {\r
+ free( (char*) self->Buffer + self->OffsetToHeapBlockFirst );\r
+ self->IsBufferInHeap = false;\r
}\r
+ self->Buffer = NULL;\r
+ return e;\r
+}\r
\r
- /* \83G\83\89\81[\82ª\94\90¶\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
- err->ErrorID += 1;\r
- err->IsError = true;\r
- err->FilePath = FilePath;\r
- err->LineNum = LineNum;\r
\r
- #if ERR2_ENABLE_ERROR_LOG\r
- printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
- err->ErrorID, (int) err );\r
- #endif\r
+/*[StrFile_readLine]*/\r
+errnum_t StrFile_readLine( StrFile* self, TCHAR* out_Line, size_t LineSize )\r
+{\r
+ errnum_t e;\r
+ TCHAR* last_of_line;\r
\r
- is_break = ( err->ErrorID == err->BreakErrorID );\r
+ if ( self->CharSize == 1 ) {\r
+ char* ptr = (char*) self->Pointer;\r
+ char* first = ptr;\r
+ char* over = (char*) self->Buffer + self->BufferSize;\r
+ size_t size;\r
\r
- if ( is_break ) {\r
- printf( "Break in (%d) %s\n", LineNum, FilePath );\r
- }\r
- return ( err->ErrorID == err->BreakErrorID );\r
+ if ( ptr >= over ) goto err_nn;\r
\r
-#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+ for (;;) {\r
+ if ( ptr >= over ) { self->Pointer = (void*)0xFFFFFFFF; break; }\r
+ if ( *ptr == '\n' ) { ptr++; self->Pointer = ptr; break; }\r
+ ptr ++;\r
+ }\r
+ size = ptr - first;\r
\r
- errnum_t e;\r
- bool is_break = false;\r
- ErrorClass* err;\r
+ #if _UNICODE\r
+ if ( ptr < over ) {\r
+ char ch = *ptr;\r
\r
- e= ErrorClass_initializeIfNot_Sub( &err ); IF_(e){goto fin;}\r
+ *ptr = '\0';\r
+ e= stprintf_r( out_Line, LineSize, _T("%S"), first );\r
+ *ptr = ch;\r
+ IF(e)goto fin;\r
+ }\r
+ else { // if cannot access *ptr\r
+ char* line;\r
\r
+ line = malloc( size + sizeof(char) );\r
+ line[ size ] = '\0';\r
+ memcpy( line, first, size );\r
\r
- /* \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
- if ( err->IsError ) {\r
- return false;\r
- }\r
+ e= stprintf_r( out_Line, LineSize, _T("%S"), line );\r
+ free( line );\r
+ IF(e)goto fin;\r
+ }\r
+ last_of_line = StrT_chr( out_Line, _T('\0') );\r
+ #else\r
+ if ( size > LineSize - sizeof(char) ) goto err_fa;\r
\r
- /* \83G\83\89\81[\82ª\94\90¶\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
+ last_of_line = out_Line + size;\r
+ *last_of_line = '\0';\r
+ memcpy( out_Line, first, size );\r
+ #endif\r
+ }\r
else {\r
- GlobalErrorClass* err_global = &g_GlobalError;\r
+ wchar_t* ptr = (wchar_t*) self->Pointer;\r
+ wchar_t* first = ptr;\r
+ wchar_t* over = (wchar_t*)( (char*) self->Buffer + self->BufferSize );\r
+ size_t size;\r
\r
- EnterCriticalSection( &err_global->CriticalSection );\r
+ ASSERT_D( self->CharSize == 2, goto err );\r
\r
+ if ( ptr >= over ) goto err_nn;\r
\r
- err_global->ErrorThreadCount += 1;\r
- err_global->RaisedGlobalErrorID += 1;\r
- err->GlobalErrorID = err_global->RaisedGlobalErrorID;\r
+ for (;;) {\r
+ if ( ptr >= over ) { self->Pointer = (void*)0xFFFFFFFF; break; }\r
+ if ( *ptr == L'\n' ) { ptr++; self->Pointer = ptr; break; }\r
+ ptr ++;\r
+ }\r
+ size = (char*) ptr - (char*) first;\r
\r
- err->ErrorID += 1;\r
- err->IsError = true;\r
- err->FilePath = FilePath;\r
- err->LineNum = LineNum;\r
+ #if _UNICODE\r
+ IF( size > LineSize - sizeof(TCHAR) ) goto err_fa;\r
\r
- is_break = ( err->ErrorID == err->BreakErrorID ) ||\r
- ( err->GlobalErrorID == err_global->BreakGlobalErrorID );\r
+ last_of_line = (TCHAR*)( (char*) out_Line + size );\r
+ *last_of_line = _T('\0');\r
+ memcpy( out_Line, first, size );\r
+ #else\r
+ if ( ptr < over ) {\r
+ wchar_t ch = *ptr;\r
+\r
+ *ptr = L'\0';\r
+ e= stprintf_r( out_Line, LineSize, _T("%S"), first );\r
+ *ptr = ch;\r
+ IF(e)goto fin;\r
+ last_of_line = StrT_chr( out_Line, _T('\0') );\r
+ }\r
+ else { // if cannot access *ptr\r
+ wchar_t last_str[2];\r
\r
+ ptr --;\r
\r
- /* \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
- /* \8fã\8bL\82Ì if ( err->IsError ) \82Å\81A\82·\82®\96ß\82é\82½\82ß */\r
+ last_str[0] = *ptr;\r
+ last_str[1] = L'\0';\r
\r
+ *ptr = L'\0';\r
+ e= stprintf_r( out_Line, LineSize, "%S", first );\r
+ *ptr = last_str[0];\r
+ IF(e)goto fin;\r
\r
- #if ERR2_ENABLE_ERROR_LOG\r
- printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
- err->GlobalErrorID, (int) err );\r
+ last_of_line = StrT_chr( out_Line, _T('\0') );\r
+ LineSize -= (char*) last_of_line - (char*) out_Line;\r
+ e= stprintf_r( last_of_line, LineSize, "%S", last_str ); IF(e)goto fin;\r
+ last_of_line = StrT_chr( last_of_line, _T('\0') );\r
+ }\r
#endif\r
+ }\r
\r
-\r
- if ( err->ErrorID == 1 ) {\r
- FinalizerClass_initConst( &err->Finalizer, err, ErrorClass_finalize );\r
- e= AddThreadLocalFinalizer( &err->Finalizer );\r
- }\r
- else {\r
- e = 0;\r
+ // change from CR+LF to LF (text mode)\r
+ if ( last_of_line >= out_Line + 2 ) {\r
+ if ( *(last_of_line - 2) == _T('\r') && *(last_of_line - 1) == _T('\n') ) {\r
+ *(last_of_line - 2) = _T('\n'); *(last_of_line - 1) = _T('\0');\r
}\r
- LeaveCriticalSection( &err_global->CriticalSection );\r
- IF(e){goto fin;}\r
}\r
\r
e=0;\r
fin:\r
- if ( is_break ) {\r
- printf( "Break in (%d) %s\n", LineNum, FilePath );\r
- }\r
- return is_break;\r
+ return e;\r
\r
-#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+err_fa: e = E_FEW_ARRAY; goto fin;\r
+err_nn: self->Pointer = (void*)0xFFFFFFFF; e=0; goto fin; // not [e = E_NO_NEXT], because ferror()==0\r
+#if _DEBUG\r
+err: e = E_OTHERS; goto fin;\r
+#endif\r
}\r
\r
\r
-//[ClearError]\r
-void ClearError()\r
-{\r
-#if ! IS_MULTI_THREAD_ERROR_CLASS\r
-\r
- ErrorClass* err = &g_Error;\r
-\r
- #if ERR2_ENABLE_ERROR_LOG\r
- if ( err->IsError ) {\r
- printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
- err->ErrorID, (int) err );\r
- }\r
- #endif\r
+ \r
+/*-------------------------------------------------------------------------*/\r
+/* <<<< ### (StrFile) Write Class implement >>>> */ \r
+/*-------------------------------------------------------------------------*/\r
\r
- err->IsError = false;\r
+errnum_t StrFile_expandIfOver_sub( StrFile* self, size_t DataSize );\r
\r
-#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
\r
- errnum_t e;\r
- ErrorClass* err;\r
+//[StrFile_init_toHeap]\r
+errnum_t StrFile_init_toHeap( StrFile* self, int Flags )\r
+{\r
+ void* mem;\r
+ enum { start_size = 480 };\r
\r
- e= ErrorClass_initializeIfNot_Sub( &err );\r
- if ( e == 0 ) {\r
- #if ERR2_ENABLE_ERROR_LOG\r
- if ( err->IsError )\r
- printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
- err->GlobalErrorID, (int) err );\r
- #endif\r
+ mem = malloc( start_size ); IF ( mem == NULL ) return E_FEW_MEMORY;\r
\r
- if ( err->IsError ) {\r
- GlobalErrorClass* err_global = &g_GlobalError;\r
+ self->Buffer = (char*) mem + sizeof(size_t);\r
+ self->BufferSize = start_size - sizeof(size_t);\r
+ self->IsBufferInHeap = true;\r
+ self->IsTextMode = ( (Flags & STR_FILE_BINARY) == 0 );\r
+ self->OffsetToHeapBlockFirst = - (int) sizeof(size_t);\r
+ if ( Flags & STR_FILE_WCHAR ) {\r
+ wchar_t* wp = (wchar_t*) self->Buffer;\r
\r
- EnterCriticalSection( &err_global->CriticalSection );\r
- err_global->ErrorThreadCount -= 1;\r
- LeaveCriticalSection( &err_global->CriticalSection );\r
+ wp[0] = 0xFEFF;\r
+ wp[1] = L'\0';\r
\r
- err->IsError = false;\r
- }\r
+ self->CharSize = 2;\r
+ self->Pointer = (char*) self->Buffer + sizeof(wchar_t);\r
}\r
else {\r
- #if ERR2_ENABLE_ERROR_LOG\r
- printf( "<ERROR_LOG msg=\"clear_miss\"/>\n" );\r
- #endif\r
- }\r
+ char* ap = (char*) self->Buffer;\r
\r
-#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+ ap[0] = '\0';\r
+\r
+ self->CharSize = 1;\r
+ self->Pointer = (char*) self->Buffer;\r
+ }\r
+ return 0;\r
}\r
\r
\r
-//[IfErrThenBreak]\r
-void IfErrThenBreak()\r
+//[StrFile_write_s]\r
+errnum_t StrFile_write_s( StrFile* self, const TCHAR* Text )\r
{\r
-#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+ errnum_t e;\r
+ const char* pos1;\r
+ const char* pos2;\r
+ #if _UNICODE\r
+ char* str = NULL;\r
+ size_t str_size;\r
+ #endif\r
\r
- ErrorClass* err = &g_Error;\r
+ #if _UNICODE\r
+ str_size = (_tcslen( Text ) + 1) * sizeof(wchar_t); // max is for all 2byte charactors\r
+ str = malloc( str_size ); IF( str == NULL )goto err_fm;\r
+ sprintf_s( str, str_size, "%S", Text ); // conver to multi byte char\r
+ pos1 = str;\r
+ #else\r
+ pos1 = Text;\r
+ #endif\r
\r
- if ( err->IsError &&\r
- ( err->ErrorID != err->BreakErrorID || err->BreakErrorID == 0 )\r
- ) {\r
- printf( "in IfErrThenBreak\n" );\r
- DebugBreakR();\r
+ if ( self->IsTextMode ) {\r
+ for (;;) {\r
+ pos2 = strchr( pos1, '\n' );\r
+ if ( pos2 == NULL ) break;\r
\r
- // \83E\83H\83b\83`\82Å\81Aerr->ErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
- // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82\82¾\82³\82¢\81B\r
- // \83G\83\89\81[\82ª\94\90¶\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
- // \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
- // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
- #if ERR2_ENABLE_ERROR_LOG\r
- printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
- err->ErrorID, err->BreakErrorID );\r
- #endif\r
+ // write 1 line and change from \n to CR LF\r
+ e= StrFile_writeBinary( self, pos1, (char*) pos2 - (char*) pos1 + 2 * sizeof(char) );\r
+ IF(e)goto fin;\r
+ ( (char*) self->Pointer )[-2] = '\r';\r
+ ( (char*) self->Pointer )[-1] = '\n';\r
\r
- {\r
- char str[512];\r
- sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
- err->FilePath, err->LineNum );\r
- OutputDebugStringA( str );\r
+ pos1 = pos2 + 1;\r
}\r
}\r
- ClearError();\r
\r
-#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+ // if "IsTextMode", write last line\r
+ // if not "IsTextMode", write whole text\r
+ pos2 = strchr( pos1, '\0' );\r
+ e= StrFile_writeBinary( self, pos1, (char*) pos2 - (char*) pos1 + sizeof(char) );\r
+ IF(e)goto fin;\r
+ self->Pointer = (char*) self->Pointer - sizeof(char);\r
\r
- errnum_t e;\r
- GlobalErrorClass* err_global = &g_GlobalError;\r
- ErrorClass* err;\r
\r
- e= ErrorClass_initializeIfNot_Sub( &err );\r
- if ( e ) { DebugBreakR(); ClearError(); return; } /* \93à\95\94\83G\83\89\81[ */\r
+ e=0;\r
+fin:\r
+ #if _UNICODE\r
+ if ( str != NULL ) free( str );\r
+ #endif\r
+ return e;\r
\r
- if ( err_global->ErrorThreadCount != 0 &&\r
- ( err->GlobalErrorID != err_global->BreakGlobalErrorID || err_global->BreakGlobalErrorID == 0 )\r
- ) {\r
- printf( "in IfErrThenBreak\n" );\r
- DebugBreakR();\r
+#if _UNICODE\r
+err_fm: e = E_FEW_MEMORY; goto fin;\r
+#endif\r
+}\r
\r
- // \83E\83H\83b\83`\82Å\81Aerr->GlobalErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
- // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82\82¾\82³\82¢\81B\r
- // \83G\83\89\81[\82ª\94\90¶\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
- // \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
- // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
- #if ERR2_ENABLE_ERROR_LOG\r
- printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
- err->ErrorID, err->BreakErrorID );\r
- #endif\r
\r
- {\r
- char str[512];\r
- sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
- err->FilePath, err->LineNum );\r
- OutputDebugStringA( str );\r
+//[StrFile_write_w]\r
+errnum_t StrFile_write_w( StrFile* self, const TCHAR* Text )\r
+{\r
+ errnum_t e;\r
+ const wchar_t* pos1;\r
+ const wchar_t* pos2;\r
+ #if ! _UNICODE\r
+ wchar_t* str = NULL;\r
+ size_t str_size;\r
+ #endif\r
+\r
+ #if _UNICODE\r
+ pos1 = Text;\r
+ #else\r
+ str_size = (_tcslen( Text ) + 1) * sizeof(wchar_t); // max is for all 1byte char to wchar_t\r
+ str = malloc( str_size ); IF( str == NULL )goto err_fm;\r
+ swprintf_s( str, str_size / sizeof(wchar_t), L"%S", Text ); // conver to wide byte char\r
+ pos1 = str;\r
+ #endif\r
+\r
+ if ( self->IsTextMode ) {\r
+ for (;;) {\r
+ pos2 = wcschr( pos1, L'\n' );\r
+ if ( pos2 == NULL ) break;\r
+\r
+ // write 1 line and change from \n to CR LF\r
+ e= StrFile_writeBinary( self, pos1, (char*) pos2 - (char*) pos1 + 2 * sizeof(wchar_t) );\r
+ IF(e)goto fin;\r
+ ( (wchar_t*) self->Pointer )[-2] = L'\r';\r
+ ( (wchar_t*) self->Pointer )[-1] = L'\n';\r
+\r
+ pos1 = pos2 + 1;\r
}\r
}\r
- ClearError();\r
\r
-#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+ // if "IsTextMode", write last line\r
+ // if not "IsTextMode", write whole text\r
+ pos2 = wcschr( pos1, L'\0' );\r
+ e= StrFile_writeBinary( self, pos1, (char*) pos2 - (char*) pos1 + sizeof(wchar_t) );\r
+ IF(e)goto fin;\r
+ self->Pointer = (char*) self->Pointer - sizeof(wchar_t);\r
+\r
+ e=0;\r
+fin:\r
+ #if ! _UNICODE\r
+ if ( str != NULL ) free( str );\r
+ #endif\r
+ return e;\r
+\r
+#if ! _UNICODE\r
+err_fm: e = E_FEW_MEMORY; goto fin;\r
+#endif\r
}\r
\r
\r
-//[PushErr]\r
-void PushErr( ErrStackAreaClass* ErrStackArea )\r
+//[StrFile_write]\r
+errnum_t StrFile_write( StrFile* self, const TCHAR* Text )\r
{\r
-#if ! IS_MULTI_THREAD_ERROR_CLASS\r
-\r
- ErrorClass* err = &g_Error;\r
+ if ( self->CharSize == 1 ) return StrFile_write_s( self, Text );\r
+ else return StrFile_write_w( self, Text );\r
+}\r
\r
- ErrStackArea->ErrorID = err->ErrorID;\r
- ErrStackArea->IsError = err->IsError;\r
- err->IsError = false;\r
\r
-#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+//[StrFile_expandIfOver]\r
+errnum_t StrFile_expandIfOver( StrFile* self, size_t DataSize )\r
+{\r
+ if ( (char*) self->Pointer + DataSize <= (char*) self->Buffer + self->BufferSize ) return 0;\r
+ else return StrFile_expandIfOver_sub( self, DataSize );\r
+}\r
\r
- errnum_t e;\r
- ErrorClass* err;\r
\r
- e= ErrorClass_initializeIfNot_Sub( &err );\r
- if ( e == 0 ) {\r
- ErrStackArea->ErrorID = err->ErrorID;\r
- ErrStackArea->IsError = err->IsError;\r
- err->IsError = false;\r
- }\r
+//[StrFile_writeBinary]\r
+errnum_t StrFile_writeBinary( StrFile* self, const void* Data, size_t DataSize )\r
+{\r
+ errnum_t e;\r
\r
-#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+ e= StrFile_expandIfOver( self, DataSize ); if(e)return e;\r
+ memcpy( self->Pointer, Data, DataSize );\r
+ self->Pointer = (char*) self->Pointer + DataSize;\r
+ return 0;\r
}\r
\r
-//[PopErr]\r
-void PopErr( ErrStackAreaClass* ErrStackArea )\r
-{\r
-#if ! IS_MULTI_THREAD_ERROR_CLASS\r
\r
- ErrorClass* err = &g_Error;\r
+//[StrFile_expandIfOver_sub]\r
+errnum_t StrFile_expandIfOver_sub( StrFile* self, size_t DataSize )\r
+{\r
+ errnum_t e;\r
+ void* mem;\r
+ size_t old_size = (char*) self->Pointer - (char*) self->Buffer;\r
+ size_t new_size = ( self->BufferSize + sizeof(size_t) ) * 2 + DataSize;\r
\r
- if ( ErrStackArea->IsError )\r
- { err->IsError = true; }\r
+ IF( ! self->IsBufferInHeap ) {goto err;}\r
+ // Writing must expand self->Buffer from heap when self->Buffer is small\r
\r
-#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+ mem = realloc( (char*) self->Buffer + self->OffsetToHeapBlockFirst, new_size );\r
+ IF(mem == NULL) goto err_fa;\r
\r
- errnum_t e;\r
- ErrorClass* err;\r
+ self->Buffer = (char*) mem + sizeof(size_t);\r
+ self->BufferSize = new_size - sizeof(size_t);\r
+ self->OffsetToHeapBlockFirst = - (int) sizeof(size_t);\r
+ self->Pointer = (char*) self->Buffer + old_size;\r
\r
- e= ErrorClass_initializeIfNot_Sub( &err );\r
- if ( e == 0 ) {\r
- if ( ErrStackArea->IsError )\r
- { err->IsError = true; }\r
- }\r
+ e=0;\r
+fin:\r
+ return e;\r
\r
-#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+err_fa: e = E_FEW_ARRAY; goto fin;\r
+err: e = E_OTHERS; goto fin;\r
}\r
\r
\r
- \r
-/*[SetBreakErrorID:2]*/\r
-#undef IF_\r
+//[StrFile_peekWrittenStringW]\r
+errnum_t StrFile_peekWrittenStringW( StrFile* self, wchar_t** out_String )\r
+{\r
+ errnum_t e;\r
\r
+ ASSERT_R( self->CharSize == 2, e=E_OTHERS; goto fin );\r
+ *out_String = (wchar_t*)( (char*) self->Buffer + sizeof(wchar_t) );\r
\r
-#endif // ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
\r
-//[MergeError]\r
-errnum_t MergeError( errnum_t e, errnum_t ee )\r
+//[StrFile_peekWrittenStringA]\r
+errnum_t StrFile_peekWrittenStringA( StrFile* self, char** out_String )\r
{\r
- if ( e == 0 ) { return ee; }\r
- else { /* ErrorLog_add( ee ); */ return e; }\r
+ errnum_t e;\r
+\r
+ ASSERT_R( self->CharSize == 1, e=E_OTHERS; goto fin );\r
+ *out_String = self->Buffer;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [g_Error4_String] >>> \r
-************************************************************************/\r
-TCHAR g_Error4_String[4096];\r
+//[StrFile_pickupSizedStruct]\r
+errnum_t StrFile_pickupSizedStruct( StrFile* self, SizedStruct** out_Struct )\r
+{\r
+ *out_Struct = (SizedStruct*)( (char*) self->Buffer - sizeof(size_t) );\r
+ *( (size_t*) self->Buffer - 1 ) = (char*) self->Pointer - (char*) self->Buffer + sizeof(size_t);\r
+ self->IsBufferInHeap = false;\r
+ return 0;\r
+}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Error4_printf] >>> \r
-************************************************************************/\r
-void Error4_printf( const TCHAR* format, ... )\r
+//[StrFile_restoreSizedStruct]\r
+errnum_t StrFile_restoreSizedStruct( StrFile* self, SizedStruct* Struct, errnum_t e )\r
{\r
- va_list va;\r
- va_start( va, format );\r
- vstprintf_r( g_Error4_String, sizeof(g_Error4_String), format, va );\r
- va_end( va );\r
+ ASSERT_R( ! self->IsBufferInHeap, goto err );\r
+\r
+ self->Buffer = (char*) Struct + sizeof(size_t);\r
+ self->IsBufferInHeap = true;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Error4_getErrStr] >>> \r
-************************************************************************/\r
-void Error4_getErrStr( int ErrNum, TCHAR* out_ErrStr, size_t ErrStrSize )\r
+//[StrFile_moveSizedStructToStream]\r
+errnum_t StrFile_moveSizedStructToStream( StrFile* self, HANDLE Stream )\r
{\r
- switch ( ErrNum ) {\r
+ errnum_t e;\r
+ SizedStruct* data = NULL;\r
\r
- case 0:\r
- stprintf_r( out_ErrStr, ErrStrSize, _T("no error") );\r
- break;\r
+ e= StrFile_pickupSizedStruct( self, &data ); IF(e)goto fin;\r
+ e= FileT_writeSizedStruct_WinAPI( Stream, data ); IF(e)goto fin;\r
+ e=0;\r
+fin:\r
+ if ( data != NULL ) { e= StrFile_restoreSizedStruct( self, data, e ); }\r
+ return e;\r
+}\r
\r
- case E_FEW_ARRAY:\r
- stprintf_r( out_ErrStr, ErrStrSize,\r
- _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
- break;\r
\r
- case E_FEW_MEMORY:\r
- stprintf_r( out_ErrStr, ErrStrSize,\r
- _T("<ERROR msg=\"\83q\81[\83v\81E\83\81\83\82\83\8a\81[\82ª\95s\91«\82µ\82Ü\82µ\82½\81B\"/>") );\r
- break;\r
+//[StrFile_setPointer]\r
+errnum_t StrFile_setPointer( StrFile* self, int OffsetOfPointer )\r
+{\r
+ if ( self->CharSize == 2 ) OffsetOfPointer += sizeof(wchar_t);\r
+ IF( OffsetOfPointer < 0 || OffsetOfPointer >= (int) self->BufferSize ) return E_INVALID_VALUE;\r
+ self->Pointer = (char*) self->Buffer + OffsetOfPointer;\r
+ return 0;\r
+}\r
\r
- #ifndef __linux__\r
- case E_GET_LAST_ERROR: {\r
- DWORD err_win;\r
- TCHAR* str_pointer;\r
\r
- err_win = gs.WindowsLastError;\r
- if ( err_win == 0 ) { err_win = GetLastError(); }\r
+/*[StrFile_getPointer]*/\r
+errnum_t StrFile_getPointer( StrFile* self, int* out_OffsetOfPointer )\r
+{\r
+ if ( (uintptr_t) self->Pointer == 0xFFFFFFFF )\r
+ { *out_OffsetOfPointer = self->BufferSize; }\r
+ else\r
+ { *out_OffsetOfPointer = (char*) self->Pointer - (char*) self->Buffer; }\r
+ return 0;\r
+}\r
\r
- stprintf_part_r( out_ErrStr, ErrStrSize, out_ErrStr, &str_pointer,\r
- _T("<ERROR GetLastError=\"0x%08X\" GetLastErrorStr=\""), err_win );\r
- FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,\r
- NULL, err_win, LANG_USER_DEFAULT,\r
- str_pointer, (TCHAR*)( (char*)out_ErrStr + ErrStrSize ) - str_pointer, NULL );\r
- str_pointer = _tcschr( str_pointer, _T('\0') );\r
- if ( *( str_pointer - 2 ) == _T('\r') && *( str_pointer - 1 ) == _T('\n') )\r
- str_pointer -= 2;\r
- stcpy_part_r( out_ErrStr, ErrStrSize, str_pointer, NULL, _T("\"/>"), NULL );\r
- break;\r
- }\r
- #endif\r
\r
- default:\r
- if ( g_Error4_String[0] != '\0' )\r
- stprintf_r( out_ErrStr, ErrStrSize, _T("%s"), g_Error4_String );\r
- else\r
- stprintf_r( out_ErrStr, ErrStrSize, _T("<ERROR errnum=\"%d\"/>"), ErrNum );\r
- break;\r
- }\r
+//[StrFile_isAtEndOfStream]\r
+bool StrFile_isAtEndOfStream( StrFile* self )\r
+{\r
+ return self->Pointer == (void*)0xFFFFFFFF;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [SaveWindowsLastError] >>> \r
-************************************************************************/\r
-errnum_t SaveWindowsLastError()\r
+//[StrFile_isInited]\r
+errnum_t StrFile_isInited( StrFile* self )\r
{\r
- gs.WindowsLastError = GetLastError();\r
- return E_GET_LAST_ERROR;\r
+ return self->Buffer != NULL;\r
}\r
\r
\r
\r
-/*=================================================================*/\r
-/* <<< [CRT_plus_2/CRT_plus_2.c] >>> */ \r
-/*=================================================================*/\r
- \r
-/**************************************************************************\r
- <<< [Interface] >>> \r
-***************************************************************************/\r
+/***********************************************************************\r
+ <<< (SearchStringByBM_Class) >>> \r
+************************************************************************/\r
+errnum_t SearchStringByBM_Class_allocateSkipArray_Sub( SearchStringByBM_Class* self );\r
\r
-/*[DefaultFunction]*/\r
-errnum_t DefaultFunction( void* self )\r
+\r
+/*[SearchStringByBM_Class_initConst]*/\r
+void SearchStringByBM_Class_initConst( SearchStringByBM_Class* self )\r
{\r
- UNREFERENCED_VARIABLE( self );\r
- return 0;\r
+ self->SkipArray = NULL;\r
}\r
\r
-/*[DefaultFunction_NotImplementYet]*/\r
-errnum_t DefaultFunction_NotImplementYet( void* self )\r
+\r
+/*[SearchStringByBM_Class_initialize]*/\r
+errnum_t SearchStringByBM_Class_initialize( SearchStringByBM_Class* self,\r
+ const TCHAR* TextString, const TCHAR* Keyword )\r
{\r
- UNREFERENCED_VARIABLE( self );\r
- return E_NOT_IMPLEMENT_YET;\r
+ return SearchStringByBM_Class_initializeFromPart( self,\r
+ TextString, _tcslen( TextString ), Keyword );\r
}\r
\r
-/*[DefaultFunction_Finalize]*/\r
-errnum_t DefaultFunction_Finalize( void* self, errnum_t e )\r
+\r
+/*[SearchStringByBM_Class_initializeFromPart]*/\r
+errnum_t SearchStringByBM_Class_initializeFromPart( SearchStringByBM_Class* self,\r
+ const TCHAR* TextString, size_t TextString_Length, const TCHAR* Keyword )\r
{\r
- UNREFERENCED_VARIABLE( self );\r
- return e;\r
+ self->TextString = TextString;\r
+ self->TextStringLength = TextString_Length;\r
+ self->Keyword = Keyword;\r
+\r
+ /* \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
+ return SearchStringByBM_Class_allocateSkipArray_Sub( self );\r
}\r
\r
-/*[VTableDefine_overwrite]*/\r
-errnum_t VTableDefine_overwrite( VTableDefine* aVTable, size_t aVTable_ByteSize, int iMethod, void* Func )\r
-{\r
- VTableDefine* p = aVTable;\r
- VTableDefine* p_over = (VTableDefine*)( (char*)aVTable + aVTable_ByteSize );\r
\r
- for ( ; p < p_over; p++ ) {\r
- if ( p->m_IMethod == iMethod ) {\r
- p->m_method = Func;\r
- return 0;\r
- }\r
+/*[SearchStringByBM_Class_finalize]*/\r
+errnum_t SearchStringByBM_Class_finalize( SearchStringByBM_Class* self, errnum_t e )\r
+{\r
+ if ( self->SkipArray != NULL ) {\r
+ free( self->SkipArray );\r
+ self->SkipArray = NULL;\r
}\r
- return E_NOT_FOUND_SYMBOL;\r
+\r
+ return e;\r
}\r
\r
\r
- \r
-/*=================================================================*/\r
-/* <<< [StrT/StrT.c] >>> */ \r
-/*=================================================================*/\r
- \r
/***********************************************************************\r
- <<< [StrT_cpy] >>> \r
-- _tcscpy is raising exception, if E_FEW_ARRAY\r
+ <<< [SearchStringByBM_Class_getSkipCount_Sub] >>> \r
+ - Boyer-Moore\96@\82Ì skip \8aÖ\90\94\r
************************************************************************/\r
-errnum_t StrT_cpy( TCHAR* Dst, size_t DstSize, const TCHAR* Src )\r
+inline int SearchStringByBM_Class_getSkipCount_Sub(\r
+ TCHAR TextCharacter, int KeywordLastIndex,\r
+ int* SkipArray, int SkipArray_MinCharacter, int SkipArray_MaxCharacter )\r
{\r
- size_t size;\r
-\r
- size = ( _tcslen( Src ) + 1 ) * sizeof(TCHAR);\r
- if ( size <= DstSize ) {\r
- memcpy( Dst, Src, size );\r
- return 0;\r
+ if (\r
+ TextCharacter < SkipArray_MinCharacter ||\r
+ TextCharacter > SkipArray_MaxCharacter ) {\r
+ return KeywordLastIndex + 1;\r
}\r
else {\r
- memcpy( Dst, Src, DstSize - sizeof(TCHAR) );\r
- *(TCHAR*)( (char*) Dst + DstSize ) = _T('\0');\r
- return E_FEW_ARRAY;\r
+ return SkipArray[ TextCharacter - SkipArray_MinCharacter ];\r
}\r
}\r
\r
- \r
+\r
/***********************************************************************\r
- <<< [MallocAndCopyString] >>> \r
+ <<< [SearchStringByBM_Class_search] >>> \r
+ - Boyer-Moore\96@\r
+ - \8fî\95ñ\8c\9f\8dõ\83A\83\8b\83S\83\8a\83Y\83\80 p106 \82Ì C\8c¾\8cê\94Å\r
************************************************************************/\r
-errnum_t MallocAndCopyString( const TCHAR** out_NewString, const TCHAR* SourceString )\r
+errnum_t SearchStringByBM_Class_search( SearchStringByBM_Class* self, int* out_KeywordIndex )\r
{\r
- TCHAR* str;\r
- size_t size = ( _tcslen( SourceString ) + 1 ) * sizeof(TCHAR);\r
+ const TCHAR* test_string = self->TextString;\r
+ const TCHAR* keyword = self->Keyword;\r
+ int text_string_length = self->TextStringLength; /* m */\r
+ int keyword_last_index = self->KeywordLastIndex; /* n - 1 */\r
+ int keyword_last_position = self->KeywordLastPosition; /* pos - 1 */\r
+ int skip_count;\r
+ int* skip_array = self->SkipArray;\r
+ TCHAR min_character = self->SkipArray_MinCharacter;\r
+ TCHAR max_character = self->SkipArray_MaxCharacter;\r
\r
- ASSERT_D( *out_NewString == NULL, __noop() );\r
+ *out_KeywordIndex = SearchString_NotFound;\r
\r
- str = (TCHAR*) malloc( size );\r
- if ( str == NULL ) { return E_FEW_MEMORY; }\r
\r
- memcpy( str, SourceString, size );\r
+ while ( keyword_last_position < text_string_length ) {\r
\r
- *out_NewString = str;\r
- return 0;\r
-}\r
+ /* \8e\9f\82Ì\8fÆ\8d\87\88Ê\92u\82Ö (1) */\r
+ skip_count = SearchStringByBM_Class_getSkipCount_Sub(\r
+ test_string[ keyword_last_position ],\r
+ keyword_last_index, skip_array, min_character, max_character );\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [MallocAndCopyString_char] >>> \r
-************************************************************************/\r
-#ifdef _UNICODE\r
-errnum_t MallocAndCopyString_char( const TCHAR** out_NewString, const char* SourceString )\r
-{\r
- TCHAR* str;\r
- size_t size = ( strlen( SourceString ) + 1 ) * sizeof(TCHAR);\r
- int r;\r
+ /* \96\96\94ö\82Ì\8fÆ\8d\87\82ª\90¬\8c÷\82µ\82½\82ç */\r
+ if ( test_string[ keyword_last_position ] == keyword[ keyword_last_index ] ) {\r
\r
- str = (TCHAR*) malloc( size );\r
- if ( str == NULL ) { return E_FEW_MEMORY; }\r
+ /* \96\96\94ö\82©\82ç\8fÆ\8d\87\82·\82é */\r
+ int text_string_index = keyword_last_position - 1; /* k - 1 */\r
+ int keyword_index = keyword_last_index - 1; /* j - 1 */\r
\r
- r = MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED, SourceString, -1, str, size / sizeof(TCHAR) );\r
- IF ( r == 0 ) {\r
- free( str );\r
- return E_GET_LAST_ERROR;\r
+ for (;;) {\r
+ /* \83L\81[\83\8f\81[\83h\91S\91Ì\82Ì\8fÆ\8d\87\82É\90¬\8c÷\82µ\82½\82ç */\r
+ if ( keyword_index < 0 ) {\r
+ *out_KeywordIndex = text_string_index + 1;\r
+ self->KeywordLastPosition = keyword_last_position + skip_count;\r
+ goto fin;\r
+ }\r
+\r
+ /* \8fÆ\8d\87\82ª\8e¸\94s\82µ\82½\82ç */\r
+ if ( test_string[ text_string_index ] != keyword[ keyword_index ] ) {\r
+ break;\r
+ }\r
+\r
+ /* \82P\82Â\91O\82Ì\95¶\8e\9a\82Ö */\r
+ text_string_index -= 1;\r
+ keyword_index -= 1;\r
+ }\r
+ }\r
+ /* \8e\9f\82Ì\8fÆ\8d\87\88Ê\92u\82Ö (2) */\r
+ keyword_last_position += skip_count;\r
}\r
- *out_NewString = str;\r
+\r
+fin:\r
return 0;\r
}\r
-#endif\r
\r
\r
- \r
/***********************************************************************\r
- <<< [MallocAndCopyStringByLength] >>> \r
+ <<< [SearchStringByBM_Class_allocateSkipArray_Sub] >>> \r
+ - Boyer-Moore\96@\82Ì skip \8aÖ\90\94\82ð\8dì\90¬\82·\82é\8aÖ\90\94\r
+ - \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
************************************************************************/\r
-errnum_t MallocAndCopyStringByLength( const TCHAR** out_NewString, const TCHAR* SourceString,\r
- unsigned CountOfCharacter )\r
-{\r
- TCHAR* str;\r
- size_t size = ( CountOfCharacter + 1 ) * sizeof(TCHAR);\r
+errnum_t SearchStringByBM_Class_allocateSkipArray_Sub( SearchStringByBM_Class* self )\r
+{\r
+ const TCHAR* keyword = self->Keyword;\r
+ const TCHAR* p; /* Pointer to "keyword" */\r
+ TCHAR c; /* Character in "keyword" */\r
+ TCHAR min_character;\r
+ TCHAR max_character;\r
+ int keyword_length;\r
+ const TCHAR* keyword_last_pointer;\r
+ int* skip_array = NULL;\r
+ errnum_t e;\r
+\r
+\r
+ /* Set "self->SkipArray_MinCharacter", "self->SkipArray_MaxCharacter" */\r
+ c = *keyword;\r
+ IF ( c == _T('\0') ) { e=E_OTHERS; goto fin; }\r
+ min_character = c;\r
+ max_character = c;\r
+ p = keyword + 1;\r
+ for (;;) {\r
+ c = *p;\r
+ if ( c == _T('\0') ) { break; }\r
+\r
+ if ( c < min_character ) { min_character = c; }\r
+ if ( c > max_character ) { max_character = c; }\r
+\r
+ p += 1;\r
+ }\r
+ self->SkipArray_MinCharacter = min_character;\r
+ self->SkipArray_MaxCharacter = max_character;\r
+\r
\r
- ASSERT_D( *out_NewString == NULL, __noop() );\r
+ /* Set ... */\r
+ keyword_length = p - keyword;\r
+ self->KeywordLastIndex = keyword_length - 1;\r
+ self->KeywordLastPosition = keyword_length - 1;\r
\r
- str = (TCHAR*) malloc( size );\r
- if ( str == NULL ) { return E_FEW_MEMORY; }\r
\r
- memcpy( str, SourceString, size - sizeof(TCHAR) );\r
- str[ CountOfCharacter ] = _T('\0');\r
+ /* Set "self->SkipArray" */\r
+ skip_array = malloc( ( max_character - min_character + 1 ) * sizeof(int) );\r
+ IF ( skip_array == NULL ) { e=E_FEW_ARRAY; goto fin; }\r
\r
- *out_NewString = str;\r
- return 0;\r
-}\r
+ for ( c = min_character; c <= max_character; c += 1 ) {\r
+ /* \83L\81[\83\8f\81[\83h\82É\8eg\82í\82ê\82Ä\82¢\82È\82¢\95¶\8e\9a\82É\82Â\82¢\82Ä */\r
+ skip_array[ c - min_character ] = keyword_length;\r
+ }\r
\r
+ keyword_last_pointer = &keyword[ keyword_length - 1 ];\r
+ for (\r
+ p = keyword;\r
+ p < keyword_last_pointer;\r
+ p += 1 ) {\r
\r
- \r
-/***********************************************************************\r
- <<< [StrT_chrs] >>> \r
-************************************************************************/\r
-TCHAR* StrT_chrs( const TCHAR* s, const TCHAR* keys )\r
-{\r
- if ( *keys == _T('\0') ) return NULL;\r
+ /* \83L\81[\83\8f\81[\83h\82É\8eg\82í\82ê\82Ä\82¢\82é\95¶\8e\9a\82É\82Â\82¢\82Ä */\r
+ /* \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
+ skip_array[ *p - min_character ] = keyword_last_pointer - p;\r
+ }\r
\r
- for ( ; *s != _T('\0'); s++ ) {\r
- if ( _tcschr( keys, *s ) != NULL )\r
- return (TCHAR*) s;\r
+\r
+ e=0;\r
+fin:\r
+ if (e) {\r
+ if ( skip_array != NULL ) {\r
+ free( skip_array );\r
+ skip_array = NULL;\r
+ }\r
}\r
- return NULL;\r
+ self->SkipArray = skip_array;\r
+ return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [StrT_rstr] >>> \r
+ <<< (SearchStringByAC_Class) >>> \r
************************************************************************/\r
-TCHAR* StrT_rstr( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keyword,\r
- void* NullConfig )\r
-{\r
- const TCHAR* p;\r
- int keyword_length = _tcslen( Keyword );\r
- TCHAR keyword_first = Keyword[0];\r
-\r
- UNREFERENCED_VARIABLE( NullConfig );\r
+errnum_t SearchStringByAC_Class_makeFunctionsStep1( SearchStringByAC_Class* self,\r
+ const TCHAR** KeywordArray, unsigned KeywordArrayCount );\r
+errnum_t SearchStringByAC_Class_makeFunctionsStep2( SearchStringByAC_Class* self );\r
+errnum_t SearchStringByAC_Class_increaseState( SearchStringByAC_Class* self );\r
+errnum_t SearchStringByAC_Class_addOutputFunction( SearchStringByAC_Class* self,\r
+ int State, const TCHAR* Keyword );\r
+errnum_t SearchStringByAC_Class_addOutputFunctions( SearchStringByAC_Class* self,\r
+ int TargetState, int SourceState );\r
\r
- p = SearchStart;\r
- while ( p >= String ) {\r
- if ( *p == keyword_first ) {\r
- if ( _tcsncmp( p, Keyword, keyword_length ) == 0 ) {\r
- return (TCHAR*) p;\r
- }\r
- }\r
- p -= 1;\r
- }\r
\r
- return NULL;\r
+/***********************************************************************\r
+ <<< [SearchStringByAC_Class_initConst] >>> \r
+************************************************************************/\r
+void SearchStringByAC_Class_initConst( SearchStringByAC_Class* self )\r
+{\r
+ Set2_initConst( &self->GoToFunction );\r
+ self->FailureFunction = NULL;\r
+ self->OutputFunction = NULL;\r
+ self->OutputCount = NULL;\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_skip] >>> \r
+ <<< [SearchStringByAC_Class_initialize] >>> \r
************************************************************************/\r
-TCHAR* StrT_skip( const TCHAR* String, const TCHAR* Keys )\r
+errnum_t SearchStringByAC_Class_initialize( SearchStringByAC_Class* self,\r
+ const TCHAR* TextString, const TCHAR** KeywordArray, size_t KeywordArrayCount )\r
{\r
- if ( *Keys == _T('\0') ) { return (TCHAR*) String; }\r
-\r
- for ( ; *String != _T('\0'); String += 1 ) {\r
- if ( _tcschr( Keys, *String ) == NULL )\r
- break;\r
- }\r
- return (TCHAR*) String;\r
+ return SearchStringByAC_Class_initializeFromPart(\r
+ self, TextString, _tcslen( TextString ), KeywordArray, KeywordArrayCount );\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_rskip] >>> \r
+ <<< [SearchStringByAC_Class_initializeFromPart] >>> \r
************************************************************************/\r
-TCHAR* StrT_rskip( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keys,\r
- void* NullConfig )\r
+errnum_t SearchStringByAC_Class_initializeFromPart( SearchStringByAC_Class* self,\r
+ const TCHAR* TextString, size_t TextString_Length,\r
+ const TCHAR** KeywordArray, size_t KeywordArrayCount )\r
{\r
- const TCHAR* pointer;\r
+ errnum_t e;\r
\r
- UNREFERENCED_VARIABLE( NullConfig );\r
+ self->StateNum = SearchStringByAC_RootState;\r
+ self->TextString = TextString;\r
+ self->TextStringLength = TextString_Length;\r
+ self->TextStringIndex = 0;\r
+ self->FoundKeywords = NULL;\r
\r
- if ( *Keys == _T('\0') ) { return (TCHAR*) SearchStart; }\r
+ e= Set2_init( &self->GoToFunction, 0x1000 ); IF(e){goto fin;}\r
+ self->FailureFunction = NULL;\r
+ self->OutputFunction = NULL;\r
+ self->OutputCount = NULL;\r
+ self->StateCount = 0;\r
\r
- for ( pointer = SearchStart; pointer >= String; pointer -= 1 ) {\r
- if ( _tcschr( Keys, *pointer ) == NULL )\r
- { return (TCHAR*) pointer; }\r
+ /* Make functions */\r
+ e= SearchStringByAC_Class_makeFunctionsStep1( self, KeywordArray, KeywordArrayCount );\r
+ IF(e){goto fin;}\r
+ e= SearchStringByAC_Class_makeFunctionsStep2( self );\r
+ IF(e){goto fin;}\r
+\r
+ e=0;\r
+fin:\r
+ if (e) {\r
+ SearchStringByAC_Class_finalize( self, e );\r
}\r
- return NULL;\r
+ return e;\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_isCIdentifier] >>> \r
+ <<< [SearchStringByAC_Class_finalize] >>> \r
************************************************************************/\r
-bool StrT_isCIdentifier( TCHAR Character )\r
+errnum_t SearchStringByAC_Class_finalize( SearchStringByAC_Class* self, errnum_t e )\r
{\r
- const TCHAR c = Character;\r
+ e= Set2_finish( &self->GoToFunction, e );\r
\r
- return (\r
- ( c >= _T('A') && c <= _T('Z') ) ||\r
- ( c >= _T('a') && c <= _T('z') ) ||\r
- ( c >= _T('0') && c <= _T('9') ) ||\r
- c == _T('_') );\r
+ if ( self->FailureFunction != NULL ) {\r
+ free( self->FailureFunction );\r
+ self->FailureFunction = NULL;\r
+ }\r
+ if ( self->OutputFunction != NULL ) {\r
+ int i;\r
+\r
+ for ( i = 0; i < self->StateCount; i += 1 ) {\r
+ const TCHAR** keywords = self->OutputFunction[i];\r
+ \r
+ if ( keywords != NULL ) {\r
+ free( (void*) keywords );\r
+ }\r
+ }\r
+ free( (void*) self->OutputFunction );\r
+ self->OutputFunction = NULL;\r
+ }\r
+ if ( self->OutputCount != NULL ) {\r
+ free( self->OutputCount );\r
+ self->OutputCount = NULL;\r
+ }\r
+ return e;\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_searchOverOfCIdentifier] >>> \r
+ <<< [SearchStringByAC_Class_search] >>> \r
+ - Aho-Corasick\96@(AC\96@)\82Ì\8c\9f\8dõ\82ð\82·\82é\8aÖ\90\94\r
+ - \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
************************************************************************/\r
-TCHAR* StrT_searchOverOfCIdentifier( const TCHAR* Text )\r
-{\r
- const TCHAR* p;\r
- TCHAR c;\r
+errnum_t SearchStringByAC_Class_search( SearchStringByAC_Class* self,\r
+ int* out_TextStringIndex, TCHAR** out_Keyword )\r
+{\r
+ int state_num = self->StateNum; /* s */\r
+ const TCHAR* text_string = self->TextString; /* text */\r
+ int text_string_length = self->TextStringLength; /* m */\r
+ int text_string_index = self->TextStringIndex; /* i - 1 */\r
+ AC_GotoFunctionType goto_function = (AC_GotoFunctionType) self->GoToFunction.First; /* g */\r
+ int* failure_function = self->FailureFunction; /* f */\r
+ const TCHAR*** output_function = self->OutputFunction; /* output */\r
+ int next_state_num;\r
+ const TCHAR** found_keywords = self->FoundKeywords;\r
+ errnum_t e;\r
\r
- p = Text;\r
- c = *p;\r
- for (;;) {\r
- if ( StrT_isCIdentifier( c ) ) {\r
- p += 1;\r
- c = *p;\r
+\r
+ /* \91O\89ñ\83}\83b\83`\82µ\82½\83L\81[\83\8f\81[\83h\82Ì\91±\82«\82ð\8fo\97Í\82·\82é */\r
+ if ( found_keywords != NULL ) {\r
+ int found_keyword_index = self->FoundKeywordIndex + 1;\r
+ const TCHAR* keyword;\r
+\r
+ if ( found_keyword_index < self->FoundKeywordsCount ) {\r
+ keyword = found_keywords[ found_keyword_index ];\r
+\r
+ *out_Keyword = (TCHAR*) keyword;\r
+ *out_TextStringIndex = text_string_index + 1 - _tcslen( keyword );\r
+ self->FoundKeywordIndex = found_keyword_index;\r
+ return 0;\r
}\r
- else {\r
- return (TCHAR*) p;\r
+ self->FoundKeywords = NULL;\r
+ text_string_index += 1;\r
+ }\r
+\r
+ /* \83e\83L\83X\83g\82Ì\92\86\82ð\82P\95¶\8e\9a\82¸\82Â\92²\82×\82é */\r
+ for ( /* "text_string_index" is already set */;\r
+ text_string_index < text_string_length;\r
+ text_string_index += 1 ) {\r
+\r
+ for (;;) {\r
+ TCHAR a_character = text_string[ text_string_index ];\r
+\r
+ /* AC\96@\82Ì goto \8aÖ\90\94\82ð\8eg\82Á\82Ä\81A\8e\9f\82Ì\8fó\91Ô\82É\91J\88Ú\82·\82é */\r
+#if 0\r
+ ASSERT_R( text_string[ text_string_index ] <= SearchStringByAC_MaxCharacterCode,\r
+ e=E_OTHERS; goto fin );\r
+#else\r
+if ( a_character > SearchStringByAC_MaxCharacterCode ) {\r
+ a_character = _T('\0');\r
+}\r
+#endif\r
+ next_state_num = goto_function[ state_num ][ a_character ];\r
+\r
+ /* AC\96@\82Ì goto \8aÖ\90\94\82ª fail \82µ\82½\82ç\81Afailure \8aÖ\90\94\82ð\8eg\82Á\82Ä\81A */\r
+ /* \8e\9f\82Ì\8fó\91Ô\82É\91J\88Ú\82µ\82Ä\81A\8dÄ\82Ñ goto \8aÖ\90\94\82ð\8eg\82¤ */\r
+ if ( next_state_num == SearchStringByAC_Fail ) {\r
+ if ( state_num == SearchStringByAC_RootState ) {\r
+ next_state_num = SearchStringByAC_RootState;\r
+ break;\r
+ }\r
+ state_num = failure_function[ state_num ];\r
+ }\r
+ else\r
+ { break; }\r
+ }\r
+ state_num = next_state_num;\r
+\r
+ /* 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
+ found_keywords = output_function[ state_num ];\r
+ if ( found_keywords != NULL ) {\r
+ const int first_keyword_index = 0;\r
+ const TCHAR* keyword = found_keywords[ first_keyword_index ];\r
+\r
+ *out_Keyword = (TCHAR*) keyword;\r
+ *out_TextStringIndex = text_string_index + 1 - _tcslen( keyword );\r
+ self->FoundKeywords = found_keywords;\r
+ self->FoundKeywordsCount = self->OutputCount[ state_num ];\r
+ self->FoundKeywordIndex = first_keyword_index;\r
+ self->TextStringIndex = text_string_index;\r
+ self->StateNum = state_num;\r
+ e=0; goto fin;\r
}\r
}\r
+\r
+ /* \83e\83L\83X\83g\82Ì\8dÅ\8cã\82Ü\82Å\92²\82×\82½\8cã */\r
+ *out_Keyword = NULL;\r
+ *out_TextStringIndex = SearchString_NotFound;\r
+ self->FoundKeywords = NULL;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_convPartStrToPointer] >>> \r
+ <<< [SearchStringByAC_Class_setTextString] >>> \r
************************************************************************/\r
-void* StrT_convPartStrToPointer( const TCHAR* StringStart, const TCHAR* StringOver,\r
- const NameOnlyClass* Table, size_t TableSize, void* Default )\r
+errnum_t SearchStringByAC_Class_setTextString( SearchStringByAC_Class* self,\r
+ const TCHAR* TextString )\r
{\r
- const NameOnlyClass* p = Table;\r
- const NameOnlyClass* p_over = (const NameOnlyClass*)( (uint8_t*) Table + TableSize );\r
-\r
- while ( p < p_over ) {\r
- if ( StrT_cmp_part( StringStart, StringOver, p->Name ) == 0 ) {\r
- return (void*) p->Delegate;\r
- }\r
- p += 1;\r
- }\r
- return Default;\r
+ return SearchStringByAC_Class_setTextStringFromPart( self,\r
+ TextString, _tcslen( TextString ) );\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_convertNumToStr] >>> \r
+ <<< [SearchStringByAC_Class_setTextStringFromPart] >>> \r
************************************************************************/\r
-TCHAR* StrT_convertNumToStr( int Number, const NameAndNumClass* Table, int TableCount,\r
- const TCHAR* DefaultStr )\r
+errnum_t SearchStringByAC_Class_setTextStringFromPart( SearchStringByAC_Class* self,\r
+ const TCHAR* TextString, size_t TextString_Length )\r
{\r
- const NameAndNumClass* p;\r
- const NameAndNumClass* p_over = Table + TableCount;\r
+ self->StateNum = SearchStringByAC_RootState;\r
+ self->TextString = TextString;\r
+ self->TextStringLength = TextString_Length;\r
+ self->TextStringIndex = 0;\r
+ self->FoundKeywords = NULL;\r
\r
- for ( p = Table; p < p_over; p += 1 ) {\r
- if ( p->Number == Number ) {\r
- return p->Name;\r
- }\r
- }\r
- return (TCHAR*) DefaultStr;\r
+ return 0;\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_cmp_part] >>> \r
+ <<< [SearchStringByAC_Class_makeFunctionsStep1] >>> \r
+ - Aho-Corasick\96@(AC\96@)\82Ì goto \8aÖ\90\94\82Æ output \8aÖ\90\94\82ð\8dì\90¬\82·\82é\r
+ - \8fî\95ñ\8c\9f\8dõ\83A\83\8b\83S\83\8a\83Y\83\80 p117 \82Ì C\8c¾\8cê\94Å\r
************************************************************************/\r
-int StrT_cmp_part( const TCHAR* StringA_Start, const TCHAR* StringA_Over,\r
- const TCHAR* StringB )\r
+errnum_t SearchStringByAC_Class_makeFunctionsStep1( SearchStringByAC_Class* self,\r
+ const TCHAR** KeywordArray, unsigned KeywordArrayCount )\r
{\r
- const TCHAR* a;\r
- const TCHAR* b;\r
- TCHAR aa;\r
- TCHAR bb;\r
+ errnum_t e;\r
+ unsigned keyword_num;\r
\r
- a = StringA_Start;\r
- b = StringB;\r
+ AC_GotoFunctionType goto_function; /* g */\r
\r
- for (;;) {\r
- if ( a >= StringA_Over ) {\r
- bb = *b;\r
- if ( bb == _T('\0') )\r
- { return 0; }\r
- else\r
- { return -bb; }\r
- }\r
+ e= SearchStringByAC_Class_increaseState( self ); IF(e){goto fin;}\r
+ /* newstate = 0; */ /* self->StateCount - 1 */\r
+ goto_function = (AC_GotoFunctionType) self->GoToFunction.First; /* g */\r
\r
- aa = *a;\r
- bb = *b;\r
+ for ( keyword_num = 0; keyword_num < KeywordArrayCount; keyword_num += 1 ) {\r
+ const TCHAR* keyword = KeywordArray[ keyword_num ];\r
+ int keyword_length = _tcslen( keyword ); /* n */\r
+ int keyword_index; /* j - 1, p - 1 */\r
+ int state;\r
+ int next_state;\r
\r
- if ( bb == _T('\0') )\r
- { return aa; }\r
+ state = SearchStringByAC_RootState;\r
+ keyword_index = 0;\r
\r
- if ( aa != bb )\r
- { return aa - bb; }\r
+ /* \8aù\82É\93o\98^\82³\82ê\82Ä\82¢\82é goto \8aÖ\90\94\82Í\90V\82½\82É\92è\8b`\82µ\82È\82¢ */\r
+ for (;;) {\r
+ ASSERT_R( keyword[ keyword_index ] <= SearchStringByAC_MaxCharacterCode,\r
+ e=E_OTHERS; goto fin );\r
+ next_state = goto_function[ state ][ keyword[ keyword_index ] ];\r
+ if ( next_state != SearchStringByAC_Fail ) {\r
+ state = next_state;\r
+ keyword_index += 1;\r
+ }\r
+ else\r
+ { break; }\r
+ }\r
\r
- a += 1;\r
- b += 1;\r
+ /* \90V\82µ\82¢\8fó\91Ô\82Ö\91J\88Ú\82·\82é goto \8aÖ\90\94\82ð\92è\8b`\82·\82é */\r
+ while ( keyword_index < keyword_length ) {\r
+ int16_t new_state = self->StateCount;\r
+\r
+ e= SearchStringByAC_Class_increaseState( self );\r
+ /* newstate += 1; */\r
+ IF(e){goto fin;}\r
+ goto_function = (AC_GotoFunctionType) self->GoToFunction.First; /* g */\r
+ ASSERT_R( keyword[ keyword_index ] <= SearchStringByAC_MaxCharacterCode,\r
+ e=E_OTHERS; goto fin );\r
+ goto_function[ state ][ keyword[ keyword_index ] ] = new_state;\r
+ state = new_state;\r
+ keyword_index += 1;\r
+ }\r
+ e= SearchStringByAC_Class_addOutputFunction( self, state, keyword );\r
+ IF(e){goto fin;}\r
}\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_cmp_part2] >>> \r
+ <<< [SearchStringByAC_Class_makeFunctionsStep2] >>> \r
+ - 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
+ - \8fî\95ñ\8c\9f\8dõ\83A\83\8b\83S\83\8a\83Y\83\80 p122 \82Ì C\8c¾\8cê\94Å\r
************************************************************************/\r
-int StrT_cmp_part2( const TCHAR* StringA_Start, const TCHAR* StringA_Over,\r
- const TCHAR* StringB_Start, const TCHAR* StringB_Over )\r
+errnum_t SearchStringByAC_Class_makeFunctionsStep2( SearchStringByAC_Class* self )\r
{\r
- int length_A = StringA_Over - StringA_Start;\r
- int length_B = StringB_Over - StringB_Start;\r
+ errnum_t e;\r
+ 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
+ int state; /* s */\r
+ int* queue = NULL;\r
+ int enqueue_index;\r
+ int dequeue_index;\r
+ int* failure_function = NULL;\r
+ AC_GotoFunctionType goto_function = (AC_GotoFunctionType) self->GoToFunction.First;\r
\r
- if ( length_A != length_B ) {\r
- return length_A - length_B;\r
+\r
+ /* \83L\83\85\81[\82ð\8f\89\8aú\89»\82·\82é */\r
+ queue = (int*) malloc( sizeof(int) * self->StateCount );\r
+ IF( queue == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ enqueue_index = 0;\r
+ dequeue_index = 0;\r
+\r
+ /* failure \8aÖ\90\94\82ð\8f\89\8aú\89»\82·\82é */\r
+ failure_function = (int*) malloc( sizeof(int) * self->StateCount );\r
+ IF( failure_function == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+\r
+ /* \90[\82³\82ª\82P\82Ì failure \8aÖ\90\94\82Ì\8fo\97Í\82ð\82O\82É\82·\82é */\r
+ for ( ch = 0; ch <= SearchStringByAC_MaxCharacterCode; ch += 1 ) {\r
+ state = goto_function[ SearchStringByAC_RootState ][ ch ];\r
+ if ( state == SearchStringByAC_Fail ) { continue; }\r
+\r
+ \r
+ /* \8fó\91Ô 0(=SearchStringByAC_RootState) \82Ì\91J\88Ú\90æ\82Ì\8fó\91Ô\82ð\83L\83\85\81[\82É\92Ç\89Á\82·\82é */\r
+ queue[ enqueue_index ] = state;\r
+ enqueue_index += 1;\r
+\r
+ failure_function[ state ] = SearchStringByAC_RootState;\r
}\r
- else {\r
- return _tcsncmp( StringA_Start, StringB_Start, length_A );\r
+\r
+ while ( enqueue_index > dequeue_index ) {\r
+ int back_state; /* r */\r
+ int back_new_state; /* state, p */\r
+ int new_state; /* q */\r
+\r
+ /* \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
+ back_state = queue[ dequeue_index ];\r
+ dequeue_index += 1;\r
+\r
+ for ( ch = 0; ch <= SearchStringByAC_MaxCharacterCode; ch += 1 ) {\r
+ state = goto_function[ back_state ][ ch ];\r
+ if ( state == SearchStringByAC_Fail ) { continue; }\r
+\r
+ /* back_state \82Ì\91J\88Ú\90æ\82Ì\8fó\91Ô\82ð\83L\83\85\81[\82É\92Ç\89Á\82·\82é */\r
+ queue[ enqueue_index ] = state;\r
+ enqueue_index += 1;\r
+\r
+ /* 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
+ back_new_state = failure_function[ back_state ];\r
+ for (;;) {\r
+ new_state = goto_function[ back_new_state ][ ch ];\r
+ if ( new_state == SearchStringByAC_Fail ) {\r
+ if ( back_new_state == SearchStringByAC_RootState ) {\r
+ new_state = SearchStringByAC_RootState;\r
+ break;\r
+ }\r
+ back_new_state = failure_function[ back_new_state ];\r
+ }\r
+ else\r
+ { break; }\r
+ }\r
+ failure_function[ state ] = new_state;\r
+\r
+ /* output \8aÖ\90\94\82ð\8dX\90V\82·\82é */\r
+ e= SearchStringByAC_Class_addOutputFunctions(\r
+ self, state, failure_function[ state ] );\r
+ IF(e){goto fin;}\r
+ }\r
}\r
+\r
+ self->FailureFunction = failure_function;\r
+ failure_function = NULL;\r
+\r
+ e=0;\r
+fin:\r
+ if ( queue != NULL ) { free( queue ); }\r
+ if ( failure_function != NULL ) { free( failure_function ); }\r
+ return e;\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_refFName] >>> \r
+ <<< [SearchStringByAC_Class_increaseState] >>> \r
************************************************************************/\r
-TCHAR* StrT_refFName( const TCHAR* s )\r
+errnum_t SearchStringByAC_Class_increaseState( SearchStringByAC_Class* self )\r
{\r
- const TCHAR* p;\r
- TCHAR c;\r
+ errnum_t e;\r
+ AC_GotoFunctionType new_goto_function;\r
+ const TCHAR*** new_output_function;\r
+ int* new_output_count;\r
+ int16_t new_state_count = self->StateCount + 1;\r
+\r
+\r
+ /* 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
+ e= Set2_allocate( &self->GoToFunction, &new_goto_function ); IF(e){goto fin;}\r
+#if 0 //[TODO]\r
+printf( "goto funcion %d/%d \n",\r
+Set2_getCount( &self->GoToFunction, *new_goto_function ),\r
+Set2_getCountMax( &self->GoToFunction, *new_goto_function ) );\r
+#endif\r
\r
- p = _tcschr( s, _T('\0') );\r
+ /* \90V\82µ\82¢ state \82Ì goto \8aÖ\90\94\82ð 0(=SearchStringByAC_Fail) \82Å\8f\89\8aú\89»\82·\82é */\r
+ memset( new_goto_function, 0, sizeof(*new_goto_function) );\r
\r
- if ( p == s ) return (TCHAR*) s;\r
\r
- for ( p--; p>s; p-- ) {\r
- c = *p;\r
- if ( c == _T('\\') || c == _T('/') ) return (TCHAR*) p+1;\r
- }\r
- if ( *p == _T('\\') || *p == _T('/') ) return (TCHAR*) p+1;\r
+ /* 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
+ new_output_function = (const TCHAR***) realloc( (void*) self->OutputFunction,\r
+ sizeof(self->OutputFunction[0]) * new_state_count );\r
+ IF ( new_output_function == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ new_output_function[ new_state_count - 1 ] = NULL;\r
\r
- return (TCHAR*) s;\r
+ new_output_count = (int*) realloc( self->OutputCount,\r
+ sizeof(self->OutputCount[0]) * new_state_count );\r
+ IF ( new_output_count == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ new_output_count[ new_state_count - 1 ] = 0;\r
+\r
+\r
+ /* Set "self->..." */\r
+ self->OutputFunction = new_output_function;\r
+ self->OutputCount = new_output_count;\r
+ self->StateCount = new_state_count;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
- \r
+\r
+\r
/***********************************************************************\r
- <<< [StrT_refExt] >>> \r
+ <<< [SearchStringByAC_Class_addOutputFunction] >>> \r
************************************************************************/\r
-TCHAR* StrT_refExt( const TCHAR* s )\r
+errnum_t SearchStringByAC_Class_addOutputFunction( SearchStringByAC_Class* self,\r
+ int State, const TCHAR* Keyword )\r
{\r
- const TCHAR* p;\r
-\r
- p = _tcschr( s, _T('\0') );\r
+ errnum_t e;\r
+ const TCHAR** new_keywords = NULL;\r
+ int old_count = self->OutputCount[ State ];\r
\r
- if ( p == s ) return (TCHAR*) s;\r
+ new_keywords = (const TCHAR**) realloc( (void*) self->OutputFunction[ State ],\r
+ sizeof(const TCHAR*) * (old_count + 1) );\r
+ IF ( new_keywords == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ new_keywords[ old_count ] = Keyword;\r
\r
- for ( p--; p>s; p-- ) {\r
- if ( *p == _T('.') ) return (TCHAR*) p+1;\r
- if ( *p == _T('/') || *p == _T('\\') ) return (TCHAR*) _tcschr( p, _T('\0') );\r
- }\r
- if ( *p == _T('.') ) return (TCHAR*) p+1;\r
+ self->OutputFunction[ State ] = new_keywords;\r
+ self->OutputCount[ State ] = old_count + 1;\r
\r
- return (TCHAR*) _tcschr( s, _T('\0') );\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_convStrToId] >>> \r
+ <<< [SearchStringByAC_Class_addOutputFunctions] >>> \r
************************************************************************/\r
-errnum_t StrT_convStrToId( const TCHAR* str, const TCHAR** strs, const int* ids,\r
- int n, int default_id )\r
+errnum_t SearchStringByAC_Class_addOutputFunctions( SearchStringByAC_Class* self,\r
+ int TargetState, int SourceState )\r
{\r
- const TCHAR** p;\r
- const TCHAR** p_over = strs + n;\r
+ errnum_t e;\r
+ const TCHAR** keywords = self->OutputFunction[ SourceState ];\r
+ int i;\r
+ int count = self->OutputCount[ SourceState ];\r
\r
- for ( p = strs; p < p_over; p++ ) {\r
- if ( _tcsicmp( *p, str ) == 0 ) return ids[p - strs];\r
+ for ( i = 0; i < count; i += 1 ) {\r
+ e= SearchStringByAC_Class_addOutputFunction( self,\r
+ TargetState, keywords[ i ] );\r
+ IF(e){goto fin;}\r
}\r
- return default_id;\r
-}\r
-\r
- \r
-/***********************************************************************\r
- <<< [StrT_convStrLeftToId] >>> \r
-************************************************************************/\r
-errnum_t StrT_convStrLeftToId( const TCHAR* Str, const TCHAR** Strs, const size_t* Lens, const int* Ids,\r
- int CountOfStrs, TCHAR* Separeters, int DefaultId, TCHAR** out_PosOfLastOfStr )\r
-{\r
- const TCHAR** pp;\r
- const TCHAR** pp_over = Strs + CountOfStrs;\r
- const size_t* p_len;\r
- const int* p_id;\r
- const TCHAR* p_last_of_str;\r
- TCHAR c;\r
\r
- p_len = Lens;\r
- p_id = Ids;\r
- for ( pp = Strs; pp < pp_over; pp += 1 ) {\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
- ASSERT_D( _tcslen( *pp ) == *p_len, goto err );\r
\r
- if ( _tcsncmp( Str, *pp, *p_len ) == 0 ) {\r
- p_last_of_str = Str + *p_len;\r
- c = *p_last_of_str;\r
- if ( c == _T('\0') || _tcschr( Separeters, c ) != NULL ) {\r
- *out_PosOfLastOfStr = (TCHAR*) p_last_of_str;\r
- return *p_id;\r
- }\r
- }\r
- p_len += 1;\r
- p_id += 1;\r
- }\r
- return DefaultId;\r
+ \r
+/*=================================================================*/\r
+/* <<< [DebugTools/DebugTools.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/**************************************************************************\r
+ <<< (g_DebugVar) >>> \r
+***************************************************************************/\r
+int g_DebugVar[10];\r
\r
-#if ! NDEBUG\r
- err: return DefaultId;\r
-#endif\r
-}\r
\r
\r
-/***********************************************************************\r
- <<< [StrT_replace1] >>> \r
-************************************************************************/\r
-errnum_t StrT_replace1( TCHAR* in_out_String, TCHAR FromCharacter, TCHAR ToCharacter,\r
- unsigned Opt )\r
-{\r
- TCHAR* p;\r
+/**************************************************************************\r
+ <<< (DebugTools) >>> \r
+***************************************************************************/\r
+#if DEBUGTOOLS_USES\r
+#define DebugTools_get() (&g_DebugTools)\r
+extern DebugTools g_DebugTools;\r
\r
- UNREFERENCED_VARIABLE( Opt );\r
\r
- IF ( FromCharacter == _T('\0') ) { return E_OTHERS; }\r
+DebugTools g_DebugTools;\r
\r
- p = in_out_String;\r
- for (;;) {\r
- p = _tcschr( p, FromCharacter );\r
- if ( p == NULL ) { break; }\r
- *p = ToCharacter;\r
- p += 1;\r
- }\r
\r
+int Debug_setReturnValueOnBreak( int ID )\r
+{\r
+ DebugTools* m = DebugTools_get();\r
+ m->m_ReturnValueOnBreak_minus1 = ID - 1;\r
return 0;\r
}\r
\r
+int Debug_disableBreak( int iExceptID )\r
+{\r
+ DebugTools* m = DebugTools_get();\r
+ m->m_DisableBreakExceptID_plus1 = iExceptID + 1;\r
+ return 0;\r
+}\r
\r
- \r
-/***********************************************************************\r
- <<< [StrT_trim] >>> \r
-************************************************************************/\r
-errnum_t StrT_trim( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str )\r
+int Debug_setBreakByFName( const TCHAR* Path )\r
{\r
- const TCHAR* p1;\r
- const TCHAR* p2;\r
- TCHAR c;\r
+ DebugTools* m = DebugTools_get();\r
+ return MallocAndCopyString( &m->m_BreakByFName, Path );\r
+}\r
\r
- p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;\r
- for ( p2 = _tcschr( p1, _T('\0') ) - 1; p2 >= p1; p2-- ) {\r
- c = *p2;\r
- if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
- break;\r
+int Debug_onBreakCase( DebugTools* m )\r
+{\r
+ m->m_BreakID ++;\r
+ if ( m->m_DisableBreakExceptID_plus1 == 0 || m->m_BreakID == m->m_DisableBreakExceptID_plus1 - 1 ) {\r
+ // DebugBreakR();\r
+ if ( m->m_ReturnValueOnBreak_minus1 == 0 ) return E_DEBUG_BREAK;\r
+ return m->m_ReturnValueOnBreak_minus1 + 1;\r
+ }\r
+ else {\r
+ _tprintf( _T("[BREAK]\n") );\r
+ return 0;\r
}\r
- return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [StrT_cutLastOf] >>> \r
-************************************************************************/\r
-errnum_t StrT_cutLastOf( TCHAR* in_out_Str, TCHAR Charactor )\r
+TCHAR* StrT_refFName( const TCHAR* s );\r
+\r
+int Debug_onOpen( const TCHAR* Path )\r
{\r
- TCHAR* last = _tcschr( in_out_Str, _T('\0') );\r
+ DebugTools* m = DebugTools_get();\r
\r
- if ( last > in_out_Str ) {\r
- if ( *( last - 1 ) == Charactor )\r
- { *( last - 1 ) = _T('\0'); }\r
+ if ( m->m_BreakByFName != NULL &&\r
+ _tcsicmp( m->m_BreakByFName, StrT_refFName( Path ) ) == 0 ) {\r
+ return Debug_onBreakCase( m );\r
}\r
return 0;\r
}\r
\r
+#endif\r
\r
\r
/***********************************************************************\r
- <<< [StrT_cutLineComment] >>> \r
+ <<< [HeapLogWatchClass] >>> \r
************************************************************************/\r
-errnum_t StrT_cutLineComment( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str, const TCHAR* CommentSign )\r
-{\r
- const TCHAR* p1;\r
- const TCHAR* p2;\r
- TCHAR c;\r
+typedef struct _HeapLogWatchClass HeapLogWatchClass;\r
+struct _HeapLogWatchClass {\r
+ int AllocatedID;\r
+ ptrdiff_t Offset;\r
+ uint32_t BreakValue;\r
+ bool IsPrintf;\r
+ bool IsEnabled;\r
+};\r
+HeapLogWatchClass g_HeapLogWatch[ 10 ];\r
\r
- p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;\r
\r
- p2 = _tcsstr( p1, CommentSign );\r
- if ( p2 == NULL ) p2 = _tcschr( p1, _T('\0') );\r
+/***********************************************************************\r
+ <<< (HeapLogClass) >>> \r
+************************************************************************/\r
+typedef struct _HeapLogClass HeapLogClass;\r
+struct _HeapLogClass {\r
+ void** Addresses;\r
+ size_t* Sizes;\r
+ int Count;\r
+ int CountMax;\r
+};\r
\r
- for ( p2 = p2 - 1; p2 >= p1; p2-- ) {\r
- c = *p2;\r
- if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
- break;\r
- }\r
- return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
-}\r
+HeapLogClass g_HeapLog;\r
\r
\r
- \r
-/**************************************************************************\r
- <<< [StrT_meltCSV] >>> \r
-*************************************************************************/\r
-errnum_t StrT_meltCSV( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pCSV )\r
+/***********************************************************************\r
+ <<< [HeapLogClass_log] >>> \r
+************************************************************************/\r
+void HeapLogClass_log( void* in_Address, size_t in_Size )\r
{\r
- errnum_t e = 0;\r
- TCHAR* t;\r
- TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
- const TCHAR* s;\r
- TCHAR dummy[2];\r
- TCHAR c;\r
+ errnum_t e;\r
+ int i;\r
\r
- t = out_Str;\r
- s = *pCSV;\r
- if ( out_Str_Size <= 1 ) { t = dummy; t_last = dummy; }\r
+ while ( g_HeapLog.Count >= g_HeapLog.CountMax ) {\r
+ void* new_address;\r
+ int new_count_max = g_HeapLog.CountMax * 2 + 4;\r
\r
- if ( s == NULL ) { *t = _T('\0'); return 0; }\r
+ new_address = realloc_no_redirected( g_HeapLog.Addresses, new_count_max * sizeof( *g_HeapLog.Addresses ) );\r
+ if ( new_address == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ g_HeapLog.Addresses = (void**) new_address;\r
\r
+ new_address = realloc_no_redirected( g_HeapLog.Sizes, new_count_max * sizeof( *g_HeapLog.Sizes ) );\r
+ if ( new_address == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ g_HeapLog.Sizes = (size_t*) new_address;\r
\r
- /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82 */\r
- while ( *s == _T(' ') || *s == _T('\t') ) s++;\r
+ g_HeapLog.CountMax = new_count_max;\r
+ }\r
\r
- switch ( *s ) {\r
+ g_HeapLog.Addresses[ g_HeapLog.Count ] = in_Address;\r
+ g_HeapLog.Sizes[ g_HeapLog.Count ] = in_Size;\r
+ g_HeapLog.Count += 1;\r
\r
- /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
- case _T('"'):\r
- s++;\r
- c = *s;\r
- while ( c != _T('"') || *(s+1) == _T('"') ) { /* " \95¶\8e\9a\82Ü\82Å */\r
- if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }\r
- if ( c == *(s+1) && c == _T('"') ) s++; /* " \95¶\8e\9a\8e©\91Ì */\r
- if ( c == _T('\0') ) break;\r
- *t = c; t++; s++; c = *s;\r
- }\r
- *t = _T('\0');\r
\r
- s++;\r
- for (;;) {\r
- if ( *s == _T(',') ) { s = s+1; break; }\r
- if ( *s == _T('\0') ) { s = NULL; break; }\r
- s++;\r
- }\r
- *pCSV = s;\r
- return e;\r
+ for ( i = 0; i < _countof( g_HeapLogWatch ); i += 1 ) {\r
+ HeapLogWatchClass* watch = &g_HeapLogWatch[ i ];\r
\r
- /* \8bó\82Ì\8d\80\96Ú\82Ì\8fê\8d\87 */\r
- case ',':\r
- *t = _T('\0');\r
- *pCSV = s+1;\r
- return 0;\r
+ if ( watch->IsEnabled ) {\r
+ if ( watch->AllocatedID == g_HeapLog.Count ) {\r
+ if ( watch->IsPrintf ) {\r
+ printf( "<HeapLogClass_log event=\"Allocated\" index=\"%d\"/>\n",\r
+ i );\r
+ }\r
+ }\r
+ }\r
+ }\r
\r
- case '\0':\r
- *t = _T('\0');\r
- *pCSV = NULL;\r
- return 0;\r
+fin:\r
+ return;\r
+}\r
\r
- /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
- default: {\r
- TCHAR* sp = NULL; /* \8dÅ\8cã\82Ì\98A\91±\82µ\82½\8bó\94\92\82Ì\90æ\93ª */\r
\r
- c = *s;\r
- while ( c != _T(',') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /* , \95¶\8e\9a\82Ü\82Å */\r
+/***********************************************************************\r
+ <<< [HeapLogClass_getID] >>> \r
+************************************************************************/\r
+int HeapLogClass_getID( const void* in_Address )\r
+{\r
+ int i;\r
\r
- /* sp \82ð\90Ý\92è\82·\82é */\r
- if ( c == ' ' ) {\r
- if ( sp == NULL ) sp = t;\r
- }\r
- else sp = NULL;\r
+ for ( i = g_HeapLog.Count - 1; i >= 0; i -= 1 ) {\r
+ const void* start = g_HeapLog.Addresses[ i ];\r
+ const void* over;\r
\r
- if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }\r
+ over = g_HeapLog.Addresses[ i ];\r
+ PointerType_plus( &over, g_HeapLog.Sizes[ i ] );\r
\r
- /* \83R\83s\81[\82·\82é */\r
- *t = c; t++; s++; c = *s;\r
- }\r
+ if ( start <= in_Address && in_Address < over ) {\r
+ break;\r
+ }\r
+ }\r
+ return i;\r
+}\r
\r
- /* \95Ô\82è\92l\82ð\8c\88\92è\82·\82é */\r
- if ( c == _T(',') ) s = s + 1;\r
- else s = NULL;\r
\r
- /* \96\96\94ö\82Ì\8bó\94\92\82ð\8eæ\82è\8f\9c\82 */\r
- if ( sp != NULL ) *sp = '\0';\r
- else *t = _T('\0');\r
+/***********************************************************************\r
+ <<< [HeapLogClass_printID] >>> \r
+************************************************************************/\r
+void HeapLogClass_printID( const void* in_Address )\r
+{\r
+ int block_ID = HeapLogClass_getID( in_Address );\r
+ ptrdiff_t offset;\r
\r
- *pCSV = s;\r
- return e;\r
- }\r
+ if ( block_ID != HeapLogClass_NotAllocatedID ) {\r
+ offset = PointerType_diff( in_Address, g_HeapLog.Addresses[ block_ID ] );\r
+ }\r
+ else {\r
+ offset = 0;\r
}\r
+\r
+ printf( "<HeapLogClass_printID allocated_id=\"%d\" offset=\"0x%04X\"/>\n",\r
+ block_ID, offset );\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [StrT_parseCSV_f] >>> \r
+ <<< [HeapLogClass_addWatch] >>> \r
************************************************************************/\r
-errnum_t StrT_parseCSV_f( const TCHAR* StringOfCSV, bit_flags32_t* out_ReadFlags, const TCHAR* Types, ... )\r
+void HeapLogClass_addWatch( int in_IndexNum, int in_AllocatedID, ptrdiff_t in_Offset,\r
+ uint32_t in_BreakValue, bool in_IsPrintf )\r
{\r
- errnum_t e;\r
- TCHAR type;\r
- int types_index;\r
- va_list va;\r
- bool is_next_omittable;\r
- bool is_next_omit;\r
- const TCHAR* column_pointer;\r
- TCHAR a_char;\r
- TCHAR column[ 32 ];\r
- bit_flags32_t read_flags;\r
- bit_flags32_t next_read_flag;\r
- TCHAR* out_str;\r
- size_t str_size;\r
+ HeapLogWatchClass* watch = &g_HeapLogWatch[ in_IndexNum ];\r
\r
+ if ( in_IndexNum >= _countof( g_HeapLogWatch ) ) {\r
+ printf( "HeapLogClass_addWatch: Error of IndexNum (%d)\n", in_IndexNum );\r
+ return;\r
+ }\r
\r
- va_start( va, Types );\r
- types_index = 0;\r
- is_next_omittable = false;\r
- column_pointer = StringOfCSV;\r
- read_flags = 0;\r
- next_read_flag = 1;\r
- while ( column_pointer != NULL ) {\r
- out_str = NULL;\r
+ if ( in_IsPrintf ) {\r
+ printf( "<HeapLogClass_addWatch index=\"%d\" allocated_id=\"%d\" offset=\"0x%04X\"/>\n",\r
+ in_IndexNum, in_AllocatedID, in_Offset );\r
+ }\r
+ watch->AllocatedID = in_AllocatedID;\r
+ watch->Offset = in_Offset;\r
+ watch->BreakValue = in_BreakValue;\r
+ watch->IsPrintf = in_IsPrintf;\r
+ watch->IsEnabled = true;\r
+}\r
\r
- type = Types[ types_index ];\r
- switch ( type ) {\r
- case _T('\0'):\r
- goto exit_for;\r
\r
- case _T('+'):\r
- is_next_omittable = true;\r
- break;\r
+/***********************************************************************\r
+ <<< [HeapLogClass_watch] >>> \r
+************************************************************************/\r
+void HeapLogClass_watch( int in_IndexNum )\r
+{\r
+ HeapLogWatchClass* watch = &g_HeapLogWatch[ in_IndexNum ];\r
+\r
+ uint32_t value;\r
+\r
\r
- case _T('s'):\r
- out_str = va_arg( va, TCHAR* );\r
- str_size = va_arg( va, size_t );\r
- ASSERT_D( str_size >= 1, e=E_OTHERS; goto fin );\r
- break;\r
+ if ( in_IndexNum >= _countof( g_HeapLogWatch ) ) {\r
+ printf( "HeapLogClass_addWatch: Error of IndexNum (%d)\n", in_IndexNum );\r
+ return;\r
+ }\r
\r
- default:\r
- out_str = column;\r
- str_size = sizeof( column );\r
- break;\r
- }\r
+ if ( watch->IsEnabled && g_HeapLog.Count > watch->AllocatedID ) {\r
+ const void* pointer = g_HeapLog.Addresses[ watch->AllocatedID ];\r
\r
- if ( out_str != NULL ) {\r
+ PointerType_plus( &pointer, watch->Offset );\r
+ value = *(uint32_t*) pointer;\r
\r
- // Set "out_str" : Column string in CSV\r
- column_pointer = StrT_skip( column_pointer, _T(" \t") );\r
- a_char = *column_pointer;\r
- if ( is_next_omittable && ( a_char == _T('\0') || a_char == _T(',') ) ) {\r
- column_pointer = StrT_chrs( column_pointer, _T(",") );\r
- if ( column_pointer != NULL ) { column_pointer += 1; }\r
- is_next_omit = true;\r
- } else {\r
- e= StrT_meltCSV( out_str, str_size, &column_pointer ); IF(e){goto fin;}\r
+ if ( watch->IsPrintf ) {\r
+ printf( "<HeapLogClass_watch index=\"%d\" value=\"%d\" value16=\"0x%08X\"/>\n",\r
+ in_IndexNum, value, value );\r
+ }\r
+ if ( value == watch->BreakValue ) { DebugBreakR(); }\r
+ }\r
\r
- is_next_omit = false;\r
- read_flags |= next_read_flag;\r
- }\r
+}\r
\r
- switch ( type ) {\r
- case _T('s'):\r
- /* "va_arg" was already called */\r
- break;\r
\r
- case _T('i'): {\r
- int* pointer_of_int = va_arg( va, int* );\r
+/***********************************************************************\r
+ <<< [HeapLogClass_getWatchingAddress] >>> \r
+************************************************************************/\r
+void* HeapLogClass_getWatchingAddress( int in_IndexNum )\r
+{\r
+ HeapLogWatchClass* watch = &g_HeapLogWatch[ in_IndexNum ];\r
+ void* return_value;\r
\r
- if ( ! is_next_omit ) {\r
- *pointer_of_int = ttoi_ex( column, 0 );\r
- }\r
- break;\r
- }\r
- case _T('f'): {\r
- double* pointer_of_double = va_arg( va, double* );\r
\r
- if ( ! is_next_omit ) {\r
- *pointer_of_double = _tstof( column );\r
- }\r
- break;\r
- }\r
- case _T('b'): {\r
- bool* pointer_of_bool = va_arg( va, bool* );\r
- int strings_index;\r
- static const TCHAR* strings[] = {\r
- _T("1"), _T("true"), _T("yes"),\r
- };\r
+ if ( in_IndexNum >= _countof( g_HeapLogWatch ) ) {\r
+ printf( "HeapLogClass_addWatch: Error of IndexNum (%d)\n", in_IndexNum );\r
+ return NULL;\r
+ }\r
\r
- if ( ! is_next_omit ) {\r
- *pointer_of_bool = false;\r
- for ( strings_index = 0;\r
- strings_index < _countof( strings );\r
- strings_index += 1 )\r
- {\r
- if ( _tcsicmp( column, strings[ strings_index ] ) == 0 ) {\r
- *pointer_of_bool = true;\r
- break;\r
- }\r
- }\r
- }\r
- break;\r
- }\r
- case _T('t'): {\r
- SYSTEMTIME* pointer_of_time = va_arg( va, SYSTEMTIME* );\r
- int* pointer_of_bias = va_arg( va, int* );\r
\r
- if ( ! is_next_omit ) {\r
- e= W3CDTF_toSYSTEMTIME( column, pointer_of_time, pointer_of_bias );\r
- IF(e){goto fin;}\r
- }\r
- break;\r
- }\r
+ if ( watch->IsEnabled && g_HeapLog.Count > watch->AllocatedID ) {\r
+ return_value = g_HeapLog.Addresses[ watch->AllocatedID ];\r
+ PointerType_plus( &return_value, watch->Offset );\r
+ } else {\r
+ return_value = NULL;\r
+ }\r
\r
- default:\r
- ASSERT_R( false, e=E_OTHERS; goto fin );\r
- }\r
+ return return_value;\r
+}\r
\r
- is_next_omittable = false;\r
- next_read_flag <<= 1;\r
- }\r
\r
- types_index += 1;\r
+/***********************************************************************\r
+ <<< [HeapLogClass_finalize] >>> \r
+************************************************************************/\r
+void HeapLogClass_finalize()\r
+{\r
+ if ( g_HeapLog.Addresses != NULL ) {\r
+ free( g_HeapLog.Addresses );\r
+ g_HeapLog.Addresses = NULL;\r
}\r
-exit_for:\r
- if ( out_ReadFlags != NULL ) {\r
- *out_ReadFlags = read_flags;\r
+ if ( g_HeapLog.Sizes != NULL ) {\r
+ free( g_HeapLog.Sizes );\r
+ g_HeapLog.Sizes = NULL;\r
}\r
-\r
- e=0;\r
-fin:\r
- va_end( va );\r
- return e;\r
+ g_HeapLog.Count = 0;\r
+ g_HeapLog.CountMax = 0;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [StrT_getExistSymbols] >>> \r
+ <<< [TestableDebugBreak] >>> \r
************************************************************************/\r
-errnum_t StrT_getExistSymbols( unsigned* out, bool bCase, const TCHAR* Str, const TCHAR* Symbols, ... )\r
-{\r
- errnum_t e;\r
- int i;\r
- bool* syms_exists = NULL;\r
- bool b_nosym = false;\r
- TCHAR* sym = NULL;\r
- size_t sym_size = ( _tcslen( Symbols ) + 1 ) * sizeof(TCHAR);\r
- int n_sym = 0;\r
- const TCHAR** syms = NULL;\r
- const TCHAR* p;\r
+typedef struct _TestableDebugBreakClass TestableDebugBreakClass;\r
+struct _TestableDebugBreakClass {\r
+ bool IsDisableTestableDebugBreak;\r
+ volatile int DebugBreakCount;\r
+ CRITICAL_SECTION Critical;\r
+ SingletonInitializerClass Initializer;\r
+};\r
+static TestableDebugBreakClass gs_TestableDebugBreak = { false, 0 };\r
\r
- UNREFERENCED_VARIABLE( bCase );\r
\r
- sym = (TCHAR*) malloc( sym_size ); IF(sym==NULL)goto err_fm;\r
+/*[SetTestableDebugBreak]*/\r
+void SetTestableDebugBreak( bool IsEnableBreak )\r
+{\r
+ TestableDebugBreakClass* self = &gs_TestableDebugBreak;\r
+ self->IsDisableTestableDebugBreak = ! IsEnableBreak;\r
+}\r
\r
+/*[TestableDebugBreak_Sub]*/\r
+int TestableDebugBreak_Sub()\r
+{\r
+ TestableDebugBreakClass* self = &gs_TestableDebugBreak;\r
\r
- //=== Get Symbols\r
- p = Symbols;\r
- do {\r
- e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
- if ( sym[0] != _T('\0') ) n_sym ++;\r
- } while ( p != NULL );\r
+ if ( ! SingletonInitializerClass_isInitialized( &self->Initializer ) ) {\r
+ if ( SingletonInitializerClass_isFirst( &self->Initializer ) ) {\r
\r
- syms = (const TCHAR**) malloc( n_sym * sizeof(TCHAR*) ); IF(syms==NULL)goto err_fm;\r
- memset( (TCHAR**) syms, 0, n_sym * sizeof(TCHAR*) );\r
- syms_exists = (bool*) malloc( n_sym * sizeof(bool) ); IF(syms_exists==NULL)goto err_fm;\r
- memset( syms_exists, 0, n_sym * sizeof(bool) );\r
+ InitializeCriticalSection( &self->Critical );\r
\r
- p = Symbols; i = 0;\r
- do {\r
- e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
- if ( sym[0] != _T('\0') ) {\r
- e= MallocAndCopyString( &syms[i], sym ); IF(e)goto fin;\r
- i++;\r
+ SingletonInitializerClass_onFinishedInitialize( &self->Initializer, 0 );\r
}\r
- } while ( p != NULL );\r
+ }\r
\r
+ EnterCriticalSection( &self->Critical );\r
+ self->DebugBreakCount += 1;\r
+ LeaveCriticalSection( &self->Critical );\r
\r
- //=== Check Str whether having Symbols\r
- p = Str;\r
- do {\r
- e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
- if ( sym[0] != _T('\0') ) {\r
- for ( i = 0; i < n_sym; i++ ) {\r
- if ( _tcscmp( sym, syms[i] ) == 0 ) { syms_exists[i] = true; break; }\r
- }\r
- if ( i == n_sym ) b_nosym = true;\r
- }\r
- } while ( p != NULL );\r
+ return ! self->IsDisableTestableDebugBreak;\r
+}\r
\r
+/*[GetDebugBreakCount]*/\r
+int GetDebugBreakCount()\r
+{\r
+ TestableDebugBreakClass* self = &gs_TestableDebugBreak;\r
+ return self->DebugBreakCount;\r
+}\r
\r
- //=== Sum numbers\r
- {\r
- va_list va;\r
- unsigned num;\r
\r
- va_start( va, Symbols );\r
- *out = 0;\r
- for ( i = 0; i < n_sym; i++ ) {\r
- num = va_arg( va, unsigned );\r
- if ( syms_exists[i] ) *out |= num;\r
- }\r
- va_end( va );\r
- }\r
+ \r
+/*=================================================================*/\r
+/* <<< [SetX/SetX.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [Set2_init] >>> \r
+************************************************************************/\r
+errnum_t Set2_init( Set2* m, int FirstSize )\r
+{\r
+ m->First = malloc( FirstSize );\r
+ if ( m->First == NULL ) return E_FEW_MEMORY;\r
+ m->Next = m->First;\r
+ m->Over = (char*)m->First + FirstSize;\r
\r
- e = ( b_nosym ? E_NOT_FOUND_SYMBOL : 0 );\r
-fin:\r
- if ( syms != NULL ) {\r
- for ( i = 0; i < n_sym; i++ ) {\r
- e= HeapMemory_free( &syms[i], e );\r
- }\r
- free( (TCHAR**) syms );\r
- }\r
- e= HeapMemory_free( &syms_exists, e );\r
- e= HeapMemory_free( &sym, e );\r
+ #ifdef _DEBUG\r
+ m->PointerOfDebugArray = NULL;\r
+ #endif\r
+\r
+ return 0;\r
+}\r
+ \r
+/***********************************************************************\r
+ <<< [Set2_finish] >>> \r
+************************************************************************/\r
+errnum_t Set2_finish( Set2* m, errnum_t e )\r
+{\r
+ if ( m->First != NULL ) { free( m->First ); m->First = NULL; }\r
return e;\r
-err_fm: e= E_FEW_MEMORY; goto fin;\r
}\r
\r
\r
-/**************************************************************************\r
- <<< [StrT_meltCmdLine] >>> \r
-*************************************************************************/\r
-errnum_t StrT_meltCmdLine( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pLine )\r
+/***********************************************************************\r
+ <<< [Set2_ref_imp] >>> \r
+************************************************************************/\r
+errnum_t Set2_ref_imp( Set2* m, int iElem, void* out_pElem, size_t ElemSize )\r
{\r
- errnum_t e = 0;\r
- TCHAR* t;\r
- TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
- const TCHAR* s;\r
- TCHAR dummy;\r
- TCHAR c;\r
-\r
- t = out_Str;\r
- s = *pLine;\r
- if ( out_Str_Size <= 1 ) { t = &dummy; t_last = &dummy; }\r
+ int e;\r
+ char* p;\r
\r
- if ( s == NULL ) { *t = _T('\0'); return 0; }\r
+ IF( iElem < 0 ) goto err_ns;\r
+ p = (char*) m->First + ( (unsigned)iElem * ElemSize );\r
+ IF( p >= (char*)m->Next ) goto err_ns;\r
+ *(char**)out_pElem = p;\r
\r
+ e=0;\r
+fin:\r
+ return e;\r
\r
- /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82 */\r
- while ( *s == _T(' ') || *s == _T('\t') ) s++;\r
+err_ns: e = E_NOT_FOUND_SYMBOL; goto fin;\r
+}\r
\r
- switch ( *s ) {\r
\r
- /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
- case _T('"'):\r
- s++;\r
- c = *s;\r
- while ( c != _T('"') || *(s+1) == _T('"') ) { /* " \95¶\8e\9a\82Ü\82Å */\r
- if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }\r
- if ( c == *(s+1) && c == _T('"') ) s++; /* " \95¶\8e\9a\8e©\91Ì */\r
- if ( c == _T('\0') ) break;\r
- *t = c; t++; s++; c = *s;\r
- }\r
- *t = _T('\0');\r
+ \r
+/***********************************************************************\r
+ <<< [Set2_getIterator] >>> \r
+************************************************************************/\r
+errnum_t Set2_getIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )\r
+{\r
+ out_Iterator->Parent = self;\r
+ out_Iterator->ElementSize = ElementSize;\r
+ out_Iterator->Current = (uint8_t*) self->First - ElementSize;\r
+ return 0;\r
+}\r
\r
- s++;\r
- for (;;) {\r
- if ( *s == _T(' ') ) { s = s+1; break; }\r
- if ( *s == _T('\0') ) { s = NULL; break; }\r
- s++;\r
- }\r
- *pLine = s;\r
- return e;\r
\r
- case '\0':\r
- *t = _T('\0');\r
- *pLine = NULL;\r
- return 0;\r
+ \r
+/***********************************************************************\r
+ <<< [Set2_getDescendingIterator] >>> \r
+************************************************************************/\r
+errnum_t Set2_getDescendingIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )\r
+{\r
+ out_Iterator->Parent = self;\r
+ out_Iterator->ElementSize = ElementSize;\r
+ out_Iterator->Current = (uint8_t*) self->Next;\r
+ return 0;\r
+}\r
\r
- /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
- default: {\r
- c = *s;\r
- while ( c != _T(' ') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /* \8bó\94\92\95¶\8e\9a\82Ü\82Å */\r
\r
- if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }\r
+ \r
+/***********************************************************************\r
+ <<< [Set2_IteratorClass_getNext] >>> \r
+************************************************************************/\r
+void* Set2_IteratorClass_getNext( Set2_IteratorClass* self )\r
+{\r
+ uint8_t* next = self->Current + self->ElementSize;\r
\r
- /* \83R\83s\81[\82·\82é */\r
- *t = c; t++; s++; c = *s;\r
- }\r
+ if ( next >= (uint8_t*) self->Parent->Next ) {\r
+ return NULL;\r
+ } else {\r
+ self->Current = next;\r
+ return next;\r
+ }\r
+}\r
\r
- /* *pLine\82ð\8c\88\92è\82·\82é */\r
- while ( *s == _T(' ') ) s = s + 1;\r
- if ( *s == _T('\0') ) s = NULL;\r
\r
- /* \96\96\94ö */\r
- *t = _T('\0');\r
+ \r
+/***********************************************************************\r
+ <<< [Set2_IteratorClass_getPrevious] >>> \r
+************************************************************************/\r
+void* Set2_IteratorClass_getPrevious( Set2_IteratorClass* self )\r
+{\r
+ uint8_t* previous = self->Current - self->ElementSize;\r
\r
- *pLine = s;\r
- return e;\r
- }\r
+ if ( previous < (uint8_t*) self->Parent->First ) {\r
+ return NULL;\r
+ } else {\r
+ self->Current = previous;\r
+ return previous;\r
}\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [W3CDTF_fromSYSTEMTIME] >>> \r
+ <<< [Set2_alloc_imp] >>> \r
************************************************************************/\r
-errnum_t W3CDTF_fromSYSTEMTIME( TCHAR* out_W3CDTF, size_t W3CDTF_ByteSize,\r
- const SYSTEMTIME* Time, int TimeZoneMinute )\r
+errnum_t Set2_alloc_imp( Set2* m, void* pp, size_t size )\r
{\r
errnum_t e;\r
- TCHAR* char_pointer = out_W3CDTF;\r
\r
- e= stprintf_part_r( out_W3CDTF, W3CDTF_ByteSize, char_pointer, &char_pointer,\r
- _T("%04d-%02d-%02dT%02d:%02d:%02d.%03d"),\r
- Time->wYear, Time->wMonth, Time->wDay,\r
- Time->wHour, Time->wMinute, Time->wSecond, Time->wMilliseconds );\r
- IF(e){goto fin;}\r
+ e= Set2_expandIfOverByAddr( m, (char*) m->Next + size ); IF(e)goto fin;\r
+ *(void**)pp = m->Next;\r
+ m->Next = (char*) m->Next + size;\r
\r
- e= W3CDTF_getTimeZoneDesignator( char_pointer,\r
- GetStringSizeFromPointer( out_W3CDTF, W3CDTF_ByteSize, char_pointer ),\r
- TimeZoneMinute ); IF(e){goto fin;}\r
+ DISCARD_BYTES( *(void**)pp, size );\r
\r
e=0;\r
fin:\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [W3CDTF_toSYSTEMTIME] >>> \r
+ <<< [Set2_allocMulti_sub] >>> \r
************************************************************************/\r
-errnum_t W3CDTF_toSYSTEMTIME( const TCHAR* String, SYSTEMTIME* out_Time, int* out_BiasMinute )\r
+errnum_t Set2_allocMulti_sub( Set2* m, void* out_pElem, size_t ElemsSize )\r
{\r
errnum_t e;\r
- size_t string_length = _tcslen( String );\r
-\r
- /* 01234567890123456789012345678 */\r
- /*"yyyy-mm-ddThh:mm:ss.sss+00:00"*/\r
- /*"0000-00-00T00:00+00:00"*/\r
-\r
- IF_D( out_BiasMinute == NULL ) { e=E_OTHERS; goto fin; }\r
-\r
- /* With time */\r
- if ( string_length >= 11 ) {\r
- TCHAR a_char;\r
- const TCHAR* time_zone;\r
- int number;\r
-\r
- IF ( String[10] != _T('T') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- IF ( String[4] != _T('-') || String[7] != _T('-') )\r
- { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
-\r
- IF ( string_length < 16 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- IF ( String[13] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
-\r
- out_Time->wYear = (WORD) _ttoi( &String[0] );\r
- out_Time->wMonth = (WORD) _ttoi( &String[5] );\r
- out_Time->wDayOfWeek = 0;\r
- out_Time->wDay = (WORD) _ttoi( &String[8] );\r
- out_Time->wHour = (WORD) _ttoi( &String[11] );\r
- out_Time->wMinute = (WORD) _ttoi( &String[14] );\r
-\r
- a_char = String[16];\r
- if ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) {\r
- time_zone = &String[16];\r
- out_Time->wSecond = 0;\r
- out_Time->wMilliseconds = 0;\r
- } else {\r
- /* Second */\r
- IF ( string_length < 19 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- IF ( a_char != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- out_Time->wSecond = (WORD) _ttoi( &String[17] );\r
-\r
-\r
- /* \8f¬\90\94\93_ */\r
- a_char = String[19];\r
- if ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) {\r
- time_zone = &String[19];\r
- out_Time->wMilliseconds = 0;\r
- }\r
- else {\r
- IF ( a_char != _T('.') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
-\r
- out_Time->wMilliseconds = 0;\r
+ char* p;\r
\r
- number = String[20] - _T('0');\r
- if ( number < 0 || number > 9 ) {\r
- time_zone = &String[20];\r
- } else {\r
- out_Time->wMilliseconds += (WORD)( number * 100 );\r
+ e= Set2_expandIfOverByAddr( m, (char*) m->Next + ElemsSize ); IF(e)goto fin;\r
+ p = (char*) m->Next;\r
+ m->Next = p + ElemsSize;\r
+ *(char**)out_pElem = p;\r
\r
- number = String[21] - _T('0');\r
- if ( number < 0 || number > 9 ) {\r
- time_zone = &String[21];\r
- } else {\r
- out_Time->wMilliseconds += (WORD)( number * 10 );\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
- number = String[22] - _T('0');\r
- if ( number < 0 || number > 9 ) {\r
- time_zone = &String[22];\r
- } else {\r
- const TCHAR* pointer = &String[23];\r
\r
- out_Time->wMilliseconds += (WORD)( number * 1 );\r
+ \r
+/***********************************************************************\r
+ <<< [Set2_expandIfOverByAddr_imp] >>> \r
+************************************************************************/\r
+errnum_t Set2_expandIfOverByAddr_imp( Set2* m, void* OverAddrBasedOnNowFirst )\r
+{\r
+ errnum_t e;\r
+ void* new_first;\r
+ unsigned offset_of_over;\r
+ unsigned offset_of_next;\r
\r
- for (;;) {\r
- number = *pointer - _T('0');\r
- if ( number < 0 || number > 9 )\r
- { break; }\r
+ if ( OverAddrBasedOnNowFirst <= m->Over ) { e=E_OTHERS; goto fin; }\r
\r
- pointer += 1;\r
- }\r
- time_zone = pointer;\r
- }\r
- }\r
- }\r
+ offset_of_next = (unsigned)( (char*)OverAddrBasedOnNowFirst - (char*)m->First );\r
+ offset_of_over = (unsigned)( ( (char*)m->Over - (char*)m->First ) ) * 2;\r
+ IF_D( offset_of_next >= 0x80000000 ) { e=E_OTHERS; goto fin; }\r
+ if ( offset_of_over == 0 ) { offset_of_over = 0x100; }\r
+ while ( offset_of_over < offset_of_next ) { offset_of_over *= 2; }\r
+ IF( offset_of_over >= 0x10000000 ) { e=E_OTHERS; goto fin; }\r
\r
- a_char = *time_zone;\r
- IF ( ! ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) )\r
- { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- }\r
- }\r
+ new_first = realloc( m->First, offset_of_over * 2 );\r
+ IF( new_first == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
\r
- /* Time zone */\r
- if ( a_char == _T('Z') ) {\r
- *out_BiasMinute = 0;\r
- }\r
- else {\r
- size_t time_zone_length = string_length - ( time_zone - String );\r
- int bias_minute;\r
+ m->Next = (char*) new_first + ( (char*)m->Next - (char*)m->First );\r
+ m->Over = (char*) new_first + offset_of_over * 2;\r
+ m->First = new_first;\r
\r
- IF ( time_zone_length < 6 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- IF ( time_zone[3] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ #ifdef _DEBUG\r
+ if ( m->PointerOfDebugArray != NULL )\r
+ { *m->PointerOfDebugArray = m->First; }\r
+ #endif\r
\r
- bias_minute = _ttoi( &time_zone[1] ) * 60 + _ttoi( &time_zone[4] );\r
- if ( a_char == _T('-') ) { bias_minute = -bias_minute; }\r
- *out_BiasMinute = bias_minute;\r
- }\r
- }\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
- /* Without time */\r
- else {\r
- out_Time->wDayOfWeek = 0;\r
- out_Time->wHour = 0;\r
- out_Time->wMinute = 0;\r
- out_Time->wSecond = 0;\r
- out_Time->wMilliseconds = 0;\r
- *out_BiasMinute = 0;\r
\r
- IF ( string_length < 4 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ \r
+/***********************************************************************\r
+ <<< [Set2_free_imp] >>> \r
+************************************************************************/\r
+errnum_t Set2_free_imp( Set2* self, void* in_PointerOfPointer, size_t in_Size_ofElement, errnum_t e )\r
+{\r
+ void* element;\r
\r
- /* Year */\r
- out_Time->wYear = (WORD) _ttoi( &String[0] );\r
+ element = *(void**) in_PointerOfPointer;\r
\r
- /* Month */\r
- if ( string_length > 4 ) {\r
- IF ( string_length < 7 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- IF ( String[4] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- out_Time->wMonth = (WORD) _ttoi( &String[5] );\r
- } else {\r
- out_Time->wMonth = 1;\r
+ if ( element != NULL ) {\r
+ if ( element != ( (byte_t*) self->Next - in_Size_ofElement ) ) {\r
+ if ( e == 0 ) { e=E_OTHERS; }\r
}\r
+ else {\r
+ #ifndef NDEBUG\r
+ memset( element, 0xFE, in_Size_ofElement );\r
+ #endif\r
\r
- /* Day */\r
- if ( string_length > 7 ) {\r
- IF ( string_length < 10 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- IF ( String[7] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
- out_Time->wDay = (WORD) _ttoi( &String[8] );\r
- } else {\r
- out_Time->wDay = 1;\r
+ self->Next = element;\r
+\r
+ *(void**) in_PointerOfPointer = NULL;\r
}\r
}\r
-\r
- e=0;\r
-fin:\r
return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [W3CDTF_getTimeZoneDesignator] >>> \r
+ <<< [Set2_separate] >>> \r
************************************************************************/\r
-errnum_t W3CDTF_getTimeZoneDesignator( TCHAR* out_TZD, size_t TZD_ByteSize,\r
- int BiasMinute )\r
+errnum_t Set2_separate( Set2* m, int NextSize, void** allocate_Array )\r
{\r
errnum_t e;\r
- TCHAR sign;\r
- TIME_ZONE_INFORMATION time_zone;\r
+ void* p = m->First;\r
\r
-\r
- /* Set "BiasMinute" */\r
- if ( BiasMinute == W3CDTF_CURRENT_TIME_ZONE ) {\r
- GetTimeZoneInformation( &time_zone );\r
- BiasMinute = -time_zone.Bias;\r
+ if ( NextSize == 0 ) {\r
+ m->First = NULL;\r
+ m->Next = NULL;\r
+ m->Over = NULL;\r
}\r
else {\r
- enum { minute_1day = 1440 };\r
-\r
- IF_D ( BiasMinute < -minute_1day || BiasMinute > minute_1day )\r
- { e=E_OTHERS; goto fin; }\r
+ e= Set2_init( m, NextSize ); IF(e)goto fin;\r
}\r
+ *allocate_Array = p;\r
\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
- /* Set "sign" */\r
- if ( BiasMinute >= 0 ) {\r
- sign = _T('+');\r
- } else {\r
- sign = _T('-');\r
- BiasMinute = -BiasMinute;\r
- }\r
\r
+ \r
+/***********************************************************************\r
+ <<< [Set2_pop_imp] >>> \r
+************************************************************************/\r
+errnum_t Set2_pop_imp( Set2* m, void* pp, size_t size )\r
+{\r
+ errnum_t e;\r
+ void* p;\r
+\r
+ p = (char*) m->Next - size;\r
\r
- /* Set "out_TZD" */\r
- _stprintf_s( out_TZD, TZD_ByteSize / sizeof(TCHAR), _T("%c%02d:%02d"),\r
- sign, BiasMinute / 60, BiasMinute % 60 );\r
+ IF ( p < m->First ) { e=E_OTHERS; goto fin; }\r
+\r
+ m->Next = p;\r
+ *(void**)pp = p;\r
\r
e=0;\r
fin:\r
\r
\r
/***********************************************************************\r
- <<< [StrT_isFullPath] >>> \r
+ <<< [Set2_setDebug] >>> \r
************************************************************************/\r
-bool StrT_isFullPath( const TCHAR* path )\r
+#ifdef _DEBUG\r
+void Set2_setDebug( Set2* m, void* PointerOfDebugArray )\r
{\r
- bool ret;\r
+ m->PointerOfDebugArray = (void**) PointerOfDebugArray;\r
+ *m->PointerOfDebugArray = m->First;\r
+}\r
+#endif\r
\r
- if ( path[0] == _T('\\') && path[1] == _T('\\') ) {\r
- ret = true;\r
- } else {\r
- const TCHAR* back_slash = _tcschr( path, _T('\\') );\r
- const TCHAR* slash = _tcschr( path, _T('/') );\r
- const TCHAR* colon = _tcschr( path, _T(':') );\r
\r
- ret = ( colon != NULL ) &&\r
- ( back_slash == colon + 1 || slash == colon + 1 );\r
- }\r
+ \r
+/***********************************************************************\r
+ <<< [Set2a_init] >>> \r
+************************************************************************/\r
+int Set2a_init( Set2a* m, void* ArrInStack, size_t ArrInStack_Size )\r
+{\r
+ int e;\r
\r
- return ret;\r
+ /* "m->First" is initialized in "Set2a_initConst" */\r
+\r
+ m->Next = m->First;\r
+ m->Over = (char*)m->First + ArrInStack_Size;\r
+\r
+ ASSERT_D( m->First == ArrInStack, e=E_OTHERS; goto fin );\r
+\r
+ #ifdef _DEBUG\r
+ m->PointerOfDebugArray = NULL;\r
+ #endif\r
+\r
+ e=0;\r
+#ifdef _DEBUG\r
+fin:\r
+#else\r
+ UNREFERENCED_VARIABLE( ArrInStack );\r
+#endif\r
+ return e;\r
}\r
\r
+\r
\r
-/**************************************************************************\r
- <<< [StrT_getFullPath_part] >>> \r
-*************************************************************************/\r
-errnum_t StrT_getFullPath_part( TCHAR* out_FullPath, size_t FullPathSize, TCHAR* OutStart,\r
- TCHAR** out_OutLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
+/***********************************************************************\r
+ <<< [Set2a_alloc_imp] >>> \r
+************************************************************************/\r
+int Set2a_alloc_imp( Set2a* m, void* ArrInStack, void* out_Pointer, size_t ElemSize )\r
{\r
- errnum_t e;\r
- TCHAR separator = (TCHAR) DUMMY_INITIAL_VALUE_TCHAR;\r
- const TCHAR* separator_path;\r
- TCHAR* out_full_path_over = (TCHAR*)( (uint8_t*) out_FullPath + FullPathSize );\r
- TCHAR* null_position = NULL;\r
+ int e;\r
\r
+ e= Set2a_expandIfOverByAddr_imp( m, ArrInStack, (char*)m->Next + ElemSize ); IF(e)goto fin;\r
+ *(void**)out_Pointer = m->Next;\r
+ m->Next = (char*) m->Next + ElemSize;\r
\r
- #if CHECK_ARG\r
- /* "BasePath" must be out of "out_FullPath" */\r
- ASSERT_R( BasePath < out_FullPath ||\r
- (uint8_t*) BasePath >= (uint8_t*) out_FullPath + FullPathSize,\r
- goto err );\r
- #endif\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
\r
- /* If "StepPath" == "", out_FullPath = "" */\r
- if ( StepPath[0] == _T('\0') ) {\r
- ASSERT_R( FullPathSize >= sizeof(TCHAR), goto err_fm );\r
- out_FullPath[0] = _T('\0');\r
- e=0; goto fin;\r
- }\r
\r
+ \r
+/***********************************************************************\r
+ <<< [Set2a_expandIfOverByAddr_imp] >>> \r
+************************************************************************/\r
+int Set2a_expandIfOverByAddr_imp( Set2a* m, void* ArrInStack, void* OverAddrBasedOnNowFirst )\r
+{\r
+ void* new_memory;\r
+ unsigned ofs;\r
\r
- /* Set "OutStart" */\r
- if ( OutStart == NULL )\r
- { OutStart = out_FullPath; }\r
+ if ( m->First == ArrInStack ) {\r
+ ofs = (char*)m->Over - (char*)m->First;\r
+ new_memory = malloc( ofs * 2 );\r
+ IF( new_memory == NULL ) return E_FEW_MEMORY;\r
\r
+ memcpy( new_memory, m->First, ofs * 2 );\r
\r
- /* Set "separator" : \ or / from "BasePath" */\r
- if ( StrT_isFullPath( StepPath ) ) {\r
- separator_path = StepPath;\r
- }\r
- else if ( BasePath == NULL ) {\r
- separator = _T('\\');\r
- separator_path = NULL;\r
+ m->First = new_memory;\r
+ m->Over = (char*)new_memory + ofs * 2;\r
+ m->Next = (char*)new_memory + ofs;\r
+ return 0;\r
}\r
else {\r
- separator_path = BasePath;\r
+ return Set2_expandIfOverByAddr_imp( (Set2*) m, OverAddrBasedOnNowFirst );\r
}\r
- if ( separator_path != NULL ) {\r
- const TCHAR* p;\r
- const TCHAR* p2;\r
+}\r
\r
- p = _tcschr( separator_path, _T('\\') );\r
- p2 = _tcschr( separator_path, _T('/') );\r
- if ( p == NULL ) {\r
- if ( p2 == NULL )\r
- { separator = _T('\\'); }\r
- else\r
- { separator = _T('/'); }\r
- } else {\r
- if ( p2 == NULL )\r
- { separator = _T('\\'); }\r
- else {\r
- if ( p < p2 )\r
- { separator = _T('\\'); }\r
- else\r
- { separator = _T('/'); }\r
- }\r
- }\r
- }\r
\r
+ \r
+/*-------------------------------------------------------------------------*/\r
+/* <<<< ### (Set4) Class >>>> */ \r
+/*-------------------------------------------------------------------------*/\r
\r
- /* Set "OutStart" : "BasePath" + / + "StepPath" */\r
- if ( StrT_isFullPath( StepPath ) ) {\r
- size_t step_path_length = _tcslen( StepPath );\r
\r
- IF( OutStart + step_path_length >= out_full_path_over ) goto err_fa;\r
- memmove( OutStart, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );\r
+ \r
+/****************************************************************\r
+ <<< [Set4_init_imp] >>> \r
+*****************************************************************/\r
+errnum_t Set4_init_imp( Set4* self, size_t in_ElementSize, size_t in_FirstHeapSize )\r
+{\r
+ int element_count;\r
\r
- /* Set "null_position" */\r
- null_position = OutStart + step_path_length;\r
- }\r
- else {\r
- TCHAR c;\r
- TCHAR* p;\r
- size_t base_path_length;\r
- size_t step_path_length = _tcslen( StepPath );\r
+ self->FirstBlock = NULL;\r
+ self->CurrentBlockFirst = NULL;\r
+ self->u.NextBlock = &self->FirstBlock;\r
+ self->CurrentBlockNext = self->u.CurrentBlockOver;\r
+ element_count = ( in_FirstHeapSize - sizeof(void*) ) / in_ElementSize;\r
+ self->HeapSize = element_count * in_ElementSize + sizeof(void*);\r
+ self->ElementSize = in_ElementSize;\r
\r
- if ( BasePath == NULL ) {\r
- base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
- }\r
- else {\r
- base_path_length = _tcslen( BasePath );\r
- c = BasePath[ base_path_length - 1 ];\r
- if ( c == _T('\\') || c == _T('/') )\r
- { base_path_length -= 1; }\r
- }\r
+ return 0;\r
+}\r
\r
- p = OutStart + base_path_length + 1;\r
- IF( p + step_path_length >= out_full_path_over ) goto err_fa;\r
- memmove( p, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );\r
- /* memmove is for "out_FullPath" == "StepPath" */\r
\r
- if ( BasePath == NULL ) {\r
- GetCurrentDirectory( base_path_length + 1, OutStart );\r
- if ( OutStart[ base_path_length - 1 ] == _T('\\') )\r
- { base_path_length -= 1; }\r
- } else {\r
- memcpy( OutStart, BasePath, base_path_length * sizeof(TCHAR) );\r
- }\r
- OutStart[ base_path_length ] = separator;\r
+ \r
+/****************************************************************\r
+ <<< [Set4_finish2_imp] >>> \r
+*****************************************************************/\r
+errnum_t Set4_finish2_imp( Set4* self, errnum_t e, size_t in_ElementSize, FinalizeFuncType in_Type_Finalize )\r
+{\r
+ Set4Iter p;\r
\r
+ ASSERT_D( self->ElementSize == in_ElementSize, e= MergeError( e, E_OTHERS ); goto fin );\r
\r
- /* Set "null_position" */\r
- null_position = p + step_path_length;\r
+ for ( Set4_forEach_imp( self, &p, in_ElementSize ) ) {\r
+ e= in_Type_Finalize( p.p, e );\r
}\r
\r
+#ifndef NDEBUG\r
+fin:\r
+#endif\r
+ return e;\r
+}\r
\r
- /* Replace \ and / to "separator" in "OutStart" */\r
- {\r
- TCHAR other_separator;\r
\r
- if ( separator == _T('/') )\r
- { other_separator = _T('\\'); }\r
- else\r
- { other_separator = _T('/'); }\r
+ \r
+/****************************************************************\r
+ <<< [Set4_finish2_imp2] >>> \r
+*****************************************************************/\r
+errnum_t Set4_finish2_imp2( Set4* self )\r
+{\r
+ byte_t* p;\r
+ byte_t* p2;\r
\r
- e= StrT_replace1( OutStart, other_separator, separator, 0 ); IF(e)goto fin;\r
+ p = self->FirstBlock;\r
+ while ( p != NULL ) {\r
+ p2 = *(void**)( p + self->HeapSize - sizeof(void*) );\r
+ free( p );\r
+ p = p2;\r
}\r
\r
+ return 0;\r
+}\r
\r
- /* Replace \*\..\ to \ */\r
- {\r
- enum { length = 4 };\r
- TCHAR parent[ length + 1 ]; /* \..\ or /../ */\r
- TCHAR* parent_position;\r
- TCHAR* p;\r
-\r
- parent[0] = separator;\r
- parent[1] = _T('.');\r
- parent[2] = _T('.');\r
- parent[3] = separator;\r
- parent[4] = _T('\0');\r
\r
- for (;;) {\r
- parent_position = _tcsstr( OutStart, parent );\r
- if ( parent_position == NULL ) { break; }\r
+ \r
+/****************************************************************\r
+ <<< [Set4_alloc_imp] >>> \r
+*****************************************************************/\r
+errnum_t Set4_alloc_imp( Set4* self, void* out_ElementPointer, size_t in_ElementSize )\r
+{\r
+ errnum_t e;\r
+ byte_t* new_block;\r
+ byte_t* element;\r
\r
- p = parent_position - 1;\r
- for (;;) {\r
- IF( p < OutStart ) {goto err;} /* "../" are too many */\r
- if ( *p == separator ) { break; }\r
- p -= 1;\r
- }\r
+ ASSERT_D( in_ElementSize == self->ElementSize, e=E_OTHERS; goto fin );\r
\r
- memmove( p + 1,\r
- parent_position + length,\r
- ( null_position - ( parent_position + length ) + 1 ) * sizeof(TCHAR) );\r
+ /* Add new element */\r
+ if ( self->CurrentBlockNext == self->u.CurrentBlockOver ) {\r
+ new_block = (byte_t*) malloc( self->HeapSize );\r
+ IF ( new_block == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ element = new_block;\r
\r
- null_position -= ( parent_position + length ) - ( p + 1 );\r
- }\r
+ *self->u.NextBlock = new_block;\r
+ self->CurrentBlockNext = new_block + in_ElementSize;\r
+\r
+ self->CurrentBlockFirst = new_block;\r
+ self->u.CurrentBlockOver = new_block + self->HeapSize - sizeof(void*);\r
+ *self->u.NextBlock = NULL;\r
}\r
\r
+ /* Add existed element */\r
+ else {\r
+ ASSERT_D( self->CurrentBlockNext < self->u.CurrentBlockOver, e=E_OTHERS; goto fin );\r
+ element = self->CurrentBlockNext;\r
+ self->CurrentBlockNext += in_ElementSize;\r
+ }\r
\r
- /* Cut last \*\.. */\r
- {\r
- enum { length = 3 };\r
- TCHAR* p;\r
+ *(void**) out_ElementPointer = element;\r
\r
- while ( null_position - length >= OutStart ) {\r
- if ( *( null_position - 3 ) != separator ||\r
- *( null_position - 2 ) != _T('.') ||\r
- *( null_position - 1 ) != _T('.') )\r
- { break; }\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
- p = null_position - 4;\r
- for (;;) {\r
- IF( p < OutStart ) {goto err;} /* "../" are too many */\r
- if ( *p == separator ) { break; }\r
- p -= 1;\r
- }\r
\r
- *p = _T('\0');\r
+ \r
+/****************************************************************\r
+ <<< [Set4_free_imp] >>> \r
+*****************************************************************/\r
+errnum_t Set4_free_imp( Set4* self, void* in_out_ElementPointer, size_t in_ElementSize, errnum_t e0 )\r
+{\r
+ errnum_t e;\r
+ void* element = *(void**) in_out_ElementPointer;\r
\r
- null_position = p;\r
- }\r
- }\r
+ ASSERT_D( in_ElementSize == self->ElementSize, e=E_OTHERS; goto fin );\r
\r
+ if ( element != NULL ) {\r
+ if ( self->CurrentBlockNext == self->CurrentBlockFirst ) {\r
+ byte_t* block;\r
+ byte_t* previous_block = NULL;\r
+ byte_t* previous_element;\r
\r
- /* Replace \.\ to \ */\r
- {\r
- enum { length = 3 };\r
- TCHAR current[ length + 1 ]; /* \.\ or /./ */\r
- TCHAR* current_position;\r
+ for (\r
+ block = self->FirstBlock;\r
+ block != NULL;\r
+ block = *(byte_t**)( block + self->HeapSize - sizeof(void*) ) )\r
+ {\r
+ if ( block == self->CurrentBlockFirst )\r
+ { break; }\r
\r
- current[0] = separator;\r
- current[1] = _T('.');\r
- current[2] = separator;\r
- current[3] = _T('\0');\r
+ previous_block = block;\r
+ }\r
+ ASSERT_R( previous_block != NULL, e=E_OTHERS; goto fin );\r
\r
- for (;;) {\r
- current_position = _tcsstr( OutStart, current );\r
- if ( current_position == NULL ) { break; }\r
+ previous_element = previous_block + self->HeapSize - sizeof(void*) - in_ElementSize;\r
+ ASSERT_R( element == previous_element, e=E_ACCESS_DENIED; goto fin );\r
\r
- memmove( current_position + 1,\r
- current_position + length,\r
- ( null_position - ( current_position + length ) + 1 ) * sizeof(TCHAR) );\r
+ free( block );\r
+ self->CurrentBlockFirst = previous_block;\r
+ self->CurrentBlockNext = previous_element;\r
+ self->u.CurrentBlockOver = previous_element + in_ElementSize;\r
+ *self->u.NextBlock = NULL;\r
+ }\r
+ else {\r
+ byte_t* previous_element = self->CurrentBlockNext - in_ElementSize;\r
\r
- null_position -= length - 1;\r
+ ASSERT_D( element == previous_element, e=E_ACCESS_DENIED; goto fin );\r
+\r
+ self->CurrentBlockNext = previous_element;\r
}\r
+\r
+ *(void**) in_out_ElementPointer = NULL;\r
}\r
\r
+ e=0;\r
+fin:\r
+ if ( e0 == 0 )\r
+ { e0 = e; }\r
+ return e0;\r
+}\r
\r
- /* Cut last \. */\r
- {\r
- TCHAR* over = _tcschr( OutStart, _T('\0') );\r
\r
- while ( over - 2 >= OutStart &&\r
- *( over - 1 ) == _T('.') && *( over - 2 ) == separator ) {\r
- over -= 2;\r
- *over = _T('\0');\r
- }\r
+ \r
+/****************************************************************\r
+ <<< [Set4_ref_imp] >>> \r
+*****************************************************************/\r
+void* Set4_ref_imp( Set4* self, int i, int size )\r
+{\r
+ byte_t* p = self->FirstBlock;\r
+ size_t offset = i * size;\r
+ size_t offset_over = self->HeapSize - sizeof(void*);\r
+\r
+ if ( i < 0 ) { return NULL; }\r
+\r
+ if ( p == NULL ) { return NULL; }\r
+ while ( offset >= offset_over ) {\r
+ p = *(void**)( (char*)p + offset_over );\r
+ if ( p == NULL ) { return NULL; }\r
+ offset -= offset_over;\r
}\r
\r
+ p += offset;\r
+ if ( p >= self->CurrentBlockNext ) { return NULL; }\r
\r
- /* Add root / */\r
- if ( null_position - 1 >= OutStart ) {\r
- if ( *( null_position - 1 ) == _T(':') ) {\r
- IF( null_position + 1 >= out_full_path_over ) goto err_fa;\r
+ return p;\r
+}\r
\r
- *( null_position + 0 ) = separator;\r
- *( null_position + 1 ) = _T('\0');\r
- null_position += 1;\r
- }\r
+\r
+ \r
+/****************************************************************\r
+ <<< [Set4_getCount_imp] >>> \r
+*****************************************************************/\r
+int Set4_getCount_imp( Set4* self, int size )\r
+{\r
+ void* p = self->FirstBlock;\r
+ void* p2 = NULL;\r
+ int offset = 0;\r
+ int offset_over = self->HeapSize - sizeof(void*);\r
+\r
+ if ( p == NULL ) { return 0; }\r
+\r
+ for (;;) {\r
+ p2 = p;\r
+ p = *(void**)( (char*)p + offset_over );\r
+ if ( p == NULL ) break;\r
+ offset += offset_over;\r
}\r
\r
+ offset += (int)( (char*)self->CurrentBlockNext - (char*)p2 );\r
\r
- /* Set "*out_OutLast" */\r
- if ( out_OutLast != NULL )\r
- { *out_OutLast = null_position; }\r
+ return offset / size;\r
+}\r
\r
- e=0;\r
-fin:\r
- return e;\r
\r
-err: e = E_OTHERS; goto fin;\r
-err_fa: e = E_FEW_ARRAY; goto fin;\r
-err_fm: e = E_FEW_MEMORY; goto fin;\r
+ \r
+/****************************************************************\r
+ <<< [Set4_forEach_imp2] >>> \r
+*****************************************************************/\r
+void Set4_forEach_imp2( Set4* self, Set4Iter* p, int size )\r
+{\r
+ if ( p->p == NULL ) { /* first */\r
+ if ( self->FirstBlock == NULL ) return; /* elem count = 0 */\r
+ p->Over = &self->FirstBlock;\r
+ }\r
+ else { /* The next of array */\r
+ p->p = (char*)p->p + size;\r
+ if ( p->p < p->Over ) return;\r
+ }\r
+\r
+ /* The last element */\r
+ if ( p->p == self->CurrentBlockNext ) { p->p = NULL; return; }\r
+\r
+ /* The next element */\r
+ p->p = *(void**) p->Over;\r
+ p->Over = (char*)p->p + self->HeapSize - sizeof(void*);\r
+ if ( *(void**)p->Over == NULL ) p->Over = self->CurrentBlockNext;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [StrT_allocateFullPath] >>> \r
+ <<< (ListClass) >>> \r
************************************************************************/\r
-errnum_t StrT_allocateFullPath( TCHAR** out_FullPath, const TCHAR* StepPath, TCHAR* BasePath )\r
+\r
+/*[ListClass_initConst]*/\r
+void ListClass_initConst( ListClass* self )\r
{\r
- errnum_t e;\r
- int step_path_length = _tcslen( StepPath );\r
- int base_path_length;\r
- int full_path_size;\r
+ self->Terminator.Data = NULL;\r
+ self->Terminator.List = self;\r
+ self->Terminator.Next = &self->Terminator;\r
+ self->Terminator.Previous = &self->Terminator;\r
+ self->Count = 0;\r
+}\r
\r
- if ( BasePath == NULL ) {\r
- base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
- } else {\r
- base_path_length = _tcslen( BasePath );\r
- }\r
\r
- full_path_size = ( step_path_length + 1 + base_path_length + 1 ) * sizeof(TCHAR);\r
+/*[ListClass_addAtIndex]*/\r
+errnum_t ListClass_addAtIndex( ListClass* self, int Index, ListElementClass* Element )\r
+{\r
+ errnum_t e;\r
+ ListElementClass* target;\r
\r
- e= HeapMemory_allocateBytes( out_FullPath, full_path_size ); IF(e){goto fin;}\r
- e= StrT_getFullPath( *out_FullPath, full_path_size, StepPath, BasePath ); IF(e){goto fin;}\r
+ if ( Index == self->Count ) {\r
+ e= ListClass_addLast( self, Element ); IF(e){goto fin;}\r
+ }\r
+ else {\r
+ e= ListClass_get( self, Index, &target ); IF(e){goto fin;}\r
+ e= ListClass_addAt_Sub( Element, target ); IF(e){goto fin;}\r
+ }\r
\r
e=0;\r
fin:\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [StrT_getParentFullPath_part] >>> \r
-************************************************************************/\r
-errnum_t StrT_getParentFullPath_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
- TCHAR** out_StrLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
+/*[ListClass_addAt_Sub]*/\r
+errnum_t ListClass_addAt_Sub( ListElementClass* AddingElement, ListElementClass* Target )\r
{\r
- errnum_t e;\r
- TCHAR* p;\r
+ errnum_t e;\r
+ ListElementClass* target_previous = Target->Previous;\r
+ ListClass* self = Target->List;\r
\r
- IF_D( StrStart < Str || (char*) StrStart >= (char*)Str + StrSize ){goto err;}\r
+ ASSERT_R( AddingElement->List == NULL, e=E_ACCESS_DENIED; goto fin );\r
\r
- if ( StepPath[0] == _T('\0') ) {\r
- *StrStart = _T('\0');\r
- return 0;\r
- }\r
+ AddingElement->Next = Target;\r
+ AddingElement->Previous = target_previous;\r
+ target_previous->Next = AddingElement;\r
+ Target->Previous = AddingElement;\r
+ AddingElement->List = self;\r
+ self->Count += 1;\r
\r
- /* \90â\91Î\83p\83X\82É\82·\82é */\r
- e= StrT_getFullPath( StrStart,\r
- StrSize - ( (char*)StrStart - (char*)Str ),\r
- StepPath, BasePath ); IF(e)goto fin;\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
\r
- /* Cut last \ */\r
- p = _tcschr( StrStart, _T('\0') );\r
- if ( p > StrStart ) {\r
- TCHAR c = *( p - 1 );\r
- if ( c == _T('\\') || c == _T('/') )\r
- { *( p - 1 ) = _T('\0'); }\r
+/*[ListClass_get]*/\r
+errnum_t ListClass_get( ListClass* self, int Index, ListElementClass** out_Element )\r
+{\r
+ errnum_t e;\r
+ ListElementClass* element = self->Terminator.Next;\r
+\r
+ ASSERT_R( Index >= 0 && Index < self->Count, e=E_NOT_FOUND_SYMBOL; goto fin );\r
+\r
+ while ( Index != 0 ) {\r
+ element = element->Next;\r
+ Index -= 1;\r
}\r
\r
+ *out_Element = element;\r
\r
- /* \90e\82Ö */\r
- p = StrT_refFName( StrStart );\r
- if ( p > StrStart ) p--;\r
- *p = _T('\0');\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
\r
- /* \83\8b\81[\83g\82È\82ç \ \82ð\95t\82¯\82é */\r
- if ( p == StrStart + 2 ) {\r
- *p = _T('\\'); p++; *p = _T('\0');\r
- }\r
+/*[ListClass_set]*/\r
+errnum_t ListClass_set( ListClass* self, int Index, ListElementClass* Element )\r
+{\r
+ errnum_t e;\r
+ ListElementClass* target;\r
\r
- if ( out_StrLast != NULL ) *out_StrLast = p;\r
+ ASSERT_R( Element->List == NULL, e=E_ACCESS_DENIED; goto fin );\r
+\r
+ e= ListClass_get( self, Index, &target ); IF(e){goto fin;}\r
+ e= ListClass_replace( self, target, Element ); IF(e){goto fin;}\r
\r
e=0;\r
fin:\r
return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [StrT_isOverOfFileName] >>> \r
-- "" or "\" or "/"\r
-************************************************************************/\r
-inline bool StrT_isOverOfFileName( const TCHAR* PointerInPath )\r
+/*[ListClass_replace]*/\r
+errnum_t ListClass_replace( ListClass* self, ListElementClass* RemovingElement,\r
+ ListElementClass* AddingElement )\r
{\r
- return PointerInPath == NULL ||\r
- *PointerInPath == _T('\0') ||\r
- ( ( *PointerInPath == _T('\\') || *PointerInPath == _T('/') ) &&\r
- *(PointerInPath + 1) == _T('\0') );\r
+ errnum_t e;\r
+\r
+ ASSERT_R( RemovingElement->List == self, e=E_NOT_FOUND_SYMBOL; goto fin );\r
+ ASSERT_R( AddingElement->List == NULL, e=E_ACCESS_DENIED; goto fin );\r
+ ASSERT_R( RemovingElement != &RemovingElement->List->Terminator,\r
+ e=E_NOT_FOUND_SYMBOL; goto fin );\r
+\r
+ RemovingElement->Next->Previous = AddingElement;\r
+ RemovingElement->Previous->Next = AddingElement;\r
+ AddingElement->Next = RemovingElement->Next;\r
+ AddingElement->Previous = RemovingElement->Previous;\r
+\r
+ AddingElement->List = self;\r
+\r
+ RemovingElement->List = NULL;\r
+ #ifndef NDEBUG\r
+ RemovingElement->Next = NULL;\r
+ RemovingElement->Previous = NULL;\r
+ #endif\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [StrT_getStepPath] >>> \r
-************************************************************************/\r
-errnum_t StrT_getStepPath( TCHAR* out_StepPath, size_t StepPathSize,\r
- const TCHAR* FullPath, const TCHAR* BasePath )\r
+/*[ListClass_getIndexOfData]*/\r
+int ListClass_getIndexOfData( ListClass* self, void* Data )\r
{\r
- errnum_t e;\r
- const TCHAR* abs_pointer;\r
- const TCHAR* base_pointer;\r
- TCHAR abs_char;\r
- TCHAR base_char;\r
- TCHAR separator;\r
- const TCHAR* abs_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
- const TCHAR* base_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
- TCHAR* step_pointer;\r
- TCHAR parent_symbol[4] = { _T('.'), _T('.'), _T('\\'), _T('\0') };\r
- TCHAR base_path_2[ MAX_PATH ];\r
+ int index;\r
+ ListElementClass* element = self->Terminator.Next;\r
+ ListElementClass* tarminator = &self->Terminator;\r
\r
+ for ( index = 0; ; index += 1 ) {\r
+ if ( element == tarminator )\r
+ { return INVALID_ARRAY_INDEX; }\r
\r
- ASSERT_D( out_StepPath != FullPath, goto err );\r
+ if ( element->Data == Data )\r
+ { return index; }\r
\r
- abs_pointer = FullPath;\r
+ element = element->Next;\r
+ }\r
+}\r
\r
\r
- /* Set "base_pointer" */\r
- if ( BasePath == NULL ) {\r
- base_pointer = _tgetcwd( base_path_2, _countof(base_path_2) );\r
- IF( base_pointer == NULL ) {goto err;}\r
+/*[ListClass_getIndexOf]*/\r
+int ListClass_getIndexOf( ListClass* self, ListElementClass* Element )\r
+{\r
+ int index;\r
+ ListElementClass* elem = self->Terminator.Next;\r
+ ListElementClass* tarminator = &self->Terminator;\r
+\r
+ for ( index = 0; ; index += 1 ) {\r
+ if ( elem == Element )\r
+ { return index; }\r
+\r
+ if ( elem == tarminator )\r
+ { return INVALID_ARRAY_INDEX; }\r
+\r
+ elem = elem->Next;\r
}\r
- else {\r
- base_pointer = BasePath;\r
+}\r
+\r
+\r
+/*[ListClass_getLastIndexOfData]*/\r
+int ListClass_getLastIndexOfData( ListClass* self, void* Data )\r
+{\r
+ int index;\r
+ ListElementClass* element = self->Terminator.Previous;\r
+ ListElementClass* tarminator = &self->Terminator;\r
+\r
+ for ( index = self->Count - 1; ; index -= 1 ) {\r
+ if ( element == tarminator )\r
+ { return INVALID_ARRAY_INDEX; }\r
+\r
+ if ( element->Data == Data )\r
+ { return index; }\r
+\r
+ element = element->Previous;\r
}\r
+}\r
\r
\r
- /* Set "abs_separator_pointer", "base_separator_pointer" : after same parent folder path */\r
- separator = 0;\r
- for (;;) { /* while abs_char == base_char */\r
- abs_char = *abs_pointer;\r
- base_char = *base_pointer;\r
+/*[ListClass_getArray]*/\r
+errnum_t ListClass_getArray( ListClass* self, void* DataArray, size_t DataArraySize )\r
+{\r
+ errnum_t e;\r
+ ListIteratorClass iterator;\r
+ void* data;\r
+ void** data_pointer;\r
\r
- abs_char = (TCHAR) _totlower( abs_char );\r
- base_char = (TCHAR) _totlower( base_char );\r
+ ASSERT_R( DataArraySize >= self->Count * sizeof(void*), e=E_FEW_ARRAY; goto fin );\r
\r
- if ( abs_char == _T('\0') ) {\r
+ e= ListClass_getListIterator( self, &iterator ); IF(e){goto fin;}\r
+ for ( data_pointer = (void**) DataArray; ; data_pointer += 1 ) {\r
+ data = ListIteratorClass_getNext( &iterator );\r
+ if ( data == NULL ) { break; }\r
\r
- /* out_StepPath = ".", if FullPath == BasePath */\r
- if ( base_char == _T('\0') ) {\r
- e= StrT_cpy( out_StepPath, StepPathSize, _T(".") ); IF(e)goto fin;\r
- e=0; goto fin;\r
- }\r
- break;\r
- }\r
- if ( base_char == _T('\0') ) { break; }\r
+ *data_pointer = data;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+/*[ListClass_removeByIndex]*/\r
+errnum_t ListClass_removeByIndex( ListClass* self, int Index )\r
+{\r
+ errnum_t e;\r
+ ListElementClass* target;\r
\r
- if ( abs_char != base_char ) {\r
- if ( ( abs_char == _T('/') || abs_char == _T('\\') ) &&\r
- ( base_char == _T('/') || base_char == _T('\\') ) )\r
- { /* Do nothing */ }\r
- else\r
- { break; }\r
- }\r
+ e= ListClass_get( self, Index, &target ); IF(e){goto fin;}\r
+ e= ListClass_remove( self, target ); IF(e){goto fin;}\r
\r
- /* Set "separator", "abs_separator_pointer", "base_separator_pointer" */\r
- if ( base_char == _T('/') || base_char == _T('\\') ) {\r
- if ( separator == 0 )\r
- { separator = base_char; }\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
\r
- abs_separator_pointer = abs_pointer;\r
- base_separator_pointer = base_pointer;\r
- }\r
\r
- abs_pointer += 1;\r
- base_pointer += 1;\r
+/*[ListClass_remove]*/\r
+errnum_t ListClass_remove( ListClass* self, ListElementClass* Element )\r
+{\r
+ if ( Element->List == self ) {\r
+ Element->Previous->Next = Element->Next;\r
+ Element->Next->Previous = Element->Previous;\r
+ Element->List = NULL;\r
+ #ifndef NDEBUG\r
+ Element->Next = NULL;\r
+ Element->Previous = NULL;\r
+ #endif\r
+ self->Count -= 1;\r
}\r
+ return 0;\r
+}\r
\r
\r
- /* 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
- if ( abs_char == _T('/') || abs_char == _T('\\') ||\r
- base_char == _T('/') || base_char == _T('\\') ) {\r
- /* other character is '\0' */\r
+/*[ListClass_clear]*/\r
+errnum_t ListClass_clear( ListClass* self )\r
+{\r
+ ListElementClass* target = self->Terminator.Next;\r
+ ListElementClass* next;\r
+ ListElementClass* terminator = &self->Terminator;\r
\r
- if ( separator == 0 )\r
- { separator = abs_char; }\r
+ while ( target != terminator ) {\r
+ target->List = NULL;\r
\r
- abs_separator_pointer = abs_pointer;\r
- base_separator_pointer = base_pointer;\r
+ next = target->Next;\r
+ #ifndef NDEBUG\r
+ target->Next = NULL;\r
+ target->Previous = NULL;\r
+ #endif\r
+ target = next;\r
}\r
\r
+ self->Terminator.Next = terminator;\r
+ self->Terminator.Previous = terminator;\r
+ self->Count = 0;\r
\r
- /* out_StepPath = FullPath, if there is not same folder */\r
- if ( separator == 0 ) {\r
- e= StrT_cpy( out_StepPath, StepPathSize, FullPath ); IF(e)goto fin;\r
- e=0; goto fin;\r
- }\r
+ return 0;\r
+}\r
\r
\r
- /* Add "..\" to "out_StepPath" */\r
- parent_symbol[2] = separator;\r
- step_pointer = out_StepPath;\r
- for (;;) {\r
- const TCHAR* p1;\r
- const TCHAR* p2;\r
+/*[ListIteratorClass_getNext]*/\r
+void* ListIteratorClass_getNext( ListIteratorClass* self )\r
+{\r
+ ListElementClass* next = self->Element->Next;\r
\r
- if ( StrT_isOverOfFileName( base_separator_pointer ) )\r
- { break; }\r
+ self->Element = next;\r
\r
+ if ( next == &next->List->Terminator )\r
+ { return NULL; }\r
+ else\r
+ { return next->Data; }\r
+}\r
\r
- /* Set "base_separator_pointer" : next separator */\r
- p1 = _tcschr( base_separator_pointer + 1, _T('/') );\r
- p2 = _tcschr( base_separator_pointer + 1, _T('\\') );\r
\r
- if ( p1 == NULL ) {\r
- if ( p2 == NULL )\r
- { base_separator_pointer = NULL; }\r
- else\r
- { base_separator_pointer = p2; }\r
- }\r
- else {\r
- if ( p2 == NULL ) {\r
- base_separator_pointer = p1;\r
- } else {\r
- if ( p1 < p2 )\r
- { base_separator_pointer = p1; }\r
- else\r
- { base_separator_pointer = p2; }\r
- }\r
- }\r
+/*[ListIteratorClass_getPrevious]*/\r
+void* ListIteratorClass_getPrevious( ListIteratorClass* self )\r
+{\r
+ ListElementClass* previous = self->Element->Previous;\r
\r
+ self->Element = previous;\r
\r
- /* Add "..\" to "out_StepPath" */\r
- e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, &step_pointer,\r
- parent_symbol, NULL ); IF(e)goto fin;\r
- }\r
+ if ( previous == &previous->List->Terminator )\r
+ { return NULL; }\r
+ else\r
+ { return previous->Data; }\r
+}\r
\r
\r
- /* Copy a part of "FullPath" to "out_StepPath" */\r
- if ( StrT_isOverOfFileName( abs_separator_pointer ) ) {\r
- ASSERT_D( step_pointer > out_StepPath, goto err );\r
- *( step_pointer - 1 ) = _T('\0');\r
- }\r
- else {\r
- e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, NULL,\r
- abs_separator_pointer + 1, NULL ); IF(e)goto fin;\r
- }\r
+/*[ListIteratorClass_replace]*/\r
+errnum_t ListIteratorClass_replace( ListIteratorClass* self, ListElementClass* AddingElement )\r
+{\r
+ errnum_t e;\r
+ ListElementClass* removing_element = self->Element;\r
+\r
+ e= ListClass_replace( removing_element->List, removing_element, AddingElement );\r
+ IF(e){goto fin;}\r
+ self->Element = AddingElement;\r
\r
e=0;\r
fin:\r
return e;\r
+}\r
\r
-err: e = E_OTHERS; goto fin;\r
+\r
+/*[ListIteratorClass_remove]*/\r
+errnum_t ListIteratorClass_remove( ListIteratorClass* self )\r
+{\r
+ errnum_t e;\r
+ ListElementClass* removing_element = self->Element;\r
+\r
+ ASSERT_R( removing_element->List != NULL, e=E_NOT_FOUND_SYMBOL; goto fin );\r
+ /* Already removed */\r
+ ASSERT_R( removing_element != &removing_element->List->Terminator,\r
+ e=E_NOT_FOUND_SYMBOL; goto fin ); /* Over next or previous */\r
+\r
+ self->ModifiedElement.Next = removing_element->Next;\r
+ self->ModifiedElement.Previous = removing_element->Previous;\r
+ self->Element = &self->ModifiedElement;\r
+\r
+ e= ListClass_remove( removing_element->List, removing_element ); IF(e){goto fin;}\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [StrT_getBaseName_part] >>> \r
+ <<< [ListClass_finalizeWithVTable] >>> \r
************************************************************************/\r
-errnum_t StrT_getBaseName_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
- TCHAR** out_StrLast, const TCHAR* SrcPath )\r
+errnum_t ListClass_finalizeWithVTable( ListClass* self, bool IsFreeElements, errnum_t e )\r
{\r
- const TCHAR* p1;\r
- const TCHAR* p2;\r
- const TCHAR* p3;\r
- const TCHAR* ps;\r
+ errnum_t ee;\r
+ ListIteratorClass iterator;\r
+ ClassID_SuperClass* element;\r
+ FinalizerVTableClass* v_table;\r
\r
- p1 = StrT_refFName( SrcPath );\r
+ ee= ListClass_getListIterator( self, &iterator );\r
+ IF ( ee ) {\r
+ if ( e == 0 ) { e = ee; }\r
+ goto fin;\r
+ }\r
\r
+ for (;;) {\r
+ element = (ClassID_SuperClass*) ListIteratorClass_getNext( &iterator );\r
+ if ( element == NULL ) { break; }\r
+ ee= ListIteratorClass_remove( &iterator );\r
+\r
+ /* Call "Finalize" */\r
+ v_table = (FinalizerVTableClass*) ClassID_Class_getVTable(\r
+ element->ClassID, &g_FinalizerInterface_ID );\r
+ IF ( v_table == NULL ) {\r
+ if ( e == 0 ) { e=E_OTHERS; }\r
+ }\r
+ else {\r
+ e= v_table->Finalize( element, e );\r
+ }\r
\r
- //=== # \82ª\96³\82¢\82Æ\82«\81A\8dÅ\8cã\82Ì\83s\83\8a\83I\83h\82Ì\91O\82Ü\82Å\82ª\81ABaseName\r
- ps = _tcschr( p1, _T('#') );\r
- if ( ps == NULL ) {\r
- p2 = _tcsrchr( p1, _T('.') );\r
- if ( p2 == NULL ) p2 = _tcsrchr( p1, _T('\0') );\r
+ /* Call "HeapMemory_free" */\r
+ if ( IsFreeElements ) {\r
+ e= HeapMemory_free( &element, e );\r
+ }\r
}\r
\r
- //=== # \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
- else {\r
- p2 = ps;\r
+fin:\r
+ return e;\r
+}\r
\r
- p3 = p1;\r
- for (;;) {\r
- p3 = _tcschr( p3, _T('.') );\r
- if ( p3 == NULL || p3 > ps ) break;\r
- p2 = p3;\r
- p3 ++;\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ListClass_printXML] >>> \r
+************************************************************************/\r
+errnum_t ListClass_printXML( ListClass* self, FILE* OutputStream )\r
+{\r
+ errnum_t e;\r
+ ListIteratorClass iterator;\r
+ ClassID_SuperClass* element;\r
+ PrintXML_VTableClass* v_table;\r
+\r
+ e= ListClass_getListIterator( self, &iterator ); IF(e){goto fin;}\r
+ for (;;) {\r
+ element = (ClassID_SuperClass*) ListIteratorClass_getNext( &iterator );\r
+ if ( element == NULL ) { break; }\r
+\r
+ /* Call "PrintXML" */\r
+ v_table = (PrintXML_VTableClass*) ClassID_Class_getVTable(\r
+ element->ClassID, &g_PrintXML_Interface_ID );\r
+ if ( v_table == NULL ) {\r
+ _ftprintf_s( OutputStream, _T("<UnknownClass error=\"Not found PrintXML_VTable\"/>\n") );\r
+ }\r
+ else {\r
+ e= v_table->PrintXML( element, OutputStream ); IF(e){goto fin;}\r
}\r
}\r
\r
- return stcpy_part_r( Str, StrSize, StrStart, out_StrLast, p1, p2 );\r
+ e=0;\r
+fin:\r
+ return e;\r
}\r
\r
+\r
\r
/***********************************************************************\r
- <<< [StrT_addLastOfFileName] >>> \r
+ <<< (VariantListClass) >>> \r
************************************************************************/\r
-errnum_t StrT_addLastOfFileName( TCHAR* out_Path, size_t PathSize,\r
- const TCHAR* BasePath, const TCHAR* AddName )\r
+\r
+/*[VariantListClass_initConst]*/\r
+void VariantListClass_initConst( VariantListClass* self )\r
{\r
- TCHAR c;\r
- size_t copy_size;\r
- size_t free_size;\r
- char* out_pos;\r
- const TCHAR* last_pos_in_base = _tcschr( BasePath, _T('\0') );\r
- const TCHAR* term_pos_in_base;\r
- const TCHAR* add_pos_in_base;\r
- const TCHAR* period_pos_in_base = _tcsrchr( BasePath, _T('.') ); // > term_pos_in_base\r
- const TCHAR* last_pos_in_add = _tcschr( AddName, _T('\0') );\r
- const TCHAR* term_pos_in_add;\r
- const TCHAR* period_pos_in_add = _tcsrchr( AddName, _T('.') ); // > term_pos_in_add\r
+ ListClass_initConst( &self->List );\r
+}\r
\r
\r
- DISCARD_BYTES( out_Path, PathSize );\r
+/*[VariantListClass_finalize]*/\r
+errnum_t VariantListClass_finalize( VariantListClass* self, errnum_t e )\r
+{\r
+ errnum_t ee;\r
+ ListIteratorClass iterator;\r
+ VariantClass* variant;\r
\r
+ ee= ListClass_getListIterator( &self->List, &iterator );\r
+ IF (ee) {\r
+ if ( e == 0 ) { e = ee; }\r
+ goto fin;\r
+ }\r
\r
- //=== term_pos_in_base\r
- for ( term_pos_in_base = last_pos_in_base; term_pos_in_base >= BasePath; term_pos_in_base -- ) {\r
- c = *term_pos_in_base;\r
- if ( c == _T('/') || c == _T('\\') ) break;\r
+ for (;;) {\r
+ variant = (VariantClass*) ListIteratorClass_getNext( &iterator );\r
+ if ( variant == NULL ) { break; }\r
+ ee= ListIteratorClass_remove( &iterator );\r
+ if ( ee == 0 ) {\r
+ Variant_SuperClass* object = variant->Object;\r
+ FinalizerVTableClass* v_table;\r
+\r
+ v_table = ClassID_Class_getVTable( object->ClassID, &g_FinalizerInterface_ID );\r
+ if ( v_table != NULL ) {\r
+ e= v_table->Finalize( object, e );\r
+ }\r
+ e= FreeMemory( &object, e );\r
+ e= FreeMemory( &variant, e );\r
+ }\r
}\r
\r
+fin:\r
+ return e;\r
+}\r
\r
- //=== term_pos_in_add\r
- for ( term_pos_in_add = last_pos_in_add; term_pos_in_add >= AddName; term_pos_in_add -- ) {\r
- c = *term_pos_in_add;\r
- if ( c == _T('/') || c == _T('\\') ) break;\r
- }\r
\r
+/*[VariantListClass_createElement]*/\r
+errnum_t VariantListClass_createElement( VariantListClass* self,\r
+ void* /*<Variant_SuperClass**>*/ out_ElementObject,\r
+ const ClassID_Class* ClassID, void* Parameter )\r
+{\r
+ errnum_t e;\r
+ VariantClass* variant = NULL;\r
+ Variant_SuperClass* object = NULL;\r
+ InitializeFuncType initialize;\r
+ bool is_initialized = false;\r
\r
- //=== add_pos_in_base\r
- if ( term_pos_in_base < period_pos_in_base ) {\r
- add_pos_in_base = period_pos_in_base;\r
- }\r
- else {\r
- if ( term_pos_in_base < BasePath )\r
- add_pos_in_base = _tcschr( BasePath, _T('\0') );\r
- else\r
- add_pos_in_base = _tcschr( term_pos_in_base, _T('\0') );\r
+ e= MallocMemory( &variant, sizeof( VariantClass ) ); IF(e){goto fin;}\r
+ ListElementClass_initConst( &variant->ListElement, variant );\r
+\r
+ e= MallocMemory( &object, ClassID->Size ); IF(e){goto fin;}\r
+ initialize = ClassID->InitializeFunction;\r
+ if ( initialize != NULL ) {\r
+ e= initialize( object, Parameter ); IF(e){goto fin;}\r
}\r
+ is_initialized = true;\r
\r
+ variant->Object = object;\r
+ object->StaticAddress = variant;\r
+ e= ListClass_addLast( &self->List, &variant->ListElement ); IF(e){goto fin;}\r
\r
- //=== setup output parameters\r
- out_pos = (char*) out_Path;\r
- free_size = PathSize;\r
+ *(Variant_SuperClass**) out_ElementObject = object;\r
\r
+ e=0;\r
+fin:\r
+ if ( e != 0 ) {\r
+ if ( is_initialized ) {\r
+ FinalizerVTableClass* v_table;\r
\r
- //=== copy BasePath .. add_pos_in_base\r
- copy_size = (char*)add_pos_in_base - (char*)BasePath;\r
- if ( copy_size > free_size ) goto err_fa;\r
- memcpy( out_pos, BasePath, copy_size );\r
- out_pos += copy_size;\r
- free_size -= copy_size;\r
+ v_table = ClassID_Class_getVTable( ClassID, &g_FinalizerInterface_ID );\r
+ if ( v_table != NULL ) {\r
+ e= v_table->Finalize( object, e );\r
+ }\r
+ }\r
+ e= FreeMemory( &object, e );\r
+ e= FreeMemory( &variant, e );\r
+ }\r
+ return e;\r
+}\r
\r
\r
- //=== copy AddName .. last_pos_in_add\r
- copy_size = (char*)last_pos_in_add - (char*)AddName;\r
- if ( copy_size > free_size ) goto err_fa;\r
- memcpy( out_pos, AddName, copy_size );\r
- out_pos += copy_size;\r
- free_size -= copy_size;\r
+/*[VariantListClass_destroyElement]*/\r
+errnum_t VariantListClass_destroyElement( VariantListClass* self,\r
+ void* /*<Variant_SuperClass**>*/ in_out_ElementObject, errnum_t e )\r
+{\r
+ errnum_t ee;\r
+ FinalizerVTableClass* v_table;\r
+ VariantClass* variant;\r
+ Variant_SuperClass* object = *(Variant_SuperClass**) in_out_ElementObject;\r
\r
+ if ( object != NULL ) {\r
+ variant = object->StaticAddress;\r
\r
- //=== add name and not change extension\r
- if ( period_pos_in_add == NULL ) {\r
+ ee= ListClass_remove( &self->List, &variant->ListElement );\r
+ UNREFERENCED_VARIABLE( ee );\r
\r
- //=== copy period_pos_in_base .. last_pos_in_base\r
- if ( period_pos_in_base > term_pos_in_base ) {\r
- copy_size = (char*)last_pos_in_base - (char*)period_pos_in_base + sizeof(TCHAR);\r
- if ( copy_size > free_size ) goto err_fa;\r
- memcpy( out_pos, period_pos_in_base, copy_size );\r
- }\r
- else {\r
- *(TCHAR*)out_pos = _T('\0');\r
+ v_table = ClassID_Class_getVTable( object->ClassID, &g_FinalizerInterface_ID );\r
+ if ( v_table != NULL ) {\r
+ e= v_table->Finalize( object, e );\r
}\r
+ e= FreeMemory( &object, e );\r
+ e= FreeMemory( &variant, e );\r
}\r
+ *(Variant_SuperClass**) in_out_ElementObject = NULL;\r
+\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (Variant_SuperClass) >>> \r
+************************************************************************/\r
+static const ClassID_Class* gs_Variant_SuperClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID,\r
+};\r
+\r
+/*[g_Variant_SuperClass_ID]*/\r
+const ClassID_Class g_Variant_SuperClass_ID = {\r
+ "Variant_SuperClass",\r
+ gs_Variant_SuperClass_SuperClassIDs,\r
+ _countof( gs_Variant_SuperClass_SuperClassIDs ),\r
+ sizeof( Variant_SuperClass ),\r
+ Variant_SuperClass_initialize,\r
+ NULL,\r
+ 0,\r
+};\r
\r
\r
- //=== add name and change extension\r
- else {\r
+/*[Variant_SuperClass_initialize]*/\r
+errnum_t Variant_SuperClass_initialize( Variant_SuperClass* self, void* Parameter )\r
+{\r
+ self->ClassID = &g_Variant_SuperClass_ID;\r
+ self->FinalizerVTable = NULL;\r
+ self->StaticAddress = NULL;\r
+ UNREFERENCED_VARIABLE( Parameter );\r
+ return 0;\r
+}\r
+\r
\r
- if ( *(period_pos_in_add + 1) == _T('\0') )\r
- *( (TCHAR*)out_pos - 1 ) = _T('\0');\r
- else\r
- *(TCHAR*)out_pos = _T('\0');\r
- }\r
+ \r
+/***********************************************************************\r
+ <<< (VariantListIteratorClass) >>> \r
+************************************************************************/\r
\r
- return 0;\r
+/*[VariantListIteratorClass_getNext]*/\r
+Variant_SuperClass* VariantListIteratorClass_getNext( VariantListIteratorClass* self )\r
+{\r
+ VariantClass* variant;\r
\r
-err_fa:\r
- return E_FEW_ARRAY;\r
+ variant = ListIteratorClass_getNext( &self->Iterator );\r
+ if ( variant == NULL ) {\r
+ return NULL;\r
+ } else {\r
+ return variant->Object;\r
+ }\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [Strs_init] >>> \r
+ <<< [PArray_setFromArray] >>> \r
************************************************************************/\r
-enum { Strs_FirstSize = 0x0F00 };\r
-\r
-errnum_t Strs_init( Strs* self )\r
+int PArray_setFromArray( void* PointerArray, size_t PointerArraySize, void* out_ppRight,\r
+ void* SrcArray, size_t SrcArraySize, size_t SrcArrayElemSize )\r
{\r
- char* p;\r
+ int e = 0;\r
+ char** pp;\r
+ char** pp_over;\r
+ char* s;\r
+ char* s_over;\r
\r
- self->MemoryAddress = NULL;\r
+ pp = (char**) PointerArray;\r
+ pp_over = (char**)( (char*)PointerArray + PointerArraySize );\r
+ s = (char*) SrcArray;\r
+ s_over = (char*) SrcArray + SrcArraySize;\r
\r
- p = (char*) malloc( Strs_FirstSize );\r
- IF( p == NULL ) return E_FEW_MEMORY;\r
+ IF ( (pp_over - pp) * SrcArraySize < SrcArraySize ) {\r
+ s_over = (char*)SrcArray + (pp_over - pp) * SrcArraySize;\r
+ e = E_FEW_ARRAY;\r
+ }\r
\r
- self->MemoryAddress = p;\r
- self->MemoryOver = p + Strs_FirstSize;\r
- self->NextElem = p + sizeof(TCHAR*);\r
- self->PointerToNextStrInPrevElem = (TCHAR**) p;\r
- self->Prev_PointerToNextStrInPrevElem = NULL;\r
- *(TCHAR**) p = NULL;\r
+ while ( s < s_over ) {\r
+ *pp = s;\r
+ pp++; s += SrcArrayElemSize;\r
+ }\r
\r
- self->FirstOfStrs = self;\r
- self->NextStrs = NULL;\r
+ if ( out_ppRight != NULL ) *(char***)out_ppRight = pp - 1;\r
\r
- return 0;\r
+ return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [Strs_finish] >>> \r
+ <<< [PArray_doShakerSort] >>> \r
************************************************************************/\r
-errnum_t Strs_finish( Strs* self, errnum_t e )\r
+errnum_t PArray_doShakerSort( const void* PointerArray, size_t PointerArraySize,\r
+ const void* ppLeft, const void* ppRight, CompareFuncType Compare, const void* Param )\r
{\r
- Strs* mp;\r
- Strs* next_mp;\r
+ errnum_t e;\r
+ void** p_left = (void**)ppLeft;\r
+ void** p_right = (void**)ppRight;\r
+ void** p1;\r
+ void** p2;\r
+ void** p_swap;\r
+ void* swap;\r
+ int cmp;\r
\r
- if ( self->MemoryAddress == NULL ) return 0;\r
+ if ( PointerArraySize == 0 ) { e=0; goto fin; }\r
+\r
+ IF_D( ppLeft != NULL && ( ppLeft < PointerArray || (char*)ppLeft >= (char*)PointerArray + PointerArraySize ) ) goto err;\r
+ IF_D( ppRight != NULL && ( ppRight < PointerArray || (char*)ppRight >= (char*)PointerArray + PointerArraySize ) ) goto err;\r
+\r
+ if ( p_left == NULL ) p_left = (void**) PointerArray;\r
+ if ( p_right == NULL ) p_right = (void**)( (char*) PointerArray + PointerArraySize - sizeof(void*) );\r
\r
- mp = self->FirstOfStrs;\r
for (;;) {\r
- free( mp->MemoryAddress );\r
- if ( mp == self ) break;\r
\r
- next_mp = mp->NextStrs;\r
- free( mp );\r
- mp = next_mp;\r
+ //=== Run to right\r
+ p1 = p_left;\r
+ p2 = p_left + 1;\r
+ p_swap = p_left;\r
+\r
+ while ( p1 < p_right ) {\r
+ e= Compare( p1, p2, Param, &cmp ); IF(e)goto fin;\r
+ if ( cmp > 0 ) {\r
+ swap = *p1; *p1 = *p2; *p2 = swap;\r
+ p_swap = p1;\r
+ }\r
+ p1++; p2++;\r
+ }\r
+ if ( p_swap == p_left ) break;\r
+ p_right = p_swap;\r
+\r
+\r
+ //=== Run to left\r
+ p1 = p_right - 1;\r
+ p2 = p_right;\r
+ p_swap = p_right;\r
+\r
+ while ( p1 >= p_left ) {\r
+ e= Compare( p1, p2, Param, &cmp ); IF(e)goto fin;\r
+ if ( cmp > 0 ) {\r
+ swap = *p1; *p1 = *p2; *p2 = swap;\r
+ p_swap = p2;\r
+ }\r
+ p1--; p2--;\r
+ }\r
+ if ( p_swap == p_right ) break;\r
+ p_left = p_swap;\r
}\r
- self->MemoryAddress = NULL;\r
\r
+ e=0;\r
+fin:\r
return e;\r
-}\r
\r
-\r
- \r
-/***********************************************************************\r
- <<< [Strs_toEmpty] >>> \r
-************************************************************************/\r
-errnum_t Strs_toEmpty( Strs* self )\r
-{\r
- Strs_finish( self, 0 );\r
- return Strs_init( self );\r
+err: e = E_OTHERS; goto fin;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [Strs_add] >>> \r
+ <<< [PArray_isSorted] >>> \r
************************************************************************/\r
-errnum_t Strs_add( Strs* self, const TCHAR* Str, const TCHAR** out_AllocStr )\r
-{\r
- return Strs_addBinary( self, Str, _tcschr( Str, _T('\0') ) + 1, out_AllocStr );\r
-}\r
-\r
-\r
-errnum_t Strs_addBinary( Strs* self, const TCHAR* Str, const TCHAR* StrOver, const TCHAR** out_AllocStr )\r
+errnum_t PArray_isSorted( const void* PointerArray, size_t PointerArraySize,\r
+ CompareFuncType Compare, const void* Param, bool* out_IsSorted )\r
{\r
- errnum_t e;\r
- size_t str_size;\r
- size_t elem_size;\r
-\r
- str_size = ( (char*) StrOver - (char*) Str );\r
- elem_size = ( sizeof(TCHAR*) + str_size + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
-\r
- if ( self->NextElem + elem_size > self->MemoryOver )\r
- { e= Strs_expandSize( self, str_size ); IF(e)goto fin; }\r
-\r
+ errnum_t e;\r
+ const void** p;\r
+ const void** p_over;\r
+ int result;\r
\r
- // [ NULL | ... ]\r
- // [ FirstStr | NULL | TCHAR[] | ... ]\r
- // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]\r
- // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
+ p = PointerArray;\r
+ p_over = (const void**)( (uintptr_t) PointerArray + PointerArraySize - sizeof(void*) );\r
\r
- if ( out_AllocStr != NULL ) *out_AllocStr = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
+ while ( p < p_over ) {\r
+ e= Compare( p, p + 1, Param, &result );\r
+ IF(e){goto fin;}\r
\r
- //=== fill elem\r
- *(TCHAR**) self->NextElem = NULL;\r
- memcpy( self->NextElem + sizeof(TCHAR*), Str, str_size );\r
+ IF ( result > 0 ) { *out_IsSorted = false; goto fin; }\r
\r
- //=== link to elem from previous elem\r
- *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
+ p += 1;\r
+ }\r
\r
- //=== update self\r
- self->Prev_PointerToNextStrInPrevElem = self->PointerToNextStrInPrevElem;\r
- self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
- self->NextElem = self->NextElem + elem_size;\r
+ *out_IsSorted = true;\r
\r
e=0;\r
fin:\r
}\r
\r
\r
- \r
/***********************************************************************\r
- <<< [Strs_freeLast] >>> \r
+ <<< [PArray_doBinarySearch] >>> \r
************************************************************************/\r
-errnum_t Strs_freeLast( Strs* self, TCHAR* AllocStr )\r
+errnum_t PArray_doBinarySearch( const void* PointerArray, size_t PointerArraySize,\r
+ const void* Key, CompareFuncType Compare, const void* Param,\r
+ int* out_FoundOrLeftIndex, int* out_CompareResult )\r
{\r
- errnum_t e;\r
- TCHAR* str;\r
- TCHAR* last_str;\r
- TCHAR* prev_of_last_str;\r
- Strs* mp;\r
- Strs* prev_of_last_mp;\r
+ errnum_t e;\r
+ uintptr_t base = (uintptr_t) PointerArray;\r
+ uintptr_t left; /* index */\r
+ uintptr_t right;\r
+ uintptr_t middle;\r
+ int result;\r
\r
- if ( self->Prev_PointerToNextStrInPrevElem == NULL ) {\r
- prev_of_last_str = NULL;\r
- last_str = NULL;\r
- for ( Strs_forEach( self, &str ) ) {\r
- prev_of_last_str = last_str;\r
- last_str = str;\r
- }\r
- }\r
- else {\r
- prev_of_last_str = (TCHAR*)( self->Prev_PointerToNextStrInPrevElem + 1 );\r
- last_str = (TCHAR*)( self->PointerToNextStrInPrevElem + 1 );\r
- }\r
+ left = 0;\r
+ right = (uintptr_t) PointerArraySize / sizeof(void*);\r
\r
- // [ NULL | ... ]\r
- IF( last_str != AllocStr ) {goto err;}\r
+ #ifndef NDEBUG\r
+ {\r
+ bool is_sorted;\r
\r
- // [ FirstStr | NULL | TCHAR[] | ... ]\r
- if ( prev_of_last_str == NULL ) {\r
- self->NextElem = self->MemoryAddress + sizeof(TCHAR*);\r
- self->PointerToNextStrInPrevElem = (TCHAR**) self->MemoryAddress;\r
- }\r
+ result = 1;\r
\r
- // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]\r
- else if ( (char*) prev_of_last_str >= self->MemoryAddress &&\r
- (char*) prev_of_last_str < self->MemoryOver ) {\r
- self->NextElem = (char*)last_str - sizeof(TCHAR*);\r
- self->PointerToNextStrInPrevElem = (TCHAR**)( (char*)prev_of_last_str - sizeof(TCHAR*) );\r
+ e= PArray_isSorted( PointerArray, PointerArraySize, Compare, Param, &is_sorted );\r
+ IF(e){goto fin;}\r
+ IF ( ! is_sorted ) { e=E_NO_NEXT; goto fin; }\r
}\r
+ #endif\r
\r
- // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
- else {\r
- prev_of_last_mp = NULL;\r
- for ( mp = self->FirstOfStrs; mp->NextStrs != self; mp = mp->NextStrs ) {\r
- prev_of_last_mp = mp;\r
- }\r
\r
- free( self->MemoryAddress );\r
+ while ( right - left >= 2 ) {\r
+ middle = ( left + right ) / 2;\r
\r
- *self = *mp;\r
+ e= Compare( &Key, ( (const void**) base + middle ), Param, &result );\r
+ IF(e){goto fin;}\r
\r
- if ( prev_of_last_mp == NULL ) {\r
- self->FirstOfStrs = self;\r
- self->NextStrs = NULL;\r
- }\r
- else {\r
- prev_of_last_mp->NextStrs = self;\r
+ if ( result == 0 ) {\r
+ left = middle;\r
+ e = 0; goto fin;\r
+ } else if ( result < 0 ) {\r
+ right = middle;\r
+ } else {\r
+ left = middle;\r
}\r
-\r
- free( mp );\r
}\r
- *self->PointerToNextStrInPrevElem = NULL;\r
- self->Prev_PointerToNextStrInPrevElem = NULL;\r
+\r
+ e= Compare( &Key, ( (const void**) base + left ), Param, &result );\r
+ IF(e){goto fin;}\r
\r
e=0;\r
fin:\r
+ *out_FoundOrLeftIndex = left;\r
+ *out_CompareResult = result;\r
return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [Strs_expandSize] >>> \r
+ <<< (DictionaryAA_NodeClass:Class) >>> \r
************************************************************************/\r
-errnum_t Strs_expandSize( Strs* self, size_t FreeSize )\r
-{\r
- Strs* mp;\r
- Strs* mp2;\r
- size_t elem_size = ( sizeof(TCHAR*) + FreeSize + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
- size_t memory_size;\r
- char* new_memory;\r
\r
- // [ NULL | ... ]\r
- // [ FirstStr | NULL | TCHAR[] | ... ]\r
- // [ FirstStr | NextStr | TCHAR[] | NULL | TCHAR[] | ... ]\r
- // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
+/*[DictionaryAA_SearchWorkClass]*/\r
+typedef struct _DictionaryAA_SearchWorkClass DictionaryAA_SearchWorkClass;\r
+struct _DictionaryAA_SearchWorkClass {\r
+ const TCHAR* SearchKey;\r
+ DictionaryAA_NodeClass* FoundNode;\r
+ bool IsErrorIfNotFound;\r
+};\r
\r
- while ( self->NextElem + elem_size > self->MemoryOver ) {\r
+/*[DictionaryAA_TraverseWorkClass]*/\r
+typedef struct _DictionaryAA_TraverseWorkClass DictionaryAA_TraverseWorkClass;\r
+struct _DictionaryAA_TraverseWorkClass {\r
+ DictionaryAA_TraverseFuncType Function;\r
+ void* UserParameter;\r
+};\r
\r
- //=== alloc\r
- mp = (Strs*) malloc( sizeof(Strs) ); IF(mp==NULL) goto err_fm;\r
- memory_size = ( self->MemoryOver - self->MemoryAddress ) * 2;\r
- new_memory = (char*) malloc( memory_size );\r
- IF( new_memory == NULL ) { free( mp ); goto err_fm; }\r
+errnum_t DictionaryAA_NodeClass_insert( DictionaryAA_NodeClass* Node,\r
+ DictionaryAA_NodeClass** out_ParentNode, DictionaryAA_SearchWorkClass* work );\r
+errnum_t DictionaryAA_NodeClass_search( DictionaryAA_NodeClass* Node,\r
+ DictionaryAA_SearchWorkClass* work );\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_remove( DictionaryAA_NodeClass* Node,\r
+ const TCHAR* Key, DictionaryAA_NodeClass** out_RemovingNode );\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_skew( DictionaryAA_NodeClass* Node );\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_split( DictionaryAA_NodeClass* Node );\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_rotateLeft( DictionaryAA_NodeClass* Node );\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_rotateRight( DictionaryAA_NodeClass* Node );\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_searchMin( DictionaryAA_NodeClass* Node );\r
+errnum_t DictionaryAA_NodeClass_toEmpty( DictionaryAA_NodeClass* Node, errnum_t e );\r
+errnum_t DictionaryAA_NodeClass_onTraverse( DictionaryAA_NodeClass* Node,\r
+ DictionaryAA_TraverseWorkClass* work );\r
+errnum_t DictionaryAA_NodeClass_print( DictionaryAA_NodeClass* Node, int RootHeight,\r
+ FILE* OutputStream );\r
\r
- //=== move old memory\r
- if ( self->FirstOfStrs == self ) {\r
- self->FirstOfStrs = mp;\r
- }\r
- else {\r
- for ( mp2 = self->FirstOfStrs; mp2->NextStrs != self; mp2 = mp2->NextStrs );\r
- mp2->NextStrs = mp;\r
- }\r
- *mp = *self;\r
- mp->NextStrs = self;\r
\r
- //=== setup new memory\r
- self->MemoryAddress = new_memory;\r
- self->MemoryOver = new_memory + memory_size;\r
- self->NextElem = new_memory;\r
- // self->PointerToNextStrInPrevElem is same value\r
- // self->FirstOfStrs is same value\r
- // self->NextStrs is always NULL\r
- }\r
- return 0;\r
+ \r
+/***********************************************************************\r
+ <<< (DictionaryAA_Class) >>> \r
+************************************************************************/\r
\r
-err_fm: return E_FEW_ARRAY;\r
+/*[DictionaryAA_Class_initConst]*/\r
+void DictionaryAA_Class_initConst( DictionaryAA_Class* self )\r
+{\r
+ self->Root = &g_DictionaryAA_NullNode;\r
}\r
\r
\r
-/***********************************************************************\r
- <<< [Strs_commit] >>>\r
-************************************************************************/\r
-errnum_t Strs_commit( Strs* self, TCHAR* StrOver )\r
+/*[DictionaryAA_Class_finalize]*/\r
+errnum_t DictionaryAA_Class_finalize( DictionaryAA_Class* self, errnum_t e )\r
{\r
- size_t elem_size;\r
+ return DictionaryAA_NodeClass_toEmpty( self->Root, e );\r
+}\r
\r
- if ( StrOver == NULL )\r
- { StrOver = _tcschr( (TCHAR*)( self->NextElem + sizeof(TCHAR*) ), _T('\0') ) + 1; }\r
- elem_size = ( ( (char*)StrOver - self->NextElem ) + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
\r
- //=== fill elem\r
- *(TCHAR**) self->NextElem = NULL;\r
+/*[DictionaryAA_Class_insert]*/\r
+errnum_t DictionaryAA_Class_insert( DictionaryAA_Class* self, const TCHAR* Key,\r
+ DictionaryAA_NodeClass** out_Node )\r
+{\r
+ errnum_t e;\r
+ DictionaryAA_SearchWorkClass work;\r
\r
- //=== link to elem from previous elem\r
- *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
+ work.SearchKey = Key;\r
\r
- //=== update self\r
- self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
- self->NextElem = self->NextElem + elem_size;\r
+ e= DictionaryAA_NodeClass_insert( self->Root, &self->Root, &work );\r
\r
- return 0;\r
+ *out_Node = work.FoundNode;\r
+\r
+ return e;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [StrArr] >>> \r
-************************************************************************/\r
+/*[DictionaryAA_Class_remove]*/\r
+errnum_t DictionaryAA_Class_remove( DictionaryAA_Class* self, const TCHAR* Key )\r
+{\r
+ errnum_t e;\r
+ DictionaryAA_NodeClass* removing_node = NULL;\r
\r
-/*[StrArr_init]*/\r
-errnum_t StrArr_init( StrArr* self )\r
+ self->Root = DictionaryAA_NodeClass_remove( self->Root, Key, &removing_node );\r
+ if ( removing_node == NULL ) { e = E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ e=0;\r
+fin:\r
+ if ( removing_node != NULL ) {\r
+ e= HeapMemory_free( &removing_node->Key, e );\r
+ e= HeapMemory_free( &removing_node, e );\r
+ }\r
+ return e;\r
+}\r
+\r
+\r
+/*[DictionaryAA_Class_search]*/\r
+errnum_t DictionaryAA_Class_search( DictionaryAA_Class* self, const TCHAR* Key,\r
+ DictionaryAA_NodeClass** out_Node )\r
{\r
errnum_t e;\r
+ DictionaryAA_SearchWorkClass work;\r
\r
- Set2_initConst( &self->Array );\r
- Strs_initConst( &self->Chars );\r
+ work.SearchKey = Key;\r
+ work.IsErrorIfNotFound = true;\r
\r
- e= Set2_init( &self->Array, 0x100 ); IF(e)goto cancel;\r
- e= Strs_init( &self->Chars ); IF(e)goto cancel;\r
- return 0;\r
+ e= DictionaryAA_NodeClass_search( self->Root, &work );\r
\r
-cancel: StrArr_finish( self, e ); return e;\r
+ *out_Node = work.FoundNode;\r
+\r
+ return e;\r
}\r
\r
\r
-/*[StrArr_finish]*/\r
-errnum_t StrArr_finish( StrArr* self, errnum_t e )\r
+/*[DictionaryAA_Class_isExist]*/\r
+bool DictionaryAA_Class_isExist( DictionaryAA_Class* self, const TCHAR* Key )\r
{\r
- if ( ! Set2_isInited( &self->Array ) ) return e;\r
+ DictionaryAA_SearchWorkClass work;\r
\r
- e= Set2_finish( &self->Array, e );\r
- e= Strs_finish( &self->Chars, e );\r
- return e;\r
+ work.SearchKey = Key;\r
+ work.IsErrorIfNotFound = false;\r
+\r
+ DictionaryAA_NodeClass_search( self->Root, &work );\r
+\r
+ return ( work.FoundNode != NULL );\r
}\r
\r
\r
-/*[StrArr_add]*/\r
-errnum_t StrArr_add( StrArr* self, const TCHAR* Str, int* out_I )\r
+/*[DictionaryAA_Class_freeAllKeysHeap]*/\r
+#if 0\r
+errnum_t DictionaryAA_Class_freeAllKeysHeap( DictionaryAA_Class* self, errnum_t e )\r
{\r
- errnum_t e;\r
+ errnum_t ee;\r
+ DictionaryAA_IteratorClass iterator;\r
+ DictionaryAA_NodeClass* node;\r
\r
- e= StrArr_expandCount( self, _tcslen( Str ) ); IF(e)goto fin;\r
- _tcscpy_s( StrArr_getFreeAddr( self ), StrArr_getFreeCount( self ), Str );\r
- e= StrArr_commit( self ); IF(e)goto fin;\r
- if ( out_I != NULL ) *out_I = Set2_getCount( &self->Array, TCHAR* ) - 1;\r
+ DictionaryAA_IteratorClass_initConst( &iterator );\r
+\r
+ ee= DictionaryAA_IteratorClass_initialize( &iterator, self );\r
+ IF ( ee != 0 && e==0 ) { e = ee; goto fin; }\r
+ for ( DictionaryAA_Class_forEach( &iterator, &node ) ) {\r
+ e= HeapMemory_free( &node->Key, e );\r
+ }\r
\r
e=0;\r
fin:\r
+ e= DictionaryAA_IteratorClass_finalize( &iterator, e );\r
return e;\r
}\r
+#endif\r
\r
\r
-/*[StrArr_commit]*/\r
-errnum_t StrArr_commit( StrArr* self )\r
+/*[DictionaryAA_Class_traverse]*/\r
+errnum_t DictionaryAA_Class_traverse( DictionaryAA_Class* self,\r
+ DictionaryAA_TraverseFuncType Function,\r
+ void* UserParameter )\r
{\r
- errnum_t e;\r
- TCHAR* p;\r
- TCHAR** pp = NULL;\r
- Set2* arr = &self->Array;\r
- Strs* ss = &self->Chars;\r
+ DictionaryAA_TraverseWorkClass work;\r
\r
- p = Strs_getFreeAddr( ss );\r
- e= Set2_alloc( arr, &pp, TCHAR* ); IF(e)goto fin;\r
- e= Strs_commit( ss, NULL ); IF(e)goto fin;\r
- *pp = p;\r
+ work.Function = Function;\r
+ work.UserParameter = UserParameter;\r
\r
- e=0;\r
-fin:\r
- if ( e && pp != NULL ) e= Set2_freeLast( arr, pp, TCHAR*, e );\r
- return e;\r
+ return DictionaryAA_NodeClass_onTraverse( self->Root, &work );\r
}\r
\r
\r
-/*[StrArr_fillTo]*/\r
-errnum_t StrArr_fillTo( StrArr* self, int n, const TCHAR* Str )\r
+/*[DictionaryAA_Class_toEmpty]*/\r
+errnum_t DictionaryAA_Class_toEmpty( DictionaryAA_Class* self )\r
{\r
errnum_t e;\r
- const TCHAR* p;\r
- const TCHAR** pp;\r
- const TCHAR** pp_over;\r
-\r
- n -= Set2_getCount( &self->Array, TCHAR* );\r
- if ( n <= 0 ) return 0;\r
-\r
- if ( Str == NULL ) {\r
- p = NULL;\r
- }\r
- else {\r
- e= Strs_add( &self->Chars, Str, &p ); IF(e)goto fin;\r
- }\r
\r
- e= Set2_allocMulti( &self->Array, &pp, TCHAR*, n ); IF(e)goto fin;\r
- pp_over = pp + n;\r
- for ( ; pp < pp_over; pp++ )\r
- *pp = p;\r
+ e= DictionaryAA_NodeClass_toEmpty( self->Root, 0 ); IF(e){goto fin;}\r
\r
e=0;\r
fin:\r
+ self->Root = &g_DictionaryAA_NullNode;\r
return e;\r
}\r
\r
\r
-/*[StrArr_toEmpty]*/\r
-errnum_t StrArr_toEmpty( StrArr* self )\r
+/*[DictionaryAA_Class_print]*/\r
+errnum_t DictionaryAA_Class_print( DictionaryAA_Class* self, FILE* OutputStream )\r
{\r
- errnum_t e, ee;\r
+ errnum_t e;\r
+ int r;\r
+\r
+ r= _ftprintf_s( OutputStream, _T("DictionaryAA -------------------\n") );\r
+ IF(r<0) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ e= DictionaryAA_NodeClass_print( self->Root, self->Root->Height, OutputStream );\r
+ IF(e){goto fin;}\r
\r
e=0;\r
- ee= Set2_toEmpty( &self->Array ); IF(ee&&!e)e=ee;\r
- ee= Strs_toEmpty( &self->Chars ); IF(ee&&!e)e=ee;\r
+fin:\r
return e;\r
}\r
\r
\r
\r
/***********************************************************************\r
- <<< [StrArr_parseCSV] >>> \r
+ <<< [DictionaryAA_Class_finalize2] >>> \r
************************************************************************/\r
-errnum_t StrArr_parseCSV( StrArr* self, const TCHAR* CSVLine )\r
+errnum_t DictionaryAA_Class_finalize2( DictionaryAA_Class* self, errnum_t e,\r
+ bool in_IsFreeItem, FinalizeFuncType in_Type_Finalize )\r
{\r
- errnum_t e;\r
- const TCHAR* p = CSVLine;\r
+ errnum_t ee;\r
\r
- e= StrArr_toEmpty( self ); IF(e)goto fin;\r
+ DictionaryAA_NodeClass* node;\r
+ DictionaryAA_IteratorClass iterator;\r
\r
- do {\r
- e= StrT_meltCSV( StrArr_getFreeAddr( self ), StrArr_getFreeSize( self ), &p );\r
- if ( e == E_FEW_ARRAY ) {\r
- e= StrArr_expandSize( self, StrArr_getFreeSize( self ) * 2 ); IF(e)goto fin;\r
- continue;\r
- }\r
- IF(e)goto fin;\r
+ DictionaryAA_IteratorClass_initConst( &iterator );\r
\r
- e = StrArr_commit( self ); IF(e)goto fin;\r
- } while ( p != NULL );\r
+ ee= DictionaryAA_IteratorClass_initialize( &iterator, self );\r
+ IF(ee){e=MergeError(e,ee);goto fin;}\r
+ for ( DictionaryAA_Class_forEach( &iterator, &node ) ) {\r
+ if ( in_Type_Finalize != NULL ) {\r
+ e= in_Type_Finalize( node->Item, e );\r
+ }\r
+ if ( in_IsFreeItem ) {\r
+ e= HeapMemory_free( &node->Item, e );\r
+ }\r
+ }\r
\r
- e=0;\r
fin:\r
+ e= DictionaryAA_IteratorClass_finalize( &iterator, e );\r
+ e= DictionaryAA_Class_finalize( self, e );\r
return e;\r
}\r
\r
\r
\r
-/*=================================================================*/\r
-/* <<< [DebugTools/DebugTools.c] >>> */ \r
-/*=================================================================*/\r
- \r
/***********************************************************************\r
- <<< [TestableDebugBreak] >>> \r
+ <<< [DictionaryAA_Class_getArray] >>> \r
************************************************************************/\r
-typedef struct _TestableDebugBreakClass TestableDebugBreakClass;\r
-struct _TestableDebugBreakClass {\r
- bool IsDisableTestableDebugBreak;\r
- volatile int DebugBreakCount;\r
- CRITICAL_SECTION Critical;\r
- SingletonInitializerClass Initializer;\r
-};\r
-static TestableDebugBreakClass gs_TestableDebugBreak = { false, 0 };\r
+errnum_t DictionaryAA_Class_getArray( DictionaryAA_Class* self,\r
+ TCHAR*** in_out_Strings, int* in_out_StringCount, NewStringsEnum in_HowToAllocate )\r
+{\r
+ errnum_t e;\r
+ int string_count = 0;\r
+ int string_count_max;\r
\r
+ TCHAR** key_array = NULL;\r
+ TCHAR** new_key_array = NULL;\r
\r
-/*[SetTestableDebugBreak]*/\r
-void SetTestableDebugBreak( bool IsEnableBreak )\r
-{\r
- TestableDebugBreakClass* self = &gs_TestableDebugBreak;\r
- self->IsDisableTestableDebugBreak = ! IsEnableBreak;\r
-}\r
+ DictionaryAA_NodeClass* node;\r
+ DictionaryAA_IteratorClass iterator;\r
\r
-/*[TestableDebugBreak_Sub]*/\r
-int TestableDebugBreak_Sub()\r
-{\r
- TestableDebugBreakClass* self = &gs_TestableDebugBreak;\r
+ DictionaryAA_IteratorClass_initConst( &iterator );\r
\r
- if ( ! SingletonInitializerClass_isInitialized( &self->Initializer ) ) {\r
- if ( SingletonInitializerClass_isFirst( &self->Initializer ) ) {\r
\r
- InitializeCriticalSection( &self->Critical );\r
+ /* Set "string_count_max", "key_array" */\r
+ if ( IsBitSet( in_HowToAllocate, NewStringsEnum_NewPointers ) ) {\r
\r
- SingletonInitializerClass_onFinishedInitialize( &self->Initializer, 0 );\r
+ string_count_max = 0;\r
+ e= DictionaryAA_IteratorClass_initialize( &iterator, self );\r
+ IF(e){goto fin;}\r
+ for ( DictionaryAA_Class_forEach( &iterator, &node ) ) {\r
+ string_count_max += 1;\r
}\r
+ e= DictionaryAA_IteratorClass_finalize( &iterator, 0 ); IF(e){goto fin;}\r
+\r
+ e= HeapMemory_allocateArray( &new_key_array, string_count_max );\r
+ IF(e){goto fin;}\r
+ *in_out_Strings = new_key_array;\r
+ key_array = new_key_array;\r
}\r
+ else {\r
+ ASSERT_R( in_out_StringCount != NULL, e=E_OTHERS; goto fin );\r
+ string_count_max = *in_out_StringCount;\r
+ key_array = *in_out_Strings;\r
+ }\r
+ memset( key_array, 0x00, string_count_max * sizeof(TCHAR*) );\r
\r
- EnterCriticalSection( &self->Critical );\r
- self->DebugBreakCount += 1;\r
- LeaveCriticalSection( &self->Critical );\r
\r
- return ! self->IsDisableTestableDebugBreak;\r
-}\r
+ /* Set "key_array[ string_count ]" */\r
+ e= DictionaryAA_IteratorClass_initialize( &iterator, self );\r
+ IF(e){goto fin;}\r
+ for ( DictionaryAA_Class_forEach( &iterator, &node ) ) {\r
+ const TCHAR* value = node->Key;\r
\r
-/*[GetDebugBreakCount]*/\r
-int GetDebugBreakCount()\r
-{\r
- TestableDebugBreakClass* self = &gs_TestableDebugBreak;\r
- return self->DebugBreakCount;\r
-}\r
+ if ( IsBitSet( in_HowToAllocate, NewStringsEnum_NewCharacters ) ) {\r
+ ASSERT_R( IsBitNotSet( in_HowToAllocate, NewStringsEnum_LinkCharacters ),\r
+ e=E_OTHERS; goto fin );\r
\r
+ e= MallocAndCopyString( &key_array[ string_count ], value );\r
+ IF(e){goto fin;}\r
+ }\r
+ else if ( IsBitSet( in_HowToAllocate, NewStringsEnum_LinkCharacters ) ) {\r
+ const TCHAR** key_pp = &key_array[ string_count ];\r
\r
- \r
-/*=================================================================*/\r
-/* <<< [SetX/SetX.c] >>> */ \r
-/*=================================================================*/\r
- \r
-/***********************************************************************\r
- <<< [Set2_init] >>> \r
-************************************************************************/\r
-int Set2_init( Set2* m, int FirstSize )\r
-{\r
- m->First = malloc( FirstSize );\r
- if ( m->First == NULL ) return E_FEW_MEMORY;\r
- m->Next = m->First;\r
- m->Over = (char*)m->First + FirstSize;\r
+ ASSERT_R( *key_pp == NULL, e=E_OTHERS; goto fin );\r
+ *key_pp = value;\r
+ }\r
+ else {\r
+ ASSERT_R( false, e=E_LIMITATION; goto fin );\r
+ }\r
+ string_count += 1;\r
+ }\r
\r
- #ifdef _DEBUG\r
- m->PointerOfDebugArray = NULL;\r
- #endif\r
+ *in_out_StringCount = string_count;\r
+ new_key_array = NULL;\r
\r
- return 0;\r
+ e=0;\r
+fin:\r
+ if ( e != 0 ) {\r
+ if ( IsBitSet( in_HowToAllocate, NewStringsEnum_NewCharacters ) ) {\r
+ if ( key_array != NULL ) {\r
+ for ( string_count -= 1; string_count >= 0; string_count -= 1 ) {\r
+ e= HeapMemory_free( &key_array[ string_count ], e );\r
+ }\r
+ }\r
+ }\r
+ }\r
+ e= HeapMemory_free( &new_key_array, e );\r
+ e= DictionaryAA_IteratorClass_finalize( &iterator, e );\r
+ return e;\r
}\r
+\r
+\r
\r
/***********************************************************************\r
- <<< [Set2_finish] >>> \r
+ <<< (DictionaryAA_NodeClass) >>> \r
************************************************************************/\r
-int Set2_finish( Set2* m, int e )\r
+\r
+/*[g_DictionaryAA_NullNode]*/\r
+DictionaryAA_NodeClass g_DictionaryAA_NullNode = {\r
+ /* Key */ _T("(NullNode)"),\r
+ /* Item */ NULL,\r
+ /* Height */ 0,\r
+ /* Left */ &g_DictionaryAA_NullNode,\r
+ /* Right */ &g_DictionaryAA_NullNode,\r
+};\r
+\r
+\r
+/*[DictionaryAA_NodeClass_insert]*/\r
+errnum_t DictionaryAA_NodeClass_insert( DictionaryAA_NodeClass* in_Node,\r
+ DictionaryAA_NodeClass** out_ParentNode, DictionaryAA_SearchWorkClass* work )\r
{\r
- if ( m->First != NULL ) { free( m->First ); m->First = NULL; }\r
+ errnum_t e;\r
+\r
+ if ( in_Node == &g_DictionaryAA_NullNode ) {\r
+ e= HeapMemory_allocate( &in_Node ); IF(e){goto fin;}\r
+ in_Node->Key = NULL;\r
+ e= MallocAndCopyString( &in_Node->Key, work->SearchKey ); IF(e){goto fin;}\r
+ in_Node->Item = NULL;\r
+ in_Node->Height = 1;\r
+ in_Node->Left = &g_DictionaryAA_NullNode;\r
+ in_Node->Right = &g_DictionaryAA_NullNode;\r
+ *out_ParentNode = in_Node;\r
+ work->FoundNode = in_Node;\r
+ }\r
+ else {\r
+ int compare = _tcscmp( work->SearchKey, in_Node->Key );\r
+\r
+ if ( compare == 0 ) {\r
+ *out_ParentNode = in_Node;\r
+ work->FoundNode = in_Node;\r
+ }\r
+ else {\r
+ if ( compare < 0 ) {\r
+ e= DictionaryAA_NodeClass_insert( in_Node->Left, &in_Node->Left, work );\r
+ IF(e){goto fin;}\r
+ }\r
+ else { /* compare > 0 */\r
+ e= DictionaryAA_NodeClass_insert( in_Node->Right, &in_Node->Right, work );\r
+ IF(e){goto fin;}\r
+ }\r
+ in_Node = DictionaryAA_NodeClass_skew( in_Node );\r
+ in_Node = DictionaryAA_NodeClass_split( in_Node );\r
+ *out_ParentNode = in_Node;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
return e;\r
}\r
\r
- \r
-/***********************************************************************\r
- <<< [Set2_ref_imp] >>> \r
-************************************************************************/\r
-int Set2_ref_imp( Set2* m, int iElem, void* out_pElem, size_t ElemSize )\r
+\r
+/*[DictionaryAA_NodeClass_search]*/\r
+errnum_t DictionaryAA_NodeClass_search( DictionaryAA_NodeClass* in_Node,\r
+ DictionaryAA_SearchWorkClass* work )\r
{\r
- int e;\r
- char* p;\r
+ errnum_t e;\r
+ int compare;\r
\r
- IF( iElem < 0 ) goto err_ns;\r
- p = (char*) m->First + ( (unsigned)iElem * ElemSize );\r
- IF( p >= (char*)m->Next ) goto err_ns;\r
- *(char**)out_pElem = p;\r
+ if ( in_Node == &g_DictionaryAA_NullNode ) {\r
+ IF ( work->IsErrorIfNotFound ) { e = E_NOT_FOUND_SYMBOL; goto fin; }\r
+ work->FoundNode = NULL;\r
+ e = 0; goto fin;\r
+ }\r
+\r
+ compare = _tcscmp( work->SearchKey, in_Node->Key );\r
+\r
+ if ( compare == 0 ) {\r
+ work->FoundNode = in_Node;\r
+ }\r
+ else {\r
+ if ( compare < 0 ) {\r
+ e= DictionaryAA_NodeClass_search( in_Node->Left, work );\r
+ IF(e){goto fin;}\r
+ }\r
+ else { /* compare > 0 */\r
+ e= DictionaryAA_NodeClass_search( in_Node->Right, work );\r
+ IF(e){goto fin;}\r
+ }\r
+ }\r
\r
e=0;\r
fin:\r
return e;\r
+}\r
\r
-err_ns: e = E_NOT_FOUND_SYMBOL; goto fin;\r
+\r
+/*[DictionaryAA_NodeClass_remove]*/\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_remove( DictionaryAA_NodeClass* in_Node,\r
+ const TCHAR* Key, DictionaryAA_NodeClass** out_RemovingNode )\r
+{\r
+ if ( in_Node != &g_DictionaryAA_NullNode ) {\r
+ int compare = _tcscmp( Key, in_Node->Key );\r
+\r
+ if ( compare == 0 ) {\r
+ if ( in_Node->Left == &g_DictionaryAA_NullNode ) {\r
+ *out_RemovingNode = in_Node;\r
+ in_Node = in_Node->Right;\r
+ } else if ( in_Node->Right == &g_DictionaryAA_NullNode ) {\r
+ *out_RemovingNode = in_Node;\r
+ in_Node = in_Node->Left;\r
+ } else {\r
+ DictionaryAA_NodeClass* reuse_node = in_Node;\r
+ DictionaryAA_NodeClass* sacrifice_node;\r
+ DictionaryAA_NodeClass swap;\r
+\r
+ sacrifice_node = DictionaryAA_NodeClass_searchMin( in_Node->Right );\r
+ reuse_node->Right = DictionaryAA_NodeClass_remove(\r
+ in_Node->Right, sacrifice_node->Key, &sacrifice_node );\r
+\r
+ swap.Key = reuse_node->Key;\r
+ swap.Item = reuse_node->Item;\r
+ reuse_node->Key = sacrifice_node->Key;\r
+ reuse_node->Item = sacrifice_node->Item;\r
+ sacrifice_node->Key = swap.Key;\r
+ sacrifice_node->Item = swap.Item;\r
+ *out_RemovingNode = sacrifice_node;\r
+ }\r
+ }\r
+ else if ( compare < 0 ) {\r
+ in_Node->Left = DictionaryAA_NodeClass_remove( in_Node->Left, Key, out_RemovingNode );\r
+ }\r
+ else { /* compare > 0 */\r
+ in_Node->Right = DictionaryAA_NodeClass_remove( in_Node->Right, Key, out_RemovingNode );\r
+ }\r
+\r
+ if ( in_Node->Left->Height < in_Node->Height - 1 ||\r
+ in_Node->Right->Height < in_Node->Height - 1 )\r
+ {\r
+ in_Node->Height -= 1;\r
+ if ( in_Node->Right->Height > in_Node->Height )\r
+ { in_Node->Right->Height = in_Node->Height; }\r
+ in_Node = DictionaryAA_NodeClass_skew( in_Node );\r
+ in_Node->Right = DictionaryAA_NodeClass_skew( in_Node->Right );\r
+ in_Node->Right->Right = DictionaryAA_NodeClass_skew( in_Node->Right->Right );\r
+ in_Node = DictionaryAA_NodeClass_split( in_Node );\r
+ in_Node->Right = DictionaryAA_NodeClass_split( in_Node->Right );\r
+ }\r
+ }\r
+ return in_Node;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Set2_getIterator] >>> \r
-************************************************************************/\r
-errnum_t Set2_getIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )\r
+/*[DictionaryAA_NodeClass_skew]*/\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_skew( DictionaryAA_NodeClass* in_Node )\r
{\r
- out_Iterator->Parent = self;\r
- out_Iterator->ElementSize = ElementSize;\r
- out_Iterator->Current = (uint8_t*) self->First - ElementSize;\r
- return 0;\r
+ if ( in_Node->Left->Height == in_Node->Height ) {\r
+ in_Node = DictionaryAA_NodeClass_rotateRight( in_Node );\r
+ }\r
+\r
+ return in_Node;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Set2_getDescendingIterator] >>> \r
-************************************************************************/\r
-errnum_t Set2_getDescendingIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )\r
+/*[DictionaryAA_NodeClass_split]*/\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_split( DictionaryAA_NodeClass* in_Node )\r
{\r
- out_Iterator->Parent = self;\r
- out_Iterator->ElementSize = ElementSize;\r
- out_Iterator->Current = (uint8_t*) self->Next;\r
- return 0;\r
+ if ( in_Node->Height == in_Node->Right->Right->Height ) {\r
+ in_Node = DictionaryAA_NodeClass_rotateLeft( in_Node );\r
+ in_Node->Height += 1;\r
+ }\r
+\r
+ return in_Node;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Set2_IteratorClass_getNext] >>> \r
-************************************************************************/\r
-void* Set2_IteratorClass_getNext( Set2_IteratorClass* self )\r
+/*[DictionaryAA_NodeClass_rotateLeft]*/\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_rotateLeft( DictionaryAA_NodeClass* in_Node )\r
{\r
- uint8_t* next = self->Current + self->ElementSize;\r
+ DictionaryAA_NodeClass* swap;\r
\r
- if ( next >= (uint8_t*) self->Parent->Next ) {\r
- return NULL;\r
- } else {\r
- self->Current = next;\r
- return next;\r
- }\r
+ swap = in_Node->Right;\r
+ in_Node->Right = swap->Left;\r
+ swap->Left = in_Node;\r
+\r
+ return swap;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Set2_IteratorClass_getPrevious] >>> \r
-************************************************************************/\r
-void* Set2_IteratorClass_getPrevious( Set2_IteratorClass* self )\r
+/*[DictionaryAA_NodeClass_rotateRight]*/\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_rotateRight( DictionaryAA_NodeClass* in_Node )\r
{\r
- uint8_t* previous = self->Current - self->ElementSize;\r
+ DictionaryAA_NodeClass* swap;\r
\r
- if ( previous < (uint8_t*) self->Parent->First ) {\r
- return NULL;\r
- } else {\r
- self->Current = previous;\r
- return previous;\r
- }\r
+ swap = in_Node->Left;\r
+ in_Node->Left = swap->Right;\r
+ swap->Right = in_Node;\r
+\r
+ return swap;\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Set2_alloc_imp] >>> \r
-************************************************************************/\r
-int Set2_alloc_imp( Set2* m, void* pp, size_t size )\r
+DictionaryAA_NodeClass* DictionaryAA_NodeClass_searchMin( DictionaryAA_NodeClass* in_Node )\r
{\r
- int e;\r
-\r
- e= Set2_expandIfOverByAddr( m, (char*) m->Next + size ); IF(e)goto fin;\r
- *(void**)pp = m->Next;\r
- m->Next = (char*) m->Next + size;\r
+ while ( in_Node->Left != &g_DictionaryAA_NullNode )\r
+ { in_Node = in_Node->Left; }\r
+ return in_Node;\r
+}\r
\r
- DISCARD_BYTES( *(void**)pp, size );\r
\r
- e=0;\r
-fin:\r
+/*[DictionaryAA_NodeClass_toEmpty]*/\r
+errnum_t DictionaryAA_NodeClass_toEmpty( DictionaryAA_NodeClass* in_Node, errnum_t e )\r
+{\r
+ if ( in_Node != &g_DictionaryAA_NullNode ) {\r
+ e= DictionaryAA_NodeClass_toEmpty( in_Node->Left, e );\r
+ e= DictionaryAA_NodeClass_toEmpty( in_Node->Right, e );\r
+ e= HeapMemory_free( &in_Node->Key, e );\r
+ e= HeapMemory_free( &in_Node, e );\r
+ }\r
return e;\r
}\r
\r
\r
-int Set2_allocMulti_sub( Set2* m, void* out_pElem, size_t ElemsSize )\r
+/*[DictionaryAA_NodeClass_onTraverse]*/\r
+errnum_t DictionaryAA_NodeClass_onTraverse( DictionaryAA_NodeClass* in_Node,\r
+ DictionaryAA_TraverseWorkClass* work )\r
{\r
- int e;\r
- char* p;\r
+ errnum_t e;\r
\r
- e= Set2_expandIfOverByAddr( m, (char*) m->Next + ElemsSize ); IF(e)goto fin;\r
- p = (char*) m->Next;\r
- m->Next = p + ElemsSize;\r
- *(char**)out_pElem = p;\r
+ if ( in_Node != &g_DictionaryAA_NullNode ) {\r
+ e= DictionaryAA_NodeClass_onTraverse( in_Node->Left, work ); IF(e){goto fin;}\r
+ e= work->Function( in_Node, work->UserParameter ); IF(e){goto fin;}\r
+ e= DictionaryAA_NodeClass_onTraverse( in_Node->Right, work ); IF(e){goto fin;}\r
+ }\r
\r
e=0;\r
fin:\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Set2_expandIfOverByAddr_imp] >>> \r
-************************************************************************/\r
-errnum_t Set2_expandIfOverByAddr_imp( Set2* m, void* OverAddrBasedOnNowFirst )\r
+/*[DictionaryAA_NodeClass_print]*/\r
+errnum_t DictionaryAA_NodeClass_print( DictionaryAA_NodeClass* in_Node, int RootHeight,\r
+ FILE* OutputStream )\r
{\r
errnum_t e;\r
- void* new_first;\r
- unsigned offset_of_over;\r
- unsigned offset_of_next;\r
-\r
- if ( OverAddrBasedOnNowFirst <= m->Over ) { e=E_OTHERS; goto fin; }\r
+ int r;\r
\r
- offset_of_next = (unsigned)( (char*)OverAddrBasedOnNowFirst - (char*)m->First );\r
- offset_of_over = (unsigned)( ( (char*)m->Over - (char*)m->First ) ) * 2;\r
- IF_D( offset_of_next >= 0x80000000 ) { e=E_OTHERS; goto fin; }\r
- IF_D( offset_of_over == 0 ) { e=E_OTHERS; goto fin; }\r
- while ( offset_of_over < offset_of_next ) { offset_of_over *= 2; }\r
- IF( offset_of_over >= 0x10000000 ) { e=E_OTHERS; goto fin; }\r
+ if ( in_Node != &g_DictionaryAA_NullNode ) {\r
\r
- new_first = realloc( m->First, offset_of_over * 2 );\r
- IF( new_first == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ e= DictionaryAA_NodeClass_print( in_Node->Left, RootHeight, OutputStream );\r
+ IF(e){goto fin;}\r
\r
- m->Next = (char*) new_first + ( (char*)m->Next - (char*)m->First );\r
- m->Over = (char*) new_first + offset_of_over * 2;\r
- m->First = new_first;\r
+ r= _ftprintf_s( OutputStream, _T("%*s%s\n"), ( RootHeight - in_Node->Height ) * 4,\r
+ _T(""), in_Node->Key ); IF(r<0) { e=E_ACCESS_DENIED; goto fin; }\r
\r
- #ifdef _DEBUG\r
- if ( m->PointerOfDebugArray != NULL )\r
- { *m->PointerOfDebugArray = m->First; }\r
- #endif\r
+ e= DictionaryAA_NodeClass_print( in_Node->Right, RootHeight, OutputStream );\r
+ IF(e){goto fin;}\r
+ }\r
\r
e=0;\r
fin:\r
\r
\r
/***********************************************************************\r
- <<< [Set2_separate] >>> \r
+ <<< (DictionaryAA_IteratorClass) >>> \r
************************************************************************/\r
-int Set2_separate( Set2* m, int NextSize, void** allocate_Array )\r
+\r
+errnum_t DictionaryAA_IteratorClass_initialize_sub( DictionaryAA_NodeClass* in_Node,\r
+ void* Array );\r
+\r
+\r
+/*[DictionaryAA_IteratorClass_initialize]*/\r
+errnum_t DictionaryAA_IteratorClass_initialize( DictionaryAA_IteratorClass* self,\r
+ DictionaryAA_Class* Collection )\r
{\r
- int e;\r
- void* p = m->First;\r
+ errnum_t e;\r
\r
- if ( NextSize == 0 ) {\r
- m->First = NULL;\r
- }\r
- else {\r
- e= Set2_init( m, NextSize ); IF(e)goto fin;\r
- }\r
- *allocate_Array = p;\r
+ e= Set2_init( &self->Nodes, 0x100 ); IF(e){goto fin;}\r
+\r
+ e= DictionaryAA_Class_traverse( Collection, DictionaryAA_IteratorClass_initialize_sub,\r
+ &self->Nodes ); IF(e){goto fin;}\r
+\r
+ self->NextNode = self->Nodes.First;\r
\r
e=0;\r
fin:\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Set2_pop_imp] >>> \r
-************************************************************************/\r
-int Set2_pop_imp( Set2* m, void* pp, size_t size )\r
+/*[DictionaryAA_IteratorClass_initialize_sub]*/\r
+errnum_t DictionaryAA_IteratorClass_initialize_sub( DictionaryAA_NodeClass* in_Node,\r
+ void* Array )\r
{\r
- int e;\r
- void* p;\r
-\r
- p = (char*) m->Next - size;\r
-\r
- IF ( p < m->First ) { e=E_OTHERS; goto fin; }\r
+ errnum_t e;\r
+ Set2* array = (Set2*) Array;\r
+ DictionaryAA_NodeClass** pp_node;\r
\r
- m->Next = p;\r
- *(void**)pp = p;\r
+ e= Set2_alloc( array, &pp_node, DictionaryAA_NodeClass* ); IF(e){goto fin;}\r
+ *pp_node = in_Node;\r
\r
e=0;\r
fin:\r
}\r
\r
\r
- \r
-/***********************************************************************\r
- <<< [Set2_setDebug] >>> \r
-************************************************************************/\r
-#ifdef _DEBUG\r
-void Set2_setDebug( Set2* m, void* PointerOfDebugArray )\r
+/*[DictionaryAA_IteratorClass_getNext]*/\r
+DictionaryAA_NodeClass* DictionaryAA_IteratorClass_getNext(\r
+ DictionaryAA_IteratorClass* self )\r
{\r
- m->PointerOfDebugArray = (void**) PointerOfDebugArray;\r
- *m->PointerOfDebugArray = m->First;\r
-}\r
-#endif\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< (Variant_SuperClass) >>> \r
-************************************************************************/\r
-static const ClassID_Class* gs_Variant_SuperClass_SuperClassIDs[] = {\r
- &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID,\r
-};\r
-\r
-/*[g_Variant_SuperClass_ID]*/\r
-const ClassID_Class g_Variant_SuperClass_ID = {\r
- "Variant_SuperClass",\r
- gs_Variant_SuperClass_SuperClassIDs,\r
- _countof( gs_Variant_SuperClass_SuperClassIDs ),\r
- sizeof( Variant_SuperClass ),\r
- Variant_SuperClass_initialize,\r
- NULL,\r
- 0,\r
-};\r
+ DictionaryAA_NodeClass* return_value;\r
\r
+ if ( self->NextNode < (DictionaryAA_NodeClass**) self->Nodes.Next ) {\r
+ return_value = *self->NextNode;\r
+ self->NextNode += 1;\r
+ }\r
+ else {\r
+ return_value = NULL;\r
+ }\r
\r
-/*[Variant_SuperClass_initialize]*/\r
-errnum_t Variant_SuperClass_initialize( Variant_SuperClass* self, void* Parameter )\r
-{\r
- self->ClassID = &g_Variant_SuperClass_ID;\r
- self->FinalizerVTable = NULL;\r
- self->StaticAddress = NULL;\r
- UNREFERENCED_VARIABLE( Parameter );\r
- return 0;\r
+ return return_value;\r
}\r
\r
\r
\r
\r
/***********************************************************************\r
- <<< [printf_to_debugger] >>> \r
-************************************************************************/\r
-#ifdef _MSC_VER\r
-void printf_to_debugger( const char* format, ... )\r
-{\r
- va_list va;\r
- char s[1024];\r
-\r
- va_start( va, format );\r
- vsprintf_r( s, sizeof(s), format, va );\r
- va_end( va );\r
-\r
- OutputDebugStringA( s );\r
-}\r
-#endif\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [wprintf_to_debugger] >>> \r
-************************************************************************/\r
-#ifdef _MSC_VER\r
-void wprintf_to_debugger( const wchar_t* format, ... )\r
-{\r
- va_list va;\r
- wchar_t s[1024];\r
-\r
- va_start( va, format );\r
- vswprintf_r( s, sizeof(s), format, va );\r
- va_end( va );\r
-\r
- OutputDebugStringW( s );\r
-}\r
-#endif\r
-\r
-\r
- \r
-/***********************************************************************\r
<<< [vsprintf_r] >>> \r
************************************************************************/\r
errnum_t vsprintf_r( char* s, size_t s_size, const char* format, va_list va )\r
{\r
size_t tsize = s_size / sizeof(wchar_t);\r
\r
- #pragma warning(push)\r
- #pragma warning(disable: 4996)\r
- int r = _vsnwprintf( s, tsize, format, va );\r
- #pragma warning(pop)\r
+ #if _MSC_VER\r
+ #pragma warning(push)\r
+ #pragma warning(disable: 4996)\r
+ #endif\r
+\r
+ int r = _vsnwprintf( s, tsize, format, va );\r
+\r
+ #if _MSC_VER\r
+ #pragma warning(pop)\r
+ #endif\r
\r
if ( r == (int) tsize || r == -1 ) { s[tsize-1] = '\0'; return E_FEW_ARRAY; }\r
else return 0;\r
\r
IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) { return 1; }\r
\r
- if ( src_over == NULL ) { src_over = _tcschr( src, _T('\0') ); }\r
+ if ( src_over == NULL ) { src_over = StrT_chr( src, _T('\0') ); }\r
+ IF_D( src > src_over ) { return 1; }\r
src_size = (char*)src_over - (char*)src;\r
IF ( src_size >= s_space ) {\r
s_space -= sizeof(TCHAR);\r
IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) {return E_OTHERS;}\r
\r
e = vstprintf_r( s_start, s_size - ( (char*)s_start - (char*)s), format, va );\r
- va_end( va ); if ( p_s_last != NULL ) *p_s_last = _tcschr( s_start, '\0' );\r
+ va_end( va ); if ( p_s_last != NULL ) *p_s_last = StrT_chr( s_start, '\0' );\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ftcopy_part_r] >>> \r
+************************************************************************/\r
+errnum_t ftcopy_part_r( FILE* OutputStream, const TCHAR* Str, const TCHAR* StrOver )\r
+{\r
+ errnum_t e;\r
+ const TCHAR* p;\r
+ bool is_last;\r
+ int size;\r
+ TCHAR buffer[256];\r
+\r
+ ASSERT_R( Str <= StrOver, e=E_OTHERS; goto fin );\r
+\r
+ p = Str;\r
+ for (;;) {\r
+ size = (uint8_t*) StrOver - (uint8_t*) p;\r
+ if ( size <= sizeof(buffer) - sizeof(TCHAR) ) {\r
+ is_last = true;\r
+ }\r
+ else {\r
+ size = sizeof(buffer) - sizeof(TCHAR);\r
+ is_last = false;\r
+ }\r
+\r
+ memcpy( buffer, p, size );\r
+ *(TCHAR*)( (uint8_t*) buffer + size ) = _T('\0');\r
+ _fputts( buffer, OutputStream ); IF(ferror(OutputStream)){e=E_ERRNO; goto fin;}\r
+\r
+ if ( is_last )\r
+ { break; }\r
+\r
+ p = (const TCHAR*)( (uint8_t*) p + size );\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+* Function: OpenConsole\r
+*\r
+* Argument:\r
+* out_IsExistOrNewConsole - NULL is permitted\r
+************************************************************************/\r
+errnum_t OpenConsole( bool in_OpenIfNoConsole, bool* out_IsExistOrNewConsole )\r
+{\r
+ errnum_t e;\r
+ BOOL b;\r
+ bool is_console;\r
+ HANDLE stdout_handle;\r
+ int stdout_file_descriptor;\r
+ FILE* stdout_stream;\r
+\r
+ PROCESSENTRY32 current_process;\r
+\r
+ current_process.dwSize = sizeof( current_process );\r
+ e= GetProcessInformation( GetCurrentProcessId(), /*Set*/ ¤t_process ); IF(e){goto fin;}\r
+\r
+\r
+ is_console = (bool) AttachConsole( current_process.th32ParentProcessID );\r
+\r
+ if ( out_IsExistOrNewConsole != NULL ) {\r
+ if ( in_OpenIfNoConsole ) {\r
+ *out_IsExistOrNewConsole = ! is_console; /* is new console */\r
+ } else {\r
+ *out_IsExistOrNewConsole = is_console; /* is exist console */\r
+ }\r
+ }\r
+\r
+ if ( ! is_console ) {\r
+ if ( in_OpenIfNoConsole ) {\r
+\r
+ b= AllocConsole();\r
+ }\r
+ else\r
+ { e=0; goto fin; }\r
+ IF(!b) { e=E_OTHERS; goto fin; }\r
+ }\r
+\r
+ stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );\r
+ IF ( stdout_handle == NULL ) { e=E_OTHERS; goto fin; }\r
+ stdout_file_descriptor = _open_osfhandle( (intptr_t) stdout_handle, _O_TEXT );\r
+ stdout_stream = _fdopen( stdout_file_descriptor, "w" );\r
+ setvbuf( stdout_stream, NULL, _IONBF, 0 );\r
+\r
+ *stdout = *stdout_stream;\r
+\r
+ e=0;\r
+fin:\r
return e;\r
}\r
\r
const InterfaceID_Class g_FinalizerInterface_ID = { "FinalizerInterface" };\r
\r
\r
-\r
\r
/***********************************************************************\r
<<< (g_PrintXML_Interface_ID) >>> \r
const InterfaceID_Class g_PrintXML_Interface_ID = { "PrintXML_Interface" };\r
\r
\r
+ \r
+/***********************************************************************\r
+ <<< [malloc_redirected] >>> \r
+************************************************************************/\r
+#undef malloc\r
+void* malloc_redirected( size_t in_Size )\r
+{\r
+ void* address = malloc( in_Size );\r
+\r
+ \r
+ HeapLogClass_log( address, in_Size ); /*(HeapLogClass_log in malloc_redirected)*/\r
+ /* \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
+\r
+ \r
+ return address;\r
+} /*(end_of_malloc_redirected)*/\r
+#define malloc malloc_redirected\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [realloc_redirected] >>> \r
+************************************************************************/\r
+#undef realloc\r
+void* realloc_redirected( void* in_Address, size_t in_Size )\r
+{\r
+ void* address = realloc( in_Address, in_Size );\r
+\r
+ \r
+ HeapLogClass_log( address, in_Size ); /*(HeapLogClass_log in realloc_redirected)*/\r
+ /* \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
+\r
+ \r
+ return address;\r
+} /*(end_of_realloc_redirected)*/\r
+#define realloc realloc_redirected\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [calloc_redirected] >>> \r
+************************************************************************/\r
+#undef calloc\r
+void* calloc_redirected( size_t in_Count, size_t in_Size )\r
+{\r
+ void* address = calloc( in_Count, in_Size );\r
+ \r
+ HeapLogClass_log( address, in_Size ); /*(HeapLogClass_log in calloc_redirected)*/\r
+ \r
+ return address;\r
+} /*(end_of_calloc_redirected)*/\r
+#define calloc calloc_redirected\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [malloc_no_redirected] >>> \r
+************************************************************************/\r
+#undef malloc\r
+void* malloc_no_redirected( size_t in_Size )\r
+{\r
+ return malloc( in_Size );\r
+}\r
+#define malloc malloc_redirected\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [realloc_no_redirected] >>> \r
+************************************************************************/\r
+#undef realloc\r
+void* realloc_no_redirected( void* in_Address, size_t in_Size )\r
+{\r
+ return realloc( in_Address, in_Size );\r
+}\r
+#define realloc realloc_redirected\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [calloc_no_redirected] >>> \r
+************************************************************************/\r
+#undef calloc\r
+void* calloc_no_redirected( size_t in_Count, size_t in_Size )\r
+{\r
+ return calloc( in_Count, in_Size );\r
+}\r
+#define calloc calloc_redirected\r
+\r
\r
\r