OSDN Git Service

Plugins: Add ApplyPatch.sct
authorsdottaka <sdottaka@users.sourceforge.net>
Sun, 21 Jun 2015 14:35:42 +0000 (23:35 +0900)
committersdottaka <sdottaka@users.sourceforge.net>
Sun, 21 Jun 2015 14:35:42 +0000 (23:35 +0900)
--HG--
branch : stable

Installer/InnoSetup/WinMerge.iss
Installer/InnoSetup/WinMergeX64.iss
Plugins/dlls/ApplyPatch.sct [new file with mode: 0644]

index 76f67b7..5dbc91d 100755 (executable)
@@ -387,7 +387,8 @@ Name: {app}\MergePlugins\editor addin.sct; Type: Files; Check: not IsComponentSe
 Name: {app}\MergePlugins\insert datetime.sct; Type: Files; Check: not IsComponentSelected('Plugins')\r
 Name: {app}\MergePlugins\CompareMSExcelFiles.dll; Type: Files; Check: IsComponentSelected('Plugins')\r
 Name: {app}\MergePlugins\CompareMSWordFiles.dll; Type: Files; Check: IsComponentSelected('Plugins')\r
-Name: {app}\MergePlugins; Type: DirIfEmpty; Check: not IsComponentSelected('Plugins')\r\r
+Name: {app}\MergePlugins; Type: DirIfEmpty; Check: not IsComponentSelected('Plugins')\r
+\r
 Name: {app}\Filters\ADAMulti.flt; Type: Files; Check: not IsComponentSelected('Filters')\r
 Name: {app}\Filters\ASPNET.flt; Type: Files; Check: not IsComponentSelected('Filters')\r
 Name: {app}\Filters\CSharp_loose.flt; Type: Files; Check: not IsComponentSelected('Filters')\r
@@ -499,6 +500,7 @@ Source: ..\..\Plugins\dlls\editor addin.sct; DestDir: {app}\MergePlugins; Flags:
 Source: ..\..\Plugins\dlls\insert datetime.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\CompareMSExcelFiles.sct; DestDir: {app}\MergePlugins; Flags: promptifolder; Components: Plugins\r
 Source: ..\..\Plugins\dlls\CompareMSWordFiles.sct; DestDir: {app}\MergePlugins; Flags: promptifolder; Components: Plugins\r
+Source: ..\..\Plugins\dlls\ApplyPatch.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\IgnoreColumns.dll; DestDir: {app}\MergePlugins; Flags: promptifolder; Components: Plugins\r
 Source: ..\..\Plugins\dlls\IgnoreCommentsC.dll; DestDir: {app}\MergePlugins; Flags: promptifolder; Components: Plugins\r
 Source: ..\..\Plugins\dlls\IgnoreFieldsComma.dll; DestDir: {app}\MergePlugins; Flags: promptifolder; Components: Plugins\r
index 2ad7681..69e353b 100644 (file)
@@ -479,6 +479,7 @@ Source: ..\..\Plugins\dlls\editor addin.sct; DestDir: {app}\MergePlugins; Flags:
 Source: ..\..\Plugins\dlls\insert datetime.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\CompareMSExcelFiles.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\CompareMSWordFiles.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
+Source: ..\..\Plugins\dlls\ApplyPatch.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\X64\IgnoreColumns.dll; DestDir: {app}\MergePlugins; Flags: promptifolder; Components: Plugins\r
 Source: ..\..\Plugins\dlls\X64\IgnoreCommentsC.dll; DestDir: {app}\MergePlugins; Flags: promptifolder; Components: Plugins\r
 Source: ..\..\Plugins\dlls\X64\IgnoreFieldsComma.dll; DestDir: {app}\MergePlugins; Flags: promptifolder; Components: Plugins\r
@@ -1200,13 +1201,15 @@ begin
 end;\r
 \r
 procedure RegisterPreviousData(PreviousDataKey: Integer);\r
-begin\r  SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));\r
+begin\r
+  SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));\r
   SetPreviousData(PreviousDataKey, 'MergeAtRightPane', BooleanToString(g_CheckListBox.Checked[1]));\r
   SetPreviousData(PreviousDataKey, 'MergeAtCenterPane', BooleanToString(g_CheckListBox.Checked[2]));\r
   SetPreviousData(PreviousDataKey, 'MergeAtLeftPane', BooleanToString(g_CheckListBox.Checked[3]));\r
   SetPreviousData(PreviousDataKey, 'AutoMergeAtStartup', BooleanToString(g_CheckListBox.Checked[4]));\r
 end;\r
