1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
33 OString
lcl_NormalizeFilename(const OString
& rFilename
)
35 return rFilename
.copy(
37 rFilename
.lastIndexOf( '\\' ),
38 rFilename
.lastIndexOf( '/' ))+1);
41 bool lcl_ReadPoChecked(
42 PoEntry
& o_rPoEntry
, PoIfstream
& rPoFile
,
43 const OString
& rFileName
)
47 rPoFile
.readEntry( o_rPoEntry
);
49 catch (const PoIfstream::Exception
&)
51 SAL_WARN("l10ntools", rFileName
<< " contains invalid entry");
61 ResData::ResData( const OString
&rGId
)
65 sGId
= sGId
.replaceAll("\r", OString());
68 ResData::ResData( const OString
&rGId
, const OString
&rFilename
)
71 sFilename( rFilename
)
73 sGId
= sGId
.replaceAll("\r", OString());
79 bool MergeEntrys::GetText( OString
&rReturn
,
80 const OString
&nLangIndex
, bool bDel
)
83 rReturn
= sText
[ nLangIndex
];
85 sText
[ nLangIndex
] = "";
86 bReturn
= bTextFirst
[ nLangIndex
];
87 bTextFirst
[ nLangIndex
] = false;
93 OString
GetDoubleBars()
95 //DOUBLE VERTICAL LINE instead of || because the translations make their
96 //way into action_names under gtk3 where || is illegal
101 OString
MergeEntrys::GetQTZText(const ResData
& rResData
, std::string_view rOrigText
)
103 const OString sFilename
= rResData
.sFilename
.copy(rResData
.sFilename
.lastIndexOf('/')+1);
105 PoEntry::genKeyId(sFilename
+ rResData
.sGId
+ rResData
.sId
+ rResData
.sResTyp
+ rOrigText
);
106 return sKey
+ GetDoubleBars() + rOrigText
;
111 MergeDataFile::MergeDataFile(
112 const OString
&rFileName
, const OString
&rFile
,
113 bool bCaseSensitive
, bool bWithQtz
)
115 auto const env
= getenv("ENABLE_RELEASE_BUILD");
116 OString
sEnableReleaseBuild(env
== nullptr ? "" : env
);
118 std::ifstream
aInputStream( rFileName
.getStr() );
119 if ( !aInputStream
.is_open() )
121 SAL_WARN("l10ntools", "Can't open po path container file for " << rFileName
);
125 aInputStream
>> sPoFile
;
126 bool bFirstLang
= true;
127 while( !aInputStream
.eof() )
129 bool bSkipCurrentPOFile
= false;
130 const OString
sFileName( lcl_NormalizeFilename(rFile
) );
131 const bool bReadAll
= sFileName
.isEmpty();
132 // coverity[tainted_data] - this is a build time tool
133 const OString
sPoFileName(sPoFile
.data(), static_cast<sal_Int32
>(sPoFile
.length()));
135 aPoInput
.open( sPoFileName
);
136 if ( !aPoInput
.isOpen() )
138 SAL_WARN("l10ntools", "Can't open file: " << sPoFileName
);
143 //Get language id from path
145 const OString
sTransSource("translations/source/");
146 const sal_Int32 nStart
=
147 sPoFileName
.indexOf(sTransSource
)+sTransSource
.getLength();
148 const sal_Int32 nCount
=
149 sPoFileName
.indexOf('/',nStart
) - nStart
;
150 sLang
= sPoFileName
.copy(nStart
,nCount
);
152 aLanguageSet
.insert( sLang
);
156 if( !lcl_ReadPoChecked(aNextPo
, aPoInput
, sPoFileName
) )
158 bSkipCurrentPOFile
= true;
161 } while( !aPoInput
.eof() && aNextPo
.getSourceFile() != sFileName
&& !bReadAll
);
162 while( !aPoInput
.eof() && (aNextPo
.getSourceFile() == sFileName
|| bReadAll
) && !bSkipCurrentPOFile
)
164 PoEntry
aActPo( aNextPo
);
166 bool bInSameComp
= false;
177 OString sTemp
= aActPo
.getMsgStr();
178 if( aActPo
.isFuzzy() || sTemp
.isEmpty() )
179 sTemp
= aActPo
.getMsgId();
180 switch( aActPo
.getType() )
184 sExText
= aActPo
.getMsgId();
186 case PoEntry::TQUICKHELPTEXT
:
188 sExQHText
= aActPo
.getMsgId();
190 case PoEntry::TTITLE
:
192 sExTitle
= aActPo
.getMsgId();
195 if( !lcl_ReadPoChecked(aNextPo
, aPoInput
, sPoFileName
) )
197 bSkipCurrentPOFile
= true;
202 bInSameComp
= PoEntry::IsInSameComp(aActPo
, aNextPo
);
203 } while( bInSameComp
);
206 aActPo
.getResourceType(), aActPo
.getGroupId(),
207 aActPo
.getLocalId(), sLang
, sText
,
208 sQHText
, sTitle
, aActPo
.getSourceFile(),
209 bFirstLang
, bCaseSensitive
);
211 if( bFirstLang
&& bWithQtz
&&
212 sEnableReleaseBuild
!= "TRUE" )
214 aLanguageSet
.insert("qtz");
216 aActPo
.getResourceType(), aActPo
.getGroupId(),
217 aActPo
.getLocalId(), "qtz",
219 sExTitle
, aActPo
.getSourceFile(),
220 false, bCaseSensitive
);
224 aInputStream
>> sPoFile
;
227 aInputStream
.close();
230 MergeDataFile::~MergeDataFile()
234 std::vector
<OString
> MergeDataFile::GetLanguages() const
236 return std::vector
<OString
>(aLanguageSet
.begin(),aLanguageSet
.end());
239 MergeEntrys
*MergeDataFile::GetMergeData( ResData
*pResData
, bool bCaseSensitive
)
241 OString sOldG
= pResData
->sGId
;
242 OString sOldL
= pResData
->sId
;
243 OString sGID
= pResData
->sGId
;
246 sGID
= pResData
->sId
;
248 sLID
= pResData
->sId
;
249 pResData
->sGId
= sGID
;
250 pResData
->sId
= sLID
;
252 OString sKey
= CreateKey( pResData
->sResTyp
, pResData
->sGId
, pResData
->sId
, pResData
->sFilename
, bCaseSensitive
);
254 auto mit
= aMap
.find( sKey
);
255 if(mit
!= aMap
.end())
257 pResData
->sGId
= sOldG
;
258 pResData
->sId
= sOldL
;
259 return mit
->second
.get();
261 pResData
->sGId
= sOldG
;
262 pResData
->sId
= sOldL
;
266 MergeEntrys
*MergeDataFile::GetMergeEntrys( ResData
*pResData
)
268 // search for requested MergeEntrys
269 return GetMergeData( pResData
);
272 MergeEntrys
*MergeDataFile::GetMergeEntrysCaseSensitive( ResData
*pResData
)
274 // search for requested MergeEntrys
275 return GetMergeData( pResData
, true );
278 void MergeDataFile::InsertEntry(
279 std::string_view rTYP
, std::string_view rGID
,
280 std::string_view rLID
, const OString
&nLANG
,
281 const OString
&rTEXT
, const OString
&rQHTEXT
,
282 const OString
&rTITLE
, const OString
&rInFilename
,
283 bool bFirstLang
, bool bCaseSensitive
)
285 MergeEntrys
*pMergeEntrys
= nullptr;
287 // search for MergeData
288 OString sKey
= CreateKey(rTYP
, rGID
, rLID
, rInFilename
, bCaseSensitive
);
292 auto mit
= aMap
.find( sKey
);
293 if(mit
!= aMap
.end())
294 pMergeEntrys
= mit
->second
.get();
300 pMergeEntrys
= new MergeEntrys
;
301 aMap
.emplace( sKey
, std::unique_ptr
<MergeEntrys
>(pMergeEntrys
) );
305 // insert the cur string
308 const OString sTemp
= rInFilename
+ rGID
+ rLID
+ rTYP
;
309 pMergeEntrys
->InsertEntry(
311 rTEXT
.isEmpty()? rTEXT
: PoEntry::genKeyId(sTemp
+ rTEXT
) + GetDoubleBars() + rTEXT
,
312 rQHTEXT
.isEmpty()? rQHTEXT
: PoEntry::genKeyId(sTemp
+ rQHTEXT
) + GetDoubleBars() + rQHTEXT
,
313 rTITLE
.isEmpty()? rTITLE
: PoEntry::genKeyId(sTemp
+ rTITLE
) + GetDoubleBars() + rTITLE
);
317 pMergeEntrys
->InsertEntry( nLANG
, rTEXT
, rQHTEXT
, rTITLE
);
321 OString
MergeDataFile::CreateKey(std::string_view rTYP
, std::string_view rGID
,
322 std::string_view rLID
, const OString
& rFilename
, bool bCaseSensitive
)
324 static const char sStroke
[] = "-";
325 OString sKey
= OString::Concat(rTYP
) + sStroke
+ rGID
+ sStroke
+ rLID
+ sStroke
+
326 lcl_NormalizeFilename(rFilename
);
328 return sKey
; // officecfg case sensitive identifier
329 return sKey
.toAsciiUpperCase();
332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */