OSDN Git Service

Currently, for some reason it takes 90 seconds to run UpdatePoFilesFromPotFile.vbs...
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Thu, 9 Apr 2020 00:34:09 +0000 (09:34 +0900)
committerTakashi Sawanaka <sdottaka@users.sourceforge.net>
Thu, 9 Apr 2020 00:34:09 +0000 (09:34 +0900)
Src/MergeLang.vs2017.vcxproj
Src/MergeLang.vs2017.vcxproj.filters
Src/MergeLang.vs2019.vcxproj
Src/MergeLang.vs2019.vcxproj.filters
Translations/WinMerge/UpdatePoFilesFromPotFile.ps1 [new file with mode: 0644]

index 0a69f61..c36efaf 100644 (file)
@@ -81,7 +81,7 @@
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\..\BuildTmp\MergeLang\$(Platform)\$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
   </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+  <ItemDefinitionGroup>
     <PreBuildEvent>
       <Command>
       </Command>
 copy /Y "$(ProjectDir)..\Translations\WinMerge\*.po" "$(OutDir)\Languages\"</Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <PreBuildEvent>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-    <Midl>
-      <TargetEnvironment>X64</TargetEnvironment>
-    </Midl>
-    <PostBuildEvent>
-      <Command>pushd $(ProjectDir)..\Translations\WinMerge
-cscript UpdatePoFilesFromPotFile.vbs
-popd
-mkdir $(OutDir)\Languages\ 2&gt; NUL
-copy /Y "$(ProjectDir)..\Translations\WinMerge\*.po" "$(OutDir)\Languages\"</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <PreBuildEvent>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-    <PostBuildEvent>
-      <Command>pushd $(ProjectDir)..\Translations\WinMerge
-cscript UpdatePoFilesFromPotFile.vbs
-popd
-mkdir $(OutDir)\Languages\ 2&gt; NUL
-copy /Y "$(ProjectDir)..\Translations\WinMerge\*.po" "$(OutDir)\Languages\"
-</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <PreBuildEvent>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-    <Midl>
-      <TargetEnvironment>X64</TargetEnvironment>
-    </Midl>
-    <PostBuildEvent>
-      <Command>pushd $(ProjectDir)..\Translations\WinMerge
-cscript UpdatePoFilesFromPotFile.vbs
-popd
-mkdir $(OutDir)\Languages\ 2&gt; NUL
-copy /Y "$(ProjectDir)..\Translations\WinMerge\*.po" "$(OutDir)\Languages\"</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
   <ItemGroup>
     <CustomBuild Include="Merge.rc">
       <Command>pushd ..\Translations\WinMerge
 
-cscript CreateMasterPotFile.vbs
-cscript UpdatePoFilesFromPotFile.vbs
-popd
-</Command>
-      <Command>pushd ..\Translations\WinMerge
 date /t &gt; MergeLang.lastbuild
 attrib -a English.pot
 del English.pot.prev English.pot.flt English.pot.prev.flt 2&gt; NUL
@@ -157,7 +106,7 @@ findstr /v POT-Creation-Date English.pot.prev &gt; English.pot.prev.flt
 fc English.pot.flt English.pot.prev.flt
 if not errorlevel 1 copy /y English.pot.prev English.pot
 del English.pot.prev English.pot.flt English.pot.prev.flt
-cscript UpdatePoFilesFromPotFile.vbs
+powershell -ExecutionPolicy ByPass -File UpdatePoFilesFromPotFile.ps1
 popd
 </Command>
       <Outputs>$(ProjectDir)..\Translations\WinMerge\MergeLang.lastbuild</Outputs>
@@ -165,9 +114,9 @@ popd
   </ItemGroup>
   <ItemGroup>
     <None Include="..\Translations\WinMerge\CreateMasterPotFile.vbs" />
-    <None Include="..\Translations\WinMerge\UpdatePoFilesFromPotFile.vbs" />
+    <None Include="..\Translations\WinMerge\UpdatePoFilesFromPotFile.ps1" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
index 67e92b3..6b467dd 100644 (file)
@@ -2,19 +2,19 @@
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
   <ItemGroup>\r
     <None Include="..\Translations\WinMerge\CreateMasterPotFile.vbs">\r
-      <Filter>VBS Scripts</Filter>\r
+      <Filter>Scripts</Filter>\r
     </None>\r
-    <None Include="..\Translations\WinMerge\UpdatePoFilesFromPotFile.vbs">\r
-      <Filter>VBS Scripts</Filter>\r
+    <None Include="..\Translations\WinMerge\UpdatePoFilesFromPotFile.ps1">\r
+      <Filter>Scripts</Filter>\r
     </None>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <Filter Include="VBS Scripts">\r
-      <UniqueIdentifier>{51a3b56c-eeee-43c9-a0e7-c2561a2e74fe}</UniqueIdentifier>\r
-    </Filter>\r
     <Filter Include="Resource FIles">\r
       <UniqueIdentifier>{6ed17c4f-f8ad-4783-b08d-accd2076a66b}</UniqueIdentifier>\r
     </Filter>\r
+    <Filter Include="Scripts">\r
+      <UniqueIdentifier>{51a3b56c-eeee-43c9-a0e7-c2561a2e74fe}</UniqueIdentifier>\r
+    </Filter>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <CustomBuild Include="Merge.rc">\r
index 2449fe0..a2bfa5a 100644 (file)
@@ -80,7 +80,7 @@
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\..\BuildTmp\MergeLang\$(Platform)\$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
   </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+  <ItemDefinitionGroup>
     <PreBuildEvent>
       <Command>
       </Command>
 copy /Y "$(ProjectDir)..\Translations\WinMerge\*.po" "$(OutDir)\Languages\"</Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <PreBuildEvent>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-    <Midl>
-      <TargetEnvironment>X64</TargetEnvironment>
-    </Midl>
-    <PostBuildEvent>
-      <Command>pushd $(ProjectDir)..\Translations\WinMerge
-cscript UpdatePoFilesFromPotFile.vbs
-popd
-mkdir $(OutDir)\Languages\ 2&gt; NUL
-copy /Y "$(ProjectDir)..\Translations\WinMerge\*.po" "$(OutDir)\Languages\"</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <PreBuildEvent>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-    <PostBuildEvent>
-      <Command>pushd $(ProjectDir)..\Translations\WinMerge
-cscript UpdatePoFilesFromPotFile.vbs
-popd
-mkdir $(OutDir)\Languages\ 2&gt; NUL
-copy /Y "$(ProjectDir)..\Translations\WinMerge\*.po" "$(OutDir)\Languages\"
-</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <PreBuildEvent>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-    <Midl>
-      <TargetEnvironment>X64</TargetEnvironment>
-    </Midl>
-    <PostBuildEvent>
-      <Command>pushd $(ProjectDir)..\Translations\WinMerge
-cscript UpdatePoFilesFromPotFile.vbs
-popd
-mkdir $(OutDir)\Languages\ 2&gt; NUL
-copy /Y "$(ProjectDir)..\Translations\WinMerge\*.po" "$(OutDir)\Languages\"</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
   <ItemGroup>
     <CustomBuild Include="Merge.rc">
       <Command>pushd ..\Translations\WinMerge
 
-cscript CreateMasterPotFile.vbs
-cscript UpdatePoFilesFromPotFile.vbs
-popd
-</Command>
-      <Command>pushd ..\Translations\WinMerge
 date /t &gt; MergeLang.lastbuild
 attrib -a English.pot
 del English.pot.prev English.pot.flt English.pot.prev.flt 2&gt; NUL
@@ -156,7 +105,7 @@ findstr /v POT-Creation-Date English.pot.prev &gt; English.pot.prev.flt
 fc English.pot.flt English.pot.prev.flt
 if not errorlevel 1 copy /y English.pot.prev English.pot
 del English.pot.prev English.pot.flt English.pot.prev.flt
-cscript UpdatePoFilesFromPotFile.vbs
+powershell -ExecutionPolicy ByPass -File UpdatePoFilesFromPotFile.ps1
 popd
 </Command>
       <Outputs>$(ProjectDir)..\Translations\WinMerge\MergeLang.lastbuild</Outputs>
@@ -164,9 +113,9 @@ popd
   </ItemGroup>
   <ItemGroup>
     <None Include="..\Translations\WinMerge\CreateMasterPotFile.vbs" />
-    <None Include="..\Translations\WinMerge\UpdatePoFilesFromPotFile.vbs" />
+    <None Include="..\Translations\WinMerge\UpdatePoFilesFromPotFile.ps1" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
index 73cf91a..4cf46d2 100644 (file)
@@ -2,19 +2,19 @@
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <None Include="..\Translations\WinMerge\CreateMasterPotFile.vbs">
-      <Filter>VBS Scripts</Filter>
+      <Filter>Scripts</Filter>
     </None>
-    <None Include="..\Translations\WinMerge\UpdatePoFilesFromPotFile.vbs">
-      <Filter>VBS Scripts</Filter>
+    <None Include="..\Translations\WinMerge\UpdatePoFilesFromPotFile.ps1">
+      <Filter>Scripts</Filter>
     </None>
   </ItemGroup>
   <ItemGroup>
-    <Filter Include="VBS Scripts">
-      <UniqueIdentifier>{51a3b56c-eeee-43c9-a0e7-c2561a2e74fe}</UniqueIdentifier>
-    </Filter>
     <Filter Include="Resource FIles">
       <UniqueIdentifier>{6ed17c4f-f8ad-4783-b08d-accd2076a66b}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Scripts">
+      <UniqueIdentifier>{51a3b56c-eeee-43c9-a0e7-c2561a2e74fe}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="Merge.rc">
diff --git a/Translations/WinMerge/UpdatePoFilesFromPotFile.ps1 b/Translations/WinMerge/UpdatePoFilesFromPotFile.ps1
new file mode 100644 (file)
index 0000000..8341e65
--- /dev/null
@@ -0,0 +1,259 @@
+Add-Type -Language CSharp @"
+/**
+* This script updates the language PO files from the master POT file.
+*
+* Copyright (C) 2007-2008 by Tim Gerundt
+* Released under the "GNU General Public License"
+*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
+
+public class PoFileUpdater
+{
+    public static void Main(string[] args)
+    {
+        DateTime startTime = DateTime.Now;
+
+        Console.WriteLine("Updating PO files from POT file...");
+
+        string sDir = Directory.GetCurrentDirectory();
+        string sPotFile = Path.Combine(sDir, "English.pot");
+        var oEnglishPotContent = GetContentFromPoFile(sPotFile);
+        if (oEnglishPotContent.Count == 0)
+        {
+            Console.Error.WriteLine("Error reading content from English.pot");
+            return;
+        }
+        bool bPotChanged = GetArchiveBit(sPotFile);
+        string[] oLanguages = args;
+        if (oLanguages.Length == 0) { oLanguages = Directory.GetFiles(sDir); }
+        foreach (string sLanguage in oLanguages) //For all languages...
+        {
+            if (Path.GetExtension(sLanguage).ToLower() == ".po")
+            {
+                if (bPotChanged || (GetArchiveBit(sLanguage))) //If update necessary...
+                {
+                    Console.WriteLine(sLanguage);
+                }
+                var oLanguagePoContent = GetContentFromPoFile(sLanguage);
+                if (oLanguagePoContent.Count > 0) //If content exists...
+                {
+                    CreateUpdatedPoFile(sLanguage, oEnglishPotContent, oLanguagePoContent);
+                }
+                SetArchiveBit(sLanguage, false);
+            }
+        }
+
+        double seconds = (DateTime.Now - startTime).TotalSeconds;
+        Console.WriteLine("All PO files updated, after " + seconds + " second(s).");
+    }
+
+    ////
+    // ...
+    class CSubContent
+    {
+        public string sMsgCtxt2;
+        public string sMsgId2;
+        public string sMsgStr2;
+        public string sTranslatorComments;
+        public string sExtractedComments;
+        public string sReferences;
+        public string sFlags;
+    }
+
+    ////
+    // ...
+    static IDictionary<string, CSubContent> GetContentFromPoFile(string sPoPath)
+    {
+        var reMsgCtxt = new Regex(@"^msgctxt ""(.*)""", RegexOptions.IgnoreCase);
+        var reMsgId = new Regex(@"^msgid ""(.*)""", RegexOptions.IgnoreCase);
+        var reMsgContinued = new Regex(@"^""(.*)""", RegexOptions.IgnoreCase);
+        var oContent = new Dictionary<string, CSubContent>();
+
+        int iMsgStarted = 0;
+        string sMsgCtxt = "";
+        string sMsgId = "";
+        Match oMatch = null;
+        var oSubContent = new CSubContent();
+        string[] lines = File.ReadAllLines(sPoPath, System.Text.Encoding.UTF8);
+        for (int i = 0; i < lines.Length; i++) //For all lines...
+        {
+            string sLine = lines[i].Trim();
+            if (sLine.Length != 0) //If NOT empty line...
+            {
+                if (sLine.Substring(0, 1) != "#") //If NOT comment line...
+                {
+                    if (reMsgCtxt.IsMatch(sLine)) //If "msgctxt"...
+                    {
+                        iMsgStarted = 1;
+                        oMatch = reMsgCtxt.Match(sLine);
+                        sMsgCtxt = oMatch.Groups[1].Value;
+                        oSubContent.sMsgCtxt2 = sLine + "\n";
+                    }
+                    else if (reMsgId.IsMatch(sLine)) //If "msgid"...
+                    {
+                        iMsgStarted = 2;
+                        oMatch = reMsgId.Match(sLine);
+                        sMsgId = oMatch.Groups[1].Value;
+                        oSubContent.sMsgId2 = sLine + "\n";
+                    }
+                    else if (sLine.Length >= 8 && sLine.Substring(0, 8) == "msgstr \"") //If "msgstr"...
+                    {
+                        iMsgStarted = 3;
+                        oSubContent.sMsgStr2 = sLine + "\n";
+                    }
+                    else if (reMsgContinued.IsMatch(sLine)) //If "msgctxt", "msgid" or "msgstr" continued...
+                    {
+                        if (iMsgStarted == 1)
+                        {
+                            sMsgCtxt = sMsgCtxt + oMatch.Groups[1].Value;
+                            oSubContent.sMsgCtxt2 = oSubContent.sMsgCtxt2 + sLine + "\n";
+                        }
+                        else if (iMsgStarted == 2)
+                        {
+                            oMatch = reMsgContinued.Match(sLine);
+                            sMsgId = sMsgId + oMatch.Groups[1].Value;
+                            oSubContent.sMsgId2 = oSubContent.sMsgId2 + sLine + "\n";
+                        }
+                        else if (iMsgStarted == 3)
+                        {
+                            oSubContent.sMsgStr2 = oSubContent.sMsgStr2 + sLine + "\n";
+                        }
+                    }
+                }
+                else //If comment line...
+                {
+                    iMsgStarted = -1;
+                    string sLeft = (sLine.Length < 2) ? sLine : sLine.Substring(0, 2);
+                    switch (sLeft)
+                    {
+                        case "#~": //Obsolete message...
+                            iMsgStarted = 0;
+                            break;
+                        case "#.": //Extracted comment...
+                            oSubContent.sExtractedComments = oSubContent.sExtractedComments + sLine + "\n";
+                            break;
+                        case "#:": //Reference...
+                            oSubContent.sReferences = oSubContent.sReferences + sLine + "\n";
+                            break;
+                        case "#,": //Flag...
+                            oSubContent.sFlags = oSubContent.sFlags + sLine + "\n";
+                            break;
+                        default: //Translator comment...
+                            oSubContent.sTranslatorComments = oSubContent.sTranslatorComments + sLine + "\n";
+                            break;
+                    }
+                }
+            }
+            else if (iMsgStarted != 0) //If empty line AND there is pending translation...
+            {
+                iMsgStarted = 0; //Don't process same translation twice
+                if (sMsgId == "") { sMsgId = "__head__"; }
+                if (oContent.ContainsKey(sMsgCtxt + sMsgId) == false) //If the key is NOT already used...
+                {
+                    oContent.Add(sMsgCtxt + sMsgId, oSubContent);
+                }
+                sMsgCtxt = "";
+                oSubContent = new CSubContent();
+            }
+        }
+        if (iMsgStarted != 0) //If there is pending translation...
+        {
+            if (oContent.ContainsKey(sMsgCtxt + sMsgId) == false) //If the key is NOT already used...
+            {
+                oContent.Add(sMsgCtxt + sMsgId, oSubContent);
+            }
+        }
+        return oContent;
+    }
+
+    ////
+    // ...
+    static void CreateUpdatedPoFile(string sPoPath, IDictionary<string, CSubContent> oEnglishPotContent, IDictionary<string, CSubContent> oLanguagePoContent)
+    {
+        //--------------------------------------------------------------------------------
+        // Backup the old PO file...
+        //--------------------------------------------------------------------------------
+        string sBakPath = "sPoPath.bak";
+        if (File.Exists(sBakPath))
+        {
+            File.Delete(sBakPath);
+        }
+        File.Move(sPoPath, sBakPath);
+        //--------------------------------------------------------------------------------
+
+        using (var oPoFile = new StreamWriter(sPoPath, false, System.Text.Encoding.UTF8))
+        {
+            var oLanguage = oLanguagePoContent["__head__"];
+            oPoFile.Write(oLanguage.sTranslatorComments);
+            oPoFile.Write(oLanguage.sMsgId2);
+            oPoFile.Write(oLanguage.sMsgStr2);
+            oPoFile.Write("\n");
+            foreach (var sKey in oEnglishPotContent.Keys) //For all English content...
+            {
+                if (sKey != "__head__")
+                {
+                    var oEnglish = oEnglishPotContent[sKey];
+                    if (oLanguagePoContent.ContainsKey(sKey)) //If translation exists...
+                    {
+                        oLanguage = oLanguagePoContent[sKey];
+                    }
+                    else //If translation NOT exists...
+                    {
+                        oLanguage = oEnglish;
+                    }
+                    oPoFile.Write(oLanguage.sTranslatorComments);
+                    oPoFile.Write(oEnglish.sExtractedComments);
+                    oPoFile.Write(oEnglish.sReferences);
+                    oPoFile.Write(oLanguage.sFlags);
+                    oPoFile.Write(oLanguage.sMsgCtxt2);
+                    oPoFile.Write(oLanguage.sMsgId2);
+                    oPoFile.Write(oLanguage.sMsgStr2);
+                    oPoFile.Write("\n");
+                }
+            }
+        }
+    }
+
+    ////
+    // ...
+    static bool GetArchiveBit(string sFilePath)
+    {
+        if (File.Exists(sFilePath)) //If the file exists...
+        {
+            if (File.GetAttributes(sFilePath).HasFlag(FileAttributes.Archive)) //If archive bit set...
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    ////
+    // ...
+    static void SetArchiveBit(string sFilePath, bool bValue)
+    {
+        if (File.Exists(sFilePath)) //If the file exists...
+        {
+            if (File.GetAttributes(sFilePath).HasFlag(FileAttributes.Archive)) //If archive bit set...
+            {
+                if (bValue == false)
+                {
+                    File.SetAttributes(sFilePath, File.GetAttributes(sFilePath) & ~FileAttributes.Archive);
+                }
+            }
+            else //If archive bit NOT set...
+            {
+                if (bValue == true)
+                {
+                    File.SetAttributes(sFilePath, File.GetAttributes(sFilePath) | FileAttributes.Archive);
+                }
+            }
+        }
+    }
+}
+"@
+
+[PoFileUpdater]::Main($args)