-\rfunction GetSysColor(ColorType: Integer): Integer;\r
+\r
+function GetSysColor(ColorType: Integer): Integer;\r
 external 'GetSysColor@user32.dll';\r
 \r
 procedure InitializeWizard();\r
@@ -1227,4 +1230,5 @@ begin
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtRightPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtRightPane', 'true')), True, nil);\r
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtCenterPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtCenterPane', 'false')), True, nil);\r
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtLeftPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtLeftPane', 'false')), True, nil);\r
-  g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);\rend;\r
+  g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);\r
+end;\r
diff --git a/Plugins/dlls/ApplyPatch.sct b/Plugins/dlls/ApplyPatch.sct
new file mode 100644 (file)
index 0000000..911c88d
--- /dev/null
@@ -0,0 +1,530 @@
+<scriptlet>
+<implements type="Automation" id="dispatcher">
+    <property name="PluginEvent">
+        <get/>
+    </property>
+    <property name="PluginDescription">
+        <get/>
+    </property>
+    <property name="PluginFileFilters">
+        <get/>
+    </property>
+    <property name="PluginIsAutomatic">
+        <get/>
+    </property>
+    <method name="UnpackFile"/>
+    <method name="PackFile"/>
+    <method name="IsFolder"/>
+    <method name="UnpackFolder"/>
+    <method name="PackFolder"/>
+    <method name="ShowSettingsDialog"/>
+</implements>
+
+<script language="VBS">
+
+'/////////////////////////////////////////////////////////////////////////////
+'    This is a plugin for WinMerge.
+'    It will apply selected patch to specified file or folder using GnuWin32 Patch For Windows.
+'    Copyright (C) 2015 Takashi Sawanaka
+'
+'    This program is free software; you can redistribute it and/or modify
+'    it under the terms of the GNU General Public License as published by
+'    the Free Software Foundation; either version 2 of the License, or
+'    (at your option) any later version.
+'
+'    This program is distributed in the hope that it will be useful,
+'    but WITHOUT ANY WARRANTY; without even the implied warranty of
+'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+'    GNU General Public License for more details.
+'
+'    You should have received a copy of the GNU General Public License
+'    along with this program; if not, write to the Free Software
+'    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+'
+
+Option Explicit
+
+Const REGKEY_PATH = "HKEY_CURRENT_USER\Software\Thingamahoochie\WinMerge"
+Const PLUGIN_NAME = "ApplyPatch.sct WinMerge Plugin"
+
+Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
+Dim wsh: Set wsh = CreateObject("WScript.Shell")
+
+Function get_PluginEvent()
+    get_PluginEvent = "FILE_FOLDER_PACK_UNPACK"
+End Function
+
+Function get_PluginDescription()
+    get_PluginDescription = "Apply patch using GnuWin32 Patch for Windows"
+End Function
+
+Function get_PluginFileFilters()
+    get_PluginFileFilters = "\.diff$;\.patch$"
+End Function
+
+Function get_PluginIsAutomatic()
+    get_PluginIsAutomatic = True
+End Function
+
+Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
+    Dim filePatched, cmdLine, msg
+
+    UnpackFile = False
+
+    If Not IsPatchFile(fileSrc) Then
+        ' FIXME:
+        fso.CopyFile fileSrc, fileDst
+        pbChanged = True
+        pSubcode = 1
+        UnpackFile = True
+        Exit Function
+    End If
+
+    filePatched = wsh.RegRead(REGKEY_PATH & "\Files\Left\Item_0")
+    If IsPatchFile(filePatched) Then
+        filePatched = wsh.RegRead(REGKEY_PATH & "\Files\Right\Item_0")
+    End If
+
+    If IsLangJapanese() Then
+        msg = "\83p\83b\83` '" & fso.GetFileName(fileSrc) & "' \82ð\93K\97p\82·\82é\83t\83@\83C\83\8b\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢" & vbCrLf & "(\81¦ \8ew\92è\82µ\82½\83t\83@\83C\83\8b\82ð\88ê\8e\9e\83t\83H\83\8b\83_\82É\83R\83s\81[\82µ\81A\88ê\8e\9e\83t\83H\83\8b\83_\91¤\82Ì\83t\83@\83C\83\8b\82É\83p\83b\83`\82ð\93K\97p\82µ\82Ü\82·)"
+    Else
+        msg = "Enter the name of the file to which the patch '" & fso.GetFileName(fileSrc) & "' is applied"
+    End If
+    Do While True
+        filePatched = InputBox(msg, PLUGIN_NAME, filePatched)
+        If filePatched = "" Then
+            Exit Function
+        End If
+        If fso.FileExists(filePatched) Then Exit Do
+        If IsLangJapanese() Then
+            MsgBox "\83t\83@\83C\83\8b '" & filePatched & "' \82Í\91\8dÝ\82µ\82Ü\82¹\82ñ", vbExclamation
+        Else
+            MsgBox "file '" & filePatched & "' does not exist", vbExclamation
+        End If
+    Loop
+
+    cmdLine = "type """ & fileSrc & """ | patch " & IIf(IsWindowsTextFormat(fileSrc), "", "--binary ") & "$FILE"
+    If IsLangJapanese() Then
+        msg = "patch \83R\83}\83\93\83h\82Ö\93n\82·\88ø\90\94\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢"
+    Else
+        msg = "Enter the command line arguments for patch command"
+    End If
+    cmdLine = InputBox(msg, PLUGIN_NAME, cmdLine)
+    If cmdLine = "" Then Exit Function
+    cmdLine = Replace(cmdLine, "$FILE", fileDst)
+        
+    fso.CopyFile filePatched, fileDst
+
+    Run wsh, "cmd.exe /s /c ""set PATH=" & GetPatchExeFolder() & ";%PATH% & " & cmdLine & " & pause"""
+
+    pbChanged = True
+    pSubcode = 0
+    UnpackFile = True
+End Function
+
+Function PackFile(fileSrc, fileDst, pbChanged, pSubcode)
+    If pSubcode <> 0 Then
+        ' FIXME:
+        fso.CopyFile fileSrc, fileDst
+        pbChanged = True
+        PackFile = True
+        Exit Function
+    End If
+    PackFile = False
+End Function
+
+Function IsFolder(file)
+    IsFolder = True
+End Function
+
+Function UnpackFolder(fileSrc, folderDst, pbChanged, pSubcode)
+    Dim dirPatched, cmdLine, msg, files, stripCount
+
+    UnpackFolder = False
+
+    If Not fso.FolderExists(folderDst) Then fso.CreateFolder folderDst
+
+    dirPatched = wsh.RegRead(REGKEY_PATH & "\Files\Left\Item_0")
+    If Not fso.FolderExists(dirPatched) Then
+        dirPatched = wsh.RegRead(REGKEY_PATH & "\Files\Right\Item_0")
+    End If
+
+    If IsLangJapanese() Then
+        msg = "\83p\83b\83` '" & fso.GetFileName(fileSrc) & "'\82ð\93K\97p\82·\82é\83t\83H\83\8b\83_\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢" & vbCrLf & "(\81¦ \8ew\92è\82µ\82½\83t\83H\83\8b\83_\93à\82Ì\83t\83@\83C\83\8b\82ð\88ê\8e\9e\83t\83H\83\8b\83_\82É\83R\83s\81[\82µ\81A\88ê\8e\9e\83t\83H\83\8b\83_\91¤\82Ì\83t\83@\83C\83\8b\82É\83p\83b\83`\82ð\93K\97p\82µ\82Ü\82·)"
+    Else
+        msg = "Enter the name of the folder to which the patch '" & fso.GetFileName(fileSrc) & "' is applied"
+    End If
+    Do While True
+        dirPatched = InputBox(msg, PLUGIN_NAME, dirPatched)
+        If dirPatched = "" Then
+            fso.CopyFile fileSrc, fso.BuildPath(folderDst, fso.GetFileName(fileSrc)) & ".txt"
+            Exit Function
+        End If
+        If fso.FolderExists(dirPatched) Then Exit Do
+        If IsLangJapanese() Then
+            MsgBox "\83t\83H\83\8b\83_ '" & dirPatched & "' \82Í\91\8dÝ\82µ\82Ü\82¹\82ñ", vbExclamation
+        Else
+            MsgBox "folder '" & dirPatched & "' does not exist", vbExclamation
+        End If
+    Loop
+
+    files = GetFileNamesInPatch(fileSrc)
+    stripCount = GuessStripCount(files, dirPatched)
+
+    cmdLine = "type """ & fileSrc & """ | patch " & IIf(IsWindowsTextFormat(fileSrc), "", "--binary") & " -p" & stripCount
+    If IsLangJapanese() Then
+        msg = "patch \83R\83}\83\93\83h\82Ö\93n\82·\88ø\90\94\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢"
+    Else
+        msg = "Enter the command line arguments for patch command"
+    End If
+    cmdLine = InputBox(msg, PLUGIN_NAME, cmdLine)
+    If cmdLine = "" Then
+        fso.CopyFile fileSrc, fso.BuildPath(folderDst, fso.GetFileName(fileSrc)) & ".txt"
+        Exit Function
+    End If
+        
+    stripCount = GetStripCountFromCmdLine(cmdLine)
+    If stripCount = 0 Then
+        If HasAbsolutePathInList(files) Then
+            If IsLangJapanese() Then
+               msg = "\90â\91Î\83p\83X\82ª\8aÜ\82Ü\82ê\82Ä\82¢\82é\83p\83b\83`\83t\83@\83C\83\8b\82É '-p0' \83I\83v\83V\83\87\83\93\82ª\8ew\92è\82³\82ê\82Ü\82µ\82½\81B\82±\82Ì\82Ü\82Ü\8eÀ\8ds\82·\82é\82Æ\83p\83b\83`\82ª\88ê\8e\9e\83t\83@\83C\83\8b\82Å\82Í\82È\82­\81A\8c³\83t\83@\83C\83\8b\82É\93K\97p\82³\82ê\82Ä\82µ\82Ü\82¤\89Â\94\\90«\82ª\82 \82é\82½\82ß\81A\92\86\8e~\82µ\82Ü\82·\81B"
+            Else
+               msg = "Should not specify the '-p0' command line option for the patch file which includes absolute paths"
+            End If
+            MsgBox msg, vbExclamation
+            Exit Function
+        End If
+    End If
+
+    CopyOriginalFiles dirPatched, folderDst, files, stripCount
+
+    Run wsh, "cmd.exe /s /c ""set PATH=" & GetPatchExeFolder() & ";%PATH% & cd /d " & folderDst & " & " & cmdLine & " & pause"""
+
+    pbChanged = True
+    pSubcode = 0
+    UnpackFolder = True
+End Function
+
+Function PackFolder(fileSrc, folderDst, pbChanged, pSubcode)
+    PackFolder = False
+End Function
+
+Function ShowSettingsDialog()
+    Dim tname: tname = fso.BuildPath(fso.GetSpecialFolder(2), fso.GetTempName() & ".hta")
+    Dim tfile: Set tfile = fso.CreateTextFile(tname)
+    tfile.Write getResource("dialog1")
+    tfile.Close
+    Run wsh, "mshta.exe """ & tname & """"
+    fso.DeleteFile tname 
+End Function
+
+Sub Run(sh, cmd)
+    sh.Run cmd, 1, True
+End Sub
+
+Function GetPatchExeFolder()
+    Dim winMergeExePath
+    On Error Resume Next
+    winMergeExePath = "C:\Program Files\WinMerge\WinMergeU.exe"
+    winMergeExePath = wsh.RegRead(REGKEY_PATH & "\Executable")
+    GetPatchExeFolder = fso.BuildPath(fso.GetParentFolderName(winMergeExePath), "GnuWin32\bin")
+End Function
+
+Function SafeUBound(ary)
+    On Error Resume Next
+    SafeUBound = -1
+    SafeUBound = UBound(ary)
+End Function
+
+Function IIf(cond, t, f)
+    If cond Then IIf = t Else IIf = f
+End Function
+
+Function IsPatchFile(path)
+    Dim patterns, pattern, re
+    patterns = Split(get_PluginFileFilters(), ";")
+    For Each pattern In patterns
+        Set re = CreateObject("VBScript.RegExp")
+        re.Pattern = pattern
+        re.IgnoreCase = True
+        If re.Test(path) Then
+            IsPatchFile = True
+            Exit Function
+        End If
+    Next
+    IsPatchFile = False
+End Function
+
+Function IsWindowsTextFormat(path)
+    IsWindowsTextFormat = (InStr(ReadAllText(path), vbCrLf) > 0)
+End Function
+
+Function IsAbsolutePath(path)
+    IsAbsolutePath = (Mid(path, 2, 1) = ":" Or Left(path, 1) = "/" Or Left(path, 1) = "\")
+End Function
+
+Function HasAbsolutePathInList(files)
+    Dim i
+    For i = 0 To SafeUBound(files)
+        If IsAbsolutePath(files(i)(0)) Then
+            HasAbsolutePathInList = True
+            Exit Function
+        End If
+    Next
+    HasAbsolutePathInList = False
+End Function
+
+Function IsNullDevice(path)
+    IsNullDevice = (path = "/dev/null" Or UCase(path) = "NUL")
+End Function
+
+Function StripDir(fileName, stripCount)
+    Dim i, pos, posNext1, posNext2
+    If stripCount = -1 Then
+        StripDir = fso.GetFileName(fileName)
+        Exit Function
+    ElseIf stripCount = 0 Then
+        StripDir = fileName
+        Exit Function
+    End If
+    pos = 1
+    For i = 0 To stripCount - 1
+        posNext1 = InStr(pos, fileName, "/")
+        posNext2 = InStr(pos, fileName, "\")
+        If posNext1 > 0 And (posNext1 < posNext2 Or posNext2 = 0) Then
+            pos = posNext1 + 1
+        ElseIf posNext2 > 0 And (posNext2 < posNext1 Or posNext1 = 0) Then
+            pos = posNext2 + 1
+        Else
+            pos = 0
+            Exit For
+        End If
+    Next
+    If pos = 0 Then
+        StripDir = ""
+    Else
+        StripDir = Mid(fileName, pos)
+    End If
+End Function
+
+Function MakePatchedFileName(destDir, fileName, stripCount)
+    Dim strippedFileName
+    If Not IsNullDevice(fileName) Then
+        strippedFileName = StripDir(fileName, stripCount)
+        If strippedFileName = "" Then
+            MakePatchedFileName = ""
+        Else
+            If Not IsAbsolutePath(strippedFileName) Then
+                MakePatchedFileName = fso.BuildPath(destDir, strippedFileName)
+            Else
+                MakePatchedFileName = strippedFileName
+            End If
+        End If
+    Else
+        MakePatchedFileName = fileName
+    End If
+End Function
+
+Function GuessStripCount(fileNamesInPatch, destDir)
+    Dim i, j, fileName, stripCount
+    Dim matchCount, maxMatchCount
+    GuessStripCount = 0
+    stripCount = 0
+    maxMatchCount = 0
+    If SafeUBound(fileNamesInPatch) < 0 Then Exit Function
+    Do While True
+        matchCount = 0
+        For i = 0 To SafeUBound(fileNamesInPatch)
+            For j = 0 To 1
+                If Not IsNullDevice(fileNamesInPatch(i)(j)) Then
+                    fileName = MakePatchedFileName(destDir, fileNamesInPatch(i)(j), stripCount)
+                    If fso.FileExists(fileName) Then
+                        matchCount = matchCount + 1
+                    End If
+                End If
+            Next
+        Next
+        If matchCount > maxMatchCount Then
+            GuessStripCount = stripCount
+        End If
+        stripCount = stripCount + 1
+        If stripCount > 64 Then Exit Do
+    Loop
+End Function
+
+Sub CreateFolderEx(ByVal dirName)
+    Dim parent
+    parent = fso.GetParentFolderName(dirName)
+    If fso.FolderExists(parent) Then
+        If Not fso.FolderExists(dirName) Then
+            fso.CreateFolder dirName
+        End If
+    Else
+        CreateFolderEx parent
+        fso.CreateFolder dirName
+    End If
+End Sub
+
+Sub CopyOriginalFiles(srcDir, destDir, fileNamesInPatch, stripCount)
+    Dim i
+    Dim fileNameSrc, fileNameDest
+    For i = 0 To SafeUBound(fileNamesInPatch)
+        If Not IsNullDevice(fileNamesInPatch(i)(0)) Then
+            fileNameSrc = MakePatchedFileName(srcDir, fileNamesInPatch(i)(0), stripCount)
+            fileNameDest = MakePatchedFileName(destDir, fileNamesInPatch(i)(0), stripCount)
+            If fso.FileExists(fileNameSrc) Then
+                If Not fso.FolderExists(fso.GetParentFolderName(fileNameDest)) Then
+                    CreateFolderEx fso.GetParentFolderName(fileNameDest)
+                End If
+                fso.CopyFile fileNameSrc, fileNameDest
+            End If
+        End If
+    Next
+End Sub
+
+Function ReadAllText(fileName)
+    Dim stream
+    Set stream = CreateObject("ADODB.Stream")
+    stream.Open
+    stream.Charset = "_autodetect_all"
+    stream.LoadFromFile fileName
+    ReadAllText = stream.ReadText
+    stream.Close
+End Function
+
+Function GetFileNamesInPatch(fileName)
+    Dim i, n, count, line, lines, text
+    Dim re, ml, mr
+    Dim ary()
+
+    Set re = CreateObject("VBScript.RegExp")
+    re.Pattern = "^(---|\+\+\+|\*\*\*) ([^\t\r\n]+)"
+
+    text = ReadAllText(fileName)
+
+    lines = Split(text, vbLf)
+    Do While i <= UBound(lines)
+        line = lines(i)
+        Set ml = re.Execute(line)
+        If ml.count > 0 Then
+            i = i + 1
+            If i <= UBound(lines) Then
+                line = lines(i)
+                Set mr = re.Execute(line)
+                If mr.count > 0 Then
+                    ReDim Preserve ary(n)
+                    ary(n) = Array(ml(0).SubMatches(1), mr(0).SubMatches(1))
+                    n = n + 1
+                End If
+            End If
+        End If
+        i = i + 1
+    Loop
+    GetFileNamesInPatch = ary
+End Function
+
+Function IsLangJapanese()
+    Dim languageId
+    languageId = 1033
+    On Error Resume Next
+    languageId = CLng(wsh.RegRead(REGKEY_PATH & "\Locale\LanguageId"))
+    IsLangJapanese = (languageId = 1041)
+End Function
+
+Function GetStripCountFromCmdLine(cmdLine)
+    Dim re, m
+    Set re = CreateObject("VBScript.RegExp")
+    re.Pattern = "( -p(\d+)| --strip=(\d+))"
+    Set m = re.Execute(cmdLine)
+    If m.count > 0 Then
+        If Not IsEmpty(m(0).SubMatches(1)) Then
+            GetStripCountFromCmdLine = CLng(m(0).SubMatches(1))
+        Else
+            GetStripCountFromCmdLine = CLng(m(0).SubMatches(2))
+        End If
+    Else
+        GetStripCountFromCmdLine = -1
+    End If
+End Function
+
+</script>
+
+<resource id="dialog1">
+<![CDATA[
+<html>
+  <head>
+    <title>ApplyPatch.sct WinMerge Plugin Options</title>
+    <meta content="text/html" charset="Shift_JIS">
+    <style>
+      body { background-color: lightgray; }
+      ul { list-style:none; }
+    </style>
+    <script type="text/javascript">
+      var REGKEY_PATH = "HKCU\\Software\\Thingamahoochie\\WinMerge\\Plugins\\ApplyPatch.sct\\";
+
+      function regRead(key, defaultValue) {
+        try {
+          return (new ActiveXObject("WScript.Shell")).RegRead(key);
+        } catch (e) {
+          return defaultValue;
+        }
+      }
+
+      function regWrite(key, value, type) {
+        (new ActiveXObject("WScript.Shell")).RegWrite(key, value, type);
+      }
+
+      function isLangJapanese() {
+        var languageId = regRead(REGKEY_PATH & "\Locale\LanguageId", 1033);
+        return (languageId = 1041);
+      }
+
+      function onload() {
+
+        var w = 600, h = 400;
+        window.resizeTo(w, h);
+        window.moveTo((screen.width - w) / 2, (screen.height - h) / 2);
+
+        setLanguage();
+      }
+
+      function setLanguage() {
+        var div = document.getElementById("language") || document.createElement('div')
+        div.id = "language";
+        var html = '&shy;<style>';
+        if (isLangJapanese()) {
+          html += '.en { display: none } .ja { display: inline }';
+        } else {
+          html += '.ja { display: none } .en { display: inline }';
+        }
+        div.innerHTML = html;
+        if (!document.getElementById("language"))
+          document.body.appendChild(div);
+      }
+
+      function btnOk_onclick() {
+      }
+
+      function btnCancel_onclick() {
+        window.close();
+      }
+
+    </script>
+  </head>
+  <body onload="onload();">
+    <div>
+      <ul>
+        <li>
+          <input class="en" type="button" onclick="btnOk_onclick();" value="OK" />
+          <input class="en" type="button" onclick="btnCancel_onclick();" value="Cancel" />
+          <input class="ja" type="button" onclick="btnOk_onclick();" value="OK" />
+          <input class="ja" type="button" onclick="btnCancel_onclick();" value="\83L\83\83\83\93\83Z\83\8b" />
+        </li>
+      </ul>
+    </div>
+  </body>
+</html>
+]]>
+</resource>
+
+</scriptlet>