office-gobmx/l10ntools/source/renewpo.cxx
David Ostrovsky 835d0fb700 WaE ignoring return value, this time really
Change-Id: I5647f318000d83f1f363153c1bc7f4ae4effc88c
2012-11-20 21:31:23 +01:00

242 lines
8.3 KiB
C++

/* -*- 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);
const OString cmd = OString(rpo2loPath +
" -i " + rOldPath + "/" + LangEntryName +
" -o " + SDFFileName +
" -l " + LangEntryName +
" -t " + rSDFPath);
if (system(cmd.getStr()) != 0)
{
std::cerr << "Error: Failed to execute " << cmd.getStr() << '\n';
throw false;
}
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";
const OString cmd2 = OString("mkdir -p " + sNewPoFileName.copy(0,sNewPoFileName.lastIndexOf("/")));
if (system(cmd2.getStr()) != 0)
{
std::cerr << "Error: Failed to execute " << cmd2.getStr() << '\n';
throw false;
}
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: */