[Libreoffice-commits] .: Branch 'feature/killsdf' - l10ntools/inc l10ntools/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Sun Sep 30 08:12:16 PDT 2012
l10ntools/inc/po.hxx | 74 +++++++++++-
l10ntools/source/localize.cxx | 52 +++++---
l10ntools/source/merge.cxx | 98 +++++++++++-----
l10ntools/source/po.cxx | 246 ++++++++++++++++++++++++++++++++++--------
l10ntools/source/renewpo.cxx | 88 +++++++++------
5 files changed, 426 insertions(+), 132 deletions(-)
New commits:
commit ca12be682f28969b15b30539230ca40de88fc36d
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date: Fri Sep 28 17:52:13 2012 +0200
Make Po classes robuster
-Make PoOfstream\PoIfstream classes for
checked po input\output
-Make copyability obvious
-Handle runtime errors with exceptions
-Use assertions to define exceptations
for programmers
Plus some correction
-Use simplier indentation
-In renewpo.cxx, define sdf file as a tempfile
instead of make it in current location
-Use constructor to renew poheader
-Use const where needed
Change-Id: Ic11ce3b9eee9a9fa9fbc4ccda154623160ad9d8a
Reviewed-on: https://gerrit.libreoffice.org/728
Reviewed-by: Andras Timar <atimar at suse.com>
Tested-by: Andras Timar <atimar at suse.com>
diff --git a/l10ntools/inc/po.hxx b/l10ntools/inc/po.hxx
index 686c9f3..76312a4 100644
--- a/l10ntools/inc/po.hxx
+++ b/l10ntools/inc/po.hxx
@@ -12,10 +12,15 @@
#include <fstream>
#include <rtl/string.hxx>
+#include <boost/noncopyable.hpp>
+
+class PoOfstream;
+class PoIfstream;
class GenPoEntry
{
private:
+
OString m_sWhiteSpace;
OString m_sExtractCom;
OString m_sReference;
@@ -27,8 +32,10 @@ private:
OString m_sKeyId;
public:
+
GenPoEntry();
virtual ~GenPoEntry();
+ //Default copy constructor and copy operator work well
virtual OString getWhiteSpace() const { return m_sWhiteSpace; }
virtual OString getExtractCom() const { return m_sExtractCom; }
@@ -49,25 +56,33 @@ public:
virtual void setFuzzy(const bool bFuzzy);
virtual void genKeyId();
- virtual void writeToFile(std::ofstream& rOFStream);
+ virtual void writeToFile(std::ofstream& rOFStream) const;
virtual void readFromFile(std::ifstream& rIFStream);
};
class PoEntry
{
private:
+
GenPoEntry m_aGenPo;
+ bool m_bIsInitialized;
public:
- enum SDFPARTS { PROJECT, SOURCEFILE, DUMMY, RESOURCETYPE, GROUPID,
+
+ friend class PoOfstream;
+ friend class PoIfstream;
+
+ enum SDFPART { PROJECT, SOURCEFILE, DUMMY, RESOURCETYPE, GROUPID,
LOCALID, HELPID, PLATFORM, WIDTH, LANGUAGEID,
TEXT, HELPTEXT, QUICKHELPTEXT, TITLE, TIMESTAMP };
enum TYPE { TTEXT=TEXT, TQUICKHELPTEXT=QUICKHELPTEXT, TTITLE=TITLE };
+ enum Exception { INVALIDSDFLINE };
PoEntry();
PoEntry(const OString& rSDFLine,
const TYPE eType = TTEXT);
~PoEntry();
+ //Default copy constructor and copy operator work well
OString getSourceFile() const;
OString getGroupId() const;
@@ -77,15 +92,11 @@ public:
OString getUnTransStr() const;
OString getTransStr() const;
bool getFuzzy() const;
- bool isNull() const;
OString getKeyId() const;
void setUnTransStr(const OString& rUnTransStr);
void setTransStr(const OString& rTransStr);
void setFuzzy(const bool bFuzzy);
- void writeToFile(std::ofstream& rOFStream);
- void readFromFile(std::ifstream& rIFStream);
-
static bool IsInSameComp(const PoEntry& rPo1,const PoEntry& rPo2);
};
@@ -93,16 +104,63 @@ public:
class PoHeader
{
private:
+
GenPoEntry m_aGenPo;
+ bool m_bIsInitialized;
public:
+
+ friend class PoOfstream;
+ friend class PoIfstream;
+
PoHeader();
PoHeader( const OString& rExtSrc );
+ PoHeader( std::ifstream& rOldPo );
~PoHeader();
+ //Default copy constructor and copy operator work well
OString getLanguage() const;
- void writeToFile(std::ofstream& rOFStream);
- void readFromFile(std::ifstream& rIFStream);
+};
+
+class PoOfstream: private boost::noncopyable
+{
+private:
+
+ std::ofstream m_aOutPut;
+ bool m_bIsAfterHeader;
+
+public:
+ PoOfstream();
+ ~PoOfstream();
+ bool isOpen() const { return m_aOutPut.is_open(); }
+
+ void open(const OString& rFileName);
+ void close();
+ void writeHeader(const PoHeader& rHeader);
+ void writeEntry(const PoEntry& rPo);
+};
+
+class PoIfstream: private boost::noncopyable
+{
+private:
+
+ std::ifstream m_aInPut;
+ bool m_bIsAfterHeader;
+ bool m_bEof;
+
+public:
+
+ enum Exception { INVALIDENTRY, INVALIDHEADER };
+
+ PoIfstream();
+ ~PoIfstream();
+ bool isOpen() const { return m_aInPut.is_open(); }
+ bool eof() const { return m_bEof; }
+
+ void open(const OString& rFileName);
+ void close();
+ void readHeader(PoHeader& rHeader);
+ void readEntry(PoEntry& rPo);
};
#endif // _PO_INCLUDED
diff --git a/l10ntools/source/localize.cxx b/l10ntools/source/localize.cxx
index a9a20c8..87ee83b 100644
--- a/l10ntools/source/localize.cxx
+++ b/l10ntools/source/localize.cxx
@@ -170,7 +170,7 @@ bool passesPositiveList(rtl::OUString const & url) {
void handleCommand(
rtl::OUString const & project, rtl::OUString const & projectRoot,
rtl::OUString const & url, rtl::OUString const & actualDir,
- std::ofstream & outPut, rtl::OUString const & executable, bool positive)
+ PoOfstream & rPoOutPut, rtl::OUString const & executable, bool positive)
{
if (positive ? passesPositiveList(url) : passesNegativeList(url)) {
rtl::OUString inPath;
@@ -241,7 +241,7 @@ void handleCommand(
std::string s;
std::getline(in, s);
- if (!in.eof() && !outPut.is_open())
+ if (!in.eof() && !rPoOutPut.isOpen())
{
rtl::OUString outDirUrl;
if (osl::FileBase::getFileURLFromSystemPath(actualDir.
@@ -263,8 +263,14 @@ void handleCommand(
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);
+ rPoOutPut.open(outFilePath.getStr());
+ if (!rPoOutPut.isOpen())
+ {
+ std::cerr
+ << "Error: Cannot open po file "
+ << outFilePath.getStr() << "\n";
+ throw false; //TODO
+ }
rtl::OString relativPath;
if (!inPath.copy(inPath.indexOf(project),
inPath.lastIndexOf('/')-inPath.indexOf(project)).
@@ -275,18 +281,28 @@ void handleCommand(
std::cerr << "Error: Cannot convert pathname from UTF-16\n";
throw false; //TODO
}
- PoHeader(relativPath).writeToFile(outPut);
+ rPoOutPut.writeHeader(PoHeader(relativPath));
}
while (!in.eof())
{
OString sLine = OString(s.data(),s.length());
-
- if (!sLine.getToken(PoEntry::TEXT,'\t').isEmpty())
- PoEntry(sLine).writeToFile(outPut);
- if (!sLine.getToken(PoEntry::QUICKHELPTEXT,'\t').isEmpty())
- PoEntry(sLine,PoEntry::TQUICKHELPTEXT).writeToFile(outPut);
- if (!sLine.getToken(PoEntry::TITLE,'\t').isEmpty())
- PoEntry(sLine,PoEntry::TTITLE).writeToFile(outPut);
+ try
+ {
+ if (!sLine.getToken(PoEntry::TEXT,'\t').isEmpty())
+ rPoOutPut.writeEntry(PoEntry(sLine));
+ if (!sLine.getToken(PoEntry::QUICKHELPTEXT,'\t').isEmpty())
+ rPoOutPut.writeEntry(PoEntry(sLine,PoEntry::TQUICKHELPTEXT));
+ if (!sLine.getToken(PoEntry::TITLE,'\t').isEmpty())
+ rPoOutPut.writeEntry(PoEntry(sLine,PoEntry::TTITLE));
+ }
+ catch(PoEntry::Exception& aException)
+ {
+ if(aException == PoEntry::INVALIDSDFLINE)
+ {
+ std::cerr << executable << "'s input is invalid\n";
+ throw false; //TODO
+ }
+ }
std::getline(in, s);
};
in.close();
@@ -296,7 +312,7 @@ void handleCommand(
void handleFile(
rtl::OUString const & project, rtl::OUString const & projectRoot,
rtl::OUString const & url, rtl::OUString const & actualDir,
- std::ofstream & outPut)
+ PoOfstream & rPoOutPut)
{
struct Command {
char const * extension;
@@ -319,7 +335,7 @@ void handleFile(
commands[i].extension, commands[i].extensionLength))
{
handleCommand(
- project, projectRoot, url, actualDir, outPut,
+ project, projectRoot, url, actualDir, rPoOutPut,
rtl::OUString::createFromAscii(commands[i].executable),
commands[i].positive);
break;
@@ -430,7 +446,7 @@ void handleDirectory(
rtl::OUString const & url, int level, rtl::OUString const & project,
rtl::OUString const & projectRoot, rtl::OUString const & actualDir)
{
- std::ofstream output;
+ PoOfstream aPoOutPut;
osl::Directory dir(url);
if (dir.open() != osl::FileBase::E_None) {
std::cerr
@@ -494,13 +510,13 @@ void handleDirectory(
}
} else {
handleFile(project, projectRoot,
- stat.getFileURL(), actualDir, output);
+ stat.getFileURL(), actualDir, aPoOutPut);
}
break;
}
}
- if (output.is_open())
- output.close();
+ if (aPoOutPut.isOpen())
+ aPoOutPut.close();
if (dir.close() != osl::FileBase::E_None) {
std::cerr << "Error: Cannot close directory\n";
throw false; //TODO
diff --git a/l10ntools/source/merge.cxx b/l10ntools/source/merge.cxx
index b87024a..7e6c595 100644
--- a/l10ntools/source/merge.cxx
+++ b/l10ntools/source/merge.cxx
@@ -45,6 +45,27 @@ namespace
rFilename.lastIndexOf( '\\' ),
rFilename.lastIndexOf( '/' ))+1);
};
+
+ static bool lcl_ReadPoChecked(
+ PoEntry& o_rPoEntry, PoIfstream& rPoFile,
+ const std::string& rFileName)
+ {
+ try
+ {
+ rPoFile.readEntry( o_rPoEntry );
+ }
+ catch( PoIfstream::Exception& aException )
+ {
+ if( aException == PoIfstream::INVALIDENTRY )
+ {
+ printf(
+ "Warning : %s contains invalid entry\n",
+ rFileName.c_str() );
+ return false;
+ }
+ }
+ return true;
+ }
}
//
@@ -142,8 +163,8 @@ MergeDataFile::MergeDataFile(
const rtl::OString &rFile,
bool bCaseSensitive)
{
- std::ifstream aInputStream(rFileName.getStr());
- if (!aInputStream.is_open())
+ std::ifstream aInputStream( rFileName.getStr() );
+ if ( !aInputStream.is_open() )
{
printf("Warning : Can't open po path container file");
return;
@@ -151,30 +172,45 @@ MergeDataFile::MergeDataFile(
std::string sPoFileName;
aInputStream >> sPoFileName;
bool bFirstLang = true;
- while(!aInputStream.eof())
+ while( !aInputStream.eof() )
{
- std::ifstream aPoFile(sPoFileName.c_str());
const OString sHACK("HACK");
- const OString sFileName(lcl_NormalizeFilename(rFile));
-
- if (!aPoFile.is_open())
+ const OString sFileName( lcl_NormalizeFilename(rFile) );
+ PoIfstream aPoInput;
+ aPoInput.open( OString(sPoFileName.data(), sPoFileName.length()) );
+ if ( !aPoInput.isOpen() )
{
- printf("Warning : Can't open %s\n", sPoFileName.c_str());
+ printf( "Warning : Can't open %s\n", sPoFileName.c_str() );
return;
}
-
PoHeader aPoHeader;
- aPoHeader.readFromFile(aPoFile);
+ try
+ {
+ aPoInput.readHeader( aPoHeader );
+ }
+ catch( PoIfstream::Exception& aException )
+ {
+ if( aException == PoIfstream::INVALIDHEADER )
+ {
+ printf(
+ "Warning : %s has invalid header\n",
+ sPoFileName.c_str() );
+ return;
+ }
+ }
const OString nLANG = aPoHeader.getLanguage();
- aLanguageSet.insert(nLANG);
+ aLanguageSet.insert( nLANG );
PoEntry aNextPo;
do
{
- aNextPo.readFromFile(aPoFile);
- } while( !aNextPo.isNull() && aNextPo.getSourceFile() != sFileName );
- while( !aNextPo.isNull() && aNextPo.getSourceFile() == sFileName )
+ if( !lcl_ReadPoChecked(aNextPo, aPoInput, sPoFileName) )
+ {
+ return;
+ }
+ } while( !aPoInput.eof() && aNextPo.getSourceFile() != sFileName );
+ while( !aPoInput.eof() && aNextPo.getSourceFile() == sFileName )
{
- PoEntry aActPo(aNextPo);
+ PoEntry aActPo( aNextPo );
bool bInSameComp = false;
OString sText;
@@ -189,7 +225,7 @@ MergeDataFile::MergeDataFile(
do
{
if( bInSameComp )
- aActPo = PoEntry(aNextPo);
+ aActPo = aNextPo;
OString sTemp = aActPo.getTransStr();
if( aActPo.getFuzzy() || sTemp.isEmpty() )
sTemp = aActPo.getUnTransStr();
@@ -211,25 +247,29 @@ MergeDataFile::MergeDataFile(
sQTZTitle = aActPo.getKeyId();
break;
}
- aNextPo.readFromFile(aPoFile);
- } while(!aNextPo.isNull() &&
- (bInSameComp = PoEntry::IsInSameComp(aActPo,aNextPo)));
+ if( !lcl_ReadPoChecked(aNextPo, aPoInput, sPoFileName) )
+ {
+ return;
+ }
+ } while( !aPoInput.eof() &&
+ ( bInSameComp = PoEntry::IsInSameComp(aActPo, aNextPo) ) );
+
+ InsertEntry(
+ aActPo.getResourceType(), aActPo.getGroupId(),
+ aActPo.getLocalId(), sHACK, nLANG, sText,
+ sQHText, sTitle, sFileName, bCaseSensitive );
- InsertEntry( aActPo.getResourceType(), aActPo.getGroupId(),
- aActPo.getLocalId(), sHACK, nLANG, sText,
- sQHText, sTitle, sFileName, bCaseSensitive );
if( bFirstLang )
{
aLanguageSet.insert("qtz");
- InsertEntry( aActPo.getResourceType(), aActPo.getGroupId(),
- aActPo.getLocalId(), sHACK, "qtz",
- sQTZText + "â" + sExText,
- sQTZQHText + "â" + sExQHText,
- sQTZTitle + "â" + sExTitle,
- sFileName, bCaseSensitive );
+ InsertEntry(
+ aActPo.getResourceType(), aActPo.getGroupId(),
+ aActPo.getLocalId(), sHACK, "qtz",
+ sQTZText + "â" + sExText, sQTZQHText + "â" + sExQHText,
+ sQTZTitle + "â" + sExTitle, sFileName, bCaseSensitive );
}
}
- aPoFile.close();
+ aPoInput.close();
aInputStream >> sPoFileName;
bFirstLang = false;
}
diff --git a/l10ntools/source/po.cxx b/l10ntools/source/po.cxx
index b2082a7..cf0b963 100644
--- a/l10ntools/source/po.cxx
+++ b/l10ntools/source/po.cxx
@@ -13,10 +13,13 @@
#include <regexp/reclass.hxx>
#include <rtl/ustring.hxx>
-#include <string>
#include <cstring>
#include <ctime>
+#include <cassert>
+
#include <vector>
+#include <string>
+
#include <boost/crc.hpp>
#include "po.hxx"
@@ -49,7 +52,7 @@ OString ImplEscapeText(const OString& rText,
const OString& rUnEscaped= POUNESCAPED,
const OString& rEscaped = POESCAPED)
{
- if(rEscaped.getLength()!=2*rUnEscaped.getLength()) throw;
+ assert( rEscaped.getLength() == 2*rUnEscaped.getLength() );
OString sResult = rText;
int nCount = 0;
for(sal_Int32 nIndex=0; nIndex<rText.getLength(); ++nIndex)
@@ -67,7 +70,7 @@ OString ImplUnEscapeText(const OString& rText,
const OString& rEscaped = POESCAPED,
const OString& rUnEscaped = POUNESCAPED)
{
- if(rEscaped.getLength()!=2*rUnEscaped.getLength()) throw;
+ assert( rEscaped.getLength() == 2*rUnEscaped.getLength() );
OString sResult = rText;
int nCount = 0;
for(sal_Int32 nIndex=0; nIndex<rText.getLength()-1; ++nIndex)
@@ -171,11 +174,11 @@ void GenPoEntry::setFuzzy(const bool bFuzzy)
//Set keyid
void GenPoEntry::genKeyId()
{
- m_sKeyId = ImplGenKeyId(m_sReference + m_sContext + m_sUnTransStr);
+ m_sKeyId = ImplGenKeyId( m_sReference + m_sContext + m_sUnTransStr );
}
//Write to file
-void GenPoEntry::writeToFile(std::ofstream& rOFStream)
+void GenPoEntry::writeToFile(std::ofstream& rOFStream) const
{
if ( !m_sWhiteSpace.isEmpty() )
rOFStream << m_sWhiteSpace.getStr();
@@ -250,7 +253,7 @@ void GenPoEntry::readFromFile(std::ifstream& rIFStream)
break;
getline(rIFStream,sTemp);
}
- if (m_sKeyId.isEmpty())
+ if( m_sKeyId.isEmpty() && !m_sUnTransStr.isEmpty() )
genKeyId();
}
@@ -384,23 +387,33 @@ OString ImplEscapeSDFText(const OString& rText,const bool bHelpText = false)
//Default constructor
PoEntry::PoEntry()
: m_aGenPo( GenPoEntry() )
+ , m_bIsInitialized( false )
{
}
//Construct PoEntry from sdfline
PoEntry::PoEntry(const OString& rSDFLine, const TYPE eType)
: m_aGenPo( GenPoEntry() )
+ , m_bIsInitialized( false )
{
std::vector<OString> vParts;
ImplSplitAt(rSDFLine,'\t',vParts);
- if(vParts.size()!=15) throw;
+ if( vParts.size()!=15 ||
+ vParts[SOURCEFILE].isEmpty() ||
+ vParts[GROUPID].isEmpty() ||
+ vParts[RESOURCETYPE].isEmpty() ||
+ vParts[eType].isEmpty() )
+ {
+ throw INVALIDSDFLINE;
+ }
m_aGenPo.setWhiteSpace("\n");
m_aGenPo.setReference(vParts[SOURCEFILE].
copy(vParts[SOURCEFILE].lastIndexOf("\\")+1));
m_aGenPo.setExtractCom(vParts[HELPTEXT]);
- OString sContext = vParts[GROUPID] + "\n" +
+ OString sContext =
+ vParts[GROUPID] + "\n" +
(vParts[LOCALID].isEmpty() ? "" : vParts[LOCALID] + "\n") +
vParts[RESOURCETYPE];
switch(eType){
@@ -410,12 +423,13 @@ PoEntry::PoEntry(const OString& rSDFLine, const TYPE eType)
sContext += ".quickhelptext"; break;
case TTITLE:
sContext += ".title"; break;
- default:
- throw; break;
+ /*Default case is unneeded because the type of eType has
+ only three element*/
}
m_aGenPo.setContext(sContext);
setUnTransStr(vParts[eType]);
m_aGenPo.genKeyId();
+ m_bIsInitialized = true;
}
//Destructor
@@ -426,18 +440,21 @@ PoEntry::~PoEntry()
//Get name of file from which entry is extracted
OString PoEntry::getSourceFile() const
{
+ assert( m_bIsInitialized );
return m_aGenPo.getReference();
}
//Get groupid
OString PoEntry::getGroupId() const
{
+ assert( m_bIsInitialized );
return m_aGenPo.getContext().getToken(0,'\n');
}
//Get localid
OString PoEntry::getLocalId() const
{
+ assert( m_bIsInitialized );
const OString sContext = m_aGenPo.getContext();
if (sContext.indexOf('\n')==sContext.lastIndexOf('\n'))
return OString();
@@ -448,6 +465,7 @@ OString PoEntry::getLocalId() const
//Get the type of component from which entry is extracted
OString PoEntry::getResourceType() const
{
+ assert( m_bIsInitialized );
const OString sContext = m_aGenPo.getContext();
if (sContext.indexOf('\n')==sContext.lastIndexOf('\n'))
return sContext.getToken(1,'\n').getToken(0,'.');
@@ -459,30 +477,28 @@ OString PoEntry::getResourceType() const
PoEntry::TYPE PoEntry::getType() const
{
const OString sContext = m_aGenPo.getContext();
- if (sContext.endsWith(".text"))
+ const OString sType = sContext.copy( sContext.indexOf('.') + 1 );
+ assert( m_bIsInitialized &&
+ (sType == "text" || sType == "quickhelptext" || sType == "title") );
+ if ( sType == "text" )
return TTEXT;
- else if (sContext.endsWith(".quickhelptext"))
+ else if ( sType == "quickhelptext" )
return TQUICKHELPTEXT;
- else if (sContext.endsWith(".title"))
+ else
return TTITLE;
- else throw;
}
//Check wheather entry is fuzzy
bool PoEntry::getFuzzy() const
{
+ assert( m_bIsInitialized );
return m_aGenPo.getFuzzy();
}
-//Check wheather entry is null
-bool PoEntry::isNull() const
-{
- return m_aGenPo.isNull();
-}
-
//Get keyid
OString PoEntry::getKeyId() const
{
+ assert( m_bIsInitialized );
return m_aGenPo.getKeyId();
}
@@ -490,15 +506,19 @@ OString PoEntry::getKeyId() const
//Get translation string in sdf/merge format
OString PoEntry::getUnTransStr() const
{
- return ImplEscapeSDFText(m_aGenPo.getUnTransStr(),
- getSourceFile().endsWith(".xhp"));
+ assert( m_bIsInitialized );
+ return
+ ImplEscapeSDFText(
+ m_aGenPo.getUnTransStr(), getSourceFile().endsWith(".xhp") );
}
//Get translated string in sdf/merge format
OString PoEntry::getTransStr() const
{
- return ImplEscapeSDFText(m_aGenPo.getTransStr(),
- getSourceFile().endsWith(".xhp"));
+ assert( m_bIsInitialized );
+ return
+ ImplEscapeSDFText(
+ m_aGenPo.getTransStr(), getSourceFile().endsWith(".xhp") );
}
@@ -524,20 +544,6 @@ void PoEntry::setFuzzy(const bool bFuzzy)
m_aGenPo.setFuzzy(bFuzzy);
}
-//Write to file
-void PoEntry::writeToFile(std::ofstream& rOFStream)
-{
- m_aGenPo.writeToFile(rOFStream);
-}
-
-
-//Read from file
-void PoEntry::readFromFile(std::ifstream& rIFStream)
-{
- *this = PoEntry();
- m_aGenPo.readFromFile(rIFStream);
-}
-
//Check whether po-s belong to the same localization component
bool PoEntry::IsInSameComp(const PoEntry& rPo1,const PoEntry& rPo2)
{
@@ -559,15 +565,26 @@ OString ImplGetTime()
return pBuff;
}
+OString ImplReplaceAttribute(
+ const OString& rSource, const OString& rOld, const OString& rNew )
+{
+ const sal_Int32 nFirstIndex = rSource.indexOf( rOld ) + rOld.getLength()+2;
+ const sal_Int32 nCount =
+ rSource.indexOf( "\n", nFirstIndex ) - nFirstIndex;
+ return rSource.replaceFirst( rSource.copy(nFirstIndex, nCount), rNew );
+}
+
//Default Constructor
PoHeader::PoHeader()
: m_aGenPo( GenPoEntry() )
+ , m_bIsInitialized( false )
{
}
//Template Constructor
PoHeader::PoHeader( const OString& rExtSrc )
: m_aGenPo( GenPoEntry() )
+ , m_bIsInitialized( false )
{
m_aGenPo.setExtractCom("extracted from " + rExtSrc);
m_aGenPo.setTransStr(
@@ -583,6 +600,34 @@ PoHeader::PoHeader( const OString& rExtSrc )
"Content-Transfer-Encoding: 8bit\n"
"X-Genarator: LibreOffice\n"
"X-Accelerator_Marker: ~\n"));
+ m_bIsInitialized = true;
+}
+
+
+//Constructor for old headers to renew po files
+PoHeader::PoHeader( std::ifstream& rOldPo )
+ : m_aGenPo( GenPoEntry() )
+ , m_bIsInitialized( false )
+{
+ assert( rOldPo.is_open() );
+ m_aGenPo.readFromFile( rOldPo );
+
+ m_aGenPo.setWhiteSpace( OString() );
+ const OString sExtractCom = m_aGenPo.getExtractCom();
+ m_aGenPo.setExtractCom(
+ sExtractCom.copy( 0, sExtractCom.getLength() - 3 ) );
+
+ OString sTransStr = m_aGenPo.getTransStr();
+ sTransStr =
+ ImplReplaceAttribute( sTransStr, "Report-Msgid-Bugs-To",
+ "https://bugs.freedesktop.org/enter_bug.cgi?product="
+ "LibreOffice&bug_status=UNCONFIRMED&component=UI" );
+ sTransStr =
+ ImplReplaceAttribute( sTransStr, "X-Generator", "LibreOffice" );
+ sTransStr =
+ ImplReplaceAttribute( sTransStr, "X-Accelerator-Marker", "~" );
+ m_aGenPo.setTransStr( sTransStr );
+ m_bIsInitialized = true;
}
PoHeader::~PoHeader()
@@ -592,6 +637,7 @@ PoHeader::~PoHeader()
//Get the language of header
OString PoHeader::getLanguage() const
{
+ assert( m_bIsInitialized );
const OString sLang = "Language: ";
const OString sTransStr = m_aGenPo.getTransStr();
const sal_Int32 nFirstIndex = sTransStr.indexOf(sLang)+sLang.getLength();
@@ -599,18 +645,128 @@ OString PoHeader::getLanguage() const
return sTransStr.copy(nFirstIndex,nCount);
}
-//Write out to file
-void PoHeader::writeToFile(std::ofstream& rOFStream)
+//Class PoOfstream
+
+PoOfstream::PoOfstream()
+ : m_aOutPut()
+ , m_bIsAfterHeader( false )
+{
+}
+
+PoOfstream::~PoOfstream()
+{
+ if( isOpen() )
+ {
+ close();
+ }
+}
+
+void PoOfstream::open(const OString& rFileName)
{
- m_aGenPo.writeToFile(rOFStream);
+ assert( !isOpen() );
+ m_aOutPut.open( rFileName.getStr(),
+ std::ios_base::out | std::ios_base::trunc );
+ m_bIsAfterHeader = false;
}
-//Read from file
-void PoHeader::readFromFile(std::ifstream& rIFStream)
+void PoOfstream::close()
+{
+ assert( isOpen() );
+ m_aOutPut.close();
+}
+
+void PoOfstream::writeHeader(const PoHeader& rPoHeader)
+{
+ assert( isOpen() && !m_bIsAfterHeader && rPoHeader.m_bIsInitialized );
+ rPoHeader.m_aGenPo.writeToFile( m_aOutPut );
+ m_bIsAfterHeader = true;
+}
+
+void PoOfstream::writeEntry( const PoEntry& rPoEntry )
+{
+ assert( isOpen() && m_bIsAfterHeader && rPoEntry.m_bIsInitialized );
+ rPoEntry.m_aGenPo.writeToFile( m_aOutPut );
+}
+
+//Class PoIfstream
+
+PoIfstream::PoIfstream()
+ : m_aInPut()
+ , m_bIsAfterHeader( false )
+ , m_bEof( false )
+{
+}
+
+PoIfstream::~PoIfstream()
+{
+ if( isOpen() )
+ {
+ close();
+ }
+}
+
+void PoIfstream::open( const OString& rFileName )
+{
+ assert( !isOpen() );
+ m_aInPut.open( rFileName.getStr(), std::ios_base::in );
+ m_bIsAfterHeader = false;
+ m_bEof = false;
+}
+
+void PoIfstream::close()
{
- *this = PoHeader();
- m_aGenPo.readFromFile(rIFStream);
+ assert( isOpen() );
+ m_aInPut.close();
}
+void PoIfstream::readHeader( PoHeader& rPoHeader )
+{
+ assert( isOpen() && !eof() && !m_bIsAfterHeader );
+ GenPoEntry aGenPo;
+ aGenPo.readFromFile( m_aInPut );
+ if( !aGenPo.getExtractCom().isEmpty() &&
+ aGenPo.getUnTransStr().isEmpty() &&
+ !aGenPo.getTransStr().isEmpty() )
+ {
+ rPoHeader.m_aGenPo = aGenPo;
+ rPoHeader.m_bIsInitialized = true;
+ m_bIsAfterHeader = true;
+ }
+ else
+ {
+ throw INVALIDHEADER;
+ }
+}
+
+void PoIfstream::readEntry( PoEntry& rPoEntry )
+{
+ assert( isOpen() && !eof() && m_bIsAfterHeader );
+ GenPoEntry aGenPo;
+ aGenPo.readFromFile( m_aInPut );
+ if( aGenPo.isNull() )
+ {
+ m_bEof = true;
+ rPoEntry = PoEntry();
+ }
+ else
+ {
+ const OString sContext = aGenPo.getContext();
+ const sal_Int32 nLastDot = sContext.lastIndexOf('.');
+ const OString sType = sContext.copy( nLastDot + 1 );
+ if( !aGenPo.getReference().isEmpty() &&
+ sContext.indexOf('\n') > 0 &&
+ (sType == "text" || sType == "quickhelptext" || sType == "title") &&
+ nLastDot - sContext.lastIndexOf('\n') > 0 &&
+ !aGenPo.getUnTransStr().isEmpty() )
+ {
+ rPoEntry.m_aGenPo = aGenPo;
+ rPoEntry.m_bIsInitialized = true;
+ }
+ else
+ {
+ throw INVALIDENTRY;
+ }
+ }
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/l10ntools/source/renewpo.cxx b/l10ntools/source/renewpo.cxx
index 39152a7..83b3051 100644
--- a/l10ntools/source/renewpo.cxx
+++ b/l10ntools/source/renewpo.cxx
@@ -12,7 +12,10 @@
#include <dirent.h>
#include <string>
#include <vector>
+
+#include <osl/file.hxx>
#include <rtl/string.hxx>
+
#include "po.hxx"
using namespace std;
@@ -58,10 +61,27 @@ void HandleLanguage(struct dirent* pLangEntry, const OString& rPath,
const OString& rpo2loPath, const OString& rSDFPath)
{
const OString LangEntryName = pLangEntry->d_name;
- const OString SDFFileName = LangEntryName + ".sdf";
//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 " + rPath + "/" + LangEntryName +
" -o " + SDFFileName +
@@ -69,7 +89,7 @@ void HandleLanguage(struct dirent* pLangEntry, const OString& rPath,
" -t " + rSDFPath).getStr());
cout << "Language sdf is ready!" << endl;
- ofstream aOutPut;
+ PoOfstream aNewPo;
ifstream aSDFInput(SDFFileName.getStr());
string s;
getline(aSDFInput,s);
@@ -77,40 +97,41 @@ void HandleLanguage(struct dirent* pLangEntry, const OString& rPath,
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())
+ const OString sPath = rPath + "/"+ LangEntryName;
+ const OString sActSourcePath = GetPath(sPath,sActUnTrans);
+ //Make new po file and add header
+ if (!aNewPo.isOpen())
{
- aOutPut.open((sActSourcePath + ".po_tmp").getStr(),
- std::ios_base::out | std::ios_base::trunc);
- ifstream aPOInput((sActSourcePath + ".po").getStr());
- getline(aPOInput,s);
- while(s!="")
+ const OString sNewPoFileName = sActSourcePath + ".po_tmp";
+ aNewPo.open(sNewPoFileName);
+ if (!aNewPo.isOpen())
{
- 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();
+ cerr
+ << "Cannot open temp file for new po: "
+ << sNewPoFileName.getStr() << endl;
+ return;
+ }
+ const OString sOldPoFileName = sActSourcePath + ".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();
}
//Set PoEntry and write out
getline(aSDFInput,s);
- sLine = OString(s.data(),s.length());
OString sActTrans;
- if (!aSDFInput.eof() && IsSameEntry(sActUnTrans,sLine))
+ if (!aSDFInput.eof() &&
+ IsSameEntry(sActUnTrans,sLine = OString(s.data(),s.length())))
{
sActTrans = sLine;
getline(aSDFInput,s);
- sLine = OString(s.data(),s.length());
}
else
{
@@ -121,7 +142,7 @@ void HandleLanguage(struct dirent* pLangEntry, const OString& rPath,
const vector<PoEntry::TYPE> vTypes( vInitializer,
vInitializer + sizeof(vInitializer) / sizeof(vInitializer[0]) );
unsigned short nDummyBit = 0;
- for( unsigned nIndex=0; nIndex<vTypes.size(); ++nIndex)
+ for( unsigned short nIndex=0; nIndex<vTypes.size(); ++nIndex )
{
if (!sActUnTrans.getToken(vTypes[nIndex],'\t').isEmpty())
{
@@ -141,15 +162,15 @@ void HandleLanguage(struct dirent* pLangEntry, const OString& rPath,
aPE.setFuzzy( sActStr.isEmpty() ? false :
static_cast<bool>(sActTrans.getToken(PoEntry::DUMMY,'\t').
copy(nDummyBit++,1).toBoolean()));
- aPE.writeToFile(aOutPut);
+ aNewPo.writeEntry(aPE);
}
}
//Check wheather next entry is in the same po file
- OString sNextSourcePath =
- !aSDFInput.eof() ? GetPath(sPath,sLine) : "";
+ OString sNextSourcePath = aSDFInput.eof() ? "" :
+ GetPath(sPath,sLine = OString(s.data(),s.length()));
if (sNextSourcePath!=sActSourcePath)
{
- aOutPut.close();
+ aNewPo.close();
system(("rm " + sActSourcePath +".po").getStr());
system(("mv "+ sActSourcePath +".po_tmp " +
sActSourcePath +".po").getStr());
@@ -158,7 +179,10 @@ void HandleLanguage(struct dirent* pLangEntry, const OString& rPath,
//Close and remove sdf file
aSDFInput.close();
- system(("rm " + SDFFileName).getStr());
+ if (osl::File::remove(aTempUrl) != osl::FileBase::E_None)
+ {
+ cerr << "Warning: failure removing temporary " << aTempUrl << '\n';
+ }
}
More information about the Libreoffice-commits
mailing list