OSDN Git Service

Version 5.91
[vbslib/main.git] / _src / Test / tools / vbslib_helper_src / _setup_generated / clib.c
index 14c5e39..2442871 100644 (file)
@@ -1,3 +1,4 @@
+/* Character Code Encoding: "WHITE SQUARE" is \81  */\r
 /* The source file was composed by module mixer */ \r
 \r
 #include  "include_c.h"\r
@@ -41,6 +42,7 @@ fin:
 ************************************************************************/\r
 int  Globals_finalize( int e )\r
 {\r
+    HeapLogClass_finalize();\r
     e= AppKey_finishGlobal( e ); \r
 \r
   return  e;\r
@@ -280,6 +282,35 @@ bool  GetCommandLineExist( const TCHAR* Name, bool bCase )
 \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
@@ -326,7 +357,7 @@ int  env_part( TCHAR* Str,  unsigned StrSize,  TCHAR* StrStart, TCHAR** out_StrL
 \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
@@ -388,635 +419,1049 @@ err_fm:  e = E_FEW_MEMORY;  goto fin;
 /*=================================================================*/\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
@@ -1025,78 +1470,124 @@ fin:
 \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\83\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("&amp;"),  0 ); IF(e)goto fin;\r
+       e= StrT_replace( out_Str, Str_Size, out_Str,  _T("\""), _T("&quot;"), 0 ); IF(e)goto fin;\r
+       e= StrT_replace( out_Str, Str_Size, out_Str,  _T("<"),  _T("&lt;"),   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("&quot;"), _T("\""), 0 ); IF(e)goto fin;\r
+       e= StrT_replace( out_Str, Str_Size, out_Str,  _T("&lt;"),   _T("<"),  0 ); IF(e)goto fin;\r
+       e= StrT_replace( out_Str, Str_Size, out_Str,  _T("&amp;"),  _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("&amp;"), 0 ); IF(e)goto fin;\r
+       e= StrT_replace( out_Str, Str_Size, out_Str,  _T("<"), _T("&lt;"),  0 ); IF(e)goto fin;\r
+       e= StrT_replace( out_Str, Str_Size, out_Str,  _T(">"), _T("&gt;"),  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
@@ -2128,220 +8373,277 @@ fin:
 \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\83\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
@@ -3768,195 +10389,131 @@ fin:
 }\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
@@ -3966,296 +10523,363 @@ fin:
 \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
@@ -4263,473 +10887,675 @@ fin:
 }\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
@@ -4737,489 +11563,611 @@ fin:
 }\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
@@ -5227,37 +12175,24 @@ fin:
 }\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
@@ -5267,20 +12202,25 @@ fin:
 \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
@@ -5288,21 +12228,16 @@ fin:
 }\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
@@ -5310,47 +12245,21 @@ fin:
 }\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
@@ -5369,44 +12278,6 @@ errnum_t  Variant_SuperClass_initialize( Variant_SuperClass* self, void* Paramet
 \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
@@ -5440,10 +12311,16 @@ errnum_t  vswprintf_r( wchar_t* s, size_t s_size, const wchar_t* format, va_list
 {\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
@@ -5479,7 +12356,8 @@ errnum_t  stcpy_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_las
 \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
@@ -5514,7 +12392,104 @@ errnum_t  stprintf_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_
        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*/ &current_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
@@ -5691,7 +12666,6 @@ const ClassID_Class  g_ClassID_SuperClass_ID = {
 const InterfaceID_Class  g_FinalizerInterface_ID = { "FinalizerInterface" };\r
 \r
 \r
-\r
  \r
 /***********************************************************************\r
   <<< (g_PrintXML_Interface_ID) >>> \r
@@ -5700,5 +12674,94 @@ const InterfaceID_Class  g_FinalizerInterface_ID = { "FinalizerInterface" };
 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