Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "sal/config.h"
30 : :
31 : : #include <cstddef>
32 : : #include <fstream>
33 : : #include <iterator>
34 : : #include <string>
35 : :
36 : : #include "common.hxx"
37 : : #include "lngmerge.hxx"
38 : :
39 : : namespace {
40 : :
41 : 0 : rtl::OString getBracketedContent(rtl::OString text) {
42 : 0 : return text.getToken(1, '[').getToken(0, ']');
43 : : }
44 : :
45 : : }
46 : :
47 : : //
48 : : // class LngParser
49 : : //
50 : 0 : LngParser::LngParser(const rtl::OString &rLngFile,
51 : : sal_Bool bULFFormat)
52 : : : nError( LNG_OK )
53 : : , pLines( NULL )
54 : : , sSource( rLngFile )
55 : 0 : , bULF( bULFFormat )
56 : : {
57 : 0 : pLines = new LngLineList();
58 : 0 : std::ifstream aStream(sSource.getStr());
59 : 0 : if (aStream.is_open())
60 : : {
61 : 0 : bool bFirstLine = true;
62 : 0 : while (!aStream.eof())
63 : : {
64 : 0 : std::string s;
65 : 0 : std::getline(aStream, s);
66 : 0 : rtl::OString sLine(s.data(), s.length());
67 : :
68 : 0 : if( bFirstLine )
69 : : {
70 : : // Always remove UTF8 BOM from the first line
71 : 0 : Export::RemoveUTF8ByteOrderMarker( sLine );
72 : 0 : bFirstLine = false;
73 : : }
74 : :
75 : 0 : pLines->push_back( new rtl::OString(sLine) );
76 : 0 : }
77 : : }
78 : : else
79 : 0 : nError = LNG_COULD_NOT_OPEN;
80 : 0 : }
81 : :
82 : 0 : LngParser::~LngParser()
83 : : {
84 : 0 : for ( size_t i = 0, n = pLines->size(); i < n; ++i )
85 : 0 : delete (*pLines)[ i ];
86 : 0 : pLines->clear();
87 : 0 : delete pLines;
88 : 0 : }
89 : :
90 : 0 : sal_Bool LngParser::CreateSDF(const rtl::OString &rSDFFile,
91 : : const rtl::OString &rPrj, const rtl::OString &rRoot)
92 : : {
93 : :
94 : 0 : Export::InitLanguages( false );
95 : 0 : aLanguages = Export::GetLanguages();
96 : : std::ofstream aSDFStream(
97 : 0 : rSDFFile.getStr(), std::ios_base::out | std::ios_base::trunc);
98 : 0 : if (!aSDFStream.is_open()) {
99 : 0 : nError = SDF_COULD_NOT_OPEN;
100 : : }
101 : 0 : nError = SDF_OK;
102 : : rtl::OString sActFileName(
103 : 0 : common::pathnameToken(sSource.getStr(), rRoot.getStr()));
104 : :
105 : 0 : size_t nPos = 0;
106 : 0 : sal_Bool bStart = true;
107 : 0 : rtl::OString sGroup, sLine;
108 : 0 : OStringHashMap Text;
109 : 0 : rtl::OString sID;
110 : :
111 : 0 : while( nPos < pLines->size() ) {
112 : 0 : sLine = *(*pLines)[ nPos++ ];
113 : 0 : while( nPos < pLines->size() && !isNextGroup( sGroup , sLine ) ) {
114 : 0 : ReadLine( sLine , Text );
115 : 0 : sID = sGroup;
116 : 0 : sLine = *(*pLines)[ nPos++ ];
117 : : };
118 : 0 : if( bStart ) {
119 : 0 : bStart = false;
120 : 0 : sID = sGroup;
121 : : }
122 : : else {
123 : 0 : WriteSDF( aSDFStream , Text , rPrj , rRoot , sActFileName , sID );
124 : : }
125 : : }
126 : 0 : aSDFStream.close();
127 : 0 : return true;
128 : : }
129 : :
130 : 0 : void LngParser::WriteSDF(std::ofstream &aSDFStream,
131 : : OStringHashMap &rText_inout, const rtl::OString &rPrj,
132 : : const rtl::OString &rRoot, const rtl::OString &rActFileName,
133 : : const rtl::OString &rID)
134 : : {
135 : :
136 : 0 : sal_Bool bExport = true;
137 : 0 : if ( bExport ) {
138 : 0 : rtl::OString sCur;
139 : 0 : for( unsigned int n = 0; n < aLanguages.size(); n++ ){
140 : 0 : sCur = aLanguages[ n ];
141 : 0 : rtl::OString sAct = rText_inout[ sCur ];
142 : 0 : if ( sAct.isEmpty() && !sCur.isEmpty() )
143 : 0 : sAct = rText_inout[ rtl::OString("en-US") ];
144 : :
145 : 0 : rtl::OString sOutput( rPrj ); sOutput += "\t";
146 : 0 : if (rRoot.getLength())
147 : 0 : sOutput += rActFileName;
148 : 0 : sOutput += "\t0\t";
149 : 0 : sOutput += "LngText\t";
150 : 0 : sOutput += rID; sOutput += "\t\t\t\t0\t";
151 : 0 : sOutput += sCur; sOutput += "\t";
152 : 0 : sOutput += sAct; sOutput += "\t\t\t\t";
153 : 0 : aSDFStream << sOutput.getStr() << '\n';
154 : 0 : }
155 : : }
156 : 0 : }
157 : :
158 : 0 : bool LngParser::isNextGroup(rtl::OString &sGroup_out, rtl::OString &sLine_in)
159 : : {
160 : 0 : sLine_in = sLine_in.trim();
161 : 0 : if ((sLine_in[0] == '[') && (sLine_in[sLine_in.getLength() - 1] == ']'))
162 : : {
163 : 0 : sGroup_out = getBracketedContent(sLine_in).trim();
164 : 0 : return true;
165 : : }
166 : 0 : return false;
167 : : }
168 : :
169 : 0 : void LngParser::ReadLine(const rtl::OString &rLine_in,
170 : : OStringHashMap &rText_inout)
171 : : {
172 : 0 : rtl::OString sLang(rLine_in.getToken(0, '=').trim());
173 : 0 : if (!sLang.isEmpty()) {
174 : 0 : rtl::OString sText(rLine_in.getToken(1, '"'));
175 : 0 : rText_inout[sLang] = sText;
176 : 0 : }
177 : 0 : }
178 : :
179 : 0 : sal_Bool LngParser::Merge(
180 : : const rtl::OString &rSDFFile,
181 : : const rtl::OString &rDestinationFile)
182 : : {
183 : 0 : Export::InitLanguages( true );
184 : : std::ofstream aDestination(
185 : 0 : rDestinationFile.getStr(), std::ios_base::out | std::ios_base::trunc);
186 : 0 : if (!aDestination.is_open()) {
187 : 0 : nError = LNG_COULD_NOT_OPEN;
188 : : }
189 : 0 : nError = LNG_OK;
190 : :
191 : 0 : MergeDataFile aMergeDataFile( rSDFFile, sSource, false );
192 : 0 : rtl::OString sTmp( Export::sLanguages );
193 : 0 : if( sTmp.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("ALL")) )
194 : 0 : Export::SetLanguages( aMergeDataFile.GetLanguages() );
195 : 0 : aLanguages = Export::GetLanguages();
196 : :
197 : 0 : size_t nPos = 0;
198 : 0 : sal_Bool bGroup = sal_False;
199 : 0 : rtl::OString sGroup;
200 : :
201 : : // seek to next group
202 : 0 : while ( nPos < pLines->size() && !bGroup )
203 : : {
204 : 0 : rtl::OString sLine( *(*pLines)[ nPos ] );
205 : 0 : sLine = sLine.trim();
206 : 0 : if (( sLine[0] == '[' ) &&
207 : 0 : ( sLine[sLine.getLength() - 1] == ']' ))
208 : : {
209 : 0 : sGroup = getBracketedContent(sLine).trim();
210 : 0 : bGroup = sal_True;
211 : : }
212 : 0 : nPos ++;
213 : 0 : }
214 : :
215 : 0 : while ( nPos < pLines->size()) {
216 : 0 : OStringHashMap Text;
217 : 0 : rtl::OString sID( sGroup );
218 : 0 : std::size_t nLastLangPos = 0;
219 : :
220 : 0 : ResData *pResData = new ResData( "", sID , sSource );
221 : 0 : pResData->sResTyp = "LngText";
222 : 0 : PFormEntrys *pEntrys = aMergeDataFile.GetPFormEntrys( pResData );
223 : : // read languages
224 : 0 : bGroup = sal_False;
225 : :
226 : 0 : rtl::OString sLanguagesDone;
227 : :
228 : 0 : while ( nPos < pLines->size() && !bGroup )
229 : : {
230 : 0 : rtl::OString sLine( *(*pLines)[ nPos ] );
231 : 0 : sLine = sLine.trim();
232 : 0 : if (( sLine[0] == '[' ) &&
233 : 0 : ( sLine[sLine.getLength() - 1] == ']' ))
234 : : {
235 : 0 : sGroup = getBracketedContent(sLine).trim();
236 : 0 : bGroup = sal_True;
237 : 0 : nPos ++;
238 : 0 : sLanguagesDone = "";
239 : : }
240 : : else
241 : : {
242 : 0 : sal_Int32 n = 0;
243 : 0 : rtl::OString sLang(sLine.getToken(0, '=', n));
244 : 0 : if (n == -1)
245 : : {
246 : 0 : ++nPos;
247 : : }
248 : : else
249 : : {
250 : 0 : sLang = sLang.trim();
251 : :
252 : 0 : rtl::OString sSearch( ";" );
253 : 0 : sSearch += sLang;
254 : 0 : sSearch += ";";
255 : :
256 : 0 : if (( sLanguagesDone.indexOf( sSearch ) != -1 )) {
257 : 0 : LngLineList::iterator it = pLines->begin();
258 : 0 : std::advance( it, nPos );
259 : 0 : pLines->erase( it );
260 : : }
261 : 0 : if( bULF && pEntrys )
262 : : {
263 : 0 : if( !sLang.isEmpty() )
264 : : {
265 : 0 : rtl::OString sNewText;
266 : 0 : pEntrys->GetText( sNewText, STRING_TYP_TEXT, sLang, sal_True );
267 : :
268 : 0 : if ( !sNewText.isEmpty()) {
269 : 0 : rtl::OString *pLine = (*pLines)[ nPos ];
270 : :
271 : 0 : rtl::OString sText1( sLang );
272 : 0 : sText1 += " = \"";
273 : 0 : sText1 += sNewText;
274 : 0 : sText1 += "\"";
275 : 0 : *pLine = sText1;
276 : 0 : Text[ sLang ] = sNewText;
277 : 0 : }
278 : : }
279 : 0 : nLastLangPos = nPos;
280 : 0 : nPos ++;
281 : 0 : sLanguagesDone += sSearch;
282 : : }
283 : : else {
284 : 0 : nLastLangPos = nPos;
285 : 0 : nPos ++;
286 : 0 : sLanguagesDone += sSearch;
287 : 0 : }
288 : 0 : }
289 : : }
290 : 0 : }
291 : 0 : rtl::OString sCur;
292 : 0 : if ( nLastLangPos )
293 : : {
294 : 0 : for(size_t n = 0; n < aLanguages.size(); ++n)
295 : : {
296 : 0 : sCur = aLanguages[ n ];
297 : 0 : if( !sCur.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("en-US")) && Text[sCur].isEmpty() && pEntrys )
298 : : {
299 : :
300 : 0 : rtl::OString sNewText;
301 : 0 : pEntrys->GetText( sNewText, STRING_TYP_TEXT, sCur, sal_True );
302 : 0 : if (( !sNewText.isEmpty()) &&
303 : 0 : !(( sCur.equalsL(RTL_CONSTASCII_STRINGPARAM("x-comment"))) && ( sNewText == "-" )))
304 : : {
305 : 0 : rtl::OString sLine;
306 : 0 : sLine += sCur;
307 : 0 : sLine += " = \"";
308 : 0 : sLine += sNewText;
309 : 0 : sLine += "\"";
310 : :
311 : 0 : nLastLangPos++;
312 : 0 : nPos++;
313 : :
314 : 0 : if ( nLastLangPos < pLines->size() ) {
315 : 0 : LngLineList::iterator it = pLines->begin();
316 : 0 : std::advance( it, nLastLangPos );
317 : 0 : pLines->insert( it, new rtl::OString(sLine) );
318 : : } else {
319 : 0 : pLines->push_back( new rtl::OString(sLine) );
320 : 0 : }
321 : 0 : }
322 : : }
323 : : }
324 : : }
325 : :
326 : 0 : delete pResData;
327 : 0 : }
328 : :
329 : 0 : for ( size_t i = 0; i < pLines->size(); ++i )
330 : 0 : aDestination << (*pLines)[i]->getStr() << '\n';
331 : :
332 : 0 : aDestination.close();
333 : 0 : return sal_True;
334 : 0 : }
335 : :
336 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|