summaryrefslogtreecommitdiff
path: root/l10ntools
diff options
context:
space:
mode:
authorZolnai Tamás <zolnaitamas2000@gmail.com>2012-08-29 09:47:26 +0200
committerAndras Timar <atimar@suse.com>2012-08-29 07:59:36 +0000
commit437ae002185a81802cb31b00fa777a7b5d8f9847 (patch)
treecc117bb7725202b1764dacb174e224e22ff91ebd /l10ntools
parent42688495edac102b18014a02072ba081870059db (diff)
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@suse.com> Tested-by: Andras Timar <atimar@suse.com>
Diffstat (limited to 'l10ntools')
-rw-r--r--l10ntools/Executable_localize.mk9
-rw-r--r--l10ntools/Executable_renewpo.mk36
-rw-r--r--l10ntools/Module_l10ntools.mk1
-rw-r--r--l10ntools/StaticLibrary_transex.mk1
-rw-r--r--l10ntools/inc/po.hxx97
-rw-r--r--l10ntools/source/localize.cxx135
-rw-r--r--l10ntools/source/po.cxx309
-rw-r--r--l10ntools/source/renewpo.cxx168
8 files changed, 717 insertions, 39 deletions
diff --git a/l10ntools/Executable_localize.mk b/l10ntools/Executable_localize.mk
index 511604ac74d2..6184a8982bd5 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 000000000000..33e38b22751f
--- /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@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 e3c11344a0c9..fb2a3b3289e5 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 e8c84b7d3662..21f50e572ef6 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 000000000000..de01053ba217
--- /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 a54d096503df..c10c3f515c0f 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 000000000000..ab926792f70d
--- /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@ADDRESS>" )
+ , m_sLanguageTeam( "LANGUAGE <LL@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 000000000000..c9fad34a99f3
--- /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: */