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"
34 #include <osl/file.hxx>
35 #include <sal/log.hxx>
39 #include "helpmerge.hxx"
41 #include <sys/types.h>
46 #include <rtl/strbuf.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
)
70 fprintf(stdout
,"+------------%s-----------+\n",sKey_in
.getStr() );
71 for(LangHashMap::iterator posn
=rElem_in
->begin();posn
!=rElem_in
->end();++posn
)
74 y
=posn
->second
->ToOString();
75 fprintf(stdout
,"key=%s value=%s\n",x
.getStr(),y
.getStr());
77 fprintf(stdout
,"+--------------------------+\n");
81 HelpParser::HelpParser( const rtl::OString
&rHelpFile
, bool rUTF8
, bool rHasInputList
)
82 : sHelpFile( rHelpFile
),
84 bHasInputList( rHasInputList
)
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
)
104 (rtl::OUStringToOString(
105 aParser
.GetError().sMessage
, RTL_TEXTENCODING_ASCII_US
).
110 if( !file
->CheckExportStatus() ){
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());
121 rtl::OString
sActFileName(
122 common::pathnameToken(sHelpFile
.getStr(), rRoot_in
.getStr()));
124 XMLHashMap
* aXMLStrHM
= file
->GetStrings();
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
;
146 for( unsigned int n
= 0; n
< aLanguages
.size(); n
++ )
148 sCur
= aLanguages
[ n
];
149 pXMLElement
= (*pElem
)[ sCur
];
151 if( pXMLElement
!= NULL
)
154 pXMLElement
->ToOUString().
156 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n")),
159 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t")),
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';
185 fprintf(stdout
,"\nDBG: NullPointer in HelpParser::CreateSDF, Language %s, File %s\n", sCur
.getStr(), sHelpFile
.getStr());
194 bool HelpParser::Merge( const rtl::OString
&rSDFFile
, const rtl::OString
&rDestinationFile
,
195 const rtl::OString
& rLanguage
, MergeDataFile
& aMergeDataFile
)
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
);
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() ,
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
) );
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
)
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') ) );
259 printf("%s\n", rtl::OUStringToOString(aParser
.GetError().sMessage
, RTL_TEXTENCODING_UTF8
).getStr());
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
;
275 XMLFile
* file
= new XMLFile( *xmlfile
);
276 sFilepath
+= sHelpFile
;
277 hasNoError
= MergeSingleFile( file
, aMergeDataFile
, sCur
, sFilepath
);
280 if( !hasNoError
) return false; // Stop on error
287 bool HelpParser::MergeSingleFile( XMLFile
* file
, MergeDataFile
& aMergeDataFile
, const rtl::OString
& sLanguage
,
288 rtl::OString
const & sPath
)
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***************************************");
304 printf("DBG: sHelpFile = %s\n",sHelpFile
.getStr() );
307 pResData
.sGId
= pos
->first
;
308 pResData
.sFilename
= sHelpFile
;
310 ProcessHelp( aLangHM
, sLanguage
, &pResData
, aMergeDataFile
);
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("/"))) {
325 rtl::OString
sRelativePath( rPathY
);
326 if (sRelativePath
.matchL(RTL_CONSTASCII_STRINGPARAM("/"))) {
327 sRelativePath
= sRelativePath
.copy(1);
329 testpath
+= sRelativePath
;
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('/');
344 _mkdir( sCreateDir
.getStr() );
346 mkdir( sCreateDir
.getStr() , S_IRWXU
| S_IRWXG
| S_IROTH
| S_IXOTH
);
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
;
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
);
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: */