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"
30 #include "xrmmerge.hxx"
36 #include <boost/scoped_array.hpp>
40 void yyerror( const char * );
42 // set of global variables
45 bool bExtensionDescription
;
47 OString sInputFileName
;
50 OString sLangAttribute
;
51 OString sResourceType
;
52 XRMResParser
*pParser
= NULL
;
55 // the whole interface to lexer is in this extern "C" section
57 extern bool GetOutputFile( int argc
, char* argv
[])
60 bExtensionDescription
= false;
62 common::HandledArgs aArgs
;
63 if ( common::handleArguments(argc
, argv
, aArgs
) )
65 bMergeMode
= aArgs
.m_bMergeMode
;
66 sLanguage
= aArgs
.m_sLanguage
;
67 sInputFileName
= aArgs
.m_sInputFile
;
68 sOutputFile
= aArgs
.m_sOutputFile
;
69 sMergeSrc
= aArgs
.m_sMergeSrc
;
74 // command line is not valid
75 common::writeUsage("xrmex","*.xrm/*.xml");
80 int InitXrmExport( const char* pFilename
)
83 OString
sFilename( pFilename
);
86 pParser
= new XRMResMerge( sMergeSrc
, sOutputFile
, sFilename
);
87 else if (!sOutputFile
.isEmpty()) {
88 pParser
= new XRMResExport( sOutputFile
, sInputFileName
);
99 extern const char* getFilename()
101 return sInputFileName
.getStr();
104 extern FILE *GetXrmFile()
106 // look for valid filename
107 if (!sInputFileName
.isEmpty()) {
108 //TODO: explicit BOM handling?
109 FILE * pFile
= fopen(sInputFileName
.getStr(), "r");
111 fprintf( stderr
, "Error: Could not open file %s\n",
112 sInputFileName
.getStr());
118 // this means the file could not be opened
122 int WorkOnTokenSet( int nTyp
, char *pTokenText
)
124 //printf("Typ = %d , text = '%s'\n",nTyp , pTokenText );
125 pParser
->Execute( nTyp
, pTokenText
);
141 return pParser
->GetError();
146 // class XRMResParser
150 XRMResParser::XRMResParser()
156 XRMResParser::~XRMResParser()
160 int XRMResParser::Execute( int nToken
, char * pToken
)
162 OString
rToken( pToken
);
165 case XRM_TEXT_START
:{
166 OString sNewGID
= GetAttribute( rToken
, "id" );
167 if ( sNewGID
!= sGID
) {
172 sCurrentOpenTag
= rToken
;
178 sCurrentCloseTag
= rToken
;
179 sResourceType
= OString ( "readmeitem" );
180 sLangAttribute
= OString ( "xml:lang" );
181 WorkOnText( sCurrentOpenTag
, sCurrentText
);
182 Output( sCurrentText
);
183 EndOfText( sCurrentOpenTag
, sCurrentCloseTag
);
185 rToken
= OString("");
186 sCurrentText
= OString("");
190 case DESC_DISPLAY_NAME_START
:{
195 case DESC_DISPLAY_NAME_END
:{
196 bDisplayName
= false;
200 case DESC_TEXT_START
:{
202 sGID
= OString("dispname");
205 sCurrentOpenTag
= rToken
;
211 case DESC_TEXT_END
: {
213 sCurrentCloseTag
= rToken
;
214 sResourceType
= OString ( "description" );
215 sLangAttribute
= OString ( "lang" );
216 WorkOnText( sCurrentOpenTag
, sCurrentText
);
217 Output( sCurrentText
);
218 EndOfText( sCurrentOpenTag
, sCurrentCloseTag
);
220 rToken
= OString("");
221 sCurrentText
= OString("");
226 case DESC_EXTENSION_DESCRIPTION_START
: {
227 bExtensionDescription
= true;
231 case DESC_EXTENSION_DESCRIPTION_END
: {
232 bExtensionDescription
= false;
236 case DESC_EXTENSION_DESCRIPTION_SRC
: {
237 if (bExtensionDescription
) {
238 sGID
= OString("extdesc");
239 sResourceType
= OString ( "description" );
240 sLangAttribute
= OString ( "lang" );
241 sCurrentOpenTag
= rToken
;
242 sCurrentText
= OString("");
244 WorkOnDesc( sCurrentOpenTag
, sCurrentText
);
245 sCurrentCloseTag
= rToken
;
246 Output( sCurrentText
);
247 rToken
= OString("");
248 sCurrentText
= OString("");
255 sCurrentText
+= rToken
;
267 OString
XRMResParser::GetAttribute( const OString
&rToken
, const OString
&rAttribute
)
269 OString
sTmp( rToken
);
270 sTmp
= sTmp
.replace('\t', ' ');
272 OString
sSearch( " " );
273 sSearch
+= rAttribute
;
275 sal_Int32 nPos
= sTmp
.indexOf( sSearch
);
279 sTmp
= sTmp
.copy( nPos
);
280 OString sId
= sTmp
.getToken(1, '"');
287 void XRMResParser::Error( const OString
&rError
)
289 yyerror(rError
.getStr());
293 // class XMLResExport
296 XRMResExport::XRMResExport(
297 const OString
&rOutputFile
, const OString
&rFilePath
)
302 pOutputStream
.open( rOutputFile
, PoOfstream::APP
);
303 if (!pOutputStream
.isOpen())
305 OString
sError( "Unable to open output file: " );
306 sError
+= rOutputFile
;
311 XRMResExport::~XRMResExport()
313 pOutputStream
.close();
317 void XRMResExport::Output( const OString
& ) {}
319 void XRMResExport::WorkOnDesc(
320 const OString
&rOpenTag
,
323 OString
sDescFileName(
324 sInputFileName
.replaceAll("description.xml", OString()));
325 sDescFileName
+= GetAttribute( rOpenTag
, "xlink:href" );
326 ifstream
file (sDescFileName
.getStr(), ios::in
|ios::binary
|ios::ate
);
327 if (file
.is_open()) {
328 int size
= static_cast<int>(file
.tellg());
329 boost::scoped_array
<char> memblock(new char [size
+1]);
330 file
.seekg (0, ios::beg
);
331 file
.read (memblock
.get(), size
);
333 memblock
[size
] = '\0';
334 rText
= OString(memblock
.get());
336 WorkOnText( rOpenTag
, rText
);
337 EndOfText( rOpenTag
, rOpenTag
);
340 void XRMResExport::WorkOnText(
341 const OString
&rOpenTag
,
344 OString
sLang( GetAttribute( rOpenTag
, sLangAttribute
));
348 pResData
= new ResData( GetGID() );
350 pResData
->sText
[sLang
] = rText
;
353 void XRMResExport::EndOfText(
359 OString sAct
= pResData
->sText
["en-US"];
361 if( !sAct
.isEmpty() )
362 common::writePoEntry(
363 "Xrmex", pOutputStream
, sPath
, sResourceType
,
364 pResData
->sGId
, OString(), OString(), sAct
);
374 XRMResMerge::XRMResMerge(
375 const OString
&rMergeSource
, const OString
&rOutputFile
,
376 const OString
&rFilename
)
378 pMergeDataFile( NULL
),
379 sFilename( rFilename
) ,
382 if (!rMergeSource
.isEmpty() && sLanguage
.equalsIgnoreAsciiCase("ALL"))
384 pMergeDataFile
= new MergeDataFile(
385 rMergeSource
, sInputFileName
, false);
386 aLanguages
= pMergeDataFile
->GetLanguages();
389 aLanguages
.push_back( sLanguage
);
391 rOutputFile
.getStr(), std::ios_base::out
| std::ios_base::trunc
);
392 if (!pOutputStream
.is_open()) {
393 OString
sError( "Unable to open output file: " );
394 sError
+= rOutputFile
;
399 XRMResMerge::~XRMResMerge()
401 pOutputStream
.close();
402 delete pMergeDataFile
;
406 void XRMResMerge::WorkOnDesc(
407 const OString
&rOpenTag
,
410 WorkOnText( rOpenTag
, rText
);
411 if ( pMergeDataFile
&& pResData
) {
412 MergeEntrys
*pEntrys
= pMergeDataFile
->GetMergeEntrys( pResData
);
415 OString sDescFilename
= GetAttribute ( rOpenTag
, "xlink:href" );
416 for( unsigned int n
= 0; n
< aLanguages
.size(); n
++ ){
417 sCur
= aLanguages
[ n
];
419 if ( !sCur
.equalsIgnoreAsciiCase("en-US") &&
421 sContent
, STRING_TYP_TEXT
, sCur
, true )) &&
424 OString
sText( sContent
);
425 OString
sAdditionalLine( "\n " );
426 sAdditionalLine
+= rOpenTag
;
427 OString sSearch
= sLangAttribute
;
429 OString
sReplace( sSearch
);
431 sSearch
+= GetAttribute( rOpenTag
, sLangAttribute
);
433 sAdditionalLine
= sAdditionalLine
.replaceFirst(
436 sSearch
= OString("xlink:href=\"");
439 OString sLocDescFilename
= sDescFilename
;
440 sLocDescFilename
= sLocDescFilename
.replaceFirst(
443 sSearch
+= sDescFilename
;
444 sReplace
+= sLocDescFilename
;
445 sAdditionalLine
= sAdditionalLine
.replaceFirst(
448 Output( sAdditionalLine
);
450 sal_Int32 i
= sOutputFile
.lastIndexOf('/');
453 << "Error: output file " << sOutputFile
.getStr()
454 << " does not contain any /\n";
457 OString
sOutputDescFile(
458 sOutputFile
.copy(0, i
+ 1) + sLocDescFilename
);
459 ofstream
file(sOutputDescFile
.getStr());
460 if (file
.is_open()) {
461 file
<< sText
.getStr();
465 << "Error: cannot write "
466 << sOutputDescFile
.getStr() << '\n';
477 void XRMResMerge::WorkOnText(
481 if ( pMergeDataFile
) {
483 pResData
= new ResData( GetGID(), sFilename
);
484 pResData
->sResTyp
= sResourceType
;
489 void XRMResMerge::Output( const OString
& rOutput
)
491 if (!rOutput
.isEmpty())
492 pOutputStream
<< rOutput
.getStr();
495 void XRMResMerge::EndOfText(
496 const OString
&rOpenTag
,
497 const OString
&rCloseTag
)
501 if ( pMergeDataFile
&& pResData
) {
502 MergeEntrys
*pEntrys
= pMergeDataFile
->GetMergeEntrys( pResData
);
505 for( unsigned int n
= 0; n
< aLanguages
.size(); n
++ ){
506 sCur
= aLanguages
[ n
];
508 if (!sCur
.equalsIgnoreAsciiCase("en-US") &&
510 sContent
, STRING_TYP_TEXT
, sCur
, true )) &&
511 !sContent
.isEmpty() &&
512 helper::isWellFormedXML( sContent
))
514 OString
sText( sContent
);
515 OString
sAdditionalLine( "\n " );
516 sAdditionalLine
+= rOpenTag
;
517 OString sSearch
= sLangAttribute
;
519 OString
sReplace( sSearch
);
521 sSearch
+= GetAttribute( rOpenTag
, sLangAttribute
);
524 sAdditionalLine
= sAdditionalLine
.replaceFirst(
527 sAdditionalLine
+= sText
;
528 sAdditionalLine
+= rCloseTag
;
530 Output( sAdditionalLine
);
539 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */