+/*[PP_DirectiveClass_initConst]*/\r
+void PP_DirectiveClass_initConst( PP_DirectiveClass* self )\r
+{\r
+ self->ClassID = &g_PP_DirectiveClass_ID;\r
+ self->Start = NULL;\r
+ self->Over = NULL;\r
+ self->DirectiveName_Start = NULL;\r
+ self->DirectiveName_Over = NULL;\r
+}\r
+\r
+/*[g_PP_DirectiveClass_ID]*/\r
+static const ClassID_Class* gs_PP_DirectiveClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_DirectiveClass_FinalizerVTable = {\r
+ offsetof( PP_DirectiveClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_DirectiveClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_DirectiveClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_DirectiveClass_ID = {\r
+ "PP_DirectiveClass",\r
+ gs_PP_DirectiveClass_SuperClassIDs,\r
+ _countof( gs_PP_DirectiveClass_SuperClassIDs ),\r
+ sizeof( PP_DirectiveClass ),\r
+ NULL,\r
+ gs_PP_DirectiveClass_InterfaceToVTables,\r
+ _countof( gs_PP_DirectiveClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpDefineClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpDefineClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpDefineClass_FinalizerVTable = {\r
+ offsetof( PP_SharpDefineClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpDefineClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpDefineClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpDefineClass_ID = {\r
+ "PP_SharpDefineClass",\r
+ gs_PP_SharpDefineClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpDefineClass_SuperClassIDs ),\r
+ sizeof( PP_SharpDefineClass ),\r
+ NULL,\r
+ gs_PP_SharpDefineClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpDefineClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpIncludeClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpIncludeClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpIncludeClass_FinalizerVTable = {\r
+ offsetof( PP_SharpIncludeClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpIncludeClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpIncludeClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpIncludeClass_ID = {\r
+ "PP_SharpIncludeClass",\r
+ gs_PP_SharpIncludeClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpIncludeClass_SuperClassIDs ),\r
+ sizeof( PP_SharpIncludeClass ),\r
+ NULL,\r
+ gs_PP_SharpIncludeClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpIncludeClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpIfClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpIfClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpIfClass_FinalizerVTable = {\r
+ offsetof( PP_SharpIfClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpIfClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpIfClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpIfClass_ID = {\r
+ "PP_SharpIfClass",\r
+ gs_PP_SharpIfClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpIfClass_SuperClassIDs ),\r
+ sizeof( PP_SharpIfClass ),\r
+ NULL,\r
+ gs_PP_SharpIfClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpIfClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpElseClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpElseClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpElseClass_FinalizerVTable = {\r
+ offsetof( PP_SharpElseClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpElseClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpElseClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpElseClass_ID = {\r
+ "PP_SharpElseClass",\r
+ gs_PP_SharpElseClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpElseClass_SuperClassIDs ),\r
+ sizeof( PP_SharpElseClass ),\r
+ NULL,\r
+ gs_PP_SharpElseClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpElseClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpEndifClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpEndifClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpEndifClass_FinalizerVTable = {\r
+ offsetof( PP_SharpEndifClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpEndifClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpEndifClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpEndifClass_ID = {\r
+ "PP_SharpEndifClass",\r
+ gs_PP_SharpEndifClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpEndifClass_SuperClassIDs ),\r
+ sizeof( PP_SharpEndifClass ),\r
+ NULL,\r
+ gs_PP_SharpEndifClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpEndifClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpIfdefClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpIfdefClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpIfdefClass_FinalizerVTable = {\r
+ offsetof( PP_SharpIfdefClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpIfdefClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpIfdefClass_FinalizerVTable }\r
+};\r
+const ClassID_Class g_PP_SharpIfdefClass_ID = {\r
+ "PP_SharpIfdefClass",\r
+ gs_PP_SharpIfdefClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpIfdefClass_SuperClassIDs ),\r
+ sizeof( PP_SharpIfdefClass ),\r
+ NULL,\r
+ gs_PP_SharpIfdefClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpIfdefClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+/*[g_PP_SharpIfndefClass_ID]*/\r
+static const ClassID_Class* gs_PP_SharpIfndefClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
+ &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID, &g_PP_SharpIfdefClass_ID\r
+};\r
+static const FinalizerVTableClass gs_PP_SharpIfndefClass_FinalizerVTable = {\r
+ offsetof( PP_SharpIfndefClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize\r
+};\r
+static const InterfaceToVTableClass gs_PP_SharpIfndefClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_PP_SharpIfndefClass_FinalizerVTable }\r
+};\r
+\r
+const ClassID_Class g_PP_SharpIfndefClass_ID = {\r
+ "PP_SharpIfndefClass",\r
+ gs_PP_SharpIfndefClass_SuperClassIDs,\r
+ _countof( gs_PP_SharpIfndefClass_SuperClassIDs ),\r
+ sizeof( PP_SharpIfndefClass ),\r
+ NULL,\r
+ gs_PP_SharpIfndefClass_InterfaceToVTables,\r
+ _countof( gs_PP_SharpIfndefClass_InterfaceToVTables )\r
+};\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (SyntaxSubNodeClass) >>> \r
+************************************************************************/\r
+\r
+/*[g_SyntaxSubNodeClass_ID]*/\r
+const ClassID_Class g_SyntaxSubNodeClass_ID = {\r
+ "SyntaxSubNodeClass",\r
+ NULL,\r
+ 0,\r
+ sizeof( SyntaxSubNodeClass ),\r
+ NULL,\r
+ NULL,\r
+ 0,\r
+};\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Delete_SyntaxNodeList] >>> \r
+************************************************************************/\r
+errnum_t Delete_SyntaxNodeList( ListClass* /*<SyntaxNodeClass*>*/ NodeList, errnum_t e )\r
+{\r
+ return ListClass_finalizeWithVTable( NodeList, true, e );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (SyntaxNodeClass) >>> \r
+************************************************************************/\r
+\r
+static const FinalizerVTableClass gs_SyntaxNodeClass_FinalizerVTable = {\r
+ offsetof( SyntaxNodeClass, FinalizerVTable ),\r
+ DefaultFunction_Finalize,\r
+};\r
+static const PrintXML_VTableClass gs_SyntaxNodeClass_PrintXML_VTable = {\r
+ offsetof( SyntaxNodeClass, PrintXML_VTable ),\r
+ SyntaxNodeClass_printXML,\r
+};\r
+static const InterfaceToVTableClass gs_SyntaxNodeClass_InterfaceToVTables[] = {\r
+ { &g_FinalizerInterface_ID, &gs_SyntaxNodeClass_FinalizerVTable },\r
+ { &g_PrintXML_Interface_ID, &gs_SyntaxNodeClass_PrintXML_VTable },\r
+};\r
+static const ClassID_Class* gs_SyntaxNodeClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_ParsedRangeClass_ID, &g_SyntaxSubNodeClass_ID,\r
+ &g_SyntaxNodeClass_ID,\r
+};\r
+\r
+/*[g_SyntaxNodeClass_ID]*/\r
+const ClassID_Class g_SyntaxNodeClass_ID = {\r
+ "SyntaxNodeClass",\r
+ gs_SyntaxNodeClass_SuperClassIDs,\r
+ _countof( gs_SyntaxNodeClass_SuperClassIDs ),\r
+ sizeof( SyntaxNodeClass ),\r
+ NULL,\r
+ gs_SyntaxNodeClass_InterfaceToVTables,\r
+ _countof( gs_SyntaxNodeClass_InterfaceToVTables ),\r
+};\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [SyntaxNodeClass_initConst] >>> \r
+************************************************************************/\r
+void SyntaxNodeClass_initConst( SyntaxNodeClass* self )\r
+{\r
+ self->ClassID = &g_SyntaxNodeClass_ID;\r
+ self->FinalizerVTable = &gs_SyntaxNodeClass_FinalizerVTable;\r
+ self->Start = NULL;\r
+ self->Over = NULL;\r
+ self->PrintXML_VTable = &gs_SyntaxNodeClass_PrintXML_VTable;\r
+ self->Parent = NULL;\r
+ ListElementClass_initConst( &self->SubNodeListElement, self );\r
+ ListClass_initConst( &self->SubNodeList );\r
+ ListElementClass_initConst( &self->ListElement, self );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [SyntaxNodeClass_printXML] >>> \r
+************************************************************************/\r
+errnum_t SyntaxNodeClass_printXML( SyntaxNodeClass* self, FILE* OutputStream )\r
+{\r
+ errnum_t e;\r
+ int r;\r
+\r
+ r= _ftprintf_s( OutputStream, _T("<SyntaxNodeClass") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ r= _ftprintf_s( OutputStream, _T(" Address=\"0x%08X\""), self );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ r= _ftprintf_s( OutputStream, _T("/>\n") );\r
+ IF ( r < 0 ) { e=E_ACCESS_DENIED; goto fin; }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [SyntaxNodeClass_addSubNode] >>> \r
+************************************************************************/\r
+errnum_t SyntaxNodeClass_addSubNode( SyntaxNodeClass* self, SyntaxSubNodeClass* SubNode )\r
+{\r
+ errnum_t e;\r
+\r
+ ASSERT_D( ClassID_Class_isSuperClass( self->ClassID, &g_SyntaxNodeClass_ID ), e=E_OTHERS; goto fin );\r
+ ASSERT_D( ClassID_Class_isSuperClass( SubNode->ClassID, &g_SyntaxSubNodeClass_ID ), e=E_OTHERS; goto fin );\r
+ ASSERT_R( SubNode->Parent == NULL, e=E_OTHERS; goto fin );\r
+\r
+ e= ListClass_addLast( &self->SubNodeList, &SubNode->SubNodeListElement ); IF(e){goto fin;}\r
+ SubNode->Parent = self;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [LineNumberIndexClass_compare_sub] >>> \r
+************************************************************************/\r
+int LineNumberIndexClass_compare_sub( const void* ppLeft, const void* ppRight, const void* Param,\r
+ int* out_Result )\r
+{\r
+ UNREFERENCED_VARIABLE( Param );\r
+ *out_Result = (const uint8_t*) *(TCHAR**) ppLeft - (const uint8_t*) *(TCHAR**) ppRight;\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (LineNumberIndexClass) >>> \r
+************************************************************************/\r
+\r
+/*[LineNumberIndexClass_initConst]*/\r
+void LineNumberIndexClass_initConst( LineNumberIndexClass* self )\r
+{\r
+ Set2_initConst( &self->LeftsOfLine );\r
+}\r
+\r
+\r
+/*[LineNumberIndexClass_finalize]*/\r
+errnum_t LineNumberIndexClass_finalize( LineNumberIndexClass* self, errnum_t e )\r
+{\r
+ return Set2_finish( &self->LeftsOfLine, e );\r
+}\r
+\r
+\r
+/*[LineNumberIndexClass_initialize]*/\r
+errnum_t LineNumberIndexClass_initialize( LineNumberIndexClass* self, const TCHAR* Text )\r
+{\r
+ errnum_t e;\r
+ const TCHAR* p;\r
+ const TCHAR* line_feed;\r
+ const TCHAR** pp_left;\r
+\r
+ e= Set2_init( &self->LeftsOfLine, 1000 * sizeof(TCHAR*) ); IF(e){goto fin;}\r
+\r
+ p = Text;\r
+ for (;;) {\r
+ e= Set2_alloc( &self->LeftsOfLine, &pp_left, const TCHAR* ); IF(e){goto fin;}\r
+ *pp_left = p;\r
+\r
+ line_feed = _tcschr( p, _T('\n') );\r
+ if ( line_feed == NULL )\r
+ { break; }\r
+\r
+ p = line_feed + 1;\r
+ }\r
+\r
+#if 0 //[TODO]\r
+ p = _tcschr( p, _T('\0') );\r
+ e= Set2_alloc( &self->LeftsOfLine, &pp_left, const TCHAR* ); IF(e){goto fin;}\r
+ *pp_left = p + 1;\r
+#else\r
+ if ( *p != _T('\0') ) {\r
+ p = _tcschr( p, _T('\0') );\r
+ e= Set2_alloc( &self->LeftsOfLine, &pp_left, const TCHAR* ); IF(e){goto fin;}\r
+ *pp_left = p + 1;\r
+#endif\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+/*[LineNumberIndexClass_searchLineNumber]*/\r
+errnum_t LineNumberIndexClass_searchLineNumber( LineNumberIndexClass* self, const TCHAR* Position,\r
+ int* out_LineNumber )\r
+{\r
+ errnum_t e;\r
+ int found_index;\r
+ int result;\r
+\r
+ e= PArray_doBinarySearch( self->LeftsOfLine.First,\r
+ (uint8_t*) self->LeftsOfLine.Next - (uint8_t*) self->LeftsOfLine.First,\r
+ Position, LineNumberIndexClass_compare_sub, NULL,\r
+ &found_index, &result );\r
+ IF(e){goto fin;}\r
+\r
+ *out_LineNumber = found_index + 1;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+/*[LineNumberIndexClass_getCountOfLines]*/\r
+int LineNumberIndexClass_getCountOfLines( LineNumberIndexClass* self )\r
+{\r
+ return Set2_getCount( &self->LeftsOfLine, const TCHAR* ) - 1;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (ParsedRangeClass) >>> \r
+************************************************************************/\r
+\r
+/*[ParsedRangeClass_initConst]*/\r
+void ParsedRangeClass_initConst( ParsedRangeClass* self )\r
+{\r
+ self->ClassID = &g_ParsedRangeClass_ID;\r
+ self->FinalizerVTable = NULL;\r
+ self->StaticAddress = NULL;\r
+ self->Start = NULL;\r
+ self->Over = NULL;\r
+}\r
+\r
+\r
+/*[g_ParsedRangeClass_ID]*/\r
+static const ClassID_Class* gs_ParsedRangeClass_SuperClassIDs[] = {\r
+ &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID\r
+};\r
+const ClassID_Class g_ParsedRangeClass_ID = {\r
+ "ParsedRangeClass",\r
+ gs_ParsedRangeClass_SuperClassIDs,\r
+ _countof( gs_ParsedRangeClass_SuperClassIDs ),\r
+ sizeof( ParsedRangeClass ),\r
+ NULL,\r
+};\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParsedRanges_getCut_by_PP_Directive] >>> \r
+************************************************************************/\r
+errnum_t ParsedRanges_getCut_by_PP_Directive(\r
+ Set2* /*<ParsedRangeClass>*/ CutRanges,\r
+ Set2* /*<PP_DirectiveClass*>*/ DirectivePointerArray,\r
+ const TCHAR* Symbol, bool IsCutDefine )\r
+{\r
+ errnum_t e;\r
+ PP_DirectiveClass** p;\r
+ PP_DirectiveClass** p_over;\r
+\r
+ for ( Set2_forEach( DirectivePointerArray, &p, &p_over, PP_DirectiveClass* ) ) {\r
+ PP_DirectiveClass* directive = *p;\r
+ PP_SharpIfClass* sh_if = NULL; /* sh = sharp */\r
+ bool is_not_condition = false;\r
+\r
+ if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfdefClass_ID ) ) {\r
+ PP_SharpIfdefClass* sh_ifdef = (PP_SharpIfdefClass*) directive; /* sh = sharp */\r
+\r
+ if ( StrT_cmp_part( sh_ifdef->Symbol_Start, sh_ifdef->Symbol_Over, Symbol ) == 0 ) {\r
+ sh_if = (PP_SharpIfClass*) sh_ifdef;\r
+ is_not_condition = ( sh_ifdef->ClassID == &g_PP_SharpIfndefClass_ID );\r
+ }\r
+ }\r
+ else if ( directive->ClassID == &g_PP_SharpIfClass_ID ) {\r
+ const TCHAR* condition_start;\r
+ const TCHAR* condition_over;\r
+\r
+ sh_if = (PP_SharpIfClass*) directive; /* sh = sharp */\r
+ condition_start = sh_if->DirectiveName_Over;\r
+ condition_over = sh_if->Over;\r
+\r
+ while ( condition_start < condition_over ) {\r
+ if ( _istspace( *condition_start ) ) {\r
+ condition_start += 1;\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+ while ( condition_start < condition_over ) {\r
+ if ( _istspace( *( condition_over - 1 ) ) ) {\r
+ condition_over -= 1;\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+ if ( ! StrT_cmp_part( condition_start, condition_over, Symbol ) == 0 ) {\r
+ sh_if = NULL;\r
+ }\r
+ }\r
+\r
+ if ( sh_if != NULL ) {\r
+ PP_SharpElseClass* sh_else; /* sh = sharp */\r
+ PP_SharpEndifClass* sh_endif; /* sh = sharp */\r
+ ParsedRangeClass* cut;\r
+\r
+\r
+ /* Set "sh_else", "sh_endif" */\r
+ if ( ClassID_Class_isSuperClass( sh_if->NextDirective->ClassID,\r
+ &g_PP_SharpElseClass_ID ) ) {\r
+ sh_else = (PP_SharpElseClass*) sh_if->NextDirective;\r
+ sh_endif = sh_if->EndDirective;\r
+ } else {\r
+ sh_else = NULL;\r
+ sh_endif = (PP_SharpEndifClass*) sh_if->NextDirective;\r
+ }\r
+\r
+\r
+ /* Add to "CutRanges" */\r
+ e= Set2_alloc( CutRanges, &cut, ParsedRangeClass ); IF(e){goto fin;}\r
+ cut->Start = sh_if->Start;\r
+ if ( is_not_condition == ! IsCutDefine ) {\r
+ if ( sh_else != NULL ) {\r
+ cut->Over = sh_else->Over;\r
+\r
+ e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );\r
+ IF(e){goto fin;}\r
+ cut->Start = sh_endif->Start;\r
+ }\r
+ cut->Over = sh_endif->Over;\r
+ }\r
+ else {\r
+ cut->Over = sh_if->Over;\r
+\r
+ e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );\r
+ IF(e){goto fin;}\r
+ if ( sh_else != NULL ) {\r
+ cut->Start = sh_else->Start;\r
+ } else {\r
+ cut->Start = sh_endif->Start;\r
+ }\r
+ cut->Over = sh_endif->Over;\r
+ }\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParsedRangeClass_onInitializedForDebug] >>> \r
+************************************************************************/\r
+#if ! defined( NDEBUG )\r
+void ParsedRangeClass_onInitializedForDebug( ParsedRangeClass* self )\r
+{\r
+ /* These code can be modified for Debug. */\r
+ #if 0 // IS_USED_DEBUG_CHECK_CLASS\r
+ TCHAR* text;\r
+ ptrdiff_t break_diff = 0x1FA6A;\r
+\r
+ START_D( 10 );\r
+ text = GET_D( 1, TCHAR* );\r
+ PointerType_plus( &text, break_diff );\r
+ if ( text == self->Start ) {\r
+ if ( self->ClassID == &g_ParsedRangeClass_ID ) {\r
+ SET_D( 2, self );\r
+ }\r
+ }\r
+ END_D();\r
+ #else\r
+ UNREFERENCED_VARIABLE( self );\r
+ #endif\r
+}\r
+#endif\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParsedRanges_compareByStart] >>> \r
+************************************************************************/\r
+int ParsedRanges_compareByStart( const void* _a1, const void* _a2 )\r
+{\r
+ ParsedRangeClass* a1 = (ParsedRangeClass*) _a1;\r
+ ParsedRangeClass* a2 = (ParsedRangeClass*) _a2;\r
+\r
+ return a1->Start - a2->Start;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParsedRanges_write_by_Cut] >>> \r
+************************************************************************/\r
+errnum_t ParsedRanges_write_by_Cut(\r
+ Set2* /*<ParsedRangeClass>*/ CutRanges,\r
+ const TCHAR* Text, FILE* OutFile )\r
+{\r
+ errnum_t e;\r
+ const TCHAR* position;\r
+ ParsedRangeClass* p;\r
+ ParsedRangeClass* p_over;\r
+\r
+ qsort( CutRanges->First, Set2_getCount( CutRanges, ParsedRangeClass ),\r
+ sizeof(ParsedRangeClass), ParsedRanges_compareByStart );\r
+\r
+ position = Text;\r
+ for ( Set2_forEach( CutRanges, &p, &p_over, ParsedRangeClass ) ) {\r
+ const TCHAR* cut_start_position;\r
+ const TCHAR* cut_over_position;\r
+\r
+ cut_start_position = p->Start;\r
+ if ( position < cut_start_position ) {\r
+ e= FileT_writePart( OutFile, (TCHAR*)position, (TCHAR*)cut_start_position );\r
+ IF(e){goto fin;}\r
+ }\r
+\r
+ cut_over_position = p->Over;\r
+ if ( position < cut_over_position ) {\r
+ position = cut_over_position;\r
+ }\r
+ }\r
+ _fputts( position, OutFile ); IF(ferror(OutFile)){e=E_ERRNO; goto fin;}\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [Locale/Locale.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [g_LocaleSymbol] >>> \r
+************************************************************************/\r
+char* g_LocaleSymbol = "";\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Locale_init] >>> \r
+************************************************************************/\r
+int Locale_init()\r
+{\r
+ g_LocaleSymbol = ".OCP";\r
+ setlocale( LC_ALL, ".OCP" );\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Locale_isInited] >>> \r
+************************************************************************/\r
+int Locale_isInited()\r
+{\r
+ return ( g_LocaleSymbol[0] != '\0' );\r
+ // \82±\82±\82ª false \82ð\95Ô\82·\82Æ\82«\82Ì\91Î\8f\88\96@\82Í\81ALocale_isInited \82Ì\83w\83\8b\83v\82ð\8eQ\8fÆ\82µ\82Ä\82\82¾\82³\82¢\81B\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [IniFile2/IniFile2.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [IniStr_isLeft] >>> \r
+************************************************************************/\r
+bool IniStr_isLeft( const TCHAR* line, const TCHAR* symbol )\r
+{\r
+ const TCHAR* p;\r
+ size_t symbol_len = _tcslen( symbol );\r
+\r
+ /* Skip spaces at the top of line */\r
+ for ( p = line; *p == _T(' ') || *p == _T('\t'); p++ );\r
+\r
+ /* Compare symbol */\r
+ if ( _tcsnicmp( p, symbol, symbol_len ) != 0 ) return false;\r
+\r
+ switch ( *(p + symbol_len) ) {\r
+ case _T(' '): case _T('\t'): case _T('='): return true;\r
+ default: return false;\r
+ }\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [IniStr_refRight] >>> \r
+************************************************************************/\r
+TCHAR* IniStr_refRight( const TCHAR* line, bool bTrimRight )\r
+{\r
+ const TCHAR* p;\r
+\r
+ for ( p = line; *p != _T('\0') && *p != _T('='); p++ );\r
+ if ( *p == _T('=') ) {\r
+\r
+ //=== Skip spaces at the right of equal. Trim the left of value\r
+ for ( p++ ; *p == _T(' ') || *p == _T('\t'); p++ );\r
+\r
+ //=== Trim the right of value\r
+ if ( bTrimRight ) {\r
+ const TCHAR* t;\r
+ TCHAR c;\r
+\r
+ t = StrT_chr( p, _T('\0') );\r
+ if ( t != p ) {\r
+ for ( t--; ; t-- ) {\r
+ if ( t < p )\r
+ { p = StrT_chr( p, _T('\0') ); break; }\r
+\r
+ c = *t;\r
+ if ( c != ' ' && c != '\t' && c != '\n' && c != '\r' )\r
+ { *(TCHAR*)(t+1) = _T('\0'); break; }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return (TCHAR*) p;\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [FileT/FileT.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_isExist] >>> \r
+************************************************************************/\r
+bool FileT_isExist( const TCHAR* path )\r
+{\r
+ #if ! FileT_isExistWildcard\r
+\r
+ DWORD r;\r
+\r
+ if ( path[0] == _T('\0') ) return false;\r
+ r = GetFileAttributes( path );\r
+ return r != (DWORD)-1;\r
+\r
+ #else\r
+\r
+ HANDLE find;\r
+ WIN32_FIND_DATA data;\r
+\r
+ find = FindFirstFileEx( path, FindExInfoStandard, &data,\r
+ FindExSearchNameMatch, NULL, 0 );\r
+\r
+ if ( find == INVALID_HANDLE_VALUE ) {\r
+ return false;\r
+ }\r
+ else {\r
+ FindClose( find );\r
+ return true;\r
+ }\r
+\r
+ #endif\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_isFile] >>> \r
+************************************************************************/\r
+bool FileT_isFile( const TCHAR* path )\r
+{\r
+ DWORD r = GetFileAttributes( path );\r
+ return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == 0;\r
+ // 0x80000000 \82Í\81A\83t\83@\83C\83\8b\82â\83t\83H\83\8b\83_\82ª\91¶\8dÝ\82µ\82È\82¢\82±\82Æ\82ð\94»\92è\82·\82é\82½\82ß\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_isDir] >>> \r
+************************************************************************/\r
+bool FileT_isDir( const TCHAR* path )\r
+{\r
+ DWORD r = GetFileAttributes( path );\r
+ return ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == FILE_ATTRIBUTE_DIRECTORY;\r
+ // 0x80000000 \82Í\81A\83t\83@\83C\83\8b\82â\83t\83H\83\8b\83_\82ª\91¶\8dÝ\82µ\82È\82¢\82±\82Æ\82ð\94»\92è\82·\82é\82½\82ß\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_callByNestFind] \83T\83u\83t\83H\83\8b\83_\82à\8aÜ\82ß\82Ä\8ae\83t\83@\83C\83\8b\82Ì\83p\83X\82ð\93n\82· >>> \r
+************************************************************************/\r
+typedef struct {\r
+ /*--- inherit from FileT_CallByNestFindData */\r
+ void* CallerArgument;\r
+ TCHAR* FullPath; // abstruct path\r
+ TCHAR* StepPath;\r
+ TCHAR* FileName;\r
+ DWORD FileAttributes;\r
+\r
+ /*---*/\r
+ BitField Flags;\r
+ FuncType CallbackFromNestFind;\r
+ TCHAR FullPathMem[4096];\r
+} FileT_CallByNestFindDataIn;\r
+\r
+int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m );\r
+\r
+\r
+int FileT_callByNestFind( const TCHAR* Path, BitField Flags, void* Argument, FuncType Callback )\r
+{\r
+ int e;\r
+ FileT_CallByNestFindDataIn data;\r
+\r
+ {\r
+ TCHAR* p;\r
+\r
+ e= StrT_cpy( data.FullPathMem, sizeof(data.FullPathMem), Path ); IF(e)goto fin;\r
+\r
+\r
+ /* FullPathMem \82Ì\8dÅ\8cã\82É \ \82ª\96³\82¢\82È\82ç\92Ç\89Á\82·\82é */\r
+ p = StrT_chr( data.FullPathMem, _T('\0') );\r
+ p--;\r
+ if ( *p != _T('\\') ) {\r
+ p++;\r
+ IF( p >= data.FullPathMem + (sizeof(data.FullPathMem) / sizeof(TCHAR)) - 1 )goto err_fa;\r
+ *p = _T('\\');\r
+ }\r
+\r
+\r
+ /* data \82ð\8f\89\8aú\89»\82·\82é */\r
+ data.CallerArgument = Argument;\r
+ data.FullPath = data.FullPathMem;\r
+ data.StepPath = p + 1;\r
+ data.FileName = p + 1;\r
+ data.Flags = Flags;\r
+ data.CallbackFromNestFind = Callback;\r
+ }\r
+\r
+ /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ\8aÖ\90\94\82Ö */\r
+ e= FileT_callByNestFind_sub( &data ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+err_fa: e= E_FEW_ARRAY; goto fin;\r
+}\r
+\r
+\r
+int FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m )\r
+{\r
+ int e;\r
+ HANDLE find;\r
+ WIN32_FIND_DATA data;\r
+ TCHAR* p;\r
+ int done;\r
+\r
+\r
+ /* Path \82É\8ew\92è\82µ\82½\83t\83H\83\8b\83_\82É\91Î\82µ\82Ä\83R\81[\83\8b\83o\83b\83N\82·\82é */\r
+ if ( m->Flags & FileT_FolderBeforeFiles ) {\r
+ *( m->FileName - 1 ) = _T('\0'); // m->FullPath \82Ì\8dÅ\8cã\82Ì \ \82ð\88ê\8e\9e\93I\82É\83J\83b\83g\r
+ *( m->FileName ) = _T('\0'); // m->FileName, m->StepPath \82ð "" \82É\82·\82é\r
+ m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
+\r
+ if ( m->StepPath[0] == _T('\0') ) {\r
+ TCHAR* step_path = m->StepPath;\r
+ TCHAR* fname = m->FileName;\r
+\r
+ m->StepPath = _T(".");\r
+ m->FileName = StrT_refFName( m->FullPath );\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ m->StepPath = step_path;\r
+ m->FileName = fname;\r
+ }\r
+ else if ( m->FileName[0] == _T('\0') ) {\r
+ TCHAR* fname = m->FileName;\r
+\r
+ m->FileName = StrT_refFName( m->FullPath );\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ m->FileName = fname;\r
+ }\r
+ else {\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ }\r
+ *( m->FileName - 1 ) = _T('\\');\r
+ }\r
+\r
+\r
+ /* * \82ð\92Ç\89Á */\r
+ p = m->FileName;\r
+ IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
+ *p = _T('*'); *(p+1) = _T('\0');\r
+\r
+\r
+ /* \83t\83@\83C\83\8b\82©\83t\83H\83\8b\83_\82ð\97ñ\8b\93\82µ\82Ü\82· */\r
+ find = FindFirstFileEx( m->FullPathMem, FindExInfoStandard, &data,\r
+ FindExSearchNameMatch, NULL, 0 );\r
+ done = ( find == INVALID_HANDLE_VALUE );\r
+\r
+ while (!done)\r
+ {\r
+ if ( _tcscmp( data.cFileName, _T(".") ) == 0 ||\r
+ _tcscmp( data.cFileName, _T("..") ) == 0 ) {\r
+ done = ! FindNextFile( find, &data );\r
+ continue;\r
+ }\r
+\r
+ StrT_cpy( m->FileName,\r
+ sizeof(m->FullPathMem) - ( (char*)m->FileName - (char*)m->FullPathMem ),\r
+ data.cFileName );\r
+ m->FileAttributes = data.dwFileAttributes;\r
+\r
+ if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
+ TCHAR* prev_fname = m->FileName;\r
+\r
+ p = StrT_chr( m->FileName, _T('\0') );\r
+\r
+ IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
+ *p = _T('\\'); *(p+1) = _T('\0');\r
+ m->FileName = p + 1;\r
+\r
+ e= FileT_callByNestFind_sub( m ); IF(e)goto fin; /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ */\r
+\r
+ m->FileName = prev_fname;\r
+ }\r
+ else {\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+ }\r
+\r
+ done = ! FindNextFile( find, &data );\r
+ }\r
+ FindClose( find );\r
+\r
+\r
+ /* Path \82É\8ew\92è\82µ\82½\83t\83H\83\8b\83_\82É\91Î\82µ\82Ä\83R\81[\83\8b\83o\83b\83N\82·\82é */\r
+ if ( m->Flags & FileT_FolderAfterFiles ) {\r
+ TCHAR* step_path = m->StepPath;\r
+ TCHAR* fname = m->FileName;\r
+\r
+ *( m->FileName - 1 ) = _T('\0');\r
+ m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
+ if ( ( *( m->StepPath - 1 ) == _T('\0') ) && ( m->StepPath > m->FullPath ) ) {\r
+ m->StepPath = _T(".");\r
+ }\r
+ m->FileName = StrT_refFName( m->FullPath );\r
+\r
+ e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
+\r
+ m->StepPath = step_path;\r
+ m->FileName = fname;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+err_fa: e= E_FEW_ARRAY; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_openForRead] >>> \r
+************************************************************************/\r
+int FileT_openForRead( FILE** out_pFile, const TCHAR* Path )\r
+{\r
+ errno_t en;\r
+\r
+ assert( Locale_isInited() );\r
+\r
+ #if DEBUGTOOLS_USES\r
+ { int e= Debug_onOpen( Path ); if(e) return e; }\r
+ #endif\r
+\r
+ en = _tfopen_s( out_pFile, Path, _T("r")_T(fopen_ccs) );\r
+ if ( en == ENOENT ) {\r
+ #ifndef UNDER_CE\r
+ {\r
+ TCHAR cwd[512];\r
+\r
+ if ( _tgetcwd( cwd, _countof(cwd) ) == NULL ) {\r
+ cwd[0] = _T('\0');\r
+ }\r
+ Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\" current=\"%s\"/>"),\r
+ Path, cwd );\r
+ }\r
+ #else\r
+ Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\"/>"), Path );\r
+ #endif\r
+\r
+ return E_PATH_NOT_FOUND;\r
+ }\r
+ if ( en == EACCES ) {\r
+ Error4_printf( _T("access denied \"%s\"\n"), Path );\r
+ return E_ACCESS_DENIED;\r
+ }\r
+ IF(en)return E_OTHERS;\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_openForWrite] >>> \r
+************************************************************************/\r
+int FileT_openForWrite( FILE** out_pFile, const TCHAR* Path, bit_flags_fast32_t Flags )\r
+{\r
+ int e;\r
+ errno_t en;\r
+ TCHAR* open_type;\r
+ BOOL b;\r
+ int retry_count;\r
+\r
+ IF_D( ! Locale_isInited() ) return E_NOT_INIT_GLOBAL;\r
+\r
+ #if Uses_AppKey\r
+ e= AppKey_addNewWritableFolder( Path ); IF(e)goto fin;\r
+ #endif\r
+\r
+ if ( Flags & F_Append )\r
+ open_type = ( Flags & F_Unicode ? _T("a")_T(fopen_ccs) : _T("at") );\r
+ else\r
+ open_type = ( Flags & F_Unicode ? _T("w")_T(fopen_ccs) : _T("wt") );\r
+\r
+ #if DEBUGTOOLS_USES\r
+ { int e= Debug_onOpen( Path ); if(e) return e; }\r
+ #endif\r
+\r
+ for ( retry_count = 0; ; retry_count ++ ) {\r
+ en = _tfopen_s( out_pFile, Path, open_type );\r
+ if ( en != EACCES ) break;\r
+ IF ( GetFileAttributes( Path ) == FILE_ATTRIBUTE_DIRECTORY ) { goto err_gt; }\r
+\r
+ retry_count += 1;\r
+ if ( retry_count == 15 ) break;\r
+ Sleep( 1000 );\r
+ }\r
+ if ( en == 2 ) { // ENOENT\r
+ e= FileT_mkdir( Path ); IF(e)goto fin;\r
+ b= RemoveDirectory( Path ); IF(!b)goto err_gt;\r
+ en = _tfopen_s( out_pFile, Path, open_type );\r
+\r
+ IF ( en == 2 ) {\r
+ _tprintf( _T("cannot open \"%s\"\n"), Path );\r
+\r
+ #ifndef UNDER_CE\r
+ {\r
+ TCHAR cwd[512];\r
+\r
+ if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )\r
+ _tprintf( _T("current = \"%s\"\n"), cwd );\r
+ }\r
+ #endif\r
+\r
+ e = E_NOT_FOUND_SYMBOL;\r
+ goto fin;\r
+ }\r
+ }\r
+ IF(en)goto err;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_close] >>> \r
+************************************************************************/\r
+int FileT_close( FILE* File, int e )\r
+{\r
+ if ( File != NULL ) {\r
+ int r = fclose( File );\r
+ IF(r&&!e)e=E_ERRNO;\r
+ }\r
+ return e;\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_closeAndNULL] >>> \r
+************************************************************************/\r
+errnum_t FileT_closeAndNULL( FILE** in_out_File, errnum_t e )\r
+{\r
+ FILE* file = *in_out_File;\r
+\r
+ if ( file != NULL ) {\r
+ int r = fclose( file );\r
+ IF ( r && e == 0 ) { e = E_ERRNO; }\r
+ *in_out_File = NULL;\r
+ }\r
+\r
+ return e;\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_readAll] >>> \r
+************************************************************************/\r
+#ifdef IsTest_FileT_readAll\r
+ #define _CV(x) CoverageLogClass_output( x, _T("FileT_readAll") )\r
+#else\r
+ #define _CV(x)\r
+#endif\r
+\r
+errnum_t FileT_readAll( FILE* File, TCHAR** out_Text, size_t* out_TextLength )\r
+{\r
+#ifdef IsTest_FileT_readAll\r
+ enum { text_max_size_first = 0x10 };\r
+#else\r
+ enum { text_max_size_first = 0xFF00 };\r
+#endif\r
+ errnum_t e;\r
+ TCHAR* text = NULL;\r
+ TCHAR* text_over = (TCHAR*) DUMMY_INITIAL_VALUE;\r
+ size_t text_max_size = text_max_size_first;\r
+ TCHAR* text_max_over;\r
+\r
+\r
+ text = (TCHAR*) malloc( text_max_size ); IF( text == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ text_over = text;\r
+ text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );\r
+\r
+ text[0] = _T('\0'); /* for empty file */\r
+\r
+ for (;;) {\r
+ _fgetts( text_over, text_max_over - text_over, File );\r
+\r
+ if ( *text_over == _T('\0') ) { /* End of file. If space line, *text_over == _T('\n'). */\r
+ _CV(1);\r
+ ASSERT_R( feof( File ), e=E_OTHERS; goto fin );\r
+ break;\r
+ }\r
+ text_over = StrT_chr( text_over, _T('\0') );\r
+ if ( feof( File ) ) { break; }\r
+\r
+ if ( (uint8_t*) text_over - (uint8_t*) text == (int)( text_max_size - sizeof(TCHAR) ) ) {\r
+ /* if full in text */\r
+ TCHAR* new_text;\r
+ size_t old_text_max_size = text_max_size;\r
+\r
+ #ifdef IsTest_FileT_readAll\r
+ EmptyHeapMemoryEmulation( _T("T_FileT_readAll_FewMemory"), 1 );\r
+ #endif\r
+\r
+ text_max_size *= 4;\r
+ new_text = (TCHAR*) realloc( text, text_max_size );\r
+ IF( new_text == NULL ) { e=E_FEW_MEMORY; _CV(2); goto fin; }\r
+ text = new_text;\r
+ text_over = (TCHAR*)( (uint8_t*) new_text + old_text_max_size - sizeof(TCHAR) );\r
+ text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );\r
+ }\r
+ else {\r
+ _CV(3);\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( e ) {\r
+ if ( text != NULL ) { _CV(4); free( text ); }\r
+ }\r
+ else {\r
+ *out_Text = text;\r
+ if ( out_TextLength != NULL ) { *out_TextLength = text_over - text; }\r
+ }\r
+ return e;\r
+}\r
+#undef _CV\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_writePart] >>> \r
+************************************************************************/\r
+errnum_t FileT_writePart( FILE* File, const TCHAR* Start, TCHAR* Over )\r
+{\r
+ errnum_t e;\r
+ TCHAR back_char;\r
+ int r;\r
+\r
+ back_char = *Over;\r
+\r
+ IF ( Start > Over ) { e=E_OTHERS; goto fin; }\r
+\r
+ *Over = _T('\0');\r
+ r= _ftprintf_s( File, _T("%s"), Start ); IF(r<0){ e=E_ERRNO; goto fin; }\r
+\r
+ e=0;\r
+fin:\r
+ *Over = back_char;\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_mkdir] >>> \r
+************************************************************************/\r
+int FileT_mkdir( const TCHAR* Path )\r
+{\r
+ int e;\r
+ DWORD r;\r
+ TCHAR* p = (TCHAR*) DUMMY_INITIAL_VALUE;\r
+ BOOL b;\r
+ int n_folder = 0;\r
+ TCHAR path2[MAX_PATH];\r
+\r
+\r
+ e= StrT_getFullPath( path2, sizeof(path2), Path, NULL ); IF(e)goto fin;\r
+ #if Uses_AppKey\r
+ e= AppKey_addNewWritableFolder( path2 ); IF(e)goto fin;\r
+ #endif\r
+\r
+\r
+ //=== \91¶\8dÝ\82·\82é\83t\83H\83\8b\83_\82ð\92T\82·\r
+ for (;;) {\r
+ r = GetFileAttributes( path2 );\r
+ if ( r != (DWORD)-1 ) break; // "C:" \82à\83t\83H\83\8b\83_\82Æ\94»\92è\82³\82ê\82é\r
+\r
+ p = StrT_refFName( path2 ) - 1; // \90â\91Î\83p\83X\82È\82Ì\82Å\95K\82¸ *p=='\\'\r
+ *p = _T('\0');\r
+ n_folder ++;\r
+ }\r
+ IF ( ! (r & FILE_ATTRIBUTE_DIRECTORY) ) goto err; // \83t\83@\83C\83\8b\82È\82ç\83G\83\89\81[\r
+\r
+\r
+ //=== \83t\83H\83\8b\83_\82ð\8dì\90¬\82·\82é\r
+ for ( ; n_folder > 0; n_folder -- ) {\r
+ *p = _T('\\');\r
+ b= CreateDirectory( path2, NULL ); IF(!b)goto err;\r
+ p = StrT_chr( p, _T('\0') );\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_copy] >>> \r
+************************************************************************/\r
+int FileT_copy_sub( FileT_CallByNestFindData* m );\r
+\r
+int FileT_copy( const TCHAR* SrcPath, const TCHAR* DstPath )\r
+{\r
+ const TCHAR* p_last;\r
+ int e;\r
+ BOOL b;\r
+ TCHAR path[MAX_PATH*4];\r
+\r
+\r
+ #if Uses_AppKey\r
+ e= AppKey_addNewWritableFolder( DstPath ); IF(e)goto fin;\r
+ #endif\r
+\r
+ p_last = StrT_chr( SrcPath, _T('\0') );\r
+ IF_D( p_last <= SrcPath + 1 )goto err_ni;\r
+\r
+\r
+ //=== \83t\83H\83\8b\83_\82ð\83R\83s\81[\82·\82é\r
+ if ( *(p_last - 1) == _T('*') ) {\r
+ IF_D( *(p_last - 2) != _T('\\') ) goto err_ni;\r
+\r
+ e= StrT_getParentFullPath( path, sizeof(path), SrcPath, NULL ); IF(e)goto fin;\r
+ IF_D( ! FileT_isDir( path ) )goto err_nf;\r
+\r
+ e= FileT_callByNestFind( path, FileT_FolderBeforeFiles, (void*) DstPath, (FuncType) FileT_copy_sub );\r
+ IF(e)goto fin;\r
+ }\r
+\r
+\r
+ //=== \83t\83@\83C\83\8b\82ð\83R\83s\81[\82·\82é\r
+ else {\r
+ IF_D( _tcschr( SrcPath, _T('*') ) != NULL )goto err_ni;\r
+ IF_D( ! FileT_isFile( SrcPath ) ) goto err_nf;\r
+\r
+ b= CopyFile( SrcPath, DstPath, FALSE );\r
+ if (!b) {\r
+ if ( FileT_isDir( DstPath ) ) {\r
+ e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
+ b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
+ }\r
+ else {\r
+ int ee;\r
+\r
+ p_last = StrT_chr( DstPath, _T('\0') ) - 1;\r
+ IF_D( p_last < DstPath )goto err;\r
+ if ( *p_last == _T('\\') ) {\r
+ ee= FileT_mkdir( DstPath ); IF(ee)goto fin;\r
+ e= stprintf_r( path, sizeof(path), _T("%s%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
+ b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
+ }\r
+ else {\r
+ e = E_ACCESS_DENIED;\r
+ ee= StrT_getParentFullPath( path, sizeof(path), DstPath, NULL ); IF(ee)goto fin;\r
+ ee= FileT_mkdir( path ); IF(ee)goto fin;\r
+ b= CopyFile( SrcPath, DstPath, FALSE ); IF(!b)goto err_gt;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_ni: e = E_NOT_IMPLEMENT_YET; goto fin;\r
+err_nf: e = E_PATH_NOT_FOUND; goto fin;\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+\r
+int FileT_copy_sub( FileT_CallByNestFindData* m )\r
+{\r
+ const TCHAR* DstPath = (const TCHAR*) m->CallerArgument;\r
+ int e;\r
+ BOOL b;\r
+ TCHAR path[MAX_PATH*4];\r
+\r
+ e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, m->StepPath ); IF(e)goto fin;\r
+\r
+ if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
+ if ( ! FileT_isDir( path ) )\r
+ { b= CreateDirectory( path, NULL ); IF(!b)goto err_gt; }\r
+ }\r
+ else {\r
+ b= CopyFile( m->FullPath, path, FALSE ); IF(!b)goto err_gt;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+}\r
+\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_del] >>> \r
+************************************************************************/\r
+int FileT_del_sub( FileT_CallByNestFindData* m );\r
+\r
+int FileT_del( const TCHAR* Path )\r
+{\r
+ int e;\r
+ DWORD r;\r
+ TCHAR abs_path[MAX_PATH];\r
+\r
+ e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto fin;\r
+ #if Uses_AppKey\r
+ e= AppKey_addNewWritableFolder( abs_path ); IF(e)goto fin;\r
+ #endif\r
+\r
+ r= GetFileAttributes( Path );\r
+ if ( r != (DWORD)-1 ) {\r
+ if ( r & FILE_ATTRIBUTE_DIRECTORY ) {\r
+ e= FileT_callByNestFind( Path, FileT_FolderAfterFiles, NULL, (FuncType) FileT_del_sub );\r
+ }\r
+ else {\r
+ BOOL b= DeleteFile( Path ); IF(!b)goto err_gt;\r
+ }\r
+ }\r
+ IF_D( FileT_isExist( Path ) )goto err_ad;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+err_ad: e = E_ACCESS_DENIED; goto fin;\r
+}\r
+\r
+\r
+int FileT_del_sub( FileT_CallByNestFindData* m )\r
+{\r
+ int e;\r
+ BOOL b;\r
+\r
+ if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
+ b= RemoveDirectory( m->FullPath ); IF(!b)goto err_gt;\r
+ }\r
+ else {\r
+ b= DeleteFile( m->FullPath ); IF(!b)goto err_gt;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+}\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_writeSizedStruct_WinAPI] >>> \r
+************************************************************************/\r
+int FileT_writeSizedStruct_WinAPI( HANDLE* Stream, SizedStruct* OutputSizedStruct )\r
+{\r
+ DWORD wrote_size;\r
+ BOOL r;\r
+ int e;\r
+\r
+ r= WriteFile( Stream, &OutputSizedStruct->ThisStructSize,\r
+ sizeof(OutputSizedStruct->ThisStructSize), &wrote_size, NULL );\r
+ IF(!r) goto err_gt;\r
+\r
+ r= WriteFile( Stream, &OutputSizedStruct->OthersData,\r
+ OutputSizedStruct->ThisStructSize - sizeof(OutputSizedStruct->ThisStructSize),\r
+ &wrote_size, NULL );\r
+ IF(!r) goto err_gt;\r
+ e=0;\r
+fin:\r
+ return 0;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [FileT_readSizedStruct_WinAPI] >>> \r
+************************************************************************/\r
+int FileT_readSizedStruct_WinAPI( HANDLE* Stream, void** out_SizedStruct )\r
+{\r
+ int e;\r
+ DWORD read_size;\r
+ DWORD data_size;\r
+ void* out = NULL;\r
+ BOOL b;\r
+\r
+ b= ReadFile( Stream, &data_size, sizeof(data_size), &read_size, NULL ); IF(!b) goto err_gt;\r
+ IF( data_size & 0xC0000000 ) goto err_fm;\r
+\r
+ out = malloc( data_size ); IF( out == NULL ) goto err_fm;\r
+ *(size_t*) out = data_size;\r
+\r
+ b= ReadFile( Stream, (size_t*) out + 1, data_size - sizeof(size_t), &read_size, NULL ); IF(!b) goto err_gt;\r
+\r
+ *out_SizedStruct = out;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto rollback;\r
+err_fm: e = E_FEW_MEMORY; goto rollback;\r
+rollback:\r
+ if ( out != NULL ) free( out );\r
+ goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+* Implement: FileT_readUnicodeFileBOM\r
+************************************************************************/\r
+errnum_t FileT_readUnicodeFileBOM( const TCHAR* Path, FileFormatEnum* out_Format )\r
+{\r
+ errnum_t e;\r
+ HANDLE file = INVALID_HANDLE_VALUE;\r
+ unsigned char data[4];\r
+ DWORD read_size;\r
+ BOOL b;\r
+\r
+ if ( ! FileT_isExist( Path ) ) {\r
+ *out_Format = FILE_FORMAT_NOT_EXIST;\r
+ }\r
+ else {\r
+ file = CreateFile( Path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
+ FILE_ATTRIBUTE_NORMAL, 0 );\r
+ IF( file == INVALID_HANDLE_VALUE ) goto err_gt;\r
+\r
+ data[0] = '\0';\r
+ b= ReadFile( file, data, 3, &read_size, NULL ); IF(!b)goto err;\r
+ if ( read_size < 2 ) {\r
+ *out_Format = FILE_FORMAT_NO_BOM;\r
+ }\r
+ else if ( ( data[0] == 0xFF ) && ( data[1] == 0xFE ) ) {\r
+ *out_Format = FILE_FORMAT_UNICODE;\r
+ }\r
+ else if ( ( read_size >= 3 ) &&\r
+ ( data[0] == 0xEF ) && ( data[1] == 0xBB ) && ( data[2] == 0xBF ) ) {\r
+\r
+ *out_Format = FILE_FORMAT_UTF_8;\r
+ }\r
+ else {\r
+ *out_Format = FILE_FORMAT_NO_BOM;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( file != INVALID_HANDLE_VALUE ) { b= CloseHandle( file ); IF(!b&&!e) e = E_OTHERS; }\r
+ return e;\r
+\r
+err_gt: e = SaveWindowsLastError(); goto fin;\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+* Implement: FileT_cutFFFE\r
+************************************************************************/\r
+errnum_t FileT_cutFFFE( const TCHAR* in_InputPath, const TCHAR* in_OutputPath, bool in_IsAppend )\r
+{\r
+ errnum_t e;\r
+ HANDLE reading_file = INVALID_HANDLE_VALUE;\r
+ HANDLE writing_file = INVALID_HANDLE_VALUE;\r
+ wchar_t buffer[4096];\r
+ uint8_t* buffer8 = (uint8_t*) buffer;\r
+ wchar_t a_character;\r
+ uint8_t a_character8;\r
+ int index_of_BOM;\r
+ DWORD read_size;\r
+ DWORD writing_size;\r
+ DWORD wrote_size;\r
+ DWORD reading_index;\r
+ DWORD reading_index_over;\r
+ DWORD writing_index;\r
+ DWORD creation;\r
+ BOOL b;\r
+\r
+ FileFormatEnum format;\r
+\r
+ e= FileT_readUnicodeFileBOM( in_InputPath, /*Set*/ &format ); IF(e){goto fin;}\r
+\r
+ if ( ! in_IsAppend ) {\r
+ creation = CREATE_ALWAYS;\r
+ } else {\r
+ creation = OPEN_ALWAYS;\r
+ }\r
+\r
+ reading_file = CreateFile( in_InputPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
+ FILE_ATTRIBUTE_NORMAL, 0 );\r
+ IF( reading_file == INVALID_HANDLE_VALUE ) { e=E_GET_LAST_ERROR; goto fin; }\r
+\r
+ writing_file = CreateFile( in_OutputPath, GENERIC_WRITE, 0, NULL, creation,\r
+ FILE_ATTRIBUTE_NORMAL, 0 );\r
+ IF ( writing_file == INVALID_HANDLE_VALUE ) { e=E_GET_LAST_ERROR; goto fin; }\r
+\r
+ if ( in_IsAppend ) {\r
+ SetFilePointer( writing_file, 0, NULL, FILE_END );\r
+ }\r
+\r
+\r
+ for (;;) {\r
+\r
+ b= ReadFile( reading_file, buffer, sizeof( buffer ), &read_size, NULL );\r
+ IF(!b){ e=SaveWindowsLastError(); goto fin; }\r
+ if ( read_size == 0 )\r
+ { break; }\r
+\r
+ if ( format == FILE_FORMAT_UNICODE ) {\r
+ writing_index = 0;\r
+ reading_index_over = read_size / sizeof( buffer[0] );\r
+ for ( reading_index = 0; reading_index < reading_index_over; reading_index += 1 ) {\r
+\r
+ a_character = buffer[ reading_index ];\r
+\r
+ if ( a_character != 0xFEFF ) { /* FEFF = BOM character */\r
+\r
+ buffer[ writing_index ] = a_character;\r
+ writing_index += 1;\r
+ }\r
+ }\r
+ writing_size = writing_index * sizeof( buffer[0] );\r
+ }\r
+ else if ( format == FILE_FORMAT_UTF_8 ) {\r
+ writing_index = 0;\r
+ index_of_BOM = 0;\r
+ reading_index_over = read_size / sizeof( buffer8[0] );\r
+ for ( reading_index = 0; reading_index < reading_index_over; reading_index += 1 ) {\r
+\r
+ a_character8 = buffer8[ reading_index ];\r
+\r
+ if ( a_character8 == 0xEF ) {\r
+ if ( index_of_BOM >= 1 ) {\r
+ buffer8[ writing_index ] = 0xEF;\r
+ writing_index += 1;\r
+ if ( index_of_BOM >= 2 ) {\r
+ buffer8[ writing_index ] = 0xBB;\r
+ writing_index += 1;\r
+ }\r
+ }\r
+ index_of_BOM = 1;\r
+ }\r
+ else if ( a_character8 == 0xBB && index_of_BOM == 1 ) {\r
+ index_of_BOM = 2;\r
+ }\r
+ else if ( a_character8 == 0xBF && index_of_BOM == 2 ) {\r
+\r
+ /* Skip BOM */\r
+ index_of_BOM = 0;\r
+ }\r
+ else {\r
+ if ( index_of_BOM >= 1 ) {\r
+ buffer8[ writing_index ] = 0xEF;\r
+ writing_index += 1;\r
+ if ( index_of_BOM >= 2 ) {\r
+ buffer8[ writing_index ] = 0xBB;\r
+ writing_index += 1;\r
+ }\r
+ }\r
+\r
+ buffer8[ writing_index ] = a_character8;\r
+ writing_index += 1;\r
+\r
+ index_of_BOM = 0;\r
+ }\r
+ }\r
+ writing_size = writing_index * sizeof( buffer8[0] );\r
+ }\r
+ else {\r
+ writing_size = read_size;\r
+ }\r
+\r
+ b= WriteFile( writing_file, buffer, writing_size, &wrote_size, NULL );\r
+ IF(!b) { e=E_GET_LAST_ERROR; goto fin; }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ e= CloseHandleInFin( writing_file, e );\r
+ e= CloseHandleInFin( reading_file, e );\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParseXML2_StatusClass_getAttribute] >>>\r
+************************************************************************/\r
+errnum_t ParseXML2_StatusClass_getAttribute( ParseXML2_StatusClass* self,\r
+ const TCHAR* AttributeName, TCHAR** out_AttribyteValue )\r
+{\r
+ TCHAR** attr;\r
+\r
+ for ( attr = (TCHAR**) self->u.OnStartElement.Attributes; *attr != NULL; attr += 2 ) {\r
+ if ( _tcsicmp( *attr, AttributeName ) == 0 ) {\r
+ *out_AttribyteValue = *( attr + 1 );\r
+ return 0;\r
+ }\r
+ }\r
+ *out_AttribyteValue = NULL;\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParseXML2_StatusClass_mallocCopyText] >>>\r
+************************************************************************/\r
+errnum_t ParseXML2_StatusClass_mallocCopyText( ParseXML2_StatusClass* self,\r
+ TCHAR** out_Text )\r
+{\r
+ return MallocAndCopyStringByLength( out_Text,\r
+ self->u.OnText.Text, self->u.OnText.TextLength );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [ParseXML2] >>>\r
+************************************************************************/\r
+\r
+/*[ParseXML2_WorkClass]*/\r
+typedef struct _ParseXML2_WorkClass ParseXML2_WorkClass;\r
+struct _ParseXML2_WorkClass {\r
+ ParseXML2_StatusClass Status;\r
+ ParseXML2_CallbackType OnStartElement;\r
+ ParseXML2_CallbackType OnEndElement;\r
+ ParseXML2_CallbackType OnText;\r
+ Set2 XPath; /* Array of TCHAR */\r
+ Set2 XPathLengths; /* Array of int. Element is TCHAR count. Array count is Status.Depth */\r
+ StrFile TextBuffer;\r
+ int TextStartLineNum; /* 0 = no text */\r
+ errnum_t e;\r
+};\r
+\r
+/*[BOM]*/\r
+enum { BOM = 0xFEFF };\r
+\r
+\r
+static errnum_t ParseXML2_makeXML_Declare_Sub( XML_Parser parser, ParseXML2_WorkClass* work,\r
+ const TCHAR* XML_Path, TCHAR* line, bool* is_xml_declare );\r
+static void Expat_printfToError4( XML_Parser parser, const TCHAR* XML_Path );\r
+static void ParseXML2_onStartElement( void* UserData, const XML_Char* Name, const XML_Char** Atts );\r
+static void ParseXML2_onEndElement( void* UserData, const XML_Char* name );\r
+static void ParseXML2_onText( void* UserData, const XML_Char* Text, int TextLength );\r
+static void ParseXML2_callOnText( ParseXML2_WorkClass* work );\r
+\r
+\r
+errnum_t ParseXML2( const TCHAR* XML_Path, ParseXML2_ConfigClass* in_out_Config )\r
+{\r
+ errnum_t e;\r
+ FILE* file = NULL;\r
+ XML_Parser parser = (XML_Parser) DUMMY_INITIAL_VALUE;\r
+ bool is_parser = false;\r
+ int is_EOF;\r
+ wchar_t bom[1] = { BOM };\r
+ bool is_xml_declare = false; /* <?xml ... ?> */\r
+ enum XML_Status xs;\r
+ ParseXML2_ConfigClass* config = in_out_Config;\r
+ ParseXML2_ConfigClass default_config;\r
+ ParseXML2_WorkClass work_x;\r
+ ParseXML2_WorkClass* work = &work_x;\r
+ TCHAR line[4096];\r
+\r
+ Set2_initConst( &work->XPath );\r
+ Set2_initConst( &work->XPathLengths );\r
+ StrFile_initConst( &work->TextBuffer );\r
+\r
+\r
+ /* Set "config" */\r
+ if ( config == NULL ) { config = &default_config; }\r
+ if ( ! ( config->Flags & F_ParseXML2_Delegate ) ) { config->Delegate = NULL; }\r
+ if ( ! ( config->Flags & F_ParseXML2_OnStartElement ) ) { config->OnStartElement = DefaultFunction; }\r
+ if ( ! ( config->Flags & F_ParseXML2_OnEndElement ) ) { config->OnEndElement = DefaultFunction; }\r
+ if ( ! ( config->Flags & F_ParseXML2_OnText ) ) { config->OnText = DefaultFunction; }\r
+\r
+ /* Set "work" */\r
+ work->Status.Delegate = config->Delegate;\r
+ work->Status.LineNum = 0;\r
+ work->Status.Depth = -1;\r
+ work->Status.PreviousCallbackType = 0;\r
+ work->Status.TagName = NULL;\r
+ work->Status.u.OnStartElement.Attributes = NULL;\r
+ work->OnStartElement = config->OnStartElement;\r
+ work->OnEndElement = config->OnEndElement;\r
+ work->OnText = config->OnText;\r
+ work->e = 0;\r
+\r
+ /* Set "work->XPath", "work->XPathLengths" */\r
+ {\r
+ TCHAR* xpath;\r
+\r
+ e= Set2_init( &work->XPath, MAX_PATH * sizeof(TCHAR) ); IF(e)goto fin;\r
+ e= Set2_init( &work->XPathLengths, 10 * sizeof(int) ); IF(e)goto fin;\r
+ xpath = (TCHAR*) work->XPath.First;\r
+\r
+ xpath[0] = _T('/');\r
+ xpath[1] = _T('\0');\r
+ }\r
+\r
+ /* Set "work->TextBuffer" */\r
+ e= StrFile_init_toHeap( &work->TextBuffer, 0 );\r
+ work->TextStartLineNum = 0;\r
+\r
+ /* Set "parser" */\r
+ parser = XML_ParserCreate( NULL );\r
+ is_parser = true;\r
+ XML_SetUserData( parser, work );\r
+ XML_SetElementHandler( parser, ParseXML2_onStartElement, ParseXML2_onEndElement );\r
+ XML_SetCharacterDataHandler( parser, ParseXML2_onText );\r
+\r
+ /* Parse BOM */\r
+ xs= XML_Parse( parser, (char*)bom, sizeof(bom), 0 );\r
+ IF( xs == XML_STATUS_ERROR ) goto err_ex;\r
+\r
+\r
+ /* Loop of lines of XML file */\r
+ e= FileT_openForRead( &file, XML_Path ); IF(e)goto fin;\r
+ for (;;) {\r
+ line[0] = _T('\0');\r
+ _fgetts( line, _countof(line), file );\r
+ is_EOF = feof( file );\r
+ work->Status.LineNum += 1;\r
+\r
+ /* _fgetts \82ª UTF-16 \82É\95¶\8e\9a\97ñ\82ð\93\9d\88ê\82µ\81A\82»\82ê\82ð XML_Parser \82É\93n\82·\82½\82ß\81A*/\r
+ /* <?xml encoding="UTF-16" ?> \82É\95Ï\8dX\82·\82é */\r
+ if ( ! is_xml_declare ) {\r
+ e= ParseXML2_makeXML_Declare_Sub( parser, work, XML_Path, line, &is_xml_declare );\r
+ IF(e)goto fin;\r
+ }\r
+\r
+ /* Parse XML */\r
+ xs= XML_Parse( parser, (char*)line, _tcslen( line ) * sizeof(TCHAR), is_EOF );\r
+ IF( xs == XML_STATUS_ERROR ) goto err_ex;\r
+ IF( work->e != 0 ) { e = work->e; goto fin; }\r
+ if ( is_EOF ) { break; }\r
+ }\r
+ e=0;\r
+fin:\r
+ if ( is_parser ) { XML_ParserFree( parser ); }\r
+ e= FileT_close( file, e );\r
+ e= StrFile_finish( &work->TextBuffer, e );\r
+ e= Set2_finish( &work->XPath, e );\r
+ e= Set2_finish( &work->XPathLengths, e );\r
+ return e;\r
+\r
+err_ex: Expat_printfToError4( parser, XML_Path ); e= E_XML_PARSER; goto fin;\r
+}\r
+\r
+\r
+/*[ParseXML2_makeXML_Declare_Sub]*/\r
+static errnum_t ParseXML2_makeXML_Declare_Sub( XML_Parser parser, ParseXML2_WorkClass* work,\r
+ const TCHAR* XML_Path, TCHAR* line, bool* is_xml_declare )\r
+{\r
+ errnum_t e;\r
+ TCHAR* p;\r
+ TCHAR* str = NULL;\r
+ enum XML_Status xs;\r
+\r
+ UNREFERENCED_VARIABLE( work );\r
+\r
+ if ( _tcschr( line, _T('<') ) > 0 ) {\r
+ if ( _tcsstr( line, _T("<?") ) > 0 ) {\r
+ bool is_replaced = false;\r
+\r
+ {\r
+ static const TCHAR* enc_sjis = _T("encoding=\"Shift_JIS\"");\r
+ static const TCHAR* enc_sjis_utf16 = _T("encoding=\"UTF-16\" ");\r
+\r
+ p = _tcsstr( line, enc_sjis );\r
+ if ( p != NULL ) {\r
+ memcpy( p, enc_sjis_utf16, _tcslen( enc_sjis_utf16 ) * sizeof(TCHAR) );\r
+ is_replaced = true;\r
+ }\r
+ }\r
+ if ( ! is_replaced ) {\r
+ static const TCHAR* enc_utf8 = _T("encoding=\"UTF-8\"");\r
+ static const TCHAR* enc_utf8_utf16 = _T("encoding=\"UTF-16\"");\r
+ size_t str_size;\r
+\r
+ p = _tcsstr( line, enc_utf8 );\r
+ if ( p != NULL ) {\r
+ str_size = ( _tcslen( line ) + 2 ) * sizeof(TCHAR);\r
+ str = (TCHAR*) malloc( str_size ); IF(str==NULL) goto err_fm;\r
+\r
+ e= StrT_replace( str, str_size, line, enc_utf8, enc_utf8_utf16, 0 );\r
+ IF(e)goto fin;\r
+\r
+ xs= XML_Parse( parser, (char*)str, _tcslen( str ) * sizeof(TCHAR), 0 );\r
+ IF( xs == XML_STATUS_ERROR ) goto err_ex;\r
+\r
+ line[0] = _T('\0');\r
+ *is_xml_declare = true;\r
+ e=0;\r
+ goto fin;\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ static const TCHAR* xml_declare = _T("<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n");\r
+\r
+ XML_Parse( parser, (char*)xml_declare, _tcslen( xml_declare ) * sizeof(TCHAR), 0 );\r
+ *is_xml_declare = true;\r
+ e=0;\r
+ goto fin;\r
+ }\r
+ }\r
+ if ( _tcsstr( line, _T("?>") ) != NULL ) {\r
+ *is_xml_declare = true;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( str != NULL ) { free( str ); }\r
+ return e;\r
+\r
+err_fm: e = E_FEW_MEMORY; goto fin;\r
+err_ex: Expat_printfToError4( parser, XML_Path ); e= E_XML_PARSER; goto fin;\r
+}\r
+\r
+\r
+/*[Expat_printfToError4]*/\r
+static void Expat_printfToError4( XML_Parser parser, const TCHAR* XML_Path )\r
+{\r
+ Error4_printf( _T("<ERROR msg=\"%s\" file=\"%s(%lu)\"/>\n"),\r
+ XML_ErrorString( XML_GetErrorCode( parser ) ),\r
+ XML_Path,\r
+ XML_GetCurrentLineNumber(parser) );\r
+}\r
+\r
+\r
+/*[ParseXML2_onStartElement]*/\r
+static void ParseXML2_onStartElement( void* UserData, const XML_Char* Name, const XML_Char** Atts )\r
+{\r
+ ParseXML2_WorkClass* work = (ParseXML2_WorkClass*) UserData;\r
+ TCHAR* xpath = (TCHAR*) DUMMY_INITIAL_VALUE;\r
+ int* xpath_lengths;\r
+ int old_depth = work->Status.Depth;\r
+ int new_depth = work->Status.Depth + 1;\r
+\r
+ if ( work->e != 0 ) return;\r
+\r
+\r
+ /* Call "work->OnText" */\r
+ if ( work->OnText != DefaultFunction )\r
+ { ParseXML2_callOnText( work ); }\r
+\r
+\r
+ /* Set "work->XPath" : Add "Name" */\r
+ {\r
+ errnum_t e;\r
+ int old_xpath_length;\r
+ int name_length = _tcslen( Name );\r
+\r
+\r
+ /* Set "old_xpath_length" */\r
+ xpath_lengths = (int*) work->XPathLengths.First;\r
+ if ( old_depth >= 0 )\r
+ { old_xpath_length = xpath_lengths[ old_depth ]; }\r
+ else\r
+ { old_xpath_length = 0; } /* Length("/") == 1, But 0 for next operation */\r
+\r
+ /* Add "Name" to "work->XPath" */\r
+ e= Set2_expandIfOverByOffset( &work->XPath,\r
+ ( old_xpath_length + name_length + 2 ) * sizeof(TCHAR) );\r
+ IF(e)goto fin2;\r
+ xpath = (TCHAR*) work->XPath.First;\r
+ xpath[ old_xpath_length ] = _T('/');\r
+ memcpy( &xpath[ old_xpath_length + 1 ], Name, name_length * sizeof(TCHAR) );\r
+ xpath[ old_xpath_length + 1 + name_length ] = _T('\0');\r
+\r
+ /* "work->XPathLengths[]" = new XPath length */\r
+ e= Set2_expandIfOverByOffset( &work->XPathLengths, ( new_depth + 1 ) * sizeof(int) );\r
+ IF(e)goto fin2;\r
+ xpath_lengths = (int*) work->XPathLengths.First;\r
+ xpath_lengths[ new_depth ] = old_xpath_length + 1 + name_length;\r
+\r
+ e=0;\r
+ fin2:\r
+ if (e) {\r
+ work->e = e;\r
+ return;\r
+ }\r
+ }\r
+\r
+\r
+ /* Call "work->OnStartElement" */\r
+ work->Status.XPath = xpath;\r
+ if ( old_depth >= 0 )\r
+ { work->Status.TagName = &xpath[ xpath_lengths[ old_depth ] + 1 ]; }\r
+ else\r
+ { work->Status.TagName = &xpath[ 1 ]; }\r
+ work->Status.u.OnStartElement.Attributes = Atts;\r
+ work->Status.Depth += 1;\r
+\r
+ work->e = work->OnStartElement( &work->Status );\r
+\r
+ work->Status.u.OnStartElement.Attributes = NULL;\r
+\r
+ work->Status.PreviousCallbackType = F_ParseXML2_OnStartElement;\r
+}\r
+\r
+\r
+/*[ParseXML2_onEndElement]*/\r
+static void ParseXML2_onEndElement( void* UserData, const XML_Char* Name )\r
+{\r
+ ParseXML2_WorkClass* work = (ParseXML2_WorkClass*) UserData;\r
+ TCHAR* xpath = (TCHAR*) work->XPath.First;\r
+ int* xpath_lengths = (int*) work->XPathLengths.First;\r
+ int new_depth = work->Status.Depth - 1;\r
+\r
+ UNREFERENCED_VARIABLE( Name );\r
+\r
+ if ( work->e != 0 ) return;\r
+\r
+ if ( new_depth >= 0 )\r
+ { work->Status.TagName = &xpath[ xpath_lengths[ new_depth ] + 1 ]; }\r
+ else\r
+ { work->Status.TagName = &xpath[ 1 ]; }\r
+\r
+\r
+ /* Call "work->OnText" */\r
+ if ( work->OnText != DefaultFunction )\r
+ { ParseXML2_callOnText( work ); }\r
+\r
+\r
+ /* Call "work->OnEndElement" */\r
+ work->e = work->OnEndElement( &work->Status );\r
+ work->Status.Depth -= 1;\r
+\r
+\r
+ /* Set "work->XPath" : Remove "Name" */\r
+ if ( new_depth >= 0 ) {\r
+ xpath[ xpath_lengths[ new_depth ] ] = _T('\0');\r
+ if ( new_depth - 1 >= 0 )\r
+ { work->Status.TagName = &xpath[ xpath_lengths[ new_depth - 1 ] + 1 ]; }\r
+ else\r
+ { work->Status.TagName = &xpath[ 1 ]; }\r
+ }\r
+ else {\r
+ xpath[ 1 ] = _T('\0'); /* xpath = "/" */\r
+ work->Status.TagName = &xpath[ 0 ];\r
+ }\r
+\r
+ work->Status.PreviousCallbackType = F_ParseXML2_OnEndElement;\r
+}\r
+\r
+\r
+/*[ParseXML2_onText]*/\r
+static void ParseXML2_onText( void* UserData, const XML_Char* Text, int TextLength )\r
+{\r
+ ParseXML2_WorkClass* work = (ParseXML2_WorkClass*) UserData;\r
+\r
+ if ( work->e != 0 ) return;\r
+\r
+ if ( work->OnText != DefaultFunction ) {\r
+\r
+ #if 1\r
+ work->e = StrFile_writeBinary( &work->TextBuffer, Text, TextLength * sizeof(TCHAR) );\r
+\r
+ if ( work->TextStartLineNum == 0 )\r
+ { work->TextStartLineNum = work->Status.LineNum; }\r
+ #else\r
+ work->Status.u.OnText.Text = Text;\r
+ work->Status.u.OnText.TextLength = TextLength;\r
+\r
+ work->e = work->OnText( &work->Status );\r
+\r
+ work->Status.u.OnText.Text = NULL;\r
+ work->Status.u.OnText.TextLength = 0;\r
+\r
+ work->Status.PreviousCallbackType = F_ParseXML2_OnText;\r
+ #endif\r
+ }\r
+}\r
+\r
+\r
+/*[ParseXML2_callOnText]*/\r
+static void ParseXML2_callOnText( ParseXML2_WorkClass* work )\r
+{\r
+ if ( work->TextStartLineNum != 0 ) {\r
+ int line_num_back_up = work->Status.LineNum;\r
+\r
+ work->Status.u.OnText.Text = work->TextBuffer.Buffer;\r
+ work->Status.u.OnText.TextLength = (TCHAR*) work->TextBuffer.Pointer -\r
+ (TCHAR*) work->TextBuffer.Buffer;\r
+ work->Status.LineNum = work->TextStartLineNum;\r
+\r
+ work->e = work->OnText( &work->Status );\r
+\r
+ if ( work->e == 0 ) {\r
+ work->e = StrFile_setPointer( &work->TextBuffer, 0 );\r
+ IF( work->e ) __noop();\r
+ }\r
+ work->Status.LineNum = line_num_back_up;\r
+ work->TextStartLineNum = 0;\r
+ work->Status.PreviousCallbackType = F_ParseXML2_OnText;\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey] >>> \r
+************************************************************************/\r
+static errnum_t AppKey_create( AppKey** out_m );\r
+static bool AppKey_isSame( AppKey* m );\r
+static void Writables_initConst( Writables* m );\r
+static errnum_t Writables_init( Writables* m, AppKey* Key );\r
+static errnum_t Writables_finish( Writables* m, int e );\r
+static bool Writables_isInited( Writables* m );\r
+static errnum_t Writables_clearPaths( Writables* m );\r
+static errnum_t Writables_create( Writables** out_m, AppKey* Key );\r
+static errnum_t Writables_copyToConst( Writables* To, Writables* From );\r
+\r
+\r
+typedef struct _CurrentWritables CurrentWritables;\r
+struct _CurrentWritables {\r
+ Writables m_CurrentWritables;\r
+ TCHAR* m_ProgramFiles; size_t m_ProgramFiles_Len;\r
+ TCHAR* m_windir; size_t m_windir_Len;\r
+ TCHAR* m_APPDATA; size_t m_APPDATA_Len;\r
+ TCHAR* m_LOCALAPPDATA; size_t m_LOCALAPPDATA_Len;\r
+};\r
+static void CurrentWritables_initConst( CurrentWritables* m );\r
+static errnum_t CurrentWritables_init( CurrentWritables* m );\r
+static errnum_t CurrentWritables_finish( CurrentWritables* m, int e );\r
+static errnum_t CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath );\r
+\r
+\r
+//////////////////////////////\r
+\r
+static AppKey g_AppKey;\r
+static AppKey* g_AppKeyPrivate;\r
+\r
+// under g_AppKey\r
+Writables g_DefaultWritables;\r
+Writables g_CurrentWritables; // public\r
+static CurrentWritables g_CurrentWritablesPrivate;\r
+\r
+\r
+static errnum_t AppKey_create( AppKey** out_m )\r
+{\r
+ errnum_t e;\r
+\r
+ IF( g_AppKeyPrivate != NULL ) { e=1; goto fin; }\r
+ // AppKey_newWritable \82Ì in_out_m = NULL \82Ì\82Æ\82«\82Í\81A2\89ñ\8cÄ\82Ñ\8fo\82·\82±\82Æ\82Í\82Å\82«\82Ü\82¹\82ñ\81B\r
+\r
+ Writables_initConst( &g_DefaultWritables );\r
+ CurrentWritables_initConst( &g_CurrentWritablesPrivate );\r
+\r
+ e= CurrentWritables_init( &g_CurrentWritablesPrivate ); IF(e)goto fin;\r
+ e= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(e)goto fin;\r
+\r
+ *out_m = &g_AppKey;\r
+ g_AppKeyPrivate = &g_AppKey;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+static bool AppKey_isSame( AppKey* m )\r
+{\r
+ return ( m == g_AppKeyPrivate );\r
+}\r
+\r
+\r
+void AppKey_initGlobal_const()\r
+{\r
+ Writables_initConst( &g_DefaultWritables );\r
+}\r
+\r
+\r
+errnum_t AppKey_finishGlobal( errnum_t e )\r
+{\r
+ errnum_t ee;\r
+\r
+ e= Writables_finish( &g_DefaultWritables, e );\r
+ e= CurrentWritables_finish( &g_CurrentWritablesPrivate, e );\r
+ ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
+\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_newWritable_Sub] >>> \r
+************************************************************************/\r
+errnum_t AppKey_newWritable_Sub( AppKey** in_out_m, Writables** out_Writable,\r
+ va_list va,\r
+ TCHAR** in_Paths, int in_PathCount )\r
+{\r
+ errnum_t e;\r
+ AppKey* m = NULL;\r
+ Writables* wr = NULL;\r
+#if Uses_OutMallocIDTool\r
+ bool is_prev_out_malloc;\r
+\r
+ is_prev_out_malloc = OutMallocID_setEnable( false );\r
+#endif\r
+\r
+\r
+ //=== AppKey* m \82ð\97L\8cø\82É\82·\82é\r
+ if ( in_out_m == NULL ) { // \8d¡\89ñ\82Ì\8aÖ\90\94\82Ì\92\86\82¾\82¯\82Å\8eQ\8fÆ\82·\82é\r
+ e= AppKey_create( &m ); IF(e)goto resume;\r
+ }\r
+ else if ( *in_out_m == NULL ) { // \82P\89ñ\96Ú\82É\96{\8aÖ\90\94\82ð\8cÄ\82Ñ\8fo\82µ\82½\83\82\83W\83\85\81[\83\8b\82É\93n\82·\r
+ e= AppKey_create( &m ); IF(e)goto resume;\r
+ *in_out_m = m;\r
+ }\r
+ else { // \96{\8aÖ\90\94\82ð\8cÄ\82Ñ\8fo\82µ\82½\83\82\83W\83\85\81[\83\8b\82©\82ç\93n\82Á\82½\82à\82Ì\82ð\8eg\82¤\r
+ m = *in_out_m;\r
+ }\r
+\r
+\r
+ //=== \90³\8bK\82Ì AppKey \82©\83`\83F\83b\83N\82·\82é\r
+ IF( ! AppKey_isSame( m ) )goto err;\r
+\r
+\r
+ //=== Writable \82ð\90¶\90¬\82·\82é\r
+ if ( out_Writable == NULL ) {\r
+ wr = &g_DefaultWritables;\r
+ e= Writables_finish( wr, 0 ); IF(e)goto resume;\r
+ e= Writables_init( wr, m ); IF(e)goto resume;\r
+ }\r
+ else {\r
+ e= Writables_create( &wr, m ); IF(e)goto resume;\r
+ *out_Writable = wr;\r
+ }\r
+\r
+\r
+ //=== Writable \82É\83p\83X\82ð\93o\98^\82·\82é\r
+ if ( in_Paths == NULL ) {\r
+ TCHAR* path;\r
+ int i;\r
+\r
+ for ( i=0; ; i++ ) {\r
+ path = va_arg( va, TCHAR* );\r
+ if ( path == NULL ) break;\r
+ IF( i == 5 ) goto err; // \8dÅ\8cã\82Ì NULL \96Y\82ê\91Î\8dô\r
+\r
+ e= Writables_add( wr, m, path ); IF(e)goto resume;\r
+ }\r
+ }\r
+ else {\r
+ int i;\r
+\r
+ for ( i = 0; i < in_PathCount; i += 1 ) {\r
+ e= Writables_add( wr, m, in_Paths[i] ); IF(e){goto fin;}\r
+ }\r
+ }\r
+\r
+ #if defined(TempFile_get)\r
+ {\r
+ TempFile* temp;\r
+\r
+ e= TempFile_get( &temp ); IF(e)goto resume;\r
+ e= Writables_add( wr, m, temp->TempPath ); IF(e)goto resume;\r
+ }\r
+ #endif\r
+\r
+\r
+ //=== \82·\82®\82É Writable \82ð\97L\8cø\82É\82·\82é\r
+ if ( out_Writable == NULL ) {\r
+ e= Writables_enable( wr ); IF(e)goto resume;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ #if Uses_OutMallocIDTool\r
+ OutMallocID_setEnable( is_prev_out_malloc );\r
+ #endif\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto resume;\r
+resume:\r
+ if ( wr != NULL ) {\r
+ if ( out_Writable == NULL )\r
+ e= Writables_finish( wr, e ); // g_DefaultWritables\r
+ else\r
+ e= Writables_delete( wr, e );\r
+ }\r
+ goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_newWritable] >>> \r
+************************************************************************/\r
+errnum_t AppKey_newWritable( AppKey** in_out_m, Writables** out_Writable, ... )\r
+{\r
+ errnum_t e;\r
+ va_list va;\r
+\r
+ va_start( va, out_Writable );\r
+ e = AppKey_newWritable_Sub( in_out_m, out_Writable, va, NULL, 0 );\r
+ va_end( va );\r
+\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_newWritable_byArray] >>> \r
+************************************************************************/\r
+errnum_t AppKey_newWritable_byArray( AppKey** in_out_m, Writables** out_Writable,\r
+ TCHAR** in_Paths, int in_PathCount )\r
+{\r
+ IF ( in_Paths == NULL ) {\r
+ return E_OTHERS;\r
+ } else {\r
+ return AppKey_newWritable_Sub( in_out_m, out_Writable, NULL,\r
+ in_Paths, in_PathCount );\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_addNewWritableFolder] \83`\83F\83b\83N\82·\82é\81A\82Ü\82½\82Í\92Ç\89Á\82·\82é >>> \r
+************************************************************************/\r
+errnum_t AppKey_addNewWritableFolder_Sub( const TCHAR* Path, bool* out_IsWritable );\r
+\r
+errnum_t AppKey_addNewWritableFolder( const TCHAR* Path )\r
+{\r
+ errnum_t e;\r
+ bool is_writable;\r
+\r
+ e= AppKey_addNewWritableFolder_Sub( Path, &is_writable ); IF(e){goto fin;}\r
+ IF ( ! is_writable ) { e=E_OUT_OF_WRITABLE; goto fin; }\r
+ // Path (abs_path) \82Í\81AAppKey_newWritable \82Å\8b\96\89Â\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\81B\r
+ // \83E\83H\83b\83`\81E\83E\83B\83\93\83h\83E\82É g_CurrentWritables.m_Paths,3 \82È\82Ç\82ð\93ü\97Í\82µ\82Ä\r
+ // \8b\96\89Â\82³\82ê\82Ä\82¢\82é\83p\83X\82ð\8am\94F\82µ\82Ä\82\82¾\82³\82¢\81B\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+errnum_t AppKey_addNewWritableFolder_Sub( const TCHAR* Path, bool* out_IsWritable )\r
+{\r
+ errnum_t e;\r
+ TCHAR** pp;\r
+ TCHAR** pp_over;\r
+ Writables* wr = &g_CurrentWritablesPrivate.m_CurrentWritables;\r
+ size_t path_len;\r
+ TCHAR abs_path[MAX_PATH];\r
+\r
+ *out_IsWritable = true;\r
+\r
+ if ( g_AppKeyPrivate == NULL ) {\r
+ e= AppKey_newWritable( NULL, NULL, ".", NULL ); IF(e){goto fin;}\r
+ }\r
+\r
+ e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e){goto fin;}\r
+\r
+ pp_over = wr->m_Paths + wr->m_nPath;\r
+ for ( pp = wr->m_Paths; ; pp++ ) {\r
+ if ( pp >= pp_over ) {\r
+ *out_IsWritable = false;\r
+ break;\r
+ }\r
+ path_len = _tcslen( *pp );\r
+ if ( _tcsnicmp( *pp, abs_path, path_len ) == 0 &&\r
+ ( abs_path[ path_len ] == _T('\\') || abs_path[ path_len ] == _T('\0') ) )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_addWritableFolder] \83`\83F\83b\83N\82µ\82È\82¢\82Å\81A\92Ç\89Á\82·\82é >>> \r
+************************************************************************/\r
+errnum_t AppKey_addWritableFolder( AppKey* m, const TCHAR* Path )\r
+{\r
+ errnum_t e;\r
+ Writables* wr = &g_CurrentWritablesPrivate.m_CurrentWritables;\r
+ bool is_writable;\r
+\r
+ e= AppKey_addNewWritableFolder_Sub( Path, &is_writable ); IF(e){goto fin;}\r
+ if ( ! is_writable ) {\r
+ e= Writables_add( wr, m, Path ); IF(e){goto fin;}\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [AppKey_checkWritable] >>> \r
+************************************************************************/\r
+errnum_t AppKey_checkWritable( const TCHAR* Path )\r
+{\r
+ return AppKey_addNewWritableFolder( Path );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Writables_init] >>> \r
+************************************************************************/\r
+static void Writables_initConst( Writables* m )\r
+{\r
+ m->m_Paths = NULL;\r
+ m->m_nPath = -1;\r
+}\r
+\r
+\r
+static errnum_t Writables_init( Writables* m, AppKey* Key )\r
+{\r
+ IF( ! AppKey_isSame( Key ) ) return E_OTHERS;\r
+\r
+ m->m_Paths = NULL;\r
+ m->m_nPath = 0;\r
+ return 0;\r
+}\r
+\r
+\r
+static errnum_t Writables_finish( Writables* m, int e )\r
+{\r
+ errnum_t ee;\r
+\r
+ ee= Writables_clearPaths( m ); IF(ee&&!e) e=ee;\r
+ m->m_nPath = -1;\r
+ return e;\r
+}\r
+\r
+\r
+static bool Writables_isInited( Writables* m )\r
+{\r
+ return ( m->m_nPath != -1 );\r
+}\r
+\r
+\r
+static errnum_t Writables_clearPaths( Writables* m )\r
+{\r
+ TCHAR** p;\r
+ TCHAR** p_over;\r
+\r
+ if ( m->m_Paths != NULL ) {\r
+ p_over = m->m_Paths + m->m_nPath;\r
+ for ( p = m->m_Paths; p < p_over; p++ ) {\r
+ free( *p );\r
+ }\r
+ free( m->m_Paths ); m->m_Paths = NULL;\r
+ }\r
+ m->m_nPath = 0;\r
+ return 0;\r
+}\r
+\r
+\r
+static errnum_t Writables_create( Writables** out_m, AppKey* Key )\r
+{\r
+ errnum_t e;\r
+ Writables* m;\r
+\r
+ m = (Writables*) malloc( sizeof(*m) ); IF(m==NULL)return E_FEW_MEMORY;\r
+ Writables_initConst( m );\r
+ e= Writables_init( m, Key ); IF(e)goto resume;\r
+ *out_m = m;\r
+ return 0;\r
+resume: Writables_delete( m, 0 ); free(m); return e;\r
+}\r
+\r
+\r
+errnum_t Writables_delete( Writables* m, errnum_t e )\r
+{\r
+ if ( m == NULL ) goto fin;\r
+ e= Writables_finish( m, e );\r
+ free( m );\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Writables_add] >>> \r
+************************************************************************/\r
+int Writables_add( Writables* m, AppKey* Key, const TCHAR* Path )\r
+{\r
+ int e;\r
+ TCHAR** pp;\r
+ TCHAR* p = NULL;\r
+ size_t path_size;\r
+ TCHAR abs_path[MAX_PATH];\r
+\r
+ IF( ! AppKey_isSame( Key ) )goto err;\r
+ if ( Path[0] == _T('\0') ) return 0;\r
+\r
+ e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto resume;\r
+\r
+ e= CurrentWritables_askFileAccess( &g_CurrentWritablesPrivate, abs_path ); IF(e)goto resume;\r
+\r
+ pp = (TCHAR**) realloc( m->m_Paths, (m->m_nPath + 1) * sizeof(TCHAR*) );\r
+ IF( pp == NULL ) goto err;\r
+ m->m_Paths = pp;\r
+\r
+ path_size = (_tcslen( abs_path ) + 1) * sizeof(TCHAR);\r
+ p = (TCHAR*) malloc( path_size );\r
+ m->m_Paths[ m->m_nPath ] = p;\r
+ IF( p == NULL )goto err;\r
+\r
+ memcpy( p, abs_path, path_size );\r
+ if ( p[ path_size/sizeof(TCHAR) - 2 ] == _T('\\') )\r
+ p[ path_size/sizeof(TCHAR) - 2 ] = _T('\0');\r
+ m->m_nPath ++;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto resume;\r
+resume:\r
+ if ( p != NULL ) free( p );\r
+ goto fin;\r
+}\r
+\r
+\r
+int Writables_remove( Writables* m, const TCHAR* Path )\r
+{\r
+ TCHAR** pp;\r
+ TCHAR** pp_over;\r
+\r
+ pp_over = m->m_Paths + m->m_nPath;\r
+ for ( pp = m->m_Paths; ; pp++ ) {\r
+ if ( pp >= pp_over ) return 0;\r
+ if ( _tcscmp( *pp, Path ) == 0 ) break;\r
+ }\r
+ free( *pp );\r
+ memmove( pp, pp+1, (char*)pp - (char*)pp_over - sizeof(TCHAR) );\r
+ m->m_nPath --;\r
+\r
+ #if _DEBUG\r
+ *( pp_over - 1 ) = NULL;\r
+ #endif\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Writables_enable] >>> \r
+************************************************************************/\r
+int Writables_enable( Writables* m )\r
+{\r
+ int e;\r
+\r
+ e= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, m ); IF(e)goto fin;\r
+ e= Writables_copyToConst( &g_CurrentWritables, &g_CurrentWritablesPrivate.m_CurrentWritables ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+int Writables_disable( Writables* m, int e )\r
+{\r
+ int ee;\r
+\r
+ UNREFERENCED_VARIABLE( m );\r
+\r
+ ee= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
+ ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+static int Writables_copyToConst( Writables* To, Writables* From )\r
+{\r
+ int e;\r
+ TCHAR** pp;\r
+ TCHAR** pp_over;\r
+ TCHAR* p2;\r
+ TCHAR** pp2;\r
+ size_t path_size;\r
+\r
+ if ( To->m_Paths != NULL ) {\r
+ free( To->m_Paths );\r
+ To->m_Paths = NULL;\r
+ To->m_nPath = 0;\r
+ }\r
+\r
+ if ( From != NULL && From->m_nPath > 0 ) {\r
+\r
+ path_size = 0;\r
+ pp_over = From->m_Paths + From->m_nPath;\r
+ for ( pp = From->m_Paths; pp < pp_over; pp++ ) {\r
+ path_size += _tcslen( *pp ) + 1;\r
+ }\r
+\r
+ path_size = From->m_nPath * sizeof(TCHAR*) + path_size * sizeof(TCHAR);\r
+ To->m_Paths = (TCHAR**) malloc( path_size );\r
+ IF( To->m_Paths == NULL ) goto err;\r
+\r
+ p2 = (TCHAR*)( (char*)To->m_Paths + From->m_nPath * sizeof(TCHAR*) );\r
+ pp2 = To->m_Paths;\r
+ for ( pp = From->m_Paths; pp < pp_over; pp++ ) {\r
+ *pp2 = p2;\r
+ path_size = (_tcslen( *pp ) + 1) * sizeof(TCHAR);\r
+ memcpy( p2, *pp, path_size );\r
+ p2 = (TCHAR*)( (char*)p2 + path_size );\r
+ pp2 ++;\r
+ }\r
+ To->m_nPath = From->m_nPath;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [CurrentWritables] >>> \r
+************************************************************************/\r
+static void CurrentWritables_initConst( CurrentWritables* m )\r
+{\r
+ Writables_initConst( &m->m_CurrentWritables );\r
+ m->m_ProgramFiles = NULL;\r
+ m->m_windir = NULL;\r
+ m->m_APPDATA = NULL;\r
+ m->m_LOCALAPPDATA = NULL;\r
+}\r
+\r
+\r
+static int CurrentWritables_init( CurrentWritables* m )\r
+{\r
+ int e;\r
+ #if Uses_OutMallocIDTool\r
+ bool is_prev_out_malloc;\r
+\r
+ is_prev_out_malloc = OutMallocID_setEnable( false );\r
+ #endif\r
+\r
+ e= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(e)goto fin;\r
+\r
+ e= env_malloc( &m->m_ProgramFiles, &m->m_ProgramFiles_Len, _T("ProgramFiles") ); IF(e)goto fin;\r
+ e= env_malloc( &m->m_windir, &m->m_windir_Len, _T("windir") ); IF(e)goto fin;\r
+ e= env_malloc( &m->m_APPDATA, &m->m_APPDATA_Len, _T("APPDATA") ); IF(e)goto fin;\r
+ // e= env_malloc( &m->m_LOCALAPPDATA, &m->m_LOCALAPPDATA_Len, _T("LOCALAPPDATA") ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ #if Uses_OutMallocIDTool\r
+ OutMallocID_setEnable( is_prev_out_malloc );\r
+ #endif\r
+ return e;\r
+}\r
+\r
+\r
+static int CurrentWritables_finish( CurrentWritables* m, int e )\r
+{\r
+ int ee;\r
+\r
+ ee= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
+\r
+ if ( m->m_ProgramFiles != NULL ) free( m->m_ProgramFiles );\r
+ if ( m->m_windir != NULL ) free( m->m_windir );\r
+ if ( m->m_APPDATA != NULL ) free( m->m_APPDATA );\r
+ if ( m->m_LOCALAPPDATA != NULL ) free( m->m_LOCALAPPDATA );\r
+\r
+ m->m_ProgramFiles = NULL;\r
+ m->m_windir = NULL;\r
+ m->m_APPDATA = NULL;\r
+ m->m_LOCALAPPDATA = NULL;\r
+\r
+ return e;\r
+}\r
+\r
+\r
+static int CurrentWritables_askFileAccess_sub(\r
+ const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* FullPath, size_t FullPath_Len );\r
+\r
+static int CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath )\r
+{\r
+ int e;\r
+ size_t abs_len;\r
+\r
+ abs_len = _tcslen( FullPath );\r
+ e= CurrentWritables_askFileAccess_sub( m->m_ProgramFiles, m->m_ProgramFiles_Len, FullPath, abs_len ); IF(e)goto fin;\r
+ e= CurrentWritables_askFileAccess_sub( m->m_windir, m->m_windir_Len, FullPath, abs_len ); IF(e)goto fin;\r
+ e= CurrentWritables_askFileAccess_sub( m->m_APPDATA, m->m_APPDATA_Len, FullPath, abs_len ); IF(e)goto fin;\r
+ e= CurrentWritables_askFileAccess_sub( m->m_LOCALAPPDATA, m->m_LOCALAPPDATA_Len, FullPath, abs_len ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+static int CurrentWritables_askFileAccess_sub(\r
+ const TCHAR* SystemPath, size_t SystemPath_Len, const TCHAR* FullPath, size_t FullPath_Len )\r
+{\r
+ if ( SystemPath == NULL ) return 0;\r
+\r
+ IF ( _tcsncmp( SystemPath, FullPath, SystemPath_Len ) == 0 )\r
+ return E_OUT_OF_WRITABLE; // \83V\83X\83e\83\80\83t\83H\83\8b\83_\82Ì\92\86\82ð\8f\91\82«\8d\9e\82Ý\8b\96\89Â\82µ\82æ\82¤\82Æ\82µ\82Ä\82¢\82é\r
+\r
+ IF ( _tcsncmp( SystemPath, FullPath, FullPath_Len ) == 0 )\r
+ return E_OUT_OF_WRITABLE; // \83V\83X\83e\83\80\83t\83H\83\8b\83_\82ð\8aÜ\82ß\82Ä\8b\96\89Â\8f\91\82«\8d\9e\82Ý\8b\96\89Â\82µ\82æ\82¤\82Æ\82µ\82Ä\82¢\82é\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [Error4/Error4.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [Get_Error4_Variables] >>> \r
+************************************************************************/\r
+static Error4_VariablesClass gs;\r
+#ifdef _DEBUG\r
+ extern Error4_VariablesClass* g_Error4_Variables = &gs;\r
+#endif\r
+\r
+Error4_VariablesClass* Get_Error4_Variables()\r
+{\r
+ return &gs;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< (SetBreakErrorID) >>> \r
+************************************************************************/\r
+\r
+/*[DebugBreakR]*/\r
+void DebugBreakR()\r
+{\r
+ printf( "\83u\83\8c\81[\83N\82µ\82Ü\82·\81B\82à\82µ\83f\83o\83b\83K\81[\82ª\90Ú\91±\82³\82ê\82Ä\82¢\82È\82¯\82ê\82Î\8b\90§\8fI\97¹\82µ\82Ü\82·\81B\n" );\r
+ DebugBreak();\r
+ // Visual Studio 2008 \82Å\82Í\81A\82±\82±\82Å [ \83f\83o\83b\83O > \83X\83e\83b\83v \83A\83E\83g ] \82µ\82È\82¢\82Æ\r
+ // \8cÄ\82Ñ\8fo\82µ\97\9a\97ð\82â\83E\83H\83b\83`\82Ì\93à\97e\82ª\90³\82µ\82\82È\82è\82Ü\82¹\82ñ\81B\r
+}\r
+\r
+\r
+#if ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
+\r
+\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+ dll_global_g_DebugBreakCount ErrorClass g_Error; /* \8f\89\8aú\92l\82Í\82·\82×\82Ä\83[\83\8d */\r
+#else\r
+ dll_global_g_DebugBreakCount GlobalErrorClass g_GlobalError;\r
+\r
+ static errnum_t ErrorClass_initializeIfNot_Sub( ErrorClass** out_Error );\r
+ static errnum_t ErrorClass_initializeIfNot_Sub2(void);\r
+#endif\r
+\r
+\r
+#define IF_ if /* Error check for in "IF" macro */\r
+\r
+\r
+/*[SetBreakErrorID]*/\r
+void SetBreakErrorID( int ErrorID )\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+ bool is_print;\r
+\r
+ is_print = ( err->BreakErrorID != ErrorID );\r
+\r
+ err->BreakErrorID = ErrorID;\r
+ /* printf \82Ì\92\86\82Å\94\90¶\82·\82é\83G\83\89\81[\82Å\8e~\82ß\82é\82½\82ß */\r
+\r
+ if ( is_print )\r
+ { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
+\r
+#else\r
+\r
+ GlobalErrorClass* err_global = &g_GlobalError;\r
+\r
+ if ( err_global->BreakGlobalErrorID != ErrorID )\r
+ { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
+ err_global->BreakGlobalErrorID = ErrorID;\r
+\r
+#endif\r
+}\r
+\r
+\r
+\r
+bool OnRaisingError_Sub( const char* FilePath, int LineNum )\r
+ // \96{\8aÖ\90\94\82Í\81AIF \83}\83N\83\8d\82Ì\92\86\82©\82ç\8cÄ\82Î\82ê\82Ü\82·\r
+ // \95Ô\82è\92l\82Í\81A\83u\83\8c\81[\83N\82·\82é\82©\82Ç\82¤\82©\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+ bool is_break;\r
+\r
+ /* \83G\83\89\81[\8e\9e\82Ì\92\86\92f\8f\88\97\9d\81i\83W\83\83\83\93\83v\81j\82ð\82µ\82Ä\82¢\82é\82Æ\82«\81i\8d\82\91¬\83\8a\83^\81[\83\93\81j */\r
+ if ( err->IsError ) {\r
+ return false;\r
+ }\r
+\r
+ /* \83G\83\89\81[\82ª\94\90¶\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
+ err->ErrorID += 1;\r
+ err->IsError = true;\r
+ err->FilePath = FilePath;\r
+ err->LineNum = LineNum;\r
+\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
+ err->ErrorID, (int) err );\r
+ #endif\r
+\r
+ is_break = ( err->ErrorID == err->BreakErrorID );\r
+\r
+ if ( is_break ) {\r
+ printf( "Break in (%d) %s\n", LineNum, FilePath );\r
+ }\r
+ return ( err->ErrorID == err->BreakErrorID );\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ bool is_break = false;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err ); IF_(e){goto fin;}\r
+\r
+\r
+ /* \83G\83\89\81[\8e\9e\82Ì\92\86\92f\8f\88\97\9d\81i\83W\83\83\83\93\83v\81j\82ð\82µ\82Ä\82¢\82é\82Æ\82«\81i\8d\82\91¬\83\8a\83^\81[\83\93\81j */\r
+ if ( err->IsError ) {\r
+ return false;\r
+ }\r
+\r
+ /* \83G\83\89\81[\82ª\94\90¶\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
+ else {\r
+ GlobalErrorClass* err_global = &g_GlobalError;\r
+\r
+ EnterCriticalSection( &err_global->CriticalSection );\r
+\r
+\r
+ err_global->ErrorThreadCount += 1;\r
+ err_global->RaisedGlobalErrorID += 1;\r
+ err->GlobalErrorID = err_global->RaisedGlobalErrorID;\r
+\r
+ err->ErrorID += 1;\r
+ err->IsError = true;\r
+ err->FilePath = FilePath;\r
+ err->LineNum = LineNum;\r
+\r
+ is_break = ( err->ErrorID == err->BreakErrorID ) ||\r
+ ( err->GlobalErrorID == err_global->BreakGlobalErrorID );\r
+\r
+\r
+ /* \82±\82±\82æ\82è\88È\8d~\82Í\81AIF \83}\83N\83\8d\82È\82Ç\82ð\8cÄ\82Ñ\8fo\82µ\89Â\94\\81i\83\8a\83G\83\93\83g\83\89\83\93\83g\89Â\94\\81j */\r
+ /* \8fã\8bL\82Ì if ( err->IsError ) \82Å\81A\82·\82®\96ß\82é\82½\82ß */\r
+\r
+\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
+ err->GlobalErrorID, (int) err );\r
+ #endif\r
+\r
+\r
+ if ( err->ErrorID == 1 ) {\r
+ FinalizerClass_initConst( &err->Finalizer, err, ErrorClass_finalize );\r
+ e= AddThreadLocalFinalizer( &err->Finalizer );\r
+ }\r
+ else {\r
+ e = 0;\r
+ }\r
+ LeaveCriticalSection( &err_global->CriticalSection );\r
+ IF(e){goto fin;}\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( is_break ) {\r
+ printf( "Break in (%d) %s\n", LineNum, FilePath );\r
+ }\r
+ return is_break;\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+\r
+//[ClearError]\r
+void ClearError()\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ if ( err->IsError ) {\r
+ printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
+ err->ErrorID, (int) err );\r
+ }\r
+ #endif\r
+\r
+ err->IsError = false;\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err );\r
+ if ( e == 0 ) {\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ if ( err->IsError )\r
+ printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
+ err->GlobalErrorID, (int) err );\r
+ #endif\r
+\r
+ if ( err->IsError ) {\r
+ GlobalErrorClass* err_global = &g_GlobalError;\r
+\r
+ EnterCriticalSection( &err_global->CriticalSection );\r
+ err_global->ErrorThreadCount -= 1;\r
+ LeaveCriticalSection( &err_global->CriticalSection );\r
+\r
+ err->IsError = false;\r
+ }\r
+ }\r
+ else {\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"clear_miss\"/>\n" );\r
+ #endif\r
+ }\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+\r
+//[IfErrThenBreak]\r
+void IfErrThenBreak()\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+\r
+ if ( err->IsError &&\r
+ ( err->ErrorID != err->BreakErrorID || err->BreakErrorID == 0 )\r
+ ) {\r
+ printf( "in IfErrThenBreak\n" );\r
+ DebugBreakR();\r
+\r
+ // \83E\83H\83b\83`\82Å\81Aerr->ErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
+ // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82\82¾\82³\82¢\81B\r
+ // \83G\83\89\81[\82ª\94\90¶\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
+ // \90³\8fí\8fI\97¹\82µ\82Ä\82¢\82é\82Â\82à\82è\82È\82Ì\82É\82±\82±\82Å\83u\83\8c\81[\83N\82·\82é\82Æ\82«\82Í\81A\r
+ // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
+ err->ErrorID, err->BreakErrorID );\r
+ #endif\r
+\r
+ {\r
+ char str[512];\r
+ sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
+ err->FilePath, err->LineNum );\r
+ OutputDebugStringA( str );\r
+ }\r
+ }\r
+ ClearError();\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ GlobalErrorClass* err_global = &g_GlobalError;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err );\r
+ if ( e ) { DebugBreakR(); ClearError(); return; } /* \93à\95\94\83G\83\89\81[ */\r
+\r
+ if ( err_global->ErrorThreadCount != 0 &&\r
+ ( err->GlobalErrorID != err_global->BreakGlobalErrorID || err_global->BreakGlobalErrorID == 0 )\r
+ ) {\r
+ printf( "in IfErrThenBreak\n" );\r
+ DebugBreakR();\r
+\r
+ // \83E\83H\83b\83`\82Å\81Aerr->GlobalErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
+ // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82\82¾\82³\82¢\81B\r
+ // \83G\83\89\81[\82ª\94\90¶\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
+ // \90³\8fí\8fI\97¹\82µ\82Ä\82¢\82é\82Â\82à\82è\82È\82Ì\82É\82±\82±\82Å\83u\83\8c\81[\83N\82·\82é\82Æ\82«\82Í\81A\r
+ // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
+ #if ERR2_ENABLE_ERROR_LOG\r
+ printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
+ err->ErrorID, err->BreakErrorID );\r
+ #endif\r
+\r
+ {\r
+ char str[512];\r
+ sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
+ err->FilePath, err->LineNum );\r
+ OutputDebugStringA( str );\r
+ }\r
+ }\r
+ ClearError();\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+\r
+//[PushErr]\r
+void PushErr( ErrStackAreaClass* ErrStackArea )\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+\r
+ ErrStackArea->ErrorID = err->ErrorID;\r
+ ErrStackArea->IsError = err->IsError;\r
+ err->IsError = false;\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err );\r
+ if ( e == 0 ) {\r
+ ErrStackArea->ErrorID = err->ErrorID;\r
+ ErrStackArea->IsError = err->IsError;\r
+ err->IsError = false;\r
+ }\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+//[PopErr]\r
+void PopErr( ErrStackAreaClass* ErrStackArea )\r
+{\r
+#if ! IS_MULTI_THREAD_ERROR_CLASS\r
+\r
+ ErrorClass* err = &g_Error;\r
+\r
+ if ( ErrStackArea->IsError )\r
+ { err->IsError = true; }\r
+\r
+#else /* IS_MULTI_THREAD_ERROR_CLASS */\r
+\r
+ errnum_t e;\r
+ ErrorClass* err;\r
+\r
+ e= ErrorClass_initializeIfNot_Sub( &err );\r
+ if ( e == 0 ) {\r
+ if ( ErrStackArea->IsError )\r
+ { err->IsError = true; }\r
+ }\r
+\r
+#endif /* IS_MULTI_THREAD_ERROR_CLASS */\r
+}\r
+\r
+\r
+ \r
+/*[SetBreakErrorID:2]*/\r
+#undef IF_\r
+\r
+\r
+#endif // ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
+\r
+\r
+//[MergeError]\r
+errnum_t MergeError( errnum_t e, errnum_t ee )\r
+{\r
+ if ( e == 0 ) { return ee; }\r
+ else { /* ErrorLog_add( ee ); */ return e; }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [g_Error4_String] >>> \r
+************************************************************************/\r
+TCHAR g_Error4_String[4096];\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Error4_printf] >>> \r
+************************************************************************/\r
+void Error4_printf( const TCHAR* format, ... )\r
+{\r
+ va_list va;\r
+ va_start( va, format );\r
+ vstprintf_r( g_Error4_String, sizeof(g_Error4_String), format, va );\r
+ va_end( va );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Error4_getErrStr] >>> \r
+************************************************************************/\r
+void Error4_getErrStr( int ErrNum, TCHAR* out_ErrStr, size_t ErrStrSize )\r
+{\r
+ switch ( ErrNum ) {\r
+\r
+ case 0:\r
+ stprintf_r( out_ErrStr, ErrStrSize, _T("no error") );\r
+ break;\r
+\r
+ case E_FEW_ARRAY:\r
+ stprintf_r( out_ErrStr, ErrStrSize,\r
+ _T("<ERROR msg=\"\83v\83\8d\83O\83\89\83\80\93à\95\94\82Ì\94z\97ñ\83\81\83\82\83\8a\81[\82ª\95s\91«\82µ\82Ü\82µ\82½\81B\"/>") );\r
+ break;\r
+\r
+ case E_FEW_MEMORY:\r
+ stprintf_r( out_ErrStr, ErrStrSize,\r
+ _T("<ERROR msg=\"\83q\81[\83v\81E\83\81\83\82\83\8a\81[\82ª\95s\91«\82µ\82Ü\82µ\82½\81B\"/>") );\r
+ break;\r
+\r
+ #ifndef __linux__\r
+ case E_GET_LAST_ERROR: {\r
+ DWORD err_win;\r
+ TCHAR* str_pointer;\r
+\r
+ err_win = gs.WindowsLastError;\r
+ if ( err_win == 0 ) { err_win = GetLastError(); }\r
+\r
+ stprintf_part_r( out_ErrStr, ErrStrSize, out_ErrStr, &str_pointer,\r
+ _T("<ERROR GetLastError=\"0x%08X\" GetLastErrorStr=\""), err_win );\r
+ FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,\r
+ NULL, err_win, LANG_USER_DEFAULT,\r
+ str_pointer, (TCHAR*)( (char*)out_ErrStr + ErrStrSize ) - str_pointer, NULL );\r
+ str_pointer = StrT_chr( str_pointer, _T('\0') );\r
+ if ( *( str_pointer - 2 ) == _T('\r') && *( str_pointer - 1 ) == _T('\n') )\r
+ str_pointer -= 2;\r
+ stcpy_part_r( out_ErrStr, ErrStrSize, str_pointer, NULL, _T("\"/>"), NULL );\r
+ break;\r
+ }\r
+ #endif\r
+\r
+ default:\r
+ if ( g_Error4_String[0] != '\0' )\r
+ stprintf_r( out_ErrStr, ErrStrSize, _T("%s"), g_Error4_String );\r
+ else\r
+ stprintf_r( out_ErrStr, ErrStrSize, _T("<ERROR errnum=\"%d\"/>"), ErrNum );\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [SaveWindowsLastError] >>> \r
+************************************************************************/\r
+errnum_t SaveWindowsLastError()\r
+{\r
+ gs.WindowsLastError = GetLastError();\r
+ return E_GET_LAST_ERROR;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Error4_showToStdErr] >>> \r
+************************************************************************/\r
+void Error4_showToStdErr( int err_num )\r
+{\r
+ Error4_showToStdIO( stderr, err_num );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [Error4_showToStdIO] >>> \r
+************************************************************************/\r
+void Error4_showToStdIO( FILE* out, int err_num )\r
+{\r
+ TCHAR msg[1024];\r
+ #if _UNICODE\r
+ char msg2[1024];\r
+ #endif\r
+\r
+ if ( err_num != 0 ) {\r
+ Error4_getErrStr( err_num, msg, sizeof(msg) );\r
+ #if _UNICODE\r
+ setlocale( LC_ALL, ".OCP" );\r
+ sprintf_s( msg2, sizeof(msg2), "%S", msg );\r
+ fprintf( out, "%s\n", msg2 ); // _ftprintf_s \82Å\82Í\93ú\96{\8cê\82ª\8fo\82Ü\82¹\82ñ\r
+ #else\r
+ fprintf( out, "%s\n", msg );\r
+ #endif\r
+\r
+ #if ERR2_ENABLE_ERROR_BREAK\r
+ fprintf( out, "\81i\8aJ\94\8eÒ\82Ö\81j\83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( %d ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82\82¾\82³\82¢\81B\n",\r
+ g_Err2.ErrID );\r
+ #else\r
+#if 0\r
+ if ( err_num == E_FEW_MEMORY || gs.WindowsLastError == ERROR_NOT_ENOUGH_MEMORY ) {\r
+ /* Not show the message for developper */\r
+ }\r
+ else {\r
+ fprintf( out, "\81i\8aJ\94\8eÒ\82Ö\81jERR2_ENABLE_ERROR_BREAK \82ð\92è\8b`\82µ\82Ä\8dÄ\83R\83\93\83p\83C\83\8b\82µ\82Ä\82\82¾\82³\82¢\81B\n" );\r
+ }\r
+#endif\r
+ #endif\r
+ }\r
+ IfErrThenBreak();\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [CRT_plus_2/CRT_plus_2.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/**************************************************************************\r
+ <<< [Interface] >>> \r
+***************************************************************************/\r
+\r
+/*[DefaultFunction]*/\r
+errnum_t DefaultFunction( void* self )\r
+{\r
+ UNREFERENCED_VARIABLE( self );\r
+ return 0;\r
+}\r
+\r
+/*[DefaultFunction_NotImplementYet]*/\r
+errnum_t DefaultFunction_NotImplementYet( void* self )\r
+{\r
+ UNREFERENCED_VARIABLE( self );\r
+ return E_NOT_IMPLEMENT_YET;\r
+}\r
+\r
+/*[DefaultFunction_Finalize]*/\r
+errnum_t DefaultFunction_Finalize( void* self, errnum_t e )\r
+{\r
+ UNREFERENCED_VARIABLE( self );\r
+ return e;\r
+}\r
+\r
+/*[VTableDefine_overwrite]*/\r
+errnum_t VTableDefine_overwrite( VTableDefine* aVTable, size_t aVTable_ByteSize, int iMethod, void* Func )\r
+{\r
+ VTableDefine* p = aVTable;\r
+ VTableDefine* p_over = (VTableDefine*)( (char*)aVTable + aVTable_ByteSize );\r
+\r
+ for ( ; p < p_over; p++ ) {\r
+ if ( p->m_IMethod == iMethod ) {\r
+ p->m_method = Func;\r
+ return 0;\r
+ }\r
+ }\r
+ return E_NOT_FOUND_SYMBOL;\r
+}\r
+\r
+\r
+ \r
+/*=================================================================*/\r
+/* <<< [StrT/StrT.c] >>> */ \r
+/*=================================================================*/\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cpy] >>> \r
+- _tcscpy is raising exception, if E_FEW_ARRAY\r
+************************************************************************/\r
+errnum_t StrT_cpy( TCHAR* Dst, size_t DstSize, const TCHAR* Src )\r
+{\r
+ size_t size;\r
+\r
+ size = ( _tcslen( Src ) + 1 ) * sizeof(TCHAR);\r
+ if ( size <= DstSize ) {\r
+ memcpy( Dst, Src, size );\r
+ return 0;\r
+ }\r
+ else {\r
+ memcpy( Dst, Src, DstSize - sizeof(TCHAR) );\r
+ *(TCHAR*)( (char*) Dst + DstSize ) = _T('\0');\r
+ return E_FEW_ARRAY;\r
+ }\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_chr] >>> \r
+************************************************************************/\r
+TCHAR* StrT_chr( const TCHAR* String, TCHAR Key )\r
+{\r
+ const TCHAR* return_value = _tcschr( String, Key );\r
+\r
+ if ( return_value == NULL && Key == _T('\0') ) {\r
+ return_value = String + _tcslen( String );\r
+ }\r
+\r
+ return (TCHAR*) return_value;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_chrNext] >>> \r
+************************************************************************/\r
+TCHAR* StrT_chrNext( const TCHAR* in_Start, TCHAR in_KeyCharactor )\r
+{\r
+ const TCHAR* p = _tcschr( in_Start, in_KeyCharactor );\r
+\r
+ if ( p != NULL )\r
+ { p += 1; }\r
+\r
+ return (TCHAR*) p;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [CharPointerArray_free] >>> \r
+************************************************************************/\r
+errnum_t CharPointerArray_free( TCHAR*** in_out_Strings, int in_StringCount,\r
+ bool in_IsFreePointers, errnum_t e )\r
+{\r
+ TCHAR** strings = *in_out_Strings;\r
+ int i;\r
+\r
+ for ( i = 0; i < in_StringCount; i += 1 ) {\r
+ e= HeapMemory_free( &strings[i], e );\r
+ }\r
+\r
+ if ( in_IsFreePointers ) {\r
+ e= HeapMemory_free( in_out_Strings, e );\r
+ }\r
+\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [MallocAndCopyString] >>> \r
+************************************************************************/\r
+errnum_t MallocAndCopyString( const TCHAR** out_NewString, const TCHAR* SourceString )\r
+{\r
+ TCHAR* str;\r
+ size_t size = ( _tcslen( SourceString ) + 1 ) * sizeof(TCHAR);\r
+\r
+ ASSERT_D( *out_NewString == NULL, __noop() );\r
+\r
+ str = (TCHAR*) malloc( size );\r
+ if ( str == NULL ) { return E_FEW_MEMORY; }\r
+\r
+ memcpy( str, SourceString, size );\r
+\r
+ *out_NewString = str;\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [MallocAndCopyString_char] >>> \r
+************************************************************************/\r
+#ifdef _UNICODE\r
+errnum_t MallocAndCopyString_char( const TCHAR** out_NewString, const char* SourceString )\r
+{\r
+ TCHAR* str;\r
+ size_t size = ( strlen( SourceString ) + 1 ) * sizeof(TCHAR);\r
+ int r;\r
+\r
+ str = (TCHAR*) malloc( size );\r
+ if ( str == NULL ) { return E_FEW_MEMORY; }\r
+\r
+ r = MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED, SourceString, -1, str, size / sizeof(TCHAR) );\r
+ IF ( r == 0 ) {\r
+ free( str );\r
+ return E_GET_LAST_ERROR;\r
+ }\r
+ *out_NewString = str;\r
+ return 0;\r
+}\r
+#endif\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [MallocAndCopyStringByLength] >>> \r
+************************************************************************/\r
+errnum_t MallocAndCopyStringByLength( const TCHAR** out_NewString, const TCHAR* SourceString,\r
+ unsigned CountOfCharacter )\r
+{\r
+ TCHAR* str;\r
+ size_t size = ( CountOfCharacter + 1 ) * sizeof(TCHAR);\r
+\r
+ ASSERT_D( *out_NewString == NULL, __noop() );\r
+ ASSERT_D( CountOfCharacter < 0x7FFFFFFF, __noop() );\r
+\r
+ str = (TCHAR*) malloc( size );\r
+ if ( str == NULL ) { return E_FEW_MEMORY; }\r
+\r
+ memcpy( str, SourceString, size - sizeof(TCHAR) );\r
+ str[ CountOfCharacter ] = _T('\0');\r
+\r
+ *out_NewString = str;\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_chrs] >>> \r
+************************************************************************/\r
+TCHAR* StrT_chrs( const TCHAR* s, const TCHAR* keys )\r
+{\r
+ if ( *keys == _T('\0') ) return NULL;\r
+\r
+ for ( ; *s != _T('\0'); s++ ) {\r
+ if ( _tcschr( keys, *s ) != NULL )\r
+ return (TCHAR*) s;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_rstr] >>> \r
+************************************************************************/\r
+TCHAR* StrT_rstr( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keyword,\r
+ void* NullConfig )\r
+{\r
+ const TCHAR* p;\r
+ int keyword_length = _tcslen( Keyword );\r
+ TCHAR keyword_first = Keyword[0];\r
+\r
+ UNREFERENCED_VARIABLE( NullConfig );\r
+\r
+ p = SearchStart;\r
+ while ( p >= String ) {\r
+ if ( *p == keyword_first ) {\r
+ if ( _tcsncmp( p, Keyword, keyword_length ) == 0 ) {\r
+ return (TCHAR*) p;\r
+ }\r
+ }\r
+ p -= 1;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_skip] >>> \r
+************************************************************************/\r
+TCHAR* StrT_skip( const TCHAR* String, const TCHAR* Keys )\r
+{\r
+ if ( *Keys == _T('\0') ) { return (TCHAR*) String; }\r
+\r
+ for ( ; *String != _T('\0'); String += 1 ) {\r
+ if ( _tcschr( Keys, *String ) == NULL )\r
+ break;\r
+ }\r
+ return (TCHAR*) String;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_rskip] >>> \r
+************************************************************************/\r
+TCHAR* StrT_rskip( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keys,\r
+ void* NullConfig )\r
+{\r
+ const TCHAR* pointer;\r
+\r
+ UNREFERENCED_VARIABLE( NullConfig );\r
+\r
+ if ( *Keys == _T('\0') ) { return (TCHAR*) SearchStart; }\r
+\r
+ for ( pointer = SearchStart; pointer >= String; pointer -= 1 ) {\r
+ if ( _tcschr( Keys, *pointer ) == NULL )\r
+ { return (TCHAR*) pointer; }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_isCIdentifier] >>> \r
+************************************************************************/\r
+bool StrT_isCIdentifier( TCHAR Character )\r
+{\r
+ const TCHAR c = Character;\r
+\r
+ return (\r
+ ( c >= _T('A') && c <= _T('Z') ) ||\r
+ ( c >= _T('a') && c <= _T('z') ) ||\r
+ ( c >= _T('0') && c <= _T('9') ) ||\r
+ c == _T('_') );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_searchOverOfCIdentifier] >>> \r
+************************************************************************/\r
+TCHAR* StrT_searchOverOfCIdentifier( const TCHAR* Text )\r
+{\r
+ const TCHAR* p;\r
+\r
+ for ( p = Text;\r
+ StrT_isCIdentifier( *p );\r
+ p += 1 )\r
+ {\r
+ }\r
+ return (TCHAR*) p;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_searchOverOfIdiom] >>> \r
+************************************************************************/\r
+TCHAR* StrT_searchOverOfIdiom( const TCHAR* Text )\r
+{\r
+ const TCHAR* p;\r
+\r
+ p = Text;\r
+ for ( p = Text;\r
+ StrT_isCIdentifier( *p ) || *p == _T(' ');\r
+ p += 1 )\r
+ {\r
+ }\r
+\r
+ for ( p -= 1;\r
+ *p == _T(' ') && p >= Text;\r
+ p -= 1 )\r
+ {\r
+ }\r
+\r
+ return (TCHAR*) p + 1;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_convPartStrToPointer] >>> \r
+************************************************************************/\r
+void* StrT_convPartStrToPointer( const TCHAR* StringStart, const TCHAR* StringOver,\r
+ const NameOnlyClass* Table, size_t TableSize, void* Default )\r
+{\r
+ const NameOnlyClass* p = Table;\r
+ const NameOnlyClass* p_over = (const NameOnlyClass*)( (uint8_t*) Table + TableSize );\r
+\r
+ while ( p < p_over ) {\r
+ if ( StrT_cmp_part( StringStart, StringOver, p->Name ) == 0 ) {\r
+ return (void*) p->Delegate;\r
+ }\r
+ p += 1;\r
+ }\r
+ return Default;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_convertNumToStr] >>> \r
+************************************************************************/\r
+TCHAR* StrT_convertNumToStr( int Number, const NameAndNumClass* Table, int TableCount,\r
+ const TCHAR* DefaultStr )\r
+{\r
+ const NameAndNumClass* p;\r
+ const NameAndNumClass* p_over = Table + TableCount;\r
+\r
+ for ( p = Table; p < p_over; p += 1 ) {\r
+ if ( p->Number == Number ) {\r
+ return p->Name;\r
+ }\r
+ }\r
+ return (TCHAR*) DefaultStr;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cmp_part] >>> \r
+************************************************************************/\r
+int StrT_cmp_part( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,\r
+ const TCHAR* in_StringB )\r
+{\r
+ const TCHAR* a;\r
+ const TCHAR* b;\r
+ TCHAR aa;\r
+ TCHAR bb;\r
+\r
+ a = in_StringA_Start;\r
+ b = in_StringB;\r
+\r
+ for (;;) {\r
+ if ( a >= in_StringA_Over ) {\r
+ bb = *b;\r
+ if ( bb == _T('\0') )\r
+ { return 0; }\r
+ else\r
+ { return -bb; }\r
+ }\r
+\r
+ aa = *a;\r
+ bb = *b;\r
+\r
+ if ( bb == _T('\0') )\r
+ { return aa; }\r
+\r
+ if ( aa != bb )\r
+ { return aa - bb; }\r
+\r
+ a += 1;\r
+ b += 1;\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cmp_i_part] >>> \r
+************************************************************************/\r
+int StrT_cmp_i_part( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,\r
+ const TCHAR* in_StringB )\r
+{\r
+ const TCHAR* a;\r
+ const TCHAR* b;\r
+ TCHAR aa;\r
+ TCHAR bb;\r
+\r
+ a = in_StringA_Start;\r
+ b = in_StringB;\r
+\r
+ for (;;) {\r
+ if ( a >= in_StringA_Over ) {\r
+ bb = *b;\r
+ if ( bb == _T('\0') )\r
+ { return 0; }\r
+ else\r
+ { return -bb; }\r
+ }\r
+\r
+ aa = *a;\r
+ bb = *b;\r
+\r
+ if ( bb == _T('\0') )\r
+ { return aa; }\r
+\r
+ if ( aa != bb ) {\r
+ if ( _totlower( aa ) != _totlower( bb ) )\r
+ { return aa - bb; }\r
+ }\r
+\r
+ a += 1;\r
+ b += 1;\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cmp_part2] >>> \r
+************************************************************************/\r
+int StrT_cmp_part2( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,\r
+ const TCHAR* in_StringB_Start, const TCHAR* in_StringB_Over )\r
+{\r
+ int length_A = in_StringA_Over - in_StringA_Start;\r
+ int length_B = in_StringB_Over - in_StringB_Start;\r
+\r
+ if ( length_A != length_B ) {\r
+ return length_A - length_B;\r
+ }\r
+ else {\r
+ return _tcsncmp( in_StringA_Start, in_StringB_Start, length_A );\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_refFName] >>> \r
+************************************************************************/\r
+TCHAR* StrT_refFName( const TCHAR* s )\r
+{\r
+ const TCHAR* p;\r
+ TCHAR c;\r
+\r
+ p = StrT_chr( s, _T('\0') );\r
+\r
+ if ( p == s ) return (TCHAR*) s;\r
+\r
+ for ( p--; p>s; p-- ) {\r
+ c = *p;\r
+ if ( c == _T('\\') || c == _T('/') ) return (TCHAR*) p+1;\r
+ }\r
+ if ( *p == _T('\\') || *p == _T('/') ) return (TCHAR*) p+1;\r
+\r
+ return (TCHAR*) s;\r
+}\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_refExt] >>> \r
+************************************************************************/\r
+TCHAR* StrT_refExt( const TCHAR* s )\r
+{\r
+ const TCHAR* p;\r
+\r
+ p = StrT_chr( s, _T('\0') );\r
+\r
+ if ( p == s ) { return (TCHAR*) s; }\r
+\r
+ for ( p--; p>s; p-- ) {\r
+ if ( *p == _T('.') ) return (TCHAR*) p+1;\r
+ if ( *p == _T('/') || *p == _T('\\') )\r
+ { return (TCHAR*) StrT_chr( p, _T('\0') ); }\r
+ }\r
+ if ( *p == _T('.') ) return (TCHAR*) p+1;\r
+\r
+ return (TCHAR*) StrT_chr( s, _T('\0') );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+* Function: StrT_cutFragmentInPath\r
+************************************************************************/\r
+void StrT_cutFragmentInPath( TCHAR* in_out_Path )\r
+{\r
+ TCHAR* p;\r
+\r
+ p = _tcschr( in_out_Path, _T('#') );\r
+ if ( p != NULL ) {\r
+ *p = _T('\0');\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_searchPartStringIndex] >>> \r
+************************************************************************/\r
+int StrT_searchPartStringIndex( const TCHAR* in_String, const TCHAR* in_StringOver,\r
+ const TCHAR** in_StringsArray, uint_fast32_t in_StringsArrayLength,\r
+ int in_DefaultIndex )\r
+{\r
+ const TCHAR** p;\r
+ const TCHAR** p_over = in_StringsArray + in_StringsArrayLength;\r
+ size_t size = (byte_t*) in_StringOver - (byte_t*) in_String;\r
+\r
+ for ( p = in_StringsArray; p < p_over; p += 1 ) {\r
+ if ( memcmp( *p, in_String, size ) == 0 ) {\r
+ return p - in_StringsArray;\r
+ }\r
+ }\r
+ return in_DefaultIndex;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_searchPartStringIndexI] >>> \r
+ - This ignores case sensitive.\r
+************************************************************************/\r
+int StrT_searchPartStringIndexI( const TCHAR* in_String, const TCHAR* in_StringOver,\r
+ const TCHAR** in_StringsArray, uint_fast32_t in_StringsArrayLength,\r
+ int in_DefaultIndex )\r
+{\r
+ const TCHAR** p;\r
+ const TCHAR** p_over = in_StringsArray + in_StringsArrayLength;\r
+ size_t count = (TCHAR*) in_StringOver - (TCHAR*) in_String;\r
+\r
+ for ( p = in_StringsArray; p < p_over; p += 1 ) {\r
+ if ( _tcsnicmp( *p, in_String, count ) == 0 ) {\r
+ return p - in_StringsArray;\r
+ }\r
+ }\r
+ return in_DefaultIndex;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_convStrToId] >>> \r
+************************************************************************/\r
+int StrT_convStrToId( const TCHAR* str, const TCHAR** strs, const int* ids,\r
+ int n, int default_id )\r
+{\r
+ const TCHAR** p;\r
+ const TCHAR** p_over = strs + n;\r
+\r
+ for ( p = strs; p < p_over; p++ ) {\r
+ if ( _tcsicmp( *p, str ) == 0 ) return ids[p - strs];\r
+ }\r
+ return default_id;\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_convStrLeftToId] >>> \r
+************************************************************************/\r
+int StrT_convStrLeftToId( const TCHAR* Str, const TCHAR** Strs, const size_t* Lens, const int* Ids,\r
+ int CountOfStrs, TCHAR* Separeters, int DefaultId, TCHAR** out_PosOfLastOfStr )\r
+{\r
+ const TCHAR** pp;\r
+ const TCHAR** pp_over = Strs + CountOfStrs;\r
+ const size_t* p_len;\r
+ const int* p_id;\r
+ const TCHAR* p_last_of_str;\r
+ TCHAR c;\r
+\r
+ p_len = Lens;\r
+ p_id = Ids;\r
+ for ( pp = Strs; pp < pp_over; pp += 1 ) {\r
+\r
+ ASSERT_D( _tcslen( *pp ) == *p_len, goto err );\r
+\r
+ if ( _tcsncmp( Str, *pp, *p_len ) == 0 ) {\r
+ p_last_of_str = Str + *p_len;\r
+ c = *p_last_of_str;\r
+ if ( c == _T('\0') || _tcschr( Separeters, c ) != NULL ) {\r
+ *out_PosOfLastOfStr = (TCHAR*) p_last_of_str;\r
+ return *p_id;\r
+ }\r
+ }\r
+ p_len += 1;\r
+ p_id += 1;\r
+ }\r
+ return DefaultId;\r
+\r
+#if ! NDEBUG\r
+ err: return DefaultId;\r
+#endif\r
+}\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_replace] >>> \r
+************************************************************************/\r
+errnum_t StrT_replace( TCHAR* Out, size_t OutSize, const TCHAR* In,\r
+ const TCHAR* FromStr, const TCHAR* ToStr, unsigned Opt )\r
+{\r
+ errnum_t e;\r
+ unsigned from_size = _tcslen( FromStr ) * sizeof(TCHAR);\r
+ unsigned to_size = _tcslen( ToStr ) * sizeof(TCHAR);\r
+ const TCHAR* p_in = In;\r
+ TCHAR* p_out = Out;\r
+ const TCHAR* p_in_from;\r
+ size_t copy_size;\r
+ int out_size = OutSize - 1;\r
+\r
+\r
+ /* \92u\8a·\82µ\82Ä\8f¬\82³\82\82È\82é\82Æ\82«\82Í\81A\8d¶\82©\82ç\89E\82Ö\91\96\8d¸\82·\82é */\r
+ if ( to_size <= from_size ) {\r
+\r
+ for (;;) {\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82Ì\90æ\93ª\88Ê\92u\82ð p_in_from \82Ö */\r
+ p_in_from = _tcsstr( p_in, FromStr );\r
+ if ( p_in_from == NULL ) break;\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82Ì\91O\82Ü\82Å In \82©\82ç Out \82Ö\83R\83s\81[\82·\82é */\r
+ copy_size = (char*)p_in_from - (char*)p_in;\r
+ out_size -= copy_size + to_size;\r
+ IF( out_size < 0 ) goto err_fa;\r
+\r
+ if ( p_out != p_in )\r
+ memcpy( p_out, p_in, copy_size );\r
+ p_in = (TCHAR*)( (char*)p_in + copy_size );\r
+ p_out = (TCHAR*)( (char*)p_out + copy_size );\r
+\r
+ /* FromStr \82ð ToStr \82É\92u\82«\8a·\82¦\82é */\r
+ memcpy( p_out, ToStr, to_size );\r
+ p_in = (TCHAR*)( (char*)p_in + from_size );\r
+ p_out = (TCHAR*)( (char*)p_out + to_size );\r
+\r
+ /* "STR_1TIME" */\r
+ if ( Opt & STR_1TIME )\r
+ { break; }\r
+ }\r
+\r
+ /* \8ec\82è\82ð In \82©\82ç Out \82Ö\83R\83s\81[\82·\82é */\r
+ #pragma warning(push)\r
+ #pragma warning(disable:4996)\r
+ if ( p_out != p_in )\r
+ _tcscpy( p_out, p_in );\r
+ p_out = NULL;\r
+ #pragma warning(pop)\r
+ }\r
+\r
+\r
+ /* \92u\8a·\82µ\82Ä\91å\82«\82\82È\82é\82Æ\82«\82Í\81A\89E\82©\82ç\8d¶\82Ö\91\96\8d¸\82·\82é */\r
+ else {\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82ª\96³\82¢\82Æ\82«\82Í\91S\95\94\83R\83s\81[\82·\82é */\r
+ p_in_from = _tcsstr( p_in, FromStr );\r
+ if ( p_in_from == NULL ) {\r
+ if ( p_out != p_in )\r
+ StrT_cpy( Out, OutSize, In );\r
+ p_out = NULL;\r
+ }\r
+ else {\r
+ Set2a froms;\r
+ TCHAR* froms_X[10];\r
+ const TCHAR** pp_froms;\r
+ size_t plus_from_to;\r
+\r
+ Set2a_initConst( &froms, froms_X );\r
+ e= Set2a_init( &froms, froms_X, sizeof(froms_X) ); IF(e)goto fin2;\r
+\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82Ì\91O\82Ü\82Å\83R\83s\81[\82·\82é */\r
+ copy_size = (char*)p_in_from - (char*)p_in;\r
+ out_size -= copy_size;\r
+ IF( out_size < 0 ) goto err_fa2;\r
+\r
+ memcpy( p_out, p_in, copy_size );\r
+ // p_in = (TCHAR*)( (char*)p_in + copy_size ); // \8cã\82Å\8eg\82í\82ê\82È\82¢\r
+ p_out = (TCHAR*)( (char*)p_out + copy_size );\r
+\r
+\r
+ /* In \82Ì\92\86\82Ì FromStr \82Ì\88Ê\92u\82ð froms \82Ö\8fW\82ß\82é */\r
+ for (;;) {\r
+\r
+ e= Set2a_expandIfOverByAddr( &froms, froms_X, (TCHAR**)froms.Next + 1 ); IF(e)goto fin2;\r
+ pp_froms = (const TCHAR**)froms.Next; froms.Next = (void*)( pp_froms + 1 );\r
+\r
+ *pp_froms = p_in_from;\r
+\r
+ if ( Opt & STR_1TIME )\r
+ { break; }\r
+\r
+ p_in = (const TCHAR*)( (char*)p_in_from + from_size );\r
+ p_in_from = _tcsstr( p_in, FromStr );\r
+ if ( p_in_from == NULL ) break;\r
+ }\r
+\r
+ plus_from_to = ( (TCHAR**)froms.Next - (TCHAR**)froms.First ) * (to_size - from_size);\r
+\r
+\r
+ /* In \82Ì\96\96\94ö\82Ì '\0' \82Ì\88Ê\92u\82à froms \82Ö */\r
+ e= Set2a_expandIfOverByAddr( &froms, froms_X, (TCHAR**)froms.Next + 1 ); IF(e)goto fin2;\r
+ pp_froms = (const TCHAR**)froms.Next; froms.Next = (void*)( pp_froms + 1 );\r
+ p_in = StrT_chr( p_in, _T('\0') );\r
+ *pp_froms = p_in;\r
+\r
+ copy_size = ( (char*)p_in - (char*)In ) + plus_from_to;\r
+ IF( copy_size >= OutSize ) goto err_fa2;\r
+ p_out = (TCHAR*)( (char*)Out + copy_size );\r
+ plus_from_to -= to_size - from_size;\r
+\r
+\r
+ /* \89E\82©\82ç\8d¶\82Ö\91\96\8d¸\82·\82é */\r
+ for ( pp_froms = (TCHAR**)froms.Next - 1;\r
+ pp_froms > (TCHAR**)froms.First;\r
+ pp_froms -- ) {\r
+\r
+ const TCHAR* p_in_from = *(pp_froms - 1);\r
+ const TCHAR* p_in_other = (const TCHAR*)( (char*)p_in_from + from_size );\r
+ const TCHAR* p_in_other_over = *pp_froms;\r
+ TCHAR* p_out_to = (TCHAR*)( (char*)Out + ( (char*)p_in_from - (char*)In ) + plus_from_to );\r
+ TCHAR* p_out_other = (TCHAR*)( (char*)p_out_to + to_size );\r
+\r
+ memmove( p_out_other, p_in_other, (char*)p_in_other_over - (char*)p_in_other );\r
+ memcpy( p_out_to, ToStr, to_size );\r
+\r
+ plus_from_to -= to_size - from_size;\r
+ }\r
+\r
+ goto fin2;\r
+ err_fa2: e = E_FEW_ARRAY; goto fin2;\r
+ fin2:\r
+ e= Set2a_finish( &froms, froms_X, e );\r
+ if ( e ) goto fin;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ if ( p_out != NULL ) *p_out = _T('\0');\r
+ return e;\r
+\r
+err_fa: e = E_FEW_ARRAY; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_replace1] >>> \r
+************************************************************************/\r
+errnum_t StrT_replace1( TCHAR* in_out_String, TCHAR FromCharacter, TCHAR ToCharacter,\r
+ unsigned Opt )\r
+{\r
+ TCHAR* p;\r
+\r
+ UNREFERENCED_VARIABLE( Opt );\r
+\r
+ IF ( FromCharacter == _T('\0') ) { return E_OTHERS; }\r
+\r
+ p = in_out_String;\r
+ for (;;) {\r
+ p = _tcschr( p, FromCharacter );\r
+ if ( p == NULL ) { break; }\r
+ *p = ToCharacter;\r
+ p += 1;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_trim] >>> \r
+************************************************************************/\r
+errnum_t StrT_trim( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str )\r
+{\r
+ const TCHAR* p1;\r
+ const TCHAR* p2;\r
+ TCHAR c;\r
+\r
+ p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;\r
+ for ( p2 = StrT_chr( p1, _T('\0') ) - 1; p2 >= p1; p2-- ) {\r
+ c = *p2;\r
+ if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
+ break;\r
+ }\r
+ return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cutPart] >>> \r
+************************************************************************/\r
+errnum_t StrT_cutPart( TCHAR* in_out_String, TCHAR* in_StartOfCut, TCHAR* in_OverOfCut )\r
+{\r
+ errnum_t e;\r
+ TCHAR* over_of_cut = StrT_chr( in_StartOfCut, _T('\0') );\r
+\r
+#ifndef NDEBUG\r
+ TCHAR* over_of_string = StrT_chr( in_out_String, _T('\0') );\r
+\r
+ ASSERT_D( over_of_cut == over_of_string, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_StartOfCut >= in_out_String, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_StartOfCut <= over_of_string, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_OverOfCut >= in_out_String, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_OverOfCut <= over_of_string, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_StartOfCut <= in_OverOfCut, e=E_OTHERS; goto fin );\r
+#endif\r
+ UNREFERENCED_VARIABLE( in_out_String );\r
+\r
+ memmove( in_StartOfCut, in_OverOfCut,\r
+ PointerType_diff( over_of_cut + 1, in_OverOfCut ) );\r
+\r
+ e=0;\r
+#ifndef NDEBUG\r
+fin:\r
+#endif\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cutLastOf] >>> \r
+************************************************************************/\r
+errnum_t StrT_cutLastOf( TCHAR* in_out_Str, TCHAR Charactor )\r
+{\r
+ TCHAR* last = StrT_chr( in_out_Str, _T('\0') );\r
+\r
+ if ( last > in_out_Str ) {\r
+ if ( *( last - 1 ) == Charactor )\r
+ { *( last - 1 ) = _T('\0'); }\r
+ }\r
+ return 0;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_cutLineComment] >>> \r
+************************************************************************/\r
+errnum_t StrT_cutLineComment( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str, const TCHAR* CommentSign )\r
+{\r
+ const TCHAR* p1;\r
+ const TCHAR* p2;\r
+ TCHAR c;\r
+\r
+ p1 = in_Str; while ( *p1 == _T(' ') || *p1 == _T('\t') ) p1++;\r
+\r
+ p2 = _tcsstr( p1, CommentSign );\r
+ if ( p2 == NULL ) p2 = StrT_chr( p1, _T('\0') );\r
+\r
+ for ( p2 = p2 - 1; p2 >= p1; p2-- ) {\r
+ c = *p2;\r
+ if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
+ break;\r
+ }\r
+ return stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_insert] >>> \r
+************************************************************************/\r
+errnum_t StrT_insert( TCHAR* in_out_WholeString, size_t in_MaxSize_of_WholeString,\r
+ TCHAR* in_out_Target_in_WholeString, TCHAR** out_NextTarget_in_WholeString,\r
+ const TCHAR* in_InsertString )\r
+{\r
+ errnum_t e;\r
+ TCHAR* over_of_whole_string = StrT_chr( in_out_WholeString, _T('\0') );\r
+ size_t insert_length = _tcslen( in_InsertString );\r
+\r
+ ASSERT_D( in_out_Target_in_WholeString >= in_out_WholeString, e=E_OTHERS; goto fin );\r
+ ASSERT_D( in_out_Target_in_WholeString <= over_of_whole_string, e=E_OTHERS; goto fin );\r
+\r
+ ASSERT_R( PointerType_diff( over_of_whole_string + 1, in_out_WholeString ) + ( insert_length * sizeof(TCHAR) )\r
+ <= in_MaxSize_of_WholeString, e=E_FEW_ARRAY; goto fin );\r
+\r
+ memmove( in_out_Target_in_WholeString + insert_length, in_out_Target_in_WholeString,\r
+ PointerType_diff( over_of_whole_string + 1, in_out_Target_in_WholeString ) );\r
+\r
+ memcpy( in_out_Target_in_WholeString, in_InsertString, insert_length * sizeof(TCHAR) );\r
+\r
+ if ( out_NextTarget_in_WholeString != NULL ) {\r
+ *out_NextTarget_in_WholeString = in_out_Target_in_WholeString + insert_length;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_insert] >>> \r
+************************************************************************/\r
+errnum_t StrHS_insert( TCHAR** in_out_WholeString,\r
+ int in_TargetIndexInWholeString, int* out_NextWholeInWholeString,\r
+ const TCHAR* in_InsertString )\r
+{\r
+ errnum_t e;\r
+ TCHAR* string = *in_out_WholeString;\r
+ size_t target_length = _tcslen( string );\r
+ size_t insert_length = _tcslen( in_InsertString );\r
+ size_t max_size = _msize( string ) / sizeof( TCHAR );\r
+ size_t new_max_size = target_length + insert_length + 1;\r
+ TCHAR* next_target;\r
+\r
+\r
+ if ( max_size < new_max_size ) {\r
+ TCHAR* new_string = (TCHAR*) realloc( string, new_max_size * sizeof( TCHAR ) );\r
+\r
+ IF ( new_string == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ max_size = new_max_size;\r
+ string = new_string;\r
+ }\r
+\r
+ e= StrT_insert( string, max_size * sizeof( TCHAR ),\r
+ string + in_TargetIndexInWholeString, &next_target,\r
+ in_InsertString ); IF(e){goto fin;}\r
+\r
+ if ( out_NextWholeInWholeString != NULL ) {\r
+ *out_NextWholeInWholeString = next_target - string;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ *in_out_WholeString = string;\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_printfPartV] >>> \r
+************************************************************************/\r
+errnum_t StrHS_printfPartV( TCHAR** in_out_String,\r
+ int in_IndexInString, int* out_NextIndexInString,\r
+ const TCHAR* in_Format, va_list in_VaList )\r
+{\r
+ enum { first_max_size = 40 };\r
+ enum { size_times = 4 };\r
+\r
+ errnum_t e;\r
+ size_t max_size;\r
+ TCHAR* string = *in_out_String;\r
+\r
+\r
+ if ( string == NULL ) {\r
+ max_size = 0;\r
+\r
+ ASSERT_R( in_IndexInString == 0, e=E_OTHERS; goto fin );\r
+ }\r
+ else {\r
+ max_size = _msize( string ) / sizeof( TCHAR );\r
+\r
+ ASSERT_R( in_IndexInString >= 0 && (size_t) in_IndexInString < max_size,\r
+ e=E_OTHERS; goto fin );\r
+ ASSERT_D( (size_t) in_IndexInString <= _tcslen( string ), __noop() );\r
+ }\r
+\r
+\r
+ if ( string == NULL ) {\r
+ string = (TCHAR*) malloc( first_max_size * sizeof( TCHAR ) );\r
+ max_size = first_max_size;\r
+ }\r
+\r
+\r
+ for (;;) {\r
+\r
+ #if _MSC_VER\r
+ #pragma warning(push)\r
+ #pragma warning(disable: 4996)\r
+ #endif\r
+\r
+ #ifdef _UNICODE\r
+ int r = _vsnwprintf( string + in_IndexInString, max_size - in_IndexInString,\r
+ in_Format, in_VaList );\r
+ #else\r
+ int r = _vsnprintf( string + in_IndexInString, max_size - in_IndexInString,\r
+ in_Format, in_VaList );\r
+ #endif\r
+\r
+ #if _MSC_VER\r
+ #pragma warning(pop)\r
+ #endif\r
+\r
+ if ( r >= 0 ) {\r
+ if ( out_NextIndexInString != NULL ) {\r
+ *out_NextIndexInString = in_IndexInString + r;\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ {\r
+ size_t new_max_size = max_size * size_times + first_max_size;\r
+ TCHAR* new_string = (TCHAR*) realloc( string, new_max_size * sizeof( TCHAR ) );\r
+\r
+ IF ( new_string == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
+ max_size = new_max_size;\r
+ string = new_string;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ *in_out_String = string;\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_printfPart] >>> \r
+************************************************************************/\r
+errnum_t StrHS_printfPart( TCHAR** in_out_String,\r
+ int in_IndexInString, int* out_NextIndexInString,\r
+ const TCHAR* in_Format, ... )\r
+{\r
+ errnum_t e;\r
+ va_list va;\r
+ va_start( va, in_Format );\r
+\r
+ e = StrHS_printfPartV( in_out_String, in_IndexInString, out_NextIndexInString, in_Format, va );\r
+\r
+ va_end( va );\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_printfV] >>> \r
+************************************************************************/\r
+errnum_t StrHS_printfV( TCHAR** in_out_String,\r
+ const TCHAR* in_Format, va_list in_VaList )\r
+{\r
+ return StrHS_printfPartV( in_out_String, 0, NULL, in_Format, in_VaList );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrHS_printf] >>> \r
+************************************************************************/\r
+errnum_t StrHS_printf( TCHAR** in_out_String,\r
+ const TCHAR* in_Format, ... )\r
+{\r
+ errnum_t e;\r
+ va_list va;\r
+ va_start( va, in_Format );\r
+\r
+ e = StrHS_printfPartV( in_out_String, 0, NULL, in_Format, va );\r
+\r
+ va_end( va );\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_meltCSV] >>> \r
+*************************************************************************/\r
+errnum_t StrT_meltCSV( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pCSV )\r
+{\r
+ errnum_t e = 0;\r
+ TCHAR* t;\r
+ TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
+ const TCHAR* s;\r
+ TCHAR dummy[2];\r
+ TCHAR c;\r
+\r
+ t = out_Str;\r
+ s = *pCSV;\r
+ if ( out_Str_Size <= 1 ) { t = dummy; t_last = dummy; }\r
+\r
+ if ( s == NULL ) { *t = _T('\0'); return 0; }\r
+\r
+\r
+ /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82 */\r
+ while ( *s == _T(' ') || *s == _T('\t') ) s++;\r
+\r
+ switch ( *s ) {\r
+\r
+ /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
+ case _T('"'):\r
+ s++;\r
+ c = *s;\r
+ while ( c != _T('"') || *(s+1) == _T('"') ) { /* " \95¶\8e\9a\82Ü\82Å */\r
+ if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }\r
+ if ( c == *(s+1) && c == _T('"') ) s++; /* " \95¶\8e\9a\8e©\91Ì */\r
+ if ( c == _T('\0') ) break;\r
+ *t = c; t++; s++; c = *s;\r
+ }\r
+ *t = _T('\0');\r
+\r
+ s++;\r
+ for (;;) {\r
+ if ( *s == _T(',') ) { s = s+1; break; }\r
+ if ( *s == _T('\0') ) { s = NULL; break; }\r
+ s++;\r
+ }\r
+ *pCSV = s;\r
+ return e;\r
+\r
+ /* \8bó\82Ì\8d\80\96Ú\82Ì\8fê\8d\87 */\r
+ case ',':\r
+ *t = _T('\0');\r
+ *pCSV = s+1;\r
+ return 0;\r
+\r
+ case '\0':\r
+ *t = _T('\0');\r
+ *pCSV = NULL;\r
+ return 0;\r
+\r
+ /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
+ default: {\r
+ TCHAR* sp = NULL; /* \8dÅ\8cã\82Ì\98A\91±\82µ\82½\8bó\94\92\82Ì\90æ\93ª */\r
+\r
+ c = *s;\r
+ while ( c != _T(',') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /* , \95¶\8e\9a\82Ü\82Å */\r
+\r
+ /* sp \82ð\90Ý\92è\82·\82é */\r
+ if ( c == ' ' ) {\r
+ if ( sp == NULL ) sp = t;\r
+ }\r
+ else sp = NULL;\r
+\r
+ if ( t == t_last ) { e = E_FEW_ARRAY; t = dummy; t_last = dummy + 1; }\r
+\r
+ /* \83R\83s\81[\82·\82é */\r
+ *t = c; t++; s++; c = *s;\r
+ }\r
+\r
+ /* \95Ô\82è\92l\82ð\8c\88\92è\82·\82é */\r
+ if ( c == _T(',') ) s = s + 1;\r
+ else s = NULL;\r
+\r
+ /* \96\96\94ö\82Ì\8bó\94\92\82ð\8eæ\82è\8f\9c\82 */\r
+ if ( sp != NULL ) *sp = '\0';\r
+ else *t = _T('\0');\r
+\r
+ *pCSV = s;\r
+ return e;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_parseCSV_f] >>> \r
+************************************************************************/\r
+errnum_t StrT_parseCSV_f( const TCHAR* StringOfCSV, bit_flags32_t* out_ReadFlags, const TCHAR* Types, ... )\r
+{\r
+ errnum_t e;\r
+ TCHAR type;\r
+ int types_index;\r
+ va_list va;\r
+ bool is_next_omittable;\r
+ bool is_next_omit;\r
+ const TCHAR* column_pointer;\r
+ TCHAR a_char;\r
+ TCHAR column[ 32 ];\r
+ bit_flags32_t read_flags;\r
+ bit_flags32_t next_read_flag;\r
+ TCHAR* out_str;\r
+ size_t str_size = SIZE_MAX; /* SIZE_MAX = Avoid warning */\r
+\r
+\r
+ va_start( va, Types );\r
+ types_index = 0;\r
+ is_next_omittable = false;\r
+ column_pointer = StringOfCSV;\r
+ read_flags = 0;\r
+ next_read_flag = 1;\r
+ while ( column_pointer != NULL ) {\r
+ out_str = NULL;\r
+\r
+ type = Types[ types_index ];\r
+ switch ( type ) {\r
+ case _T('\0'):\r
+ goto exit_for;\r
+\r
+ case _T('+'):\r
+ is_next_omittable = true;\r
+ break;\r
+\r
+ case _T('s'):\r
+ out_str = va_arg( va, TCHAR* );\r
+ str_size = va_arg( va, size_t );\r
+ ASSERT_D( str_size >= 1, e=E_OTHERS; goto fin );\r
+ break;\r
+\r
+ default:\r
+ out_str = column;\r
+ str_size = sizeof( column );\r
+ break;\r
+ }\r
+\r
+ if ( out_str != NULL ) {\r
+\r
+ // Set "out_str" : Column string in CSV\r
+ column_pointer = StrT_skip( column_pointer, _T(" \t") );\r
+ a_char = *column_pointer;\r
+ if ( is_next_omittable && ( a_char == _T('\0') || a_char == _T(',') ) ) {\r
+ column_pointer = StrT_chrs( column_pointer, _T(",") );\r
+ if ( column_pointer != NULL ) { column_pointer += 1; }\r
+ is_next_omit = true;\r
+ } else {\r
+ e= StrT_meltCSV( out_str, str_size, &column_pointer ); IF(e){goto fin;}\r
+\r
+ is_next_omit = false;\r
+ read_flags |= next_read_flag;\r
+ }\r
+\r
+ switch ( type ) {\r
+ case _T('s'):\r
+ /* "va_arg" was already called */\r
+ break;\r
+\r
+ case _T('i'): {\r
+ int* pointer_of_int = va_arg( va, int* );\r
+\r
+ if ( ! is_next_omit ) {\r
+ *pointer_of_int = ttoi_ex( column, 0 );\r
+ }\r
+ break;\r
+ }\r
+ case _T('f'): {\r
+ double* pointer_of_double = va_arg( va, double* );\r
+\r
+ if ( ! is_next_omit ) {\r
+ *pointer_of_double = _tstof( column );\r
+ }\r
+ break;\r
+ }\r
+ case _T('b'): {\r
+ bool* pointer_of_bool = va_arg( va, bool* );\r
+ int strings_index;\r
+ static const TCHAR* strings[] = {\r
+ _T("1"), _T("true"), _T("yes"),\r
+ };\r
+\r
+ if ( ! is_next_omit ) {\r
+ *pointer_of_bool = false;\r
+ for ( strings_index = 0;\r
+ strings_index < _countof( strings );\r
+ strings_index += 1 )\r
+ {\r
+ if ( _tcsicmp( column, strings[ strings_index ] ) == 0 ) {\r
+ *pointer_of_bool = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ case _T('t'): {\r
+ SYSTEMTIME* pointer_of_time = va_arg( va, SYSTEMTIME* );\r
+ int* pointer_of_bias = va_arg( va, int* );\r
+\r
+ if ( ! is_next_omit ) {\r
+ e= W3CDTF_toSYSTEMTIME( column, pointer_of_time, pointer_of_bias );\r
+ IF(e){goto fin;}\r
+ }\r
+ break;\r
+ }\r
+\r
+ default:\r
+ ASSERT_R( false, e=E_OTHERS; goto fin );\r
+ }\r
+\r
+ is_next_omittable = false;\r
+ next_read_flag <<= 1;\r
+ }\r
+\r
+ types_index += 1;\r
+ }\r
+exit_for:\r
+ if ( out_ReadFlags != NULL ) {\r
+ *out_ReadFlags = read_flags;\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ va_end( va );\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_changeToXML_Attribute] >>> \r
+*************************************************************************/\r
+errnum_t StrT_changeToXML_Attribute( TCHAR* out_Str, size_t Str_Size, const TCHAR* InputStr )\r
+{\r
+ errnum_t e;\r
+\r
+ e= StrT_replace( out_Str, Str_Size, InputStr, _T("&"), _T("&"), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("\""), _T("""), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("<"), _T("<"), 0 ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_resumeFromXML_Attribute] >>> \r
+*************************************************************************/\r
+errnum_t StrT_resumeFromXML_Attribute( TCHAR* out_Str, size_t Str_Size, const TCHAR* XML_Attr )\r
+{\r
+ errnum_t e;\r
+\r
+ e= StrT_replace( out_Str, Str_Size, XML_Attr, _T("""), _T("\""), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("<"), _T("<"), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("&"), _T("&"), 0 ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_changeToXML_Text] >>> \r
+*************************************************************************/\r
+errnum_t StrT_changeToXML_Text( TCHAR* out_Str, size_t Str_Size, const TCHAR* InputStr )\r
+{\r
+ errnum_t e;\r
+\r
+ e= StrT_replace( out_Str, Str_Size, InputStr, _T("&"), _T("&"), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T("<"), _T("<"), 0 ); IF(e)goto fin;\r
+ e= StrT_replace( out_Str, Str_Size, out_Str, _T(">"), _T(">"), 0 ); IF(e)goto fin;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_getExistSymbols] >>> \r
+************************************************************************/\r
+errnum_t StrT_getExistSymbols( unsigned* out, bool bCase, const TCHAR* Str, const TCHAR* Symbols, ... )\r
+{\r
+ errnum_t e;\r
+ int i;\r
+ bool* syms_exists = NULL;\r
+ bool b_nosym = false;\r
+ TCHAR* sym = NULL;\r
+ size_t sym_size = ( _tcslen( Symbols ) + 1 ) * sizeof(TCHAR);\r
+ int n_sym = 0;\r
+ const TCHAR** syms = NULL;\r
+ const TCHAR* p;\r
+\r
+ UNREFERENCED_VARIABLE( bCase );\r
+\r
+ sym = (TCHAR*) malloc( sym_size ); IF(sym==NULL)goto err_fm;\r
+\r
+\r
+ //=== Get Symbols\r
+ p = Symbols;\r
+ do {\r
+ e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
+ if ( sym[0] != _T('\0') ) n_sym ++;\r
+ } while ( p != NULL );\r
+\r
+ syms = (const TCHAR**) malloc( n_sym * sizeof(TCHAR*) ); IF(syms==NULL)goto err_fm;\r
+ memset( (TCHAR**) syms, 0, n_sym * sizeof(TCHAR*) );\r
+ syms_exists = (bool*) malloc( n_sym * sizeof(bool) ); IF(syms_exists==NULL)goto err_fm;\r
+ memset( syms_exists, 0, n_sym * sizeof(bool) );\r
+\r
+ p = Symbols; i = 0;\r
+ do {\r
+ e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
+ if ( sym[0] != _T('\0') ) {\r
+ e= MallocAndCopyString( &syms[i], sym ); IF(e)goto fin;\r
+ i++;\r
+ }\r
+ } while ( p != NULL );\r
+\r
+\r
+ //=== Check Str whether having Symbols\r
+ p = Str;\r
+ do {\r
+ e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
+ if ( sym[0] != _T('\0') ) {\r
+ for ( i = 0; i < n_sym; i++ ) {\r
+ if ( _tcscmp( sym, syms[i] ) == 0 ) { syms_exists[i] = true; break; }\r
+ }\r
+ if ( i == n_sym ) b_nosym = true;\r
+ }\r
+ } while ( p != NULL );\r
+\r
+\r
+ //=== Sum numbers\r
+ {\r
+ va_list va;\r
+ unsigned num;\r
+\r
+ va_start( va, Symbols );\r
+ *out = 0;\r
+ for ( i = 0; i < n_sym; i++ ) {\r
+ num = va_arg( va, unsigned );\r
+ if ( syms_exists[i] ) *out |= num;\r
+ }\r
+ va_end( va );\r
+ }\r
+\r
+ e = ( b_nosym ? E_NOT_FOUND_SYMBOL : 0 );\r
+fin:\r
+ if ( syms != NULL ) {\r
+ for ( i = 0; i < n_sym; i++ ) {\r
+ e= HeapMemory_free( &syms[i], e );\r
+ }\r
+ free( (TCHAR**) syms );\r
+ }\r
+ e= HeapMemory_free( &syms_exists, e );\r
+ e= HeapMemory_free( &sym, e );\r
+ return e;\r
+err_fm: e= E_FEW_MEMORY; goto fin;\r
+}\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_meltCmdLine] >>> \r
+*************************************************************************/\r
+errnum_t StrT_meltCmdLine( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pLine )\r
+{\r
+ errnum_t e = 0;\r
+ TCHAR* t;\r
+ TCHAR* t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
+ const TCHAR* s;\r
+ TCHAR dummy;\r
+ TCHAR c;\r
+\r
+ t = out_Str;\r
+ s = *pLine;\r
+ if ( out_Str_Size <= 1 ) { t = &dummy; t_last = &dummy; }\r
+\r
+ if ( s == NULL ) { *t = _T('\0'); return 0; }\r
+\r
+\r
+ /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82 */\r
+ while ( *s == _T(' ') || *s == _T('\t') ) s++;\r
+\r
+ switch ( *s ) {\r
+\r
+ /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
+ case _T('"'):\r
+ s++;\r
+ c = *s;\r
+ while ( c != _T('"') || *(s+1) == _T('"') ) { /* " \95¶\8e\9a\82Ü\82Å */\r
+ if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }\r
+ if ( c == *(s+1) && c == _T('"') ) s++; /* " \95¶\8e\9a\8e©\91Ì */\r
+ if ( c == _T('\0') ) break;\r
+ *t = c; t++; s++; c = *s;\r
+ }\r
+ *t = _T('\0');\r
+\r
+ s++;\r
+ for (;;) {\r
+ if ( *s == _T(' ') ) { s = s+1; break; }\r
+ if ( *s == _T('\0') ) { s = NULL; break; }\r
+ s++;\r
+ }\r
+ *pLine = s;\r
+ return e;\r
+\r
+ case '\0':\r
+ *t = _T('\0');\r
+ *pLine = NULL;\r
+ return 0;\r
+\r
+ /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
+ default: {\r
+ c = *s;\r
+ while ( c != _T(' ') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) { /* \8bó\94\92\95¶\8e\9a\82Ü\82Å */\r
+\r
+ if ( t == t_last ) { e = E_FEW_ARRAY; t = &dummy; t_last = &dummy + 1; }\r
+\r
+ /* \83R\83s\81[\82·\82é */\r
+ *t = c; t++; s++; c = *s;\r
+ }\r
+\r
+ /* *pLine\82ð\8c\88\92è\82·\82é */\r
+ while ( *s == _T(' ') ) s = s + 1;\r
+ if ( *s == _T('\0') ) s = NULL;\r
+\r
+ /* \96\96\94ö */\r
+ *t = _T('\0');\r
+\r
+ *pLine = s;\r
+ return e;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [W3CDTF_fromSYSTEMTIME] >>> \r
+************************************************************************/\r
+errnum_t W3CDTF_fromSYSTEMTIME( TCHAR* out_W3CDTF, size_t W3CDTF_ByteSize,\r
+ const SYSTEMTIME* Time, int TimeZoneMinute )\r
+{\r
+ errnum_t e;\r
+ TCHAR* char_pointer = out_W3CDTF;\r
+\r
+ e= stprintf_part_r( out_W3CDTF, W3CDTF_ByteSize, char_pointer, &char_pointer,\r
+ _T("%04d-%02d-%02dT%02d:%02d:%02d.%03d"),\r
+ Time->wYear, Time->wMonth, Time->wDay,\r
+ Time->wHour, Time->wMinute, Time->wSecond, Time->wMilliseconds );\r
+ IF(e){goto fin;}\r
+\r
+ e= W3CDTF_getTimeZoneDesignator( char_pointer,\r
+ GetStringSizeFromPointer( out_W3CDTF, W3CDTF_ByteSize, char_pointer ),\r
+ TimeZoneMinute ); IF(e){goto fin;}\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [W3CDTF_toSYSTEMTIME] >>> \r
+************************************************************************/\r
+errnum_t W3CDTF_toSYSTEMTIME( const TCHAR* String, SYSTEMTIME* out_Time, int* out_BiasMinute )\r
+{\r
+ errnum_t e;\r
+ size_t string_length = _tcslen( String );\r
+\r
+ /* 01234567890123456789012345678 */\r
+ /*"yyyy-mm-ddThh:mm:ss.sss+00:00"*/\r
+ /*"0000-00-00T00:00+00:00"*/\r
+\r
+ IF_D( out_BiasMinute == NULL ) { e=E_OTHERS; goto fin; }\r
+\r
+ /* With time */\r
+ if ( string_length >= 11 ) {\r
+ TCHAR a_char;\r
+ const TCHAR* time_zone;\r
+ int number;\r
+\r
+ IF ( String[10] != _T('T') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( String[4] != _T('-') || String[7] != _T('-') )\r
+ { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ IF ( string_length < 16 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( String[13] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ out_Time->wYear = (WORD) _ttoi( &String[0] );\r
+ out_Time->wMonth = (WORD) _ttoi( &String[5] );\r
+ out_Time->wDayOfWeek = 0;\r
+ out_Time->wDay = (WORD) _ttoi( &String[8] );\r
+ out_Time->wHour = (WORD) _ttoi( &String[11] );\r
+ out_Time->wMinute = (WORD) _ttoi( &String[14] );\r
+\r
+ a_char = String[16];\r
+ if ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) {\r
+ time_zone = &String[16];\r
+ out_Time->wSecond = 0;\r
+ out_Time->wMilliseconds = 0;\r
+ } else {\r
+ /* Second */\r
+ IF ( string_length < 19 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( a_char != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ out_Time->wSecond = (WORD) _ttoi( &String[17] );\r
+\r
+\r
+ /* \8f¬\90\94\93_ */\r
+ a_char = String[19];\r
+ if ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) {\r
+ time_zone = &String[19];\r
+ out_Time->wMilliseconds = 0;\r
+ }\r
+ else {\r
+ IF ( a_char != _T('.') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ out_Time->wMilliseconds = 0;\r
+\r
+ number = String[20] - _T('0');\r
+ if ( number < 0 || number > 9 ) {\r
+ time_zone = &String[20];\r
+ } else {\r
+ out_Time->wMilliseconds += (WORD)( number * 100 );\r
+\r
+ number = String[21] - _T('0');\r
+ if ( number < 0 || number > 9 ) {\r
+ time_zone = &String[21];\r
+ } else {\r
+ out_Time->wMilliseconds += (WORD)( number * 10 );\r
+\r
+ number = String[22] - _T('0');\r
+ if ( number < 0 || number > 9 ) {\r
+ time_zone = &String[22];\r
+ } else {\r
+ const TCHAR* pointer = &String[23];\r
+\r
+ out_Time->wMilliseconds += (WORD)( number * 1 );\r
+\r
+ for (;;) {\r
+ number = *pointer - _T('0');\r
+ if ( number < 0 || number > 9 )\r
+ { break; }\r
+\r
+ pointer += 1;\r
+ }\r
+ time_zone = pointer;\r
+ }\r
+ }\r
+ }\r
+\r
+ a_char = *time_zone;\r
+ IF ( ! ( a_char == _T('+') || a_char == _T('-') || a_char == _T('Z') ) )\r
+ { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ }\r
+ }\r
+\r
+ /* Time zone */\r
+ if ( a_char == _T('Z') ) {\r
+ *out_BiasMinute = 0;\r
+ }\r
+ else {\r
+ size_t time_zone_length = string_length - ( time_zone - String );\r
+ int bias_minute;\r
+\r
+ IF ( time_zone_length < 6 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( time_zone[3] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ bias_minute = _ttoi( &time_zone[1] ) * 60 + _ttoi( &time_zone[4] );\r
+ if ( a_char == _T('-') ) { bias_minute = -bias_minute; }\r
+ *out_BiasMinute = bias_minute;\r
+ }\r
+ }\r
+\r
+ /* Without time */\r
+ else {\r
+ out_Time->wDayOfWeek = 0;\r
+ out_Time->wHour = 0;\r
+ out_Time->wMinute = 0;\r
+ out_Time->wSecond = 0;\r
+ out_Time->wMilliseconds = 0;\r
+ *out_BiasMinute = 0;\r
+\r
+ IF ( string_length < 4 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+\r
+ /* Year */\r
+ out_Time->wYear = (WORD) _ttoi( &String[0] );\r
+\r
+ /* Month */\r
+ if ( string_length > 4 ) {\r
+ IF ( string_length < 7 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( String[4] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ out_Time->wMonth = (WORD) _ttoi( &String[5] );\r
+ } else {\r
+ out_Time->wMonth = 1;\r
+ }\r
+\r
+ /* Day */\r
+ if ( string_length > 7 ) {\r
+ IF ( string_length < 10 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ IF ( String[7] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
+ out_Time->wDay = (WORD) _ttoi( &String[8] );\r
+ } else {\r
+ out_Time->wDay = 1;\r
+ }\r
+ }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [W3CDTF_getTimeZoneDesignator] >>> \r
+************************************************************************/\r
+errnum_t W3CDTF_getTimeZoneDesignator( TCHAR* out_TZD, size_t TZD_ByteSize,\r
+ int BiasMinute )\r
+{\r
+ errnum_t e;\r
+ TCHAR sign;\r
+ TIME_ZONE_INFORMATION time_zone;\r
+\r
+\r
+ /* Set "BiasMinute" */\r
+ if ( BiasMinute == W3CDTF_CURRENT_TIME_ZONE ) {\r
+ GetTimeZoneInformation( &time_zone );\r
+ BiasMinute = -time_zone.Bias;\r
+ }\r
+ else {\r
+ enum { minute_1day = 1440 };\r
+\r
+ IF_D ( BiasMinute < -minute_1day || BiasMinute > minute_1day )\r
+ { e=E_OTHERS; goto fin; }\r
+ }\r
+\r
+\r
+ /* Set "sign" */\r
+ if ( BiasMinute >= 0 ) {\r
+ sign = _T('+');\r
+ } else {\r
+ sign = _T('-');\r
+ BiasMinute = -BiasMinute;\r
+ }\r
+\r
+\r
+ /* Set "out_TZD" */\r
+ _stprintf_s( out_TZD, TZD_ByteSize / sizeof(TCHAR), _T("%c%02d:%02d"),\r
+ sign, BiasMinute / 60, BiasMinute % 60 );\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_isFullPath] >>> \r
+************************************************************************/\r
+bool StrT_isFullPath( const TCHAR* path )\r
+{\r
+ bool ret;\r
+\r
+ if ( path[0] == _T('\\') && path[1] == _T('\\') ) {\r
+ ret = true;\r
+ } else {\r
+ const TCHAR* back_slash = _tcschr( path, _T('\\') );\r
+ const TCHAR* slash = _tcschr( path, _T('/') );\r
+ const TCHAR* colon = _tcschr( path, _T(':') );\r
+\r
+ if ( colon != NULL ) {\r
+ const TCHAR* p;\r
+\r
+ for ( p = path; p < colon; p += 1 ) {\r
+ if ( ! _istalnum( *p ) ) {\r
+ colon = NULL;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ ret = ( colon != NULL ) &&\r
+ ( back_slash == colon + 1 || slash == colon + 1 );\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+ \r
+/**************************************************************************\r
+ <<< [StrT_getFullPath_part] >>> \r
+*************************************************************************/\r
+errnum_t StrT_getFullPath_part( TCHAR* out_FullPath, size_t FullPathSize, TCHAR* OutStart,\r
+ TCHAR** out_OutLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
+{\r
+ errnum_t e;\r
+ TCHAR separator = (TCHAR) DUMMY_INITIAL_VALUE_TCHAR;\r
+ const TCHAR* separator_path;\r
+ TCHAR* out_full_path_over = (TCHAR*)( (uint8_t*) out_FullPath + FullPathSize );\r
+ TCHAR* null_position = NULL;\r
+\r
+ #if CHECK_ARG\r
+ /* "BasePath" must be out of "out_FullPath" */\r
+ ASSERT_R( BasePath < out_FullPath ||\r
+ (uint8_t*) BasePath >= (uint8_t*) out_FullPath + FullPathSize,\r
+ goto err );\r
+ #endif\r
+\r
+\r
+ /* If "StepPath" == "", out_FullPath = "" */\r
+ if ( StepPath[0] == _T('\0') ) {\r
+ ASSERT_R( FullPathSize >= sizeof(TCHAR), goto err_fm );\r
+ out_FullPath[0] = _T('\0');\r
+ e=0; goto fin;\r
+ }\r
+\r
+\r
+ /* Set "OutStart" */\r
+ if ( OutStart == NULL )\r
+ { OutStart = out_FullPath; }\r
+\r
+\r
+ /* Set "separator" : \ or / from "BasePath" */\r
+ if ( StrT_isFullPath( StepPath ) ) {\r
+ separator_path = StepPath;\r
+ }\r
+ else if ( BasePath == NULL ) {\r
+ separator = _T('\\');\r
+ separator_path = NULL;\r
+ }\r
+ else {\r
+ separator_path = BasePath;\r
+ }\r
+ if ( separator_path != NULL ) {\r
+ const TCHAR* p;\r
+ const TCHAR* p2;\r
+\r
+ p = _tcschr( separator_path, _T('\\') );\r
+ p2 = _tcschr( separator_path, _T('/') );\r
+ if ( p == NULL ) {\r
+ if ( p2 == NULL )\r
+ { separator = _T('\\'); }\r
+ else\r
+ { separator = _T('/'); }\r
+ } else {\r
+ if ( p2 == NULL )\r
+ { separator = _T('\\'); }\r
+ else {\r
+ if ( p < p2 )\r
+ { separator = _T('\\'); }\r
+ else\r
+ { separator = _T('/'); }\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /* Set "OutStart" : "BasePath" + / + "StepPath" */\r
+ if ( StrT_isFullPath( StepPath ) ) {\r
+ size_t step_path_length = _tcslen( StepPath );\r
+\r
+ IF( OutStart + step_path_length >= out_full_path_over ) goto err_fa;\r
+ memmove( OutStart, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );\r
+\r
+ /* Set "null_position" */\r
+ null_position = OutStart + step_path_length;\r
+ }\r
+ else {\r
+ TCHAR c;\r
+ TCHAR* p;\r
+ size_t base_path_length;\r
+ size_t step_path_length = _tcslen( StepPath );\r
+\r
+ if ( BasePath == NULL ) {\r
+ base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
+ }\r
+ else {\r
+ base_path_length = _tcslen( BasePath );\r
+ c = BasePath[ base_path_length - 1 ];\r
+ if ( c == _T('\\') || c == _T('/') )\r
+ { base_path_length -= 1; }\r
+ }\r
+\r
+ p = OutStart + base_path_length + 1;\r
+ IF( p + step_path_length >= out_full_path_over ) goto err_fa;\r
+ memmove( p, StepPath, ( step_path_length + 1 ) * sizeof(TCHAR) );\r
+ /* memmove is for "out_FullPath" == "StepPath" */\r
+\r
+ if ( BasePath == NULL ) {\r
+ GetCurrentDirectory( base_path_length + 1, OutStart );\r
+ if ( OutStart[ base_path_length - 1 ] == _T('\\') )\r
+ { base_path_length -= 1; }\r
+ } else {\r
+ memcpy( OutStart, BasePath, base_path_length * sizeof(TCHAR) );\r
+ }\r
+ OutStart[ base_path_length ] = separator;\r
+\r
+\r
+ /* Set "null_position" */\r
+ null_position = p + step_path_length;\r
+ }\r
+\r
+\r
+ /* Replace \ and / to "separator" in "OutStart" */\r
+ {\r
+ TCHAR other_separator;\r
+\r
+ if ( separator == _T('/') )\r
+ { other_separator = _T('\\'); }\r
+ else\r
+ { other_separator = _T('/'); }\r
+\r
+ e= StrT_replace1( OutStart, other_separator, separator, 0 ); IF(e)goto fin;\r
+ }\r
+\r
+\r
+ /* Replace \*\..\ to \ */\r
+ {\r
+ enum { length = 4 };\r
+ TCHAR parent[ length + 1 ]; /* \..\ or /../ */\r
+ TCHAR* parent_position;\r
+ TCHAR* p;\r
+\r
+ parent[0] = separator;\r
+ parent[1] = _T('.');\r
+ parent[2] = _T('.');\r
+ parent[3] = separator;\r
+ parent[4] = _T('\0');\r
+\r
+ for (;;) {\r
+ parent_position = _tcsstr( OutStart, parent );\r
+ if ( parent_position == NULL ) { break; }\r
+\r
+ p = parent_position - 1;\r
+ for (;;) {\r
+ IF( p < OutStart ) {goto err;} /* "../" are too many */\r
+ if ( *p == separator ) { break; }\r
+ p -= 1;\r
+ }\r
+\r
+ memmove( p + 1,\r
+ parent_position + length,\r
+ ( null_position - ( parent_position + length ) + 1 ) * sizeof(TCHAR) );\r
+\r
+ null_position -= ( parent_position + length ) - ( p + 1 );\r
+ }\r
+ }\r
+\r
+\r
+ /* Cut last \*\.. */\r
+ {\r
+ enum { length = 3 };\r
+ TCHAR* p;\r
+\r
+ while ( null_position - length >= OutStart ) {\r
+ if ( *( null_position - 3 ) != separator ||\r
+ *( null_position - 2 ) != _T('.') ||\r
+ *( null_position - 1 ) != _T('.') )\r
+ { break; }\r
+\r
+ p = null_position - 4;\r
+ for (;;) {\r
+ IF( p < OutStart ) {goto err;} /* "../" are too many */\r
+ if ( *p == separator ) { break; }\r
+ p -= 1;\r
+ }\r
+\r
+ *p = _T('\0');\r
+\r
+ null_position = p;\r
+ }\r
+ }\r
+\r
+\r
+ /* Replace \.\ to \ */\r
+ {\r
+ enum { length = 3 };\r
+ TCHAR current[ length + 1 ]; /* \.\ or /./ */\r
+ TCHAR* current_position;\r
+\r
+ current[0] = separator;\r
+ current[1] = _T('.');\r
+ current[2] = separator;\r
+ current[3] = _T('\0');\r
+\r
+ for (;;) {\r
+ current_position = _tcsstr( OutStart, current );\r
+ if ( current_position == NULL ) { break; }\r
+\r
+ memmove( current_position + 1,\r
+ current_position + length,\r
+ ( null_position - ( current_position + length ) + 1 ) * sizeof(TCHAR) );\r
+\r
+ null_position -= length - 1;\r
+ }\r
+ }\r
+\r
+\r
+ /* Cut last \. */\r
+ {\r
+ TCHAR* over = StrT_chr( OutStart, _T('\0') );\r
+\r
+ while ( over - 2 >= OutStart &&\r
+ *( over - 1 ) == _T('.') && *( over - 2 ) == separator ) {\r
+ over -= 2;\r
+ *over = _T('\0');\r
+ }\r
+ }\r
+\r
+\r
+ /* Add root / */\r
+ if ( null_position - 1 >= OutStart ) {\r
+ if ( *( null_position - 1 ) == _T(':') ) {\r
+ IF( null_position + 1 >= out_full_path_over ) goto err_fa;\r
+\r
+ *( null_position + 0 ) = separator;\r
+ *( null_position + 1 ) = _T('\0');\r
+ null_position += 1;\r
+ }\r
+ }\r
+\r
+\r
+ /* Set "*out_OutLast" */\r
+ if ( out_OutLast != NULL )\r
+ { *out_OutLast = null_position; }\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+err_fa: e = E_FEW_ARRAY; goto fin;\r
+err_fm: e = E_FEW_MEMORY; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_allocateFullPath] >>> \r
+************************************************************************/\r
+errnum_t StrT_allocateFullPath( TCHAR** out_FullPath, const TCHAR* StepPath, TCHAR* BasePath )\r
+{\r
+ errnum_t e;\r
+ int step_path_length = _tcslen( StepPath );\r
+ int base_path_length;\r
+ int full_path_size;\r
+\r
+ if ( BasePath == NULL ) {\r
+ base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
+ } else {\r
+ base_path_length = _tcslen( BasePath );\r
+ }\r
+\r
+ full_path_size = ( step_path_length + 1 + base_path_length + 1 ) * sizeof(TCHAR);\r
+\r
+ e= HeapMemory_allocateBytes( out_FullPath, full_path_size ); IF(e){goto fin;}\r
+ e= StrT_getFullPath( *out_FullPath, full_path_size, StepPath, BasePath ); IF(e){goto fin;}\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_getParentFullPath_part] >>> \r
+************************************************************************/\r
+errnum_t StrT_getParentFullPath_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
+ TCHAR** out_StrLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
+{\r
+ errnum_t e;\r
+ TCHAR* p;\r
+\r
+ IF_D( StrStart < Str || (char*) StrStart >= (char*)Str + StrSize ){goto err;}\r
+\r
+ if ( StepPath[0] == _T('\0') ) {\r
+ *StrStart = _T('\0');\r
+ return 0;\r
+ }\r
+\r
+ /* \90â\91Î\83p\83X\82É\82·\82é */\r
+ e= StrT_getFullPath( StrStart,\r
+ StrSize - ( (char*)StrStart - (char*)Str ),\r
+ StepPath, BasePath ); IF(e)goto fin;\r
+\r
+\r
+ /* Cut last \ */\r
+ p = StrT_chr( StrStart, _T('\0') );\r
+ if ( p > StrStart ) {\r
+ TCHAR c = *( p - 1 );\r
+ if ( c == _T('\\') || c == _T('/') )\r
+ { *( p - 1 ) = _T('\0'); }\r
+ }\r
+\r
+\r
+ /* \90e\82Ö */\r
+ p = StrT_refFName( StrStart );\r
+ if ( p > StrStart ) p--;\r
+ *p = _T('\0');\r
+\r
+\r
+ /* \83\8b\81[\83g\82È\82ç \ \82ð\95t\82¯\82é */\r
+ if ( p == StrStart + 2 ) {\r
+ *p = _T('\\'); p++; *p = _T('\0');\r
+ }\r
+\r
+ if ( out_StrLast != NULL ) *out_StrLast = p;\r
+\r
+ e=0;\r
+fin:\r
+ return e;\r
+\r
+err: e = E_OTHERS; goto fin;\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_isOverOfFileName] >>> \r
+- "" or "\" or "/"\r
+************************************************************************/\r
+inline bool StrT_isOverOfFileName( const TCHAR* PointerInPath )\r
+{\r
+ return PointerInPath == NULL ||\r
+ *PointerInPath == _T('\0') ||\r
+ ( ( *PointerInPath == _T('\\') || *PointerInPath == _T('/') ) &&\r
+ *(PointerInPath + 1) == _T('\0') );\r
+}\r
+\r
+\r
+ \r
+/***********************************************************************\r
+ <<< [StrT_getStepPath] >>> \r
+************************************************************************/\r
+errnum_t StrT_getStepPath( TCHAR* out_StepPath, size_t StepPathSize,\r
+ const TCHAR* FullPath, const TCHAR* BasePath )\r
+{\r
+ errnum_t e;\r
+ const TCHAR* abs_pointer;\r
+ const TCHAR* base_pointer;\r
+ TCHAR abs_char;\r
+ TCHAR base_char;\r
+ TCHAR separator;\r
+ const TCHAR* abs_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
+ const TCHAR* base_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
+ TCHAR* step_pointer;\r
+ TCHAR parent_symbol[4] = { _T('.'), _T('.'), _T('\\'), _T('\0') };\r
+ TCHAR base_path_2[ MAX_PATH ];\r
+\r
+\r
+ ASSERT_D( out_StepPath != FullPath, goto err );\r
+\r
+ abs_pointer = FullPath;\r
+\r
+\r
+ /* Set "base_pointer" */\r
+ if ( BasePath == NULL ) {\r
+ base_pointer = _tgetcwd( base_path_2, _countof(base_path_2) );\r
+ IF( base_pointer == NULL ) {goto err;}\r
+ }\r
+ else {\r
+ base_pointer = BasePath;\r
+ }\r
+\r
+\r
+ /* Set "abs_separator_pointer", "base_separator_pointer" : after same parent folder path */\r
+ separator = 0;\r
+ for (;;) { /* while abs_char == base_char */\r
+ abs_char = *abs_pointer;\r
+ base_char = *base_pointer;\r
+\r
+ abs_char = (TCHAR) _totlower( abs_char );\r
+ base_char = (TCHAR) _totlower( base_char );\r
+\r
+ if ( abs_char == _T('\0') ) {\r
+\r
+ /* out_StepPath = ".", if FullPath == BasePath */\r
+ if ( base_char == _T('\0') ) {\r
+ e= StrT_cpy( out_StepPath, StepPathSize, _T(".") ); IF(e)goto fin;\r
+ e=0; goto fin;\r
+ }\r
+ break;\r
+ }\r
+ if ( base_char == _T('\0') ) { break; }\r
+\r
+ if ( abs_char != base_char ) {\r
+ if ( ( abs_char == _T('/') || abs_char == _T('\\') ) &&\r
+ ( base_char == _T('/') || base_char == _T('\\') ) )\r
+ { /* Do nothing */ }\r
+ else\r
+ { break; }\r
+ }\r
+\r
+ /* Set "separator", "abs_separator_pointer", "base_separator_pointer" */\r
+ if ( base_char == _T('/') || base_char == _T('\\') ) {\r
+ if ( separator == 0 )\r
+ { separator = base_char; }\r
+\r
+ abs_separator_pointer = abs_pointer;\r
+ base_separator_pointer = base_pointer;\r
+ }\r
+\r
+ abs_pointer += 1;\r
+ base_pointer += 1;\r
+ }\r
+\r
+\r
+ /* FullPath \82Æ BasePath \82Ì\8aÖ\8cW\82ª\81A\95Ð\95û\82Ì\88ê\95\94\82ª\82à\82¤\95Ð\95û\82Ì\91S\91Ì\82Å\82 \82é\82Æ\82« */\r
+ if ( ( ( abs_char == _T('/') || abs_char == _T('\\') ) && base_char == _T('\0') ) ||\r
+ ( base_char == _T('/') || base_char == _T('\\') ) && abs_char == _T('\0') ) {\r
+\r
+ if ( separator == 0 )\r
+ { separator = abs_char; }\r
+\r
+ abs_separator_pointer = abs_pointer;\r
+ base_separator_pointer = base_pointer;\r
+ }\r
+\r
+\r
+ /* out_StepPath = FullPath, if there is not same folder */\r
+ if ( separator == 0 ) {\r
+ e= StrT_cpy( out_StepPath, StepPathSize, FullPath ); IF(e)goto fin;\r
+ e=0; goto fin;\r
+ }\r
+\r
+\r
+ /* Add "..\" to "out_StepPath" */\r
+ parent_symbol[2] = separator;\r
+ step_pointer = out_StepPath;\r
+ for (;;) {\r
+ const TCHAR* p1;\r
+ const TCHAR* p2;\r
+\r
+ if ( StrT_isOverOfFileName( base_separator_pointer ) )\r
+ { break; }\r
+\r
+\r
+ /* Set "base_separator_pointer" : next separator */\r
+ p1 = _tcschr( base_separator_pointer + 1, _T('/') );\r
+ p2 = _tcschr( base_separator_pointer + 1, _T('\\') );\r
+\r
+ if ( p1 == NULL ) {\r
+ if ( p2 == NULL )\r
+ { base_separator_pointer = NULL; }\r
+ else\r
+ { base_separator_pointer = p2; }\r
+ }\r
+ else {\r
+ if ( p2 == NULL ) {\r
+ base_separator_pointer = p1;\r
+ } else {\r
+ if ( p1 < p2 )\r
+ { base_separator_pointer = p1; }\r
+ else\r
+ { base_separator_pointer = p2; }\r
+ }\r
+ }\r
+\r
+\r
+ /* Add "..\" to "out_StepPath" */\r
+ e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, &step_pointer,\r
+ parent_symbol, NULL ); IF(e)goto fin;\r
+ }\r
+\r
+\r
+ /* Copy a part of "FullPath" to "out_StepPath" */\r
+ if ( StrT_isOverOfFileName( abs_separator_pointer ) ) {\r
+ ASSERT_D( step_pointer > out_StepPath, goto err );\r
+ *( step_pointer - 1 ) = _T('\0');\r