OSDN Git Service

Version 3.03
[vbslib/main.git] / _src / TestByFCBatAuto / TestScript / test / T_fc / T_fcNoFeq / vbslib / vbslib300 / vbslib.vbs
index 8b9be31..3eadadb 100644 (file)
@@ -1,6 +1,6 @@
 Option Explicit \r
 \r
-' vbslib  ver3.00  Sep.22, 2009\r
+' vbslib  ver3.01  Dec.15, 2009\r
 ' Copyright (c) 2008-2009, T's-Neko at Sage Plaisir 21 (Japan)\r
 ' All rights reserved. Based on 3-clause BSD license.\r
 \r
@@ -365,7 +365,10 @@ End Function
 '********************************************************************************\r
 Sub  SendKeys( ByVal window_title, ByVal keycords, ByVal late_time )\r
   WScript.Sleep late_time\r
-  If window_title <> "" Then  g_sh.AppActivate( window_title )\r
+  If window_title <> "" Then\r
+    If not g_sh.AppActivate( window_title ) Then _\r
+      Raise E_NotFoundSymbol, "<ERROR msg='\83E\83B\83\93\83h\83E\81E\83^\83C\83g\83\8b\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ' title='"& window_title &"'/>"\r
+  End If\r
   WScript.Sleep 100\r
   g_sh.SendKeys keycords\r
 End Sub\r
@@ -448,7 +451,7 @@ Public Function  input_sub( ByVal msg, bGUI_input )
         input_sub = InputBox( msg, WScript.ScriptName, "" )\r
         Wscript.StdOut.WriteLine  input_sub\r
       Else\r
-        input_sub = Wscript.StdIn.ReadLine\r
+        input_sub = StdIn_ReadLine_ForJP()\r
       End If\r
       Wscript.StdOut.WriteLine ""\r
     End If\r
@@ -458,7 +461,7 @@ Public Function  input_sub( ByVal msg, bGUI_input )
       input_sub = InputBox( msg, WScript.ScriptName, "" )\r
       Wscript.StdOut.WriteLine  input_sub\r
     Else\r
-      input_sub = Wscript.StdIn.ReadLine\r
+      input_sub = StdIn_ReadLine_ForJP()\r
     End If\r
   Else\r
     If IsEmpty( m_Auto_Src ) Then\r
@@ -470,7 +473,7 @@ Public Function  input_sub( ByVal msg, bGUI_input )
       input_sub = call_vbs_t( m_Auto_Src, m_Auto_InputFunc, msg )\r
       If Err.Number = 5 Then Wscript.StdOut.WriteLine vbCR+vbLF+"Not found function of """+_\r
             m_Auto_InputFunc +""" in """+m_Auto_Src+"""" : Err.Clear\r
-      If IsEmpty( input_sub ) Then  Wscript.StdOut.Write  msg : input_sub = Wscript.StdIn.ReadLine\r
+      If IsEmpty( input_sub ) Then  Wscript.StdOut.Write  msg : input_sub = StdIn_ReadLine_ForJP()\r
     End If\r
   End If\r
 \r
@@ -500,6 +503,44 @@ End Class
 \r
 \r
  \r
+'********************************************************************************\r
+'  <<< [StdIn_ReadLine_ForJP] >>> \r
+'********************************************************************************\r
+Function  StdIn_ReadLine_ForJP()\r
+  Dim  r, i, a\r
+  Const  msg1 = "\83R\83}\83\93\83h\83v\83\8d\83\93\83v\83g\82â InputBox \82Å\82Í\81A254\95\8e\9a\88È\8fã\82Í\93ü\82è\82Ü\82¹\82ñ\81B"\r
+  Const  msg2 = "\83R\83}\83\93\83h\83v\83\8d\83\93\83v\83g\82Å\82Í\81A\89p\95\8e\9a\88È\8aO\82Ì\8fê\8d\87\81A128\95\8e\9a\88È\8fã\82Í\93ü\82è\82Ü\82¹\82ñ\81B"\r
+  Const  msg3 = "\82à\82¤\88ê\93x\93ü\97Í\82µ\82Ä\82­\82¾\82³\82¢\81B"\r
+\r
+  Do\r
+    r = WScript.StdIn.ReadLine\r
+\r
+    If Len( r ) >= 254 Then\r
+      WScript.StdOut.WriteLine  msg1\r
+      WScript.StdOut.Write  msg3 + ">"\r
+    ElseIf Len( r ) > 128 Then\r
+      For i=1 To 128\r
+        a = Asc( Mid( r, i, 1 ) )\r
+        If a < 0 or a > 127 Then\r
+          r = InputBox( msg2+msg3, WScript.ScriptName )\r
+          While  Len( r ) >= 254\r
+            r = InputBox( msg1+msg3, WScript.ScriptName )\r
+          WEnd\r
+          WScript.StdOut.Write  msg3 +">"+ r +vbCRLF\r
+          Exit For\r
+        End If\r
+      Next\r
+      Exit Do\r
+    Else\r
+      Exit Do\r
+    End If\r
+  Loop\r
+\r
+  StdIn_ReadLine_ForJP = r\r
+End Function\r
+\r
+\r
\r
 '*-------------------------------------------------------------------------*\r
 '* ### <<<< File >>>> \r
 '*-------------------------------------------------------------------------*\r
@@ -604,9 +645,12 @@ End Function
 '  <<< [AppKeyClass::AddNewWritableFolder] >>> \r
 '********************************************************************************\r
 Public Sub  AddNewWritableFolder( Path )\r
-  If g_AppKey Is Me Then  m_Key.AddNewWritableFolder( Path ) : Exit Sub\r
+  AddNewWritableFolder_sub  Path, Empty\r
+End Sub\r
+Public Sub  AddNewWritableFolder_sub( Path, Opt )\r
+  If g_AppKey Is Me Then  m_Key.AddNewWritableFolder_sub  Path, Opt : Exit Sub\r
 \r
-  Dim  abs_path, passed_path, out\r
+  Dim  abs_path, passed_path, out, b\r
 \r
   '// Stop at debug\r
   If g_debug_or_test Then\r
@@ -618,13 +662,18 @@ Public Sub  AddNewWritableFolder( Path )
 \r
 \r
   '// If the folder in writable folder, Do nothing\r
-  abs_path = g_CurrentWritables.CheckWritable( Path )\r
+  abs_path = g_CurrentWritables.CheckWritable( Path, Opt )\r
   If IsEmpty( abs_path ) Then  Exit Sub\r
 \r
 \r
   '// If it is not able to add new writable, raise warning.\r
-  If not IsEmpty( g_CurrentWritables.CheckAddNewWritable( abs_path, out ) ) Then _\r
-    CheckWritable abs_path : Exit Sub\r
+  If not IsEmpty( g_CurrentWritables.CheckAddNewWritable( abs_path, out ) ) Then\r
+    b=True: If not(  IsEmpty( g_TempFile )  )Then b=(  g_TempFile.m_FolderPath <> abs_path  )\r
+    If b Then '// C-language's ||\r
+      CheckWritable abs_path : Exit Sub\r
+    End If\r
+    out = g_TempFile.m_FolderPath\r
+  End If\r
   passed_path = out\r
 \r
 \r
@@ -685,8 +734,7 @@ Public Sub  Ask( CheckPath )
   Next\r
 \r
   If m_WritableMode <> F_ErrIfWarn Then\r
-    echo_r  "<WARNING msg='" +msg2+ "Out of Writable, see the help of SetWritableMode.'" +_\r
-      " path='" & CheckPath & "'/>", ""\r
+    echo_r  GetWarningMessage( msg2, CheckPath ), ""\r
   End If\r
 \r
   If m_WritableMode = F_AskIfWarn Then\r
@@ -721,21 +769,40 @@ Public Sub  Ask( CheckPath )
 \r
   If m_WritableMode = F_BreakIfWarn Then  Stop  '// Look at caller function using debugger\r
   If m_WritableMode = F_BreakIfWarn  or  m_WritableMode = F_ErrIfWarn Then\r
+    echo_r  GetWarningMessage( msg2, CheckPath ), ""\r
     Err.Raise  E_OutOfWritable,, msg2+"Out of Writable """ & CheckPath & """"\r
      ' Watch  g_CurrentWritables.CurrentPathes and Path (CheckPath)\r
   End If\r
 End Sub\r
 \r
+\r
+Public Function  GetWarningMessage( msg2, CheckPath )\r
+  Dim  s, writable\r
+\r
+  s = "<Warning msg='" +msg2+ "Out of Writable, see the help of SetWritableMode.'" +_\r
+    " path='" & CheckPath & "'>"+vbCRLF\r
+\r
+  For Each writable  In g_CurrentWritables.CurrentPathes\r
+    s=s+ "  <Writable path='"+ writable +"'/>"+vbCRLF\r
+  Next\r
+  GetWarningMessage = s+ "</Warning>"\r
+End Function\r
+\r
+\r
  \r
 '********************************************************************************\r
 '  <<< [AppKeyClass::InPath] >>> \r
 '********************************************************************************\r
 Public Function  InPath( ChkPathes, WritablePathes )\r
-  If IsArray( ChkPathes ) or IsArray( WritablePathes ) Then\r
-    echo  ">InPath"\r
-  Else\r
-    echo  ">InPath  " & ChkPathes & ", " & WritablePathes\r
+  If TypeName( ChkPathes ) = "ArrayClass" Then\r
+    InPath = InPath( ChkPathes.m_Array, WritablePathes )\r
+    Exit Function\r
+  End If\r
+  If TypeName( WritablePathes ) = "ArrayClass" Then\r
+    InPath = InPath( ChkPathes, WritablePathes.m_Array )\r
+    Exit Function\r
   End If\r
+\r
   Dim  c, w, b\r
 \r
   '// ChkPathes To abs path\r
@@ -823,6 +890,8 @@ Class  Writables
     If not IsEmpty( m_AppKey ) Then  Err.Raise 1,,"Double key"\r
     If not g_AppKey.IsSame( AppKey ) Then  Err.Raise 1,,"Invalied AppKey"\r
 \r
+    GetObject_g_TempFile\r
+\r
     If IsArray( Pathes ) Then\r
       ReDim  m_Pathes( UBound( Pathes ) + 1 )\r
       For i=0 To UBound( Pathes )\r
@@ -844,8 +913,7 @@ Class  Writables
       m_Pathes(0) = abs_path + "\"\r
     End If\r
 \r
-    GetObject_g_TempFile\r
-    m_Pathes( UBound( m_Pathes ) ) = g_TempFile.m_FolderPath\r
+    m_Pathes( UBound( m_Pathes ) ) = g_TempFile.m_FolderPath  '// Last is Temp\r
 \r
     Set m_AppKey = AppKey\r
   End Sub\r
@@ -947,7 +1015,7 @@ Class  CurrentWritables
   End Sub\r
 \r
 \r
-  Public Function  CheckWritable( Path )\r
+  Public Function  CheckWritable( Path, Opt )\r
     Dim abs_path, writable, s\r
     abs_path = g_fs.GetAbsolutePathName( Path )\r
     If Right( Path, 2 ) = "\." Then  abs_path = abs_path + "\."\r
@@ -961,6 +1029,13 @@ Class  CurrentWritables
       If StrComp( writable, s, 1 ) = 0 Then  Exit Function\r
     Next\r
 \r
+    If Opt = 1 Then\r
+      s = abs_path : If Right( s, 2 ) = "\." Then  s = Left( s, Len( s ) - 1 )\r
+      For Each writable  In Me.CurrentPathes\r
+        If StrComp( s, Left( writable, Len( s ) ), 1 ) = 0 Then  Exit Function\r
+      Next\r
+    End If\r
+\r
     abs_path = g_AppKey.CheckNewWritable( abs_path )\r
     If IsEmpty( abs_path ) Then  Exit Function\r
 \r
@@ -994,6 +1069,9 @@ Class  CurrentWritables
 \r
 \r
   Public Sub  AskFileAccess( AbsPath )\r
+    If Left( AbsPath, Len( g_TempFile.m_FolderPath ) + 1 ) = g_TempFile.m_FolderPath + "\" Then _\r
+      Exit Sub\r
+\r
     If not IsEmpty( m_ProgramFiles ) Then _\r
       If Left( AbsPath, Len( m_ProgramFiles ) ) = m_ProgramFiles or _\r
          Left( m_ProgramFiles, Len( AbsPath ) ) = AbsPath Then _\r
@@ -1037,7 +1115,7 @@ End Sub
 Sub  CheckWritable( Path )\r
   Dim  abs_path\r
 \r
-  abs_path = g_CurrentWritables.CheckWritable( Path )\r
+  abs_path = g_CurrentWritables.CheckWritable( Path, Empty )\r
   If IsEmpty( abs_path ) Then  Exit Sub\r
   g_AppKey.Ask  abs_path\r
 End Sub\r
@@ -1277,15 +1355,17 @@ Sub  move( ByVal src, ByVal dst )
     If g_fs.FolderExists( dst ) Then\r
       dst = g_fs.BuildPath( dst, g_fs.GetFileName( src ) )\r
     Else\r
-      dst_fo = g_fs.GetParentFolderName( dst )\r
+      dst_fo = GetParentAbsPath( dst )\r
       If Not g_fs.FolderExists( dst_fo ) Then  mkdir  dst_fo\r
     End If\r
 \r
     echo  ">move  """ & src & """, """ & dst & """"\r
+    g_AppKey.AddNewWritableFolder  src\r
     If IsWildcard( src ) or not g_fs.FileExists( dst ) Then\r
       g_AppKey.AddNewWritableFolder  dst + "\."  '// "\." is for able to make writable folder\r
     Else\r
       g_AppKey.AddNewWritableFolder  dst\r
+      del  dst\r
     End If\r
 \r
     g_fs.MoveFile  src, dst\r
@@ -1342,7 +1422,7 @@ Sub  SafeFileUpdate( FromTmpFilePath, ToUpdateFilePath )
   Dim en,ed,en2,ed2,i,path\r
 \r
   For i=1 To 999\r
-    path = g_fs.GetParentFolderName( ToUpdateFilePath ) + "\" + _\r
+    path = GetParentAbsPath( ToUpdateFilePath ) + "\" + _\r
            g_fs.GetBaseName( ToUpdateFilePath ) + "." & i & "." + g_fs.GetExtensionName( ToUpdateFilePath )\r
     If not exist( path ) Then  Exit For\r
   Next\r
@@ -1506,7 +1586,7 @@ Function  mkdir( ByVal Path )
   echo  ">mkdir  """ & Path & """"\r
   Dim  i, n, names(), fo2\r
 \r
-  g_AppKey.AddNewWritableFolder  Path + "\."\r
+  g_AppKey.AddNewWritableFolder_sub  Path + "\.", 1\r
 \r
   If g_fs.FolderExists( Path ) Then  mkdir = 0 : Exit Function\r
 \r
@@ -1786,7 +1866,7 @@ Function  CreateFile( ByVal Path, ByVal Text )
 \r
   Path = g_fs.GetAbsolutePathName( Path )\r
   folder = g_fs.GetParentFolderName( Path )\r
-  mkdir  folder\r
+  If not g_fs.FolderExists( folder ) Then  mkdir  folder\r
 \r
   Set t = g_fs.CreateTextFile( Path, True, (g_TextFileCreateFormat = F_Unicode) )\r
   t.Write  Text\r
@@ -1808,7 +1888,8 @@ Function  ReadFile( Path )
   On Error Resume Next\r
     Set f = g_fs.OpenTextFile( Path, 1, False, -2 )\r
   en = Err.Number : ed = Err.Description : On Error GoTo 0\r
-  If en = E_FileNotExist  Then  Exit Function\r
+  If en = E_FileNotExist  or  en = E_PathNotFound  Then  Exit Function\r
+                               '// E_PathNotFound is not found parent folder\r
   If en <> 0 Then  Err.Raise en,,ed\r
 \r
   ReadFile = ReadAll( f )\r
@@ -1900,7 +1981,6 @@ Function  GetTempPath( Param )
   GetObject_g_TempFile\r
 \r
   '//=== Delete old files\r
-  g_AppKey.AddNewWritableFolder  g_TempFile.m_FolderPath + "\."\r
   If not g_fs.FolderExists( g_TempFile.m_FolderPath ) Then _\r
     mkdir  g_TempFile.m_FolderPath\r
 \r
@@ -1962,6 +2042,8 @@ Sub  GetObject_g_TempFile()
       echo  "\82±\82ê\82Í\8dí\8f\9c\82µ\82Ä\82à\82æ\82¢\88ê\8e\9e\83t\83H\83\8b\83_\82Ì\83p\83X\82Å\82·\82©\81H : " + g_TempFile.m_FolderPath\r
       pause\r
     End If\r
+\r
+    g_AppKey.AddNewWritableFolder  g_TempFile.m_FolderPath + "\."\r
   End If\r
 End Sub\r
 \r
@@ -2306,10 +2388,7 @@ End Sub
 Sub  ExpandWildcard_sub( re, flags, folder, step_folder, fnames )\r
   Dim  fo, f\r
 \r
-  If not g_fs.FolderExists( folder ) Then\r
-    Raise  E_PathNotFound, "<ERROR msg='Not found folder' jp='\83t\83H\83\8b\83_\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ' " +_\r
-      "path='"+ folder +"'/>"\r
-  End If\r
+  If not g_fs.FolderExists( folder ) Then  Exit Sub\r
 \r
   Set fo = g_fs.GetFolder( folder )\r
   If flags And F_File Then\r
@@ -2524,20 +2603,19 @@ End Function
 '********************************************************************************\r
 '  <<< [XmlAttr] >>> \r
 '********************************************************************************\r
-Function  XmlAttr( ByVal s )\r
-  s = Replace( s, "<", "&lt;" )\r
-  s = Replace( s, """", "&quot;" )\r
-  '// s = Replace( s, "'", "&apos;" )\r
+Function  XmlAttr( s )\r
   XmlAttr = Replace( s, "&", "&amp;" )\r
+  XmlAttr = Replace( XmlAttr, """", "&quot;" )\r
+  XmlAttr = Replace( XmlAttr, "<", "&lt;" )\r
 End Function\r
  \r
 '********************************************************************************\r
 '  <<< [XmlText] >>> \r
 '********************************************************************************\r
-Function  XmlText( ByVal s )\r
-  s = Replace( s, "<", "&lt;" )\r
-  s = Replace( s, ">", "&gt;" )\r
+Function  XmlText( s )\r
   XmlText = Replace( s, "&", "&amp;" )\r
+  XmlText = Replace( XmlText, "<", "&lt;" )\r
+  XmlText = Replace( XmlText, ">", "&gt;" )\r
 End Function\r
  \r
 '********************************************************************************\r
@@ -2547,7 +2625,7 @@ Const  F_NoRoot = 1
 Const  F_Str = &h8000\r
 \r
 Function  LoadXML( PathOrStr, Opt )\r
-  Dim  xml, r, t, i, c\r
+  Dim  xml, r, t, i, c, f\r
   Const  start_tag = "<Dummy_Root_>"\r
   Const  end_tag = "</Dummy_Root_>"\r
 \r
@@ -2560,7 +2638,8 @@ Function  LoadXML( PathOrStr, Opt )
       t = PathOrStr\r
     End If\r
   Else\r
-    t = ReadFile( PathOrStr )\r
+    Set f = OpenForRead( PathOrStr )\r
+    t = ReadAll( f )\r
     i=1 : Do : c = Mid( t, i, 1 ) : If c<>" " and c<>vbTab Then Exit Do\r
     i=i+1 : Loop\r
     If (Opt and F_NoRoot) or c<>"<" Then\r
@@ -3118,8 +3197,11 @@ Function  WaitForFinishAndRedirect( ex, path )
 \r
   If g_debug and IsEmpty( g_ChildHead ) Then  g_ChildHead = ">|"\r
 \r
-  If path <> "" and path <> "nul" Then _\r
-    Set f = g_fs.OpenTextFile( path, 8, True, False )\r
+  If path <> "" and path <> "nul" Then\r
+    Dim  ec : Set ec = new EchoOff\r
+    Set f = OpenForWrite( path, F_Append )\r
+    ec = Empty\r
+  End If\r
 \r
   Do While ex.Status = 0\r
     If path = "nul" or IsEmpty( path ) Then\r
@@ -3737,7 +3819,7 @@ End Sub
 '  <<< [QuickSort] >>> \r
 '********************************************************************************\r
 Sub  QuickSort( arr, i_left, i_right, compare_func, param )\r
-  Dim  pivot, i_pivot, i_big, i_small, sw\r
+  Dim  pivot, i_pivot, i_big_eq, i_small, sw, n_min_count\r
 \r
   If i_left >= i_right Then Exit Sub  ' rule-b'\r
 \r
@@ -3746,78 +3828,159 @@ Sub  QuickSort( arr, i_left, i_right, compare_func, param )
 \r
 \r
   '//== for debug\r
+  ' Const  watch_sort_id = 6  '//**********************************\r
+  ' Dim  sort_debug_id,  sort_debug_id2\r
+  ' g_SortDebugID = g_SortDebugID + 1\r
+  ' sort_debug_id = g_SortDebugID\r
   ' Dim  i, sym, value\r
-  ' echo "QuickSort start ----------------------"\r
+  ' echo "QuickSort start (" & sort_debug_id & ") ----------------------"\r
   ' For i = i_left To i_right\r
   '   QuickSort_Debug_getSym  arr, i, sym, value\r
   '   If i = i_pivot Then  value = value & " (pivot)"\r
   '   echo "(" & i & ") " & sym & " = " & value\r
   ' Next\r
-  ' If i_left = 0 and i_right = 4 Then  Stop\r
+  ' If sort_debug_id = watch_sort_id Then  Stop\r
 \r
 \r
-  i_big = i_left : i_small = i_right\r
+  '//=== Split to [ arr(i_left) ][ smaller than ][ arr(i_pivot) ][ greater equal ][ arr(i_right) ]\r
+  i_big_eq = i_left : i_small = i_right\r
   Do\r
-    '// Plus i_big if arr(i_big) is smaller than pivot\r
+\r
+    '// Plus i_big_eq.  Result is that ( *i_big_eq >= *i_pivot ).\r
     Do\r
-      If compare_func( arr(i_big), pivot, param ) >= 0 Then  Exit Do\r
-      i_big = i_big + 1\r
+      If compare_func( arr(i_big_eq), pivot, param ) >= 0 Then  Exit Do\r
+      i_big_eq = i_big_eq + 1\r
     Loop\r
 \r
-    '// Set i_small on equal or bigger than pivot\r
+    '// Minus i_small.  Result is that ( *i_pivot > *i_small ).\r
     Do\r
-      If i_small < i_pivot and i_small < i_big Then\r
-        If i_big < i_pivot Then\r
-          i_small = i_pivot : Exit Do\r
-        ElseIf i_small >= i_left Then\r
-          Exit Do\r
-        Else\r
-          Exit Sub  ' rule-c\r
-        End If\r
-      End If\r
+      If i_small < i_left Then  Exit Do\r
       If compare_func( arr(i_small), pivot, param ) < 0 Then  Exit Do\r
       i_small = i_small - 1\r
     Loop\r
 \r
-    '// Swap\r
-    If i_big < i_small Then  ' rule-a\r
-      Set sw = arr(i_big) : Set arr(i_big) = arr(i_small) : Set arr(i_small) = sw\r
-      If i_big   = i_pivot Then  i_pivot = i_small\r
-      If i_small = i_pivot Then\r
-        i_big = i_big + 1\r
-        If i_big >= i_small Then  Exit Do   ' rule-c'\r
+\r
+    '//== for debug\r
+    ' If sort_debug_id = watch_sort_id Then\r
+    '   sort_debug_id2 = sort_debug_id2 + 1\r
+    '   echo "QuickSort swap (" & sort_debug_id & "-" & sort_debug_id2 & ")-----------------"\r
+    '   For i = i_left To i_right\r
+    '     QuickSort_Debug_getSym  arr, i, sym, value\r
+    '     If i = i_small   Then  value = value & " (i_small)"\r
+    '     If i = i_big_eq     Then  value = value & " (i_big_eq)"\r
+    '     If i = i_pivot   Then  value = value & " (i_pivot)"\r
+    '     echo "(" & i & ") " & sym & " = " & value\r
+    '   Next\r
+    ' End If\r
+\r
+\r
+    '// Splitted\r
+    If i_small < i_big_eq Then\r
+      If i_left <= i_small Then\r
+        Exit Do\r
+\r
+\r
+    '// If *i_pivot is minimum Then  (4) collect minimuns at left\r
+      Else\r
+        Set sw = arr(i_left) : Set arr(i_left) = arr(i_pivot) : Set arr(i_pivot) = sw\r
+        i_big_eq = i_big_eq + 1\r
+        n_min_count = n_min_count + 1\r
+\r
+\r
+        i_small = i_right  '// i_small is iterater to same value as minimum\r
+        Do\r
+          If i_big_eq >= i_small Then  Exit Do\r
+\r
+          '// while ( *i_big_eq == *i_left )  i_big_eq++\r
+          If compare_func( arr(i_big_eq), pivot, param ) = 0 Then\r
+            i_big_eq = i_big_eq + 1\r
+            n_min_count = n_min_count + 1\r
+\r
+          '// Swap *i_big_eq  and  *i_small\r
+          Else\r
+            Do\r
+              If i_small <= i_big_eq Then  Exit Do\r
+              If compare_func( arr(i_small), pivot, param ) = 0 Then\r
+                Set sw = arr(i_small) : Set arr(i_small) = arr(i_big_eq) : Set arr(i_big_eq) = sw\r
+                Exit Do\r
+              End If\r
+              i_small = i_small - 1\r
+            Loop\r
+            If i_small <= i_big_eq Then  Exit Do\r
+          End If\r
+        Loop\r
+        Exit Do\r
+      End If\r
+\r
+\r
+    '// If i_big_eq < i_pivot < i_small Then  (1) Swap *i_big_eq and *i_small\r
+    ElseIf i_big_eq < i_pivot  and  i_pivot < i_small Then\r
+      Set sw = arr(i_big_eq) : Set arr(i_big_eq) = arr(i_small) : Set arr(i_small) = sw\r
+      i_big_eq = i_big_eq + 1 : i_small = i_small - 1\r
+\r
+\r
+    '// If i_big_eq = i_pivot < i_small Then  (2A) Rotate3 *i_small -> *i_pivot -> *(i_pivot+1);  i_pivot++\r
+    ElseIf i_big_eq = i_pivot  and  i_pivot < i_small Then\r
+      If i_pivot + 1 < i_small Then\r
+        Set sw = arr(i_pivot+1) : Set arr(i_pivot+1) = arr(i_pivot)\r
+        Set arr(i_pivot) = arr(i_small) : Set arr(i_small) = sw\r
+        i_big_eq = i_big_eq + 1 : i_pivot = i_pivot + 1\r
+\r
+\r
+    '// If i_big_eq = i_pivot  and  i_pivot+1 = i_small Then  (2B) Swap *i_big_eq and *i_small\r
+    '// (If rotate3, The result is Not swaped)\r
+      Else\r
+        Set sw = arr(i_big_eq) : Set arr(i_big_eq) = arr(i_small) : Set arr(i_small) = sw\r
+        i_big_eq = i_big_eq + 1\r
+        Exit Do\r
       End If\r
-      If i_pivot > i_small Then  i_small = i_pivot\r
+\r
+\r
+    '// If i_big_eq < i_small < i_pivot Then  (3) Rotate3 *i_small -> *i_big_eq -> *i_pivot;  i_pivot--\r
+    ElseIf i_big_eq < i_small  and  i_small < i_pivot Then\r
+      Set sw = arr(i_pivot) : Set arr(i_pivot) = arr(i_big_eq)\r
+      Set arr(i_big_eq) = arr(i_small) : Set arr(i_small) = sw\r
+      i_big_eq = i_big_eq + 1 : i_small = i_small - 1 : i_pivot = i_pivot - 1\r
+\r
+\r
     Else\r
-      Exit Do\r
+      Stop\r
     End If\r
+\r
   Loop\r
 \r
 \r
   '//== for debug\r
-  ' echo "QuickSort middle ----------------------"\r
+  ' echo "QuickSort middle (" & sort_debug_id & ") ----------------------"\r
   ' For i = i_left To i_right\r
   '   QuickSort_Debug_getSym  arr, i, sym, value\r
-  '   If i = i_big-1 Then  value = value & " (i_big-1)"\r
-  '   If i = i_big   Then  value = value & " (i_big)"\r
+  '   If i = i_big_eq-1 Then  value = value & " (i_big_eq-1)"\r
+  '   If i = i_big_eq   Then  value = value & " (i_big_eq)"\r
   '   echo "(" & i & ") " & sym & " = " & value\r
   ' Next\r
+  ' If sort_debug_id = watch_sort_id Then  Stop\r
 \r
 \r
-  QuickSort  arr, i_left, i_big-1, compare_func, param  ' rule-b\r
-  QuickSort  arr, i_big,  i_right, compare_func, param  ' rule-b\r
+  QuickSort  arr, (i_left + n_min_count), i_big_eq-1, compare_func, param  ' rule-b\r
+  QuickSort  arr, i_big_eq,  i_right, compare_func, param  ' rule-b\r
 \r
 \r
   '//== for debug\r
-  ' echo "QuickSort end ----------------------"\r
+  ' echo "QuickSort end (" & sort_debug_id & ")----------------------"\r
   ' For i = i_left To i_right\r
   '   QuickSort_Debug_getSym  arr, i, sym, value\r
   '   echo "(" & i & ") " & sym & " = " & value\r
   ' Next\r
+  'If g_debug Then\r
+  '  For  i_small = i_left  To i_right - 1\r
+  '    If compare_func( arr(i_small), arr(i_small + 1), param ) > 0 Then  Error\r
+  '  Next\r
+  'End If\r
 End Sub\r
 \r
 \r
 '//== for debug\r
+'Dim  g_SortDebugID\r
 'Sub  QuickSort_Debug_getSym( Arr, Index, out_Symbol, out_Value )\r
 '  out_Symbol = Index\r
 '  out_Value  = Arr(Index).id\r
@@ -4034,7 +4197,7 @@ Public Sub  Init1( SrcPath, TmpDstPath, bDstWillBeExist )
   m_bDstWillBeExist = bDstWillBeExist\r
 \r
   mkdir    g_fs.GetParentFolderName( g_fs.GetAbsolutePathName( m_TmpDstPath ) )\r
-  Set Me.r = OpenTextFile( m_SrcPath )\r
+  Set Me.r = OpenForRead( m_SrcPath )\r
 \r
   On Error Resume Next\r
     Set Me.w = g_fs.CreateTextFile( m_TmpDstPath, bDstWillBeExist, (g_TextFileConvertFormat = F_Unicode) )\r
@@ -4798,6 +4961,7 @@ End Sub
 '********************************************************************************\r
 Function TryStart( e )\r
   Set e = g_Err2\r
+  If e.num <> 0 Then  Stop  '// g_Err2.Clear \82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\r
   If IsEmpty( e.BreakErrID ) Then\r
     TryStart = True\r
   Else\r