summaryrefslogtreecommitdiff
path: root/l10ntools/source/renewpo.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'l10ntools/source/renewpo.cxx')
-rw-r--r--l10ntools/source/renewpo.cxx231
1 files changed, 231 insertions, 0 deletions
diff --git a/l10ntools/source/renewpo.cxx b/l10ntools/source/renewpo.cxx
new file mode 100644
index 000000000000..a9f3321d2c4b
--- /dev/null
+++ b/l10ntools/source/renewpo.cxx
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <iostream>
+#include <fstream>
+#include <dirent.h>
+#include <string>
+#include <vector>
+#include <map>
+
+#include <osl/file.hxx>
+#include <rtl/string.hxx>
+
+#include "po.hxx"
+
+using namespace std;
+
+bool isInSameFile( const OString& rFirstLine, const OString& rSecondLine)
+{
+ const OString rFirstSource =
+ rFirstLine.getToken(PoEntry::SOURCEFILE,'\t');
+ const OString rSecondSource =
+ rSecondLine.getToken(PoEntry::SOURCEFILE,'\t');
+ return
+ rFirstSource.copy(0,rFirstSource.lastIndexOf("\\")) ==
+ rSecondSource.copy(0,rSecondSource.lastIndexOf("\\"));
+}
+
+
+//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;
+}
+
+OString DelLocalId(const OString& rLine)
+{
+ unsigned nTabIndex = 0;
+ for(unsigned nComponent=0; nComponent<PoEntry::LOCALID; ++nComponent)
+ {
+ nTabIndex = rLine.indexOf('\t',nTabIndex);
+ ++nTabIndex;
+ }
+ return rLine.replaceAt(nTabIndex,
+ rLine.indexOf('\t',nTabIndex)-nTabIndex,
+ "");
+}
+
+//Renew po files of the actual language
+void HandleLanguage(struct dirent* pLangEntry, const OString& rOldPath,
+ const OString& rNewPath, const OString& rpo2loPath,
+ const OString& rSDFPath)
+{
+ const OString LangEntryName = pLangEntry->d_name;
+
+ //Generate and open sdf
+ cout << "Process start with language: " << LangEntryName.getStr() << endl;
+ OUString aTempUrl;
+ if (osl::FileBase::createTempFile(0, 0, &aTempUrl)
+ != osl::FileBase::E_None)
+ {
+ cerr << "osl::FileBase::createTempFile() failed\n";
+ return;
+ }
+ OUString aTempPath;
+ if (osl::FileBase::getSystemPathFromFileURL(aTempUrl, aTempPath)
+ != osl::FileBase::E_None)
+ {
+ cerr
+ << "osl::FileBase::getSystemPathFromFileURL(" << aTempUrl
+ << ") failed\n";
+ return;
+ }
+ const OString SDFFileName =
+ OUStringToOString(aTempPath, RTL_TEXTENCODING_UTF8);
+ system( (rpo2loPath +
+ " -i " + rOldPath + "/" + LangEntryName +
+ " -o " + SDFFileName +
+ " -l " + LangEntryName +
+ " -t " + rSDFPath).getStr());
+ cout << "Language sdf is ready!" << endl;
+
+ //Store info for po entries
+ ifstream aSDFInput(SDFFileName.getStr());
+ map<sal_Int32,pair<OString,OString> > aPoInfos;
+ string s;
+ getline(aSDFInput,s);
+ while(!aSDFInput.eof())
+ {
+ //Get strings belong to one po entry and store
+ const OString sActUnTrans = OString(s.data(),s.length());
+ if( sActUnTrans.getToken(PoEntry::LANGUAGEID,'\t')=="ast" ) throw;
+ getline(aSDFInput,s);
+ const OString sActTrans = OString(s.data(),s.length());
+
+ if(!(aPoInfos.insert( pair<sal_Int32,pair<OString,OString> >(
+ sActTrans.getToken(PoEntry::WIDTH,'\t').toInt32(),
+ pair<OString,OString>(sActUnTrans,sActTrans))).second))
+ {
+ cerr << "Error: faild to insert into map!" << '\n';
+ throw;
+ }
+ getline(aSDFInput,s);
+ }
+
+ //Close and remove sdf file
+ aSDFInput.close();
+ if (osl::File::remove(aTempUrl) != osl::FileBase::E_None)
+ {
+ cerr << "Warning: failure removing temporary " << aTempUrl << '\n';
+ }
+
+ //Construct and write out po entries
+ PoOfstream aNewPo;
+ for( map<sal_Int32,pair<OString,OString> >::iterator
+ pActInfo=aPoInfos.begin(); pActInfo!=aPoInfos.end(); ++pActInfo )
+ {
+ //Make new po file and add header
+ if ( pActInfo==aPoInfos.begin() ||
+ !isInSameFile(((--pActInfo)++)->second.first,pActInfo->second.first) )
+ {
+ if( pActInfo!=aPoInfos.begin() )
+ aNewPo.close();
+
+ const OString sNewPoFileName =
+ GetPath(rNewPath + "/" +LangEntryName,pActInfo->second.first) +
+ ".po";
+ system(("mkdir -p " + sNewPoFileName.copy(0,sNewPoFileName.lastIndexOf("/"))).getStr());
+ aNewPo.open(sNewPoFileName);
+ if (!aNewPo.isOpen())
+ {
+ cerr
+ << "Cannot open new po file: "
+ << sNewPoFileName.getStr() << endl;
+ return;
+ }
+ const OString sOldPoFileName =
+ GetPath(rOldPath + "/" +LangEntryName,pActInfo->second.first) +
+ ".po";
+ ifstream aOldPo(sOldPoFileName.getStr());
+ if (!aOldPo.is_open())
+ {
+ cerr
+ << "Cannot open old po file: "
+ << sOldPoFileName.getStr() << endl;
+ return;
+ }
+ aNewPo.writeHeader(PoHeader(aOldPo));
+ aOldPo.close();
+ }
+
+ //Write out po entries
+ const PoEntry::TYPE vInitializer[] =
+ { PoEntry::TTEXT, PoEntry::TQUICKHELPTEXT, PoEntry::TTITLE };
+ const vector<PoEntry::TYPE> vTypes( vInitializer,
+ vInitializer + sizeof(vInitializer) / sizeof(vInitializer[0]) );
+ unsigned short nDummyBit = 0;
+ for( unsigned short nIndex=0; nIndex<vTypes.size(); ++nIndex )
+ {
+ if (!pActInfo->second.first.getToken(vTypes[nIndex],'\t').isEmpty())
+ {
+ /**Because of xrmex there are duplicated id's,
+ only use this if xrmex have already fixed*/
+ const OString sSource =
+ pActInfo->second.first.getToken(PoEntry::SOURCEFILE,'\t');
+ const OString sEnding =
+ sSource.copy(sSource.getLength()-4, 4);
+ if (pActInfo->second.first.getToken(PoEntry::GROUPID,'\t')==
+ pActInfo->second.first.getToken(PoEntry::LOCALID,'\t') &&
+ ( sEnding == ".xrm" || sEnding == ".xml" ))
+ {
+ pActInfo->second.first = DelLocalId(pActInfo->second.first);
+ }
+ try
+ {
+ PoEntry aPE(pActInfo->second.first, vTypes[nIndex]);
+ const OString sActStr =
+ pActInfo->second.second.getToken(vTypes[nIndex],'\t');
+ aPE.setMsgStr(sActStr);
+ aPE.setFuzzy( sActStr.isEmpty() ? false :
+ static_cast<bool>(pActInfo->second.second.getToken(PoEntry::DUMMY,'\t').
+ copy(nDummyBit++,1).toBoolean()));
+ aNewPo.writeEntry(aPE);
+ }
+ catch( PoEntry::Exception& )
+ {
+ cerr
+ << "Invalid sdf line "
+ << pActInfo->second.first.replaceAll("\t","\\t").getStr() << '\n';
+ }
+ }
+ }
+ }
+ aNewPo.close();
+ aPoInfos.clear();
+}
+
+
+int main(int argc, char* argv[])
+{
+ //Usage
+ if (argc < 4)
+ {
+ cout << "Use: renewpot oldpots newpots po2lo en-US.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]),
+ OString(argv[4]));
+ }
+ closedir(pTranslations);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */