Bump for 3.6-28
[LibreOffice.git] / l10ntools / source / helpmerge.cxx
blobfc8e76c21debdecedaa036d898e73b66ba847b95
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
29 #include "sal/config.h"
31 #include <fstream>
32 #include <functional>
34 #include <osl/file.hxx>
35 #include <sal/log.hxx>
36 // local includes
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include "helpmerge.hxx"
40 #include <algorithm>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <iostream>
44 #include <fstream>
45 #include <vector>
46 #include <rtl/strbuf.hxx>
47 #ifdef WNT
48 #include <windows.h>
49 #undef CopyFile
50 #include <direct.h>
51 #endif
53 #include "common.hxx"
54 #include "helper.hxx"
55 #include "gsicheck.hxx"
57 #if OSL_DEBUG_LEVEL > 2
58 void HelpParser::Dump(XMLHashMap* rElem_in)
60 for(XMLHashMap::iterator pos = rElem_in->begin();pos != rElem_in->end(); ++pos)
62 Dump(pos->second,pos->first);
66 void HelpParser::Dump(LangHashMap* rElem_in,const rtl::OString & sKey_in)
68 rtl::OString x;
69 OString y;
70 fprintf(stdout,"+------------%s-----------+\n",sKey_in.getStr() );
71 for(LangHashMap::iterator posn=rElem_in->begin();posn!=rElem_in->end();++posn)
73 x=posn->first;
74 y=posn->second->ToOString();
75 fprintf(stdout,"key=%s value=%s\n",x.getStr(),y.getStr());
77 fprintf(stdout,"+--------------------------+\n");
79 #endif
81 HelpParser::HelpParser( const rtl::OString &rHelpFile, bool rUTF8 , bool rHasInputList )
82 : sHelpFile( rHelpFile ),
83 bUTF8 ( rUTF8 ),
84 bHasInputList( rHasInputList )
85 {};
87 /*****************************************************************************/
88 bool HelpParser::CreateSDF(
89 /*****************************************************************************/
90 const rtl::OString &rSDFFile_in, const rtl::OString &rPrj_in,const rtl::OString &rRoot_in,
91 const rtl::OString &sHelpFile, XMLFile *pXmlFile, const rtl::OString &rGsi1){
92 SimpleXMLParser aParser;
93 rtl::OUString sXmlFile(
94 rtl::OStringToOUString(sHelpFile, RTL_TEXTENCODING_ASCII_US));
95 //TODO: explicit BOM handling?
97 std::auto_ptr <XMLFile> file ( aParser.Execute( sXmlFile, pXmlFile ) );
99 if(file.get() == NULL)
101 printf(
102 "%s: %s\n",
103 sHelpFile.getStr(),
104 (rtl::OUStringToOString(
105 aParser.GetError().sMessage, RTL_TEXTENCODING_ASCII_US).
106 getStr()));
107 exit(-1);
109 file->Extract();
110 if( !file->CheckExportStatus() ){
111 return true;
113 std::ofstream aSDFStream(
114 rSDFFile_in.getStr(), std::ios_base::out | std::ios_base::trunc);
116 if (!aSDFStream.is_open()) {
117 fprintf(stdout,"Can't open file %s\n",rSDFFile_in.getStr());
118 return false;
121 rtl::OString sActFileName(
122 common::pathnameToken(sHelpFile.getStr(), rRoot_in.getStr()));
124 XMLHashMap* aXMLStrHM = file->GetStrings();
125 LangHashMap* pElem;
126 XMLElement* pXMLElement = NULL;
128 OUStringBuffer sBuffer;
129 const OUString sOUPrj( rPrj_in.getStr() , rPrj_in.getLength() , RTL_TEXTENCODING_ASCII_US );
130 const OUString sOUActFileName(sActFileName.getStr() , sActFileName.getLength() , RTL_TEXTENCODING_ASCII_US );
131 const OUString sOUGsi1( rGsi1.getStr() , rGsi1.getLength() , RTL_TEXTENCODING_ASCII_US );
133 Export::InitLanguages( false );
134 std::vector<rtl::OString> aLanguages = Export::GetLanguages();
136 std::vector<rtl::OString> order = file->getOrder();
137 std::vector<rtl::OString>::iterator pos;
138 XMLHashMap::iterator posm;
140 for( pos = order.begin(); pos != order.end() ; ++pos )
142 posm = aXMLStrHM->find( *pos );
143 pElem = posm->second;
144 rtl::OString sCur;
146 for( unsigned int n = 0; n < aLanguages.size(); n++ )
148 sCur = aLanguages[ n ];
149 pXMLElement = (*pElem)[ sCur ];
151 if( pXMLElement != NULL )
153 OUString data(
154 pXMLElement->ToOUString().
155 replaceAll(
156 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n")),
157 rtl::OUString()).
158 replaceAll(
159 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t")),
160 rtl::OUString()));
161 sBuffer.append( sOUPrj );
162 sBuffer.append('\t');
163 if ( !rRoot_in.isEmpty())
164 sBuffer.append( sOUActFileName );
165 sBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\t0\t"));
166 sBuffer.append( sOUGsi1 ); //"help";
167 sBuffer.append('\t');
168 rtl::OString sID = posm->first; // ID
169 sBuffer.append( rtl::OStringToOUString( sID, RTL_TEXTENCODING_UTF8 ) );
170 sBuffer.append('\t');
171 rtl::OString sOldRef = pXMLElement->GetOldref(); // oldref
172 sBuffer.append( rtl::OStringToOUString(sOldRef, RTL_TEXTENCODING_UTF8 ) );
173 sBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\t\t\t0\t"));
174 sBuffer.append( rtl::OStringToOUString( sCur, RTL_TEXTENCODING_UTF8 ) );
175 sBuffer.append('\t');
176 sBuffer.append( data );
177 sBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\t\t\t\t"));
178 rtl::OString sOut(rtl::OUStringToOString(sBuffer.makeStringAndClear().getStr() , RTL_TEXTENCODING_UTF8));
179 if( !data.isEmpty() )
180 aSDFStream << sOut.getStr() << '\n';
181 pXMLElement=NULL;
183 else
185 fprintf(stdout,"\nDBG: NullPointer in HelpParser::CreateSDF, Language %s, File %s\n", sCur.getStr(), sHelpFile.getStr());
189 aSDFStream.close();
191 return sal_True;
194 bool HelpParser::Merge( const rtl::OString &rSDFFile, const rtl::OString &rDestinationFile ,
195 const rtl::OString& rLanguage , MergeDataFile& aMergeDataFile )
198 (void) rSDFFile;
199 bool hasNoError = true;
201 SimpleXMLParser aParser;
203 rtl::OUString sXmlFile(
204 rtl::OStringToOUString(sHelpFile, RTL_TEXTENCODING_ASCII_US));
205 //TODO: explicit BOM handling?
207 XMLFile* xmlfile = ( aParser.Execute( sXmlFile, new XMLFile( rtl::OUString('0') ) ) );
208 hasNoError = MergeSingleFile( xmlfile , aMergeDataFile , rLanguage , rDestinationFile );
209 delete xmlfile;
210 return hasNoError;
213 void HelpParser::parse_languages( std::vector<rtl::OString>& aLanguages , MergeDataFile& aMergeDataFile ){
214 std::vector<rtl::OString> aTmp;
216 Export::InitLanguages( false );
218 if (Export::sLanguages.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("ALL")))
220 aLanguages = aMergeDataFile.GetLanguages();
221 aLanguages.push_back(rtl::OString(RTL_CONSTASCII_STRINGPARAM("en-US")));
223 if( !Export::sForcedLanguages.isEmpty() )
225 std::vector<rtl::OString> aFL = Export::GetForcedLanguages();
226 std::copy( aFL.begin() ,
227 aFL.end() ,
228 back_inserter( aLanguages )
230 std::sort( aLanguages.begin() , aLanguages.end() , std::less< rtl::OString >() );
231 std::vector<rtl::OString>::iterator unique_iter = std::unique( aLanguages.begin() , aLanguages.end() , std::equal_to< rtl::OString >() );
232 std::copy( aLanguages.begin() , unique_iter , back_inserter( aTmp ) );
233 aLanguages = aTmp;
236 else{
237 aLanguages = Export::GetLanguages();
242 bool HelpParser::Merge(
243 const rtl::OString &rSDFFile, const rtl::OString &rPathX , const rtl::OString &rPathY , bool bISO ,
244 const std::vector<rtl::OString>& aLanguages , MergeDataFile& aMergeDataFile , bool bCreateDir )
248 (void) rSDFFile ;
249 bool hasNoError = true;
250 SimpleXMLParser aParser;
251 rtl::OUString sXmlFile(
252 rtl::OStringToOUString(sHelpFile, RTL_TEXTENCODING_ASCII_US));
253 //TODO: explicit BOM handling?
255 XMLFile* xmlfile = aParser.Execute( sXmlFile, new XMLFile( rtl::OUString('0') ) );
257 if( xmlfile == NULL)
259 printf("%s\n", rtl::OUStringToOString(aParser.GetError().sMessage, RTL_TEXTENCODING_UTF8).getStr());
260 exit(-1);
263 xmlfile->Extract();
265 rtl::OString sCur;
266 for( unsigned int n = 0; n < aLanguages.size(); n++ ){
267 sCur = aLanguages[ n ];
269 rtl::OString sFilepath;
270 if( bISO ) sFilepath = GetOutpath( rPathX , sCur , rPathY );
271 else sFilepath = rPathX;
272 if( bCreateDir )
273 MakeDir(sFilepath);
275 XMLFile* file = new XMLFile( *xmlfile );
276 sFilepath += sHelpFile;
277 hasNoError = MergeSingleFile( file , aMergeDataFile , sCur , sFilepath );
278 delete file;
280 if( !hasNoError ) return false; // Stop on error
283 delete xmlfile;
284 return hasNoError;
287 bool HelpParser::MergeSingleFile( XMLFile* file , MergeDataFile& aMergeDataFile , const rtl::OString& sLanguage ,
288 rtl::OString const & sPath )
290 file->Extract();
292 XMLHashMap* aXMLStrHM = file->GetStrings();
293 LangHashMap* aLangHM;
294 static ResData pResData( "","","");
295 pResData.sResTyp = "help";
297 for(XMLHashMap::iterator pos=aXMLStrHM->begin();pos!=aXMLStrHM->end();++pos) // Merge every l10n related string
300 aLangHM = pos->second;
301 #if OSL_DEBUG_LEVEL > 2
302 printf("*********************DUMPING HASHMAP***************************************");
303 Dump(aXMLStrHM);
304 printf("DBG: sHelpFile = %s\n",sHelpFile.getStr() );
305 #endif
307 pResData.sGId = pos->first;
308 pResData.sFilename = sHelpFile;
310 ProcessHelp( aLangHM , sLanguage, &pResData , aMergeDataFile );
313 file->Write(sPath);
314 return true;
317 rtl::OString HelpParser::GetOutpath( const rtl::OString& rPathX , const rtl::OString& sCur , const rtl::OString& rPathY )
319 rtl::OString testpath = rPathX;
320 if (!testpath.endsWithL(RTL_CONSTASCII_STRINGPARAM("/"))) {
321 testpath += "/";
323 testpath += sCur;
324 testpath += "/";
325 rtl::OString sRelativePath( rPathY );
326 if (sRelativePath.matchL(RTL_CONSTASCII_STRINGPARAM("/"))) {
327 sRelativePath = sRelativePath.copy(1);
329 testpath += sRelativePath;
330 testpath += "/";
331 return testpath;
334 void HelpParser::MakeDir(const rtl::OString& rPath)
336 rtl::OString sTPath(rPath.replaceAll("\\", "/"));
337 sal_Int32 cnt = helper::countOccurrences(sTPath, '/');
338 rtl::OStringBuffer sCreateDir;
339 for (sal_uInt16 i = 0; i <= cnt; ++i)
341 sCreateDir.append(sTPath.getToken(i , '/'));
342 sCreateDir.append('/');
343 #ifdef WNT
344 _mkdir( sCreateDir.getStr() );
345 #else
346 mkdir( sCreateDir.getStr() , S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
347 #endif
352 /* ProcessHelp Methode: search for en-US entry and replace it with the current language*/
353 void HelpParser::ProcessHelp( LangHashMap* aLangHM , const rtl::OString& sCur , ResData *pResData , MergeDataFile& aMergeDataFile ){
355 XMLElement* pXMLElement = NULL;
356 PFormEntrys *pEntrys = NULL;
357 XMLData *data = NULL;
359 rtl::OString sLId;
360 rtl::OString sGId;
362 pEntrys = NULL;
364 if( !sCur.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("en-US")) ){
365 pXMLElement = (*aLangHM)[ "en-US" ];
366 if( pXMLElement == NULL )
368 printf("Error: Can't find en-US entry\n");
370 if( pXMLElement != NULL )
372 sLId = pXMLElement->GetOldref();
373 pResData->sId = sLId;
375 pEntrys = aMergeDataFile.GetPFormEntrys( pResData );
376 if( pEntrys != NULL)
378 rtl::OString sNewText;
379 pEntrys->GetText( sNewText, STRING_TYP_TEXT, sCur , true );
380 rtl::OUString sNewdata(
381 rtl::OStringToOUString(sNewText, RTL_TEXTENCODING_UTF8));
382 if (!sNewdata.isEmpty())
384 if( pXMLElement != NULL )
386 if (check(pEntrys->GetSDF(sCur),pEntrys->GetNLine(sCur)))
388 data = new XMLData( sNewdata , NULL , true ); // Add new one
389 pXMLElement->RemoveAndDeleteAllChildren();
390 pXMLElement->AddChild( data );
392 aLangHM->erase( sCur );
396 else if( pResData == NULL )
398 fprintf(stdout,"Can't find GID=%s LID=%s TYP=%s\n",
399 pResData->sGId.getStr(), pResData->sId.getStr(),
400 pResData->sResTyp.getStr());
402 pXMLElement->ChangeLanguageTag(
403 rtl::OStringToOUString(sCur, RTL_TEXTENCODING_ASCII_US));
409 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */