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"
29 #include "xrmmerge.hxx"
38 void yyerror( const char * );
39 void YYWarning( const char * );
41 // set of global variables
43 sal_Bool bDisplayName
;
44 sal_Bool bExtensionDescription
;
46 OString sInputFileName
;
49 OString sLangAttribute
;
50 OString sResourceType
;
51 XRMResParser
*pParser
= NULL
;
54 // the whole interface to lexer is in this extern "C" section
56 extern char *GetOutputFile( int argc
, char* argv
[])
58 bDisplayName
= sal_False
;
59 bExtensionDescription
= sal_False
;
61 common::HandledArgs aArgs
;
62 if ( common::handleArguments(argc
, argv
, aArgs
) )
64 bMergeMode
= aArgs
.m_bMergeMode
;
65 sLanguage
= aArgs
.m_sLanguage
;
66 sInputFileName
= aArgs
.m_sInputFile
;
67 sOutputFile
= aArgs
.m_sOutputFile
;
68 sMergeSrc
= aArgs
.m_sMergeSrc
;
69 char *pReturn
= new char[ sOutputFile
.getLength() + 1 ];
70 std::strcpy( pReturn
, sOutputFile
.getStr());
75 // command line is not valid
76 common::writeUsage("xrmex","*.xrm/*.xml");
81 int InitXrmExport( char*, char* pFilename
)
84 OString
sFilename( pFilename
);
87 pParser
= new XRMResMerge( sMergeSrc
, sOutputFile
, sFilename
);
88 else if (!sOutputFile
.isEmpty()) {
89 pParser
= new XRMResExport( sOutputFile
, sInputFileName
);
100 extern const char* getFilename()
102 return sInputFileName
.getStr();
105 extern FILE *GetXrmFile()
107 // look for valid filename
108 if (!sInputFileName
.isEmpty()) {
109 //TODO: explicit BOM handling?
110 FILE * pFile
= fopen(sInputFileName
.getStr(), "r");
112 fprintf( stderr
, "Error: Could not open file %s\n",
113 sInputFileName
.getStr());
119 // this means the file could not be opened
123 int WorkOnTokenSet( int nTyp
, char *pTokenText
)
125 //printf("Typ = %d , text = '%s'\n",nTyp , pTokenText );
126 pParser
->Execute( nTyp
, pTokenText
);
142 return pParser
->GetError();
147 // class XRMResParser
151 XRMResParser::XRMResParser()
152 : bError( sal_False
),
157 XRMResParser::~XRMResParser()
161 int XRMResParser::Execute( int nToken
, char * pToken
)
163 OString
rToken( pToken
);
166 case XRM_TEXT_START
:{
167 OString sNewGID
= GetAttribute( rToken
, "id" );
168 if ( sNewGID
!= sGID
) {
173 sCurrentOpenTag
= rToken
;
179 sCurrentCloseTag
= rToken
;
180 sResourceType
= OString ( "readmeitem" );
181 sLangAttribute
= OString ( "xml:lang" );
182 WorkOnText( sCurrentOpenTag
, sCurrentText
);
183 Output( sCurrentText
);
184 EndOfText( sCurrentOpenTag
, sCurrentCloseTag
);
186 rToken
= OString("");
187 sCurrentText
= OString("");
191 case DESC_DISPLAY_NAME_START
:{
192 bDisplayName
= sal_True
;
196 case DESC_DISPLAY_NAME_END
:{
197 bDisplayName
= sal_False
;
201 case DESC_TEXT_START
:{
203 sGID
= OString("dispname");
206 sCurrentOpenTag
= rToken
;
212 case DESC_TEXT_END
: {
214 sCurrentCloseTag
= rToken
;
215 sResourceType
= OString ( "description" );
216 sLangAttribute
= OString ( "lang" );
217 WorkOnText( sCurrentOpenTag
, sCurrentText
);
218 Output( sCurrentText
);
219 EndOfText( sCurrentOpenTag
, sCurrentCloseTag
);
221 rToken
= OString("");
222 sCurrentText
= OString("");
227 case DESC_EXTENSION_DESCRIPTION_START
: {
228 bExtensionDescription
= sal_True
;
232 case DESC_EXTENSION_DESCRIPTION_END
: {
233 bExtensionDescription
= sal_False
;
237 case DESC_EXTENSION_DESCRIPTION_SRC
: {
238 if (bExtensionDescription
) {
239 sGID
= OString("extdesc");
240 sResourceType
= OString ( "description" );
241 sLangAttribute
= OString ( "lang" );
242 sCurrentOpenTag
= rToken
;
243 sCurrentText
= OString("");
245 WorkOnDesc( sCurrentOpenTag
, sCurrentText
);
246 sCurrentCloseTag
= rToken
;
247 Output( sCurrentText
);
248 rToken
= OString("");
249 sCurrentText
= OString("");
256 sCurrentText
+= rToken
;
268 OString
XRMResParser::GetAttribute( const OString
&rToken
, const OString
&rAttribute
)
270 OString
sTmp( rToken
);
271 sTmp
= sTmp
.replace('\t', ' ');
273 OString
sSearch( " " );
274 sSearch
+= rAttribute
;
276 sal_Int32 nPos
= sTmp
.indexOf( sSearch
);
280 sTmp
= sTmp
.copy( nPos
);
281 OString sId
= sTmp
.getToken(1, '"');
288 void XRMResParser::Error( const OString
&rError
)
290 yyerror(( char * ) rError
.getStr());
294 // class XMLResExport
297 XRMResExport::XRMResExport(
298 const OString
&rOutputFile
, const OString
&rFilePath
)
303 pOutputStream
.open( rOutputFile
, PoOfstream::APP
);
304 if (!pOutputStream
.isOpen())
306 OString
sError( "Unable to open output file: " );
307 sError
+= rOutputFile
;
312 XRMResExport::~XRMResExport()
314 pOutputStream
.close();
318 void XRMResExport::Output( const OString
& ) {}
320 void XRMResExport::WorkOnDesc(
321 const OString
&rOpenTag
,
324 OString
sDescFileName(
325 sInputFileName
.replaceAll("description.xml", OString()));
326 sDescFileName
+= GetAttribute( rOpenTag
, "xlink:href" );
327 ifstream
file (sDescFileName
.getStr(), ios::in
|ios::binary
|ios::ate
);
328 if (file
.is_open()) {
329 int size
= static_cast<int>(file
.tellg());
330 char* memblock
= new char [size
+1];
331 file
.seekg (0, ios::beg
);
332 file
.read (memblock
, size
);
334 memblock
[size
] = '\0';
335 rText
= OString(memblock
);
338 WorkOnText( rOpenTag
, rText
);
339 EndOfText( rOpenTag
, rOpenTag
);
342 void XRMResExport::WorkOnText(
343 const OString
&rOpenTag
,
346 OString
sLang( GetAttribute( rOpenTag
, sLangAttribute
));
350 pResData
= new ResData( GetGID() );
352 pResData
->sText
[sLang
] = rText
;
355 void XRMResExport::EndOfText(
361 OString sAct
= pResData
->sText
["en-US"];
363 if( !sAct
.isEmpty() )
364 common::writePoEntry(
365 "Xrmex", pOutputStream
, sPath
, sResourceType
,
366 pResData
->sGId
, OString(), OString(), sAct
);
376 XRMResMerge::XRMResMerge(
377 const OString
&rMergeSource
, const OString
&rOutputFile
,
378 const OString
&rFilename
)
380 pMergeDataFile( NULL
),
381 sFilename( rFilename
) ,
384 if (!rMergeSource
.isEmpty() && sLanguage
.equalsIgnoreAsciiCase("ALL"))
386 pMergeDataFile
= new MergeDataFile(
387 rMergeSource
, sInputFileName
, false);
388 aLanguages
= pMergeDataFile
->GetLanguages();
391 aLanguages
.push_back( sLanguage
);
393 rOutputFile
.getStr(), std::ios_base::out
| std::ios_base::trunc
);
394 if (!pOutputStream
.is_open()) {
395 OString
sError( "Unable to open output file: " );
396 sError
+= rOutputFile
;
401 XRMResMerge::~XRMResMerge()
403 pOutputStream
.close();
404 delete pMergeDataFile
;
408 void XRMResMerge::WorkOnDesc(
409 const OString
&rOpenTag
,
412 WorkOnText( rOpenTag
, rText
);
413 if ( pMergeDataFile
&& pResData
) {
414 MergeEntrys
*pEntrys
= pMergeDataFile
->GetMergeEntrys( pResData
);
417 OString sDescFilename
= GetAttribute ( rOpenTag
, "xlink:href" );
418 for( unsigned int n
= 0; n
< aLanguages
.size(); n
++ ){
419 sCur
= aLanguages
[ n
];
421 if ( !sCur
.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("en-US")) &&
423 sContent
, STRING_TYP_TEXT
, sCur
, sal_True
)) &&
426 OString
sText( sContent
);
427 OString
sAdditionalLine( "\n " );
428 sAdditionalLine
+= rOpenTag
;
429 OString sSearch
= sLangAttribute
;
431 OString
sReplace( sSearch
);
433 sSearch
+= GetAttribute( rOpenTag
, sLangAttribute
);
435 sAdditionalLine
= sAdditionalLine
.replaceFirst(
438 sSearch
= OString("xlink:href=\"");
441 OString sLocDescFilename
= sDescFilename
;
442 sLocDescFilename
= sLocDescFilename
.replaceFirst(
445 sSearch
+= sDescFilename
;
446 sReplace
+= sLocDescFilename
;
447 sAdditionalLine
= sAdditionalLine
.replaceFirst(
450 Output( sAdditionalLine
);
452 sal_Int32 i
= sOutputFile
.lastIndexOf('/');
455 << "Error: output file " << sOutputFile
.getStr()
456 << " does not contain any /\n";
459 OString
sOutputDescFile(
460 sOutputFile
.copy(0, i
+ 1) + sLocDescFilename
);
461 ofstream
file(sOutputDescFile
.getStr());
462 if (file
.is_open()) {
463 file
<< sText
.getStr();
467 << "Error: cannot write "
468 << sOutputDescFile
.getStr() << '\n';
479 void XRMResMerge::WorkOnText(
483 if ( pMergeDataFile
) {
485 pResData
= new ResData( GetGID(), sFilename
);
486 pResData
->sResTyp
= sResourceType
;
491 void XRMResMerge::Output( const OString
& rOutput
)
493 if (!rOutput
.isEmpty())
494 pOutputStream
<< rOutput
.getStr();
497 void XRMResMerge::EndOfText(
498 const OString
&rOpenTag
,
499 const OString
&rCloseTag
)
503 if ( pMergeDataFile
&& pResData
) {
504 MergeEntrys
*pEntrys
= pMergeDataFile
->GetMergeEntrys( pResData
);
507 for( unsigned int n
= 0; n
< aLanguages
.size(); n
++ ){
508 sCur
= aLanguages
[ n
];
510 if (!sCur
.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("en-US")) &&
512 sContent
, STRING_TYP_TEXT
, sCur
, sal_True
)) &&
513 !sContent
.isEmpty() &&
514 helper::isWellFormedXML( sContent
))
516 OString
sText( sContent
);
517 OString
sAdditionalLine( "\n " );
518 sAdditionalLine
+= rOpenTag
;
519 OString sSearch
= sLangAttribute
;
521 OString
sReplace( sSearch
);
523 sSearch
+= GetAttribute( rOpenTag
, sLangAttribute
);
526 sAdditionalLine
= sAdditionalLine
.replaceFirst(
529 sAdditionalLine
+= sText
;
530 sAdditionalLine
+= rCloseTag
;
532 Output( sAdditionalLine
);
541 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */