[Libreoffice-commits] .: Branch 'feature/killsdf' - l10ntools/Executable_localize.mk l10ntools/Executable_renewpo.mk l10ntools/inc l10ntools/Module_l10ntools.mk l10ntools/source l10ntools/StaticLibrary_transex.mk Repository.mk

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Aug 29 00:59:55 PDT 2012


 Repository.mk                      |    1 
 l10ntools/Executable_localize.mk   |    9 +
 l10ntools/Executable_renewpo.mk    |   36 ++++
 l10ntools/Module_l10ntools.mk      |    1 
 l10ntools/StaticLibrary_transex.mk |    1 
 l10ntools/inc/po.hxx               |   97 +++++++++++
 l10ntools/source/localize.cxx      |  135 +++++++++++-----
 l10ntools/source/po.cxx            |  309 +++++++++++++++++++++++++++++++++++++
 l10ntools/source/renewpo.cxx       |  168 ++++++++++++++++++++
 9 files changed, 718 insertions(+), 39 deletions(-)

New commits:
commit 437ae002185a81802cb31b00fa777a7b5d8f9847
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Wed Aug 29 09:47:26 2012 +0200

    Renew localization and kill sdf 1.step
    
    Extract strings from source directly to pot files
    Implement PoHeader and PoEntry classes
    Renew fomrat of pot/po files
    Implement conversion from old po to new po
    
    Change-Id: I411b6041f7d525e76b189d7f31adc5b9ab60f6d6
    Reviewed-on: https://gerrit.libreoffice.org/506
    Reviewed-by: Andras Timar <atimar at suse.com>
    Tested-by: Andras Timar <atimar at suse.com>

diff --git a/Repository.mk b/Repository.mk
index cadf342..8e58474 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -50,6 +50,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
     rdbmaker \
     regsingleton \
     regsvrex \
+	renewpo \
     rsc \
     rscdep \
     saxparser \
diff --git a/l10ntools/Executable_localize.mk b/l10ntools/Executable_localize.mk
index 511604a..6184a89 100644
--- a/l10ntools/Executable_localize.mk
+++ b/l10ntools/Executable_localize.mk
@@ -26,10 +26,19 @@
 
 $(eval $(call gb_Executable_Executable,localize))
 
+$(eval $(call gb_Executable_set_include,localize,\
+    -I$(SRCDIR)/l10ntools/inc \
+    $$(INCLUDE) \
+))
+
 $(eval $(call gb_Executable_use_libraries,localize,\
     sal \
 ))
 
+$(eval $(call gb_Executable_use_static_libraries,localize,\
+    transex \
+))
+
 $(eval $(call gb_Executable_add_exception_objects,localize,\
     l10ntools/source/localize \
 ))
diff --git a/l10ntools/Executable_renewpo.mk b/l10ntools/Executable_renewpo.mk
new file mode 100644
index 0000000..33e38b2
--- /dev/null
+++ b/l10ntools/Executable_renewpo.mk
@@ -0,0 +1,36 @@
+# for the specific language governing rights and limitations under the
+# License.
+#
+# Major Contributor(s):
+# Copyright (C) 2012 David Ostrovsky <d.ostrovsky at gmx.de> (initial developer)
+#
+# All Rights Reserved.
+#
+# For minor contributions see the git repository.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_Executable_Executable,renewpo))
+
+$(eval $(call gb_Executable_set_include,renewpo,\
+    -I$(SRCDIR)/l10ntools/inc \
+    $$(INCLUDE) \
+))
+
+$(eval $(call gb_Executable_use_libraries,renewpo,\
+    sal \
+))
+
+$(eval $(call gb_Executable_use_static_libraries,renewpo,\
+    transex \
+))
+
+$(eval $(call gb_Executable_add_exception_objects,renewpo,\
+    l10ntools/source/renewpo \
+))
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/l10ntools/Module_l10ntools.mk b/l10ntools/Module_l10ntools.mk
index e3c1134..fb2a3b3 100644
--- a/l10ntools/Module_l10ntools.mk
+++ b/l10ntools/Module_l10ntools.mk
@@ -38,6 +38,7 @@ $(eval $(call gb_Module_add_targets,l10ntools,\
     Executable_transex3 \
     Executable_helpindexer \
     Executable_helplinker \
+    Executable_renewpo \
     StaticLibrary_transex \
     Library_helplinker \
     Package_inc \
diff --git a/l10ntools/StaticLibrary_transex.mk b/l10ntools/StaticLibrary_transex.mk
index e8c84b7..21f50e5 100644
--- a/l10ntools/StaticLibrary_transex.mk
+++ b/l10ntools/StaticLibrary_transex.mk
@@ -37,6 +37,7 @@ $(eval $(call gb_StaticLibrary_add_exception_objects,transex,\
     l10ntools/source/merge \
     l10ntools/source/file \
     l10ntools/source/directory \
+	l10ntools/source/po \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/l10ntools/inc/po.hxx b/l10ntools/inc/po.hxx
new file mode 100644
index 0000000..de01053
--- /dev/null
+++ b/l10ntools/inc/po.hxx
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PO_INCLUDED
+#define _PO_INCLUDED
+
+#include <fstream>
+#include <rtl/string.hxx>
+
+class PoEntry
+{
+
+private:
+
+    OString    m_sWhiteSpace;
+    OString    m_sExtractCom;
+    OString    m_sReference;
+    OString    m_sContext;
+    OString    m_sUnTransStr;
+    OString    m_sTransStr;
+
+    OString    m_sKeyId;
+
+protected:
+    void            setExtractCom(const OString& rExtCom)
+                    { m_sExtractCom = rExtCom; }
+
+public:
+                    PoEntry();
+                    PoEntry(const OString& i_rSDFLine,
+                            const sal_uInt16 eType = TEXT);
+    virtual         ~PoEntry();
+
+    virtual void    writeToFile(std::ofstream& io_rOFStream);
+
+    void            setTransStr(const OString& rTransStr);
+
+    enum SDFPARTS { PROJECT, SOURCEFILE, DUMMY, RESOURCETYPE, GROUPID,
+                    LOCALID, HELPID, PLATFORM, WIDTH, LANGUAGEID,
+                    TEXT, HELPTEXT, QUICKHELPTEXT, TITLE, TIMESTAMP };
+};
+
+
+
+
+class PoHeader: public PoEntry
+{
+
+private:
+    OString    m_sExtractionSource;
+    OString    m_sProjectIdVersion;
+    OString    m_sReportMsgidBugsTo;
+    OString    m_sPotCreationDate;
+    OString    m_sPoRevisionDate;
+    OString    m_sLastTranslator;
+    OString    m_sLanguageTeam;
+    OString    m_sMimeVersion;
+    OString    m_sPluralForms;
+    OString    m_sContentType;
+    OString    m_sCharset;
+    OString    m_sEncoding;
+    OString    m_sXGenerator;
+    OString    m_sXAcceleratorMarker;
+
+public:
+                    PoHeader( const OString& rExtSrc );
+                    ~PoHeader();
+};
+
+#endif // _PO_INCLUDED
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/l10ntools/source/localize.cxx b/l10ntools/source/localize.cxx
index a54d096..c10c3f5 100644
--- a/l10ntools/source/localize.cxx
+++ b/l10ntools/source/localize.cxx
@@ -50,16 +50,12 @@
 #include "sal/main.h"
 #include "sal/types.h"
 
+#include "po.hxx"
+
 using namespace std;
 
 namespace {
 
-namespace global {
-
-std::ofstream output;
-
-}
-
 rtl::OUString getEnvironment(rtl::OUString const & variable) {
     rtl::OUString value;
     if (osl_getEnvironment(variable.pData, &value.pData) != osl_Process_E_None)
@@ -174,7 +170,8 @@ bool passesPositiveList(rtl::OUString const & url) {
 
 void handleCommand(
     rtl::OUString const & project, rtl::OUString const & projectRoot,
-    rtl::OUString const & url, rtl::OUString const & executable, bool positive)
+    rtl::OUString const & url, rtl::OUString const & actualDir,
+    std::ofstream & outPut, rtl::OUString const & executable, bool positive)
 {
     if (positive ? passesPositiveList(url) : passesNegativeList(url)) {
         rtl::OUString inPath;
@@ -197,13 +194,13 @@ void handleCommand(
             throw false; //TODO
         }
         rtl::OUStringBuffer buf(
-            getEnvironment(
-                rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SOLARVER"))));
-        buf.append('/');
-        buf.append(
-            getEnvironment(
-                rtl::OUString(
-                    RTL_CONSTASCII_USTRINGPARAM("INPATH_FOR_BUILD"))));
+            //getEnvironment(
+                //rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SOLARVER"))));
+        //buf.append('/');
+        //buf.append(
+            //getEnvironment(
+                rtl::OUString("/home/zolnai/git/libo/solver/unxlngi6.pro"));
+                   // RTL_CONSTASCII_USTRINGPARAM("INPATH_FOR_BUILD"))));
         buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("/bin/"));
         buf.append(executable);
         buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(" -e -p "));
@@ -239,23 +236,70 @@ void handleCommand(
         }
         std::ifstream in(outPath8.getStr());
         if (!in.is_open()) {
-            std::cerr << "Error: Cannot open " << outPath.getStr() << "\n";
+            std::cerr << "Error: Cannot open " << outPath8.getStr() << "\n";
             throw false; //TODO
         }
+
+        std::string s;
+        std::getline(in, s);
+        if (!in.eof() && !outPut.is_open())
+        {
+            rtl::OUString outDirUrl;
+            if (osl::FileBase::getFileURLFromSystemPath(actualDir.
+                copy(0,actualDir.lastIndexOf('/')), outDirUrl)
+                != osl::FileBase::E_None)
+            {
+                std::cerr << "Error: Cannot convert pathname to URL\n";
+                throw false; //TODO
+            }
+            osl::Directory::createPath(outDirUrl);
+
+            rtl::OString outFilePath;
+            if (!actualDir.concat(".pot").
+                convertToString(
+                &outFilePath, osl_getThreadTextEncoding(),
+                (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+                | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+            {
+                std::cerr << "Error: Cannot convert pathname from UTF-16\n";
+                throw false; //TODO
+            }
+            outPut.open(outFilePath.getStr(),
+                        std::ios_base::out | std::ios_base::trunc);
+            rtl::OString relativPath;
+            if (!inPath.copy(inPath.indexOf(project),
+                inPath.lastIndexOf('/')-inPath.indexOf(project)).
+                convertToString(&relativPath, osl_getThreadTextEncoding(),
+                (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+                | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+            {
+                std::cerr << "Error: Cannot convert pathname from UTF-16\n";
+                throw false; //TODO
+            }
+            PoHeader(relativPath).writeToFile(outPut);
+        }
         while (!in.eof())
         {
-            std::string s;
+            OString sLine = OString(s.data(),s.length());
+            if (!sLine.isEmpty())
+            {
+                if (!sLine.getToken(PoEntry::TEXT,'\t').isEmpty())
+                    PoEntry(sLine).writeToFile(outPut);
+                if (!sLine.getToken(PoEntry::QUICKHELPTEXT,'\t').isEmpty())
+                    PoEntry(sLine,PoEntry::QUICKHELPTEXT).writeToFile(outPut);
+                if (!sLine.getToken(PoEntry::TITLE,'\t').isEmpty())
+                    PoEntry(sLine,PoEntry::TITLE).writeToFile(outPut);
+            }
             std::getline(in, s);
-            if (!s.empty())
-                global::output << s << '\n';
-        }
+        };
         in.close();
     }
 }
 
 void handleFile(
     rtl::OUString const & project, rtl::OUString const & projectRoot,
-    rtl::OUString const & url)
+    rtl::OUString const & url, rtl::OUString const & actualDir,
+    std::ofstream &  outPut)
 {
     struct Command {
         char const * extension;
@@ -277,7 +321,7 @@ void handleFile(
                 commands[i].extension, commands[i].extensionLength))
         {
             handleCommand(
-                project, projectRoot, url,
+                project, projectRoot, url, actualDir, outPut,
                 rtl::OUString::createFromAscii(commands[i].executable),
                 commands[i].positive);
             break;
@@ -386,8 +430,9 @@ bool excludeDirectory(rtl::OUString const & directory) {
 /// level <= 0)
 void handleDirectory(
     rtl::OUString const & url, int level, rtl::OUString const & project,
-    rtl::OUString const & projectRoot)
+    rtl::OUString const & projectRoot, rtl::OUString const & actualDir)
 {
+    std::ofstream output;
     osl::Directory dir(url);
     if (dir.open() != osl::FileBase::E_None) {
         std::cerr
@@ -417,7 +462,8 @@ void handleDirectory(
         case -1: // the clone or src directory
             if (stat.getFileType() == osl::FileStatus::Directory) {
                 handleDirectory(
-                    stat.getFileURL(), 0, rtl::OUString(), rtl::OUString());
+                    stat.getFileURL(), 0, rtl::OUString(),
+                    rtl::OUString(), actualDir);
             }
             break;
         case 0: // a root directory
@@ -425,12 +471,14 @@ void handleDirectory(
                 if (includeProject(stat.getFileName())) {
                     handleDirectory(
                         stat.getFileURL(), 1, stat.getFileName(),
-                        rtl::OUString());
-                } else if ( stat.getFileName() == "clone" || stat.getFileName() == "src" )
+                        rtl::OUString(), actualDir.concat("/").
+                        concat(stat.getFileName()));
+                } else if ( stat.getFileName() == "clone" ||
+                            stat.getFileName() == "src" )
                 {
                     handleDirectory(
                         stat.getFileURL(), -1, rtl::OUString(),
-                        rtl::OUString());
+                        rtl::OUString(), actualDir);
                 }
             }
             break;
@@ -442,24 +490,29 @@ void handleDirectory(
                         pr += rtl::OUString('/');
                     }
                     pr += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".."));
-                    handleDirectory(stat.getFileURL(), 2, project, pr);
+                    handleDirectory(stat.getFileURL(), 2, project, pr,
+                                    actualDir.concat("/").
+                                    concat(stat.getFileName()));
                 }
             } else {
-                handleFile(project, projectRoot, stat.getFileURL());
+                handleFile(project, projectRoot,
+                           stat.getFileURL(), actualDir, output);
             }
             break;
         }
     }
+    if (output.is_open())
+        output.close();
     if (dir.close() != osl::FileBase::E_None) {
         std::cerr << "Error: Cannot close directory\n";
         throw false; //TODO
     }
 }
 
-void handleProjects(char const * root) {
+void handleProjects(char const * sourceRoot, char const * destRoot) {
     rtl::OUString root16;
     if (!rtl_convertStringToUString(
-            &root16.pData, root, rtl_str_getLength(root),
+            &root16.pData, sourceRoot, rtl_str_getLength(sourceRoot),
             osl_getThreadTextEncoding(),
             (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
              | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
@@ -475,9 +528,19 @@ void handleProjects(char const * root) {
         std::cerr << "Error: Cannot convert pathname to URL\n";
         throw false; //TODO
     }
-    handleDirectory(rootUrl, 0, rtl::OUString(), rtl::OUString());
+    rtl::OUString outPutRoot;
+    if (!rtl_convertStringToUString(
+            &outPutRoot.pData, destRoot, rtl_str_getLength(destRoot),
+            osl_getThreadTextEncoding(),
+            (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+             | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+             | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
+    {
+        std::cerr << "Error: Cannot convert pathname to UTF-16\n";
+        throw false; //TODO
+    }
+    handleDirectory(rootUrl, 0, rtl::OUString(), rtl::OUString(), outPutRoot);
 }
-
 }
 
 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) {
@@ -490,17 +553,11 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) {
                 "Syntax: localize <source-root> <outfile>\n");
         std::exit(EXIT_FAILURE);
     }
-    global::output.open(argv[2], std::ios_base::out | std::ios_base::trunc);
-    if (!global::output.is_open()) {
-        std::cerr << "Error: Cannot append to " << argv[2] << '\n';
-        std::exit(EXIT_FAILURE);
-    }
     try {
-        handleProjects(argv[1]);
+        handleProjects(argv[1],argv[2]);
     } catch (bool) { //TODO
         return EXIT_FAILURE;
     }
-    global::output.close();
     return EXIT_SUCCESS;
 }
 
diff --git a/l10ntools/source/po.cxx b/l10ntools/source/po.cxx
new file mode 100644
index 0000000..ab92679
--- /dev/null
+++ b/l10ntools/source/po.cxx
@@ -0,0 +1,309 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "po.hxx"
+#include <ctime>
+#include <vector>
+
+#define ESCAPED OString("\\n\\t\\r\\\\\\\"")
+#define UNESCAPED OString("\n\t\r\\\"")
+
+
+//Get actual time in "YEAR-MO-DA HO:MI+ZONE" form
+OString ImplGetTime()
+{
+    time_t aNow(time(NULL));
+    struct tm* pNow(localtime(&aNow));
+    char pBuff[50];
+    strftime( pBuff, sizeof pBuff, "%Y-%m-%d %H:%M%z", pNow );
+    return pBuff;
+}
+
+//Split string at the delimiter char
+void ImplSplitAt(const OString& rSource, const sal_Int32 nDelimiter,
+                 std::vector<OString>& o_vParts)
+{
+    o_vParts.resize( 0 );
+    sal_Int32 nActIndex( 0 );
+    sal_Int32 nLastSplit( 0 );
+    while( nActIndex < rSource.getLength() )
+    {
+        if ( rSource[nActIndex] == nDelimiter )
+        {
+            o_vParts.push_back(rSource.copy(nLastSplit,nActIndex-nLastSplit));
+            nLastSplit = nActIndex+1;
+        }
+        ++nActIndex;
+    }
+    o_vParts.push_back(rSource.copy(nLastSplit));
+}
+
+//Escape text
+OString ImplEscapeText(const OString& rText, const OString& rUnEscaped,
+                       const OString& rEscaped)
+{
+    if(rEscaped.getLength()!=2*rUnEscaped.getLength()) throw;
+    OString sResult = rText;
+    sal_Int32 nCount = 0;
+    for(sal_Int32 nIndex=0; nIndex<rText.getLength(); ++nIndex)
+    {
+        sal_Int32 nActChar = rUnEscaped.indexOf(rText[nIndex]);
+        if(nActChar!=-1)
+            sResult = sResult.replaceAt((nIndex)+(nCount++),1,
+                                        rEscaped.copy(2*nActChar,2));
+    }
+    return sResult;
+}
+
+
+//Escape text to write to po files
+OString ImplEscapeText(const OString& rText)
+{
+    return ImplEscapeText(rText,UNESCAPED,ESCAPED);
+}
+
+//Unescape text
+OString ImplUnEscapeText(const OString& rText,const OString& rEscaped,
+                       const OString& rUnEscaped)
+{
+    if(rEscaped.getLength()!=2*rUnEscaped.getLength()) throw;
+    OString sResult = rText;
+    sal_Int32 nCount = 0;
+    for(sal_Int32 nIndex=0; nIndex<rText.getLength()-1; ++nIndex)
+    {
+        sal_Int32 nActChar = rEscaped.indexOf(rText.copy(nIndex,2));
+        if(nActChar % 2 == 0)
+            sResult = sResult.replaceAt((nIndex++)-(nCount++),2,
+                                        rUnEscaped.copy(nActChar/2,1));
+    }
+    return sResult;
+}
+
+//Unescape text from po files
+OString ImplUnEscapeText(const OString& rText)
+{
+    return ImplUnEscapeText(rText,ESCAPED,UNESCAPED);
+}
+
+//Unescape extracted helptext
+OString ImplFromSDFHelpText(const OString& rText)
+{
+    return ImplUnEscapeText(rText,"\\<\\>\\\"\\\\","<>\"\\");
+}
+
+//Unescape extracted text
+OString ImplFromSDFText(const OString& rText)
+{
+    return ImplUnEscapeText(rText,"\\n\\t\\r","\n\t\r");
+}
+
+
+//Generate msgctxt, msgid and msgstr strings
+OString ImplGenMsgString(const OString& rSource)
+{
+    if ( rSource.isEmpty() )
+        return "\"\"";
+
+    OString sResult = "\"" + rSource + "\"";
+    sal_Int32 nIndex = 0;
+    while((nIndex=sResult.indexOf("\\n",nIndex))!=-1)
+    {
+        if( sResult.copy(nIndex-1,3) != "\\\\n" )
+           sResult = sResult.replaceAt(nIndex,2,"\\n\"\n\"");
+        ++nIndex;
+    }
+
+    if ( sResult.indexOf('\n') != -1 )
+        return "\"\"\n" +  sResult;
+
+    return sResult;
+}
+
+//Generate crc24
+sal_Int32 ImplGenCRC24(const OString& rKey)
+{
+    const sal_Int32 CRC24_INIT = 0x00b704ce;
+    const sal_Int32 CRC24_POLY = 0x00864cfb;
+    sal_Int32 nCRC = CRC24_INIT;
+    sal_Int32 nPosition = 0;
+
+    while ( nPosition < rKey.getLength() )
+    {
+        nCRC ^= sal_Int32(rKey[nPosition]) << 16;
+        for (sal_uInt16 i = 0; i < 8; ++i)
+        {
+            nCRC <<= 1;
+            if (nCRC & 0x01000000)
+                nCRC ^= CRC24_POLY;
+        }
+        ++nPosition;
+    }
+    return nCRC & 0x00ffffff;
+}
+
+//Generate KeyId
+OString ImplGenKeyId(const OString& rSourcePath, const OString& rContext)
+{
+    std::vector<OString> vPathParts;
+    ImplSplitAt(rSourcePath,'\\',vPathParts);
+    if ( vPathParts.size()<3 ) throw;
+
+    sal_Int32 nCRC = ImplGenCRC24(  vPathParts[vPathParts.size()-3] + "_" +
+                                    vPathParts[vPathParts.size()-2] + "_" +
+                                    vPathParts[vPathParts.size()-1] + "_" +
+                                    rContext);
+    const OString sSymbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#_";
+    OString sKeyId = "";
+    while ( sKeyId.getLength() < 4 )
+    {
+        sKeyId += sSymbols.copy(nCRC & 63, 1);
+        nCRC >>= 6;
+    }
+    return sKeyId;
+}
+
+//Default constructor
+PoEntry::PoEntry()
+    : m_sWhiteSpace( OString() )
+    , m_sExtractCom( OString() )
+    , m_sReference( OString() )
+    , m_sContext( OString() )
+    , m_sUnTransStr( OString() )
+    , m_sTransStr( OString() )
+    , m_sKeyId( OString() )
+{
+}
+
+//Construct PoEntry from sdfline
+PoEntry::PoEntry(const OString& rSDFLine, const sal_uInt16 eType)
+    : m_sWhiteSpace( "\n" )
+    , m_sExtractCom( OString() )
+    , m_sTransStr( OString() )
+    , m_sKeyId( OString() )
+{
+    std::vector<OString> vParts;
+    ImplSplitAt(rSDFLine,'\t',vParts);
+    if(vParts.size()!=15) throw;
+
+    m_sReference = vParts[SOURCEFILE].
+                   copy(vParts[SOURCEFILE].lastIndexOf("\\")+1);
+    m_sContext = vParts[GROUPID] + "\\n" +
+                 (vParts[LOCALID].isEmpty()? "" : vParts[LOCALID] + "\\n") +
+                 vParts[RESOURCETYPE];
+
+    switch(eType){
+    case TEXT:
+        m_sContext += ".text"; break;
+    case QUICKHELPTEXT:
+        m_sContext += ".quickhelptext"; break;
+    case TITLE:
+        m_sContext += ".title"; break;
+    default:
+        throw; break;
+    }
+    if (m_sReference.endsWith(".xhp"))
+        m_sUnTransStr = ImplFromSDFHelpText(vParts[eType]);
+    else
+        m_sUnTransStr = ImplFromSDFText(vParts[eType]);
+
+    m_sExtractCom = vParts[HELPTEXT];
+    m_sKeyId = ImplGenKeyId(vParts[PROJECT] +
+               "\\" + vParts[SOURCEFILE],m_sContext);
+}
+
+PoEntry::~PoEntry()
+{
+}
+
+//Write out
+void PoEntry::writeToFile(std::ofstream& io_rOFStream)
+{
+    if ( !m_sWhiteSpace.isEmpty() )
+        io_rOFStream << m_sWhiteSpace.getStr();
+    if ( !m_sExtractCom.isEmpty() )
+        io_rOFStream << "#. " << m_sExtractCom.getStr() << std::endl;
+    if ( !m_sKeyId.isEmpty() )
+        io_rOFStream << "#. " << m_sKeyId.getStr() << std::endl;
+    if ( !m_sReference.isEmpty() )
+        io_rOFStream << "#: " << m_sReference.getStr() << std::endl;
+    if ( !m_sContext.isEmpty() )
+        io_rOFStream << "msgctxt "
+                     << ImplGenMsgString(m_sContext).getStr() << std::endl;
+        io_rOFStream << "msgid "
+                     << ImplGenMsgString(
+                            ImplEscapeText(m_sUnTransStr)).getStr()
+                     << std::endl;
+        io_rOFStream << "msgstr "
+                     << ImplGenMsgString(
+                            ImplEscapeText(m_sTransStr)).getStr()
+                     << std::endl;
+}
+
+void PoEntry::setTransStr(const OString& rTransStr)
+{
+    m_sTransStr = ImplUnEscapeText(rTransStr);
+}
+
+//Constructor
+PoHeader::PoHeader( const OString& rExtSrc )
+    : m_sExtractionSource( rExtSrc )
+    , m_sProjectIdVersion( "PACKAGE VERSION" )
+    , m_sReportMsgidBugsTo( OString("https://bugs.freedesktop.org/") +
+                            "enter_bug.cgi?product=LibreOffice&" +
+                            "bug_status=UNCONFIRMED&component=UI" )
+    , m_sPotCreationDate( ImplGetTime() )
+    , m_sPoRevisionDate( "YEAR-MO-DA HO:MI+ZONE" )
+    , m_sLastTranslator( "FULL NAME <EMAIL at ADDRESS>" )
+    , m_sLanguageTeam( "LANGUAGE <LL at li.org>" )
+    , m_sMimeVersion( "1.0" )
+    , m_sContentType( "text/plain" )
+    , m_sCharset( "UTF-8" )
+    , m_sEncoding( "8bit" )
+    , m_sXGenerator( "LibreOffice" )
+    , m_sXAcceleratorMarker( "~" )
+{
+    setExtractCom("extracted from " + rExtSrc);
+    setTransStr("Project-Id-Version: " + m_sProjectIdVersion + "\n" +
+                "Report-Msgid-Bugs-To: " + m_sReportMsgidBugsTo + "\n" +
+                "POT-Creation-Date: " + m_sPotCreationDate + "\n" +
+                "PO-Revision-Date: " + m_sPoRevisionDate + "\n" +
+                "Last-Translator: " + m_sLastTranslator + "\n" +
+                "Language-Team: " + m_sLanguageTeam + "\n" +
+                "MIME-Version: " + m_sMimeVersion + "\n" +
+                "Content-Type: " + m_sContentType + "; " +
+                "charset=" + m_sCharset + "\n" +
+                "Content-Transfer-Encoding: " + m_sEncoding + "\n" +
+                "X-Genarator: " + m_sXGenerator + "\n" +
+                "X-Accelerator_Marker: " + m_sXAcceleratorMarker + "\n");
+}
+
+PoHeader::~PoHeader()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/l10ntools/source/renewpo.cxx b/l10ntools/source/renewpo.cxx
new file mode 100644
index 0000000..c9fad34
--- /dev/null
+++ b/l10ntools/source/renewpo.cxx
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <iostream>
+#include <fstream>
+#include <dirent.h>
+#include <string>
+#include <rtl/string.hxx>
+#include "po.hxx"
+
+using namespace std;
+
+//Check wheather the two entry are the same but in different languages
+bool IsSameEntry(const OString& rFirstEntry,const OString& rSecEntry)
+{
+    for(int i = PoEntry::PROJECT; i<=PoEntry::LOCALID;++i)
+    {
+        if ( rFirstEntry.getToken(i,'\t') != rSecEntry.getToken(i,'\t'))
+            return false;
+    }
+    return true;
+}
+
+//Get path of po file
+OString GetPath(const OString& rPath, const OString& rLine)
+{
+    OString sSourceFile = rLine.getToken(PoEntry::SOURCEFILE,'\t');
+    OString sSourcePath = rPath + "/" +
+                          rLine.getToken(PoEntry::PROJECT,'\t') + "/" +
+                          sSourceFile.copy(0,sSourceFile.lastIndexOf("\\")).
+                                      replaceAll("\\","/");
+    return sSourcePath;
+}
+
+//Renew po files of the actual language
+void HandleLanguage(struct dirent* pLangEntry, const OString& rPath,
+                    const OString& rpo2ooPath, const OString& rSDFPath)
+{
+    const OString LangEntryName = pLangEntry->d_name;
+    const OString SDFFileName = LangEntryName + ".sdf";
+
+    //Generate and open sdf
+    cout << "Start process with language: " <<  LangEntryName.getStr() << endl;
+    system( (rpo2ooPath + " -t " + rSDFPath +
+            " -l " + LangEntryName + " " +
+            rPath.getStr() + LangEntryName + " " +
+            SDFFileName).getStr());
+
+    ofstream aOutPut;
+    ifstream aSDFInput(SDFFileName.getStr());
+    string s;
+    getline(aSDFInput,s);
+    OString sLine = OString(s.data(),s.length());
+    while(!aSDFInput.eof())
+    {
+        OString sActUnTrans = sLine;
+        OString sPath = rPath + LangEntryName;
+        OString sActSourcePath = GetPath(sPath,sActUnTrans);
+        //Make new po file, copy header with some changes
+        if (!aOutPut.is_open())
+        {
+            aOutPut.open((sActSourcePath + ".po_tmp").getStr(),
+                         std::ios_base::out | std::ios_base::trunc);
+            ifstream aPOInput((sActSourcePath + ".po").getStr());
+            getline(aPOInput,s);
+            while(s!="")
+            {
+                if (s.find("#. extracted from")!=string::npos)
+                    s = string(s,0,s.length()-3);
+                if (s.find("Report-Msgid-Bugs-To")!=string::npos)
+                    s = string("\"Report-Msgid-Bugs-To: ") +
+                        "https://bugs.freedesktop.org/enter_bug.cgi?product=" +
+                        "LibreOffice&bug_status=UNCONFIRMED&component=UI\\n\"";
+                if (s.find("X-Generator")!=string::npos)
+                    s = "\"X-Generator: LibreOffice\\n\"";
+                aOutPut << s << endl;
+                getline(aPOInput,s);
+            };
+            aPOInput.close();
+        }
+
+        //Set PoEntry and write out
+        getline(aSDFInput,s);
+        sLine = OString(s.data(),s.length());
+        OString sActTrans;
+        if (IsSameEntry(sActUnTrans,sLine))
+        {
+            sActTrans = sLine;
+            getline(aSDFInput,s);
+            sLine = OString(s.data(),s.length());
+        }
+        else
+        {
+            sActTrans ="";
+        }
+        PoEntry aPE(sActUnTrans);
+        aPE.setTransStr(sActTrans.getToken(PoEntry::TEXT,'\t'));
+        aPE.writeToFile(aOutPut);
+
+        //Check wheather next entry is in the same po file
+        OString sNextSourcePath = GetPath(sPath,sLine);
+        if (sNextSourcePath!=sActSourcePath)
+        {
+            aOutPut.close();
+            system(("rm " + sActSourcePath +".po").getStr());
+            system(("mv "+ sActSourcePath +".po_tmp " +
+                    sActSourcePath +".po").getStr());
+        }
+    }
+
+    //Close and remove sdf file
+    aSDFInput.close();
+    system(("rm " + SDFFileName).getStr());
+    aOutPut.close();
+}
+
+
+int main(int argc, char* argv[])
+{
+    //Usage
+    if (argc < 4)
+    {
+        cout << "Use: renewpot translationsdir po2oo en-us.sdf" << endl;
+        cout << "translationsdir: in this dir there are language" << endl;
+        cout << "directories which contain the po files. These" << endl;
+        cout << "directories have named by the languageid" << endl;
+        cout << "po2oo: the path withwhich po2oo can be call" << endl;
+        cout << "en-us.sdf: the path to call po2oo with this sdf" << endl;
+        return 1;
+    }
+
+    //Call processing function with all language directories
+    DIR* pTranslations = opendir(argv[1]);
+    while ( struct dirent* pActEntry = readdir(pTranslations) )
+    {
+        if ( OString(pActEntry->d_name).indexOf('.')==-1 )
+            HandleLanguage(pActEntry,OString(argv[1]),
+                           OString(argv[2]),OString(argv[3]));
+    }
+    closedir(pTranslations);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list