diff options
Diffstat (limited to 'l10ntools/source/renewpo.cxx')
-rw-r--r-- | l10ntools/source/renewpo.cxx | 231 |
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: */ |