fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / l10ntools / source / xrmmerge.cxx
blob421195d54e10bf311367bd325204cad477f19955
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
22 #include <cstring>
24 #include <stdio.h>
26 #include "common.hxx"
27 #include "export.hxx"
28 #include "po.hxx"
29 #include "xrmlex.hxx"
30 #include "xrmmerge.hxx"
31 #include "tokens.h"
32 #include "helper.hxx"
33 #include <iostream>
34 #include <fstream>
35 #include <vector>
36 #include <boost/scoped_array.hpp>
38 using namespace std;
40 void yyerror( const char * );
42 // set of global variables
43 bool bMergeMode;
44 bool bDisplayName;
45 bool bExtensionDescription;
46 OString sLanguage;
47 OString sInputFileName;
48 OString sOutputFile;
49 OString sMergeSrc;
50 OString sLangAttribute;
51 OString sResourceType;
52 XRMResParser *pParser = NULL;
54 extern "C" {
55 // the whole interface to lexer is in this extern "C" section
57 extern bool GetOutputFile( int argc, char* argv[])
59 bDisplayName = false;
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;
70 return true;
72 else
74 // command line is not valid
75 common::writeUsage("xrmex","*.xrm/*.xml");
76 return false;
80 int InitXrmExport( const char* pFilename)
82 // instanciate Export
83 OString sFilename( pFilename );
85 if ( bMergeMode )
86 pParser = new XRMResMerge( sMergeSrc, sOutputFile, sFilename );
87 else if (!sOutputFile.isEmpty()) {
88 pParser = new XRMResExport( sOutputFile, sInputFileName );
91 return 1;
94 int EndXrmExport()
96 delete pParser;
97 return 1;
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");
110 if ( !pFile ){
111 fprintf( stderr, "Error: Could not open file %s\n",
112 sInputFileName.getStr());
114 else {
115 return pFile;
118 // this means the file could not be opened
119 return NULL;
122 int WorkOnTokenSet( int nTyp, char *pTokenText )
124 //printf("Typ = %d , text = '%s'\n",nTyp , pTokenText );
125 pParser->Execute( nTyp, pTokenText );
127 return 1;
130 int SetError()
132 pParser->SetError();
133 return 1;
137 extern "C" {
139 int GetError()
141 return pParser->GetError();
146 // class XRMResParser
150 XRMResParser::XRMResParser()
151 : bError( false ),
152 bText( false )
156 XRMResParser::~XRMResParser()
160 int XRMResParser::Execute( int nToken, char * pToken )
162 OString rToken( pToken );
164 switch ( nToken ) {
165 case XRM_TEXT_START:{
166 OString sNewGID = GetAttribute( rToken, "id" );
167 if ( sNewGID != sGID ) {
168 sGID = sNewGID;
170 bText = true;
171 sCurrentText = "";
172 sCurrentOpenTag = rToken;
173 Output( rToken );
175 break;
177 case XRM_TEXT_END: {
178 sCurrentCloseTag = rToken;
179 sResourceType = OString ( "readmeitem" );
180 sLangAttribute = OString ( "xml:lang" );
181 WorkOnText( sCurrentOpenTag, sCurrentText );
182 Output( sCurrentText );
183 EndOfText( sCurrentOpenTag, sCurrentCloseTag );
184 bText = false;
185 rToken = OString("");
186 sCurrentText = OString("");
188 break;
190 case DESC_DISPLAY_NAME_START:{
191 bDisplayName = true;
193 break;
195 case DESC_DISPLAY_NAME_END:{
196 bDisplayName = false;
198 break;
200 case DESC_TEXT_START:{
201 if (bDisplayName) {
202 sGID = OString("dispname");
203 bText = true;
204 sCurrentText = "";
205 sCurrentOpenTag = rToken;
206 Output( rToken );
209 break;
211 case DESC_TEXT_END: {
212 if (bDisplayName) {
213 sCurrentCloseTag = rToken;
214 sResourceType = OString ( "description" );
215 sLangAttribute = OString ( "lang" );
216 WorkOnText( sCurrentOpenTag, sCurrentText );
217 Output( sCurrentText );
218 EndOfText( sCurrentOpenTag, sCurrentCloseTag );
219 bText = false;
220 rToken = OString("");
221 sCurrentText = OString("");
224 break;
226 case DESC_EXTENSION_DESCRIPTION_START: {
227 bExtensionDescription = true;
229 break;
231 case DESC_EXTENSION_DESCRIPTION_END: {
232 bExtensionDescription = false;
234 break;
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("");
243 Output( rToken );
244 WorkOnDesc( sCurrentOpenTag, sCurrentText );
245 sCurrentCloseTag = rToken;
246 Output( sCurrentText );
247 rToken = OString("");
248 sCurrentText = OString("");
251 break;
253 default:
254 if ( bText ) {
255 sCurrentText += rToken;
257 break;
260 if ( !bText )
262 Output( rToken );
264 return 0;
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;
274 sSearch += "=";
275 sal_Int32 nPos = sTmp.indexOf( sSearch );
277 if ( nPos != -1 )
279 sTmp = sTmp.copy( nPos );
280 OString sId = sTmp.getToken(1, '"');
281 return sId;
283 return OString();
287 void XRMResParser::Error( const OString &rError )
289 yyerror(rError.getStr());
293 // class XMLResExport
296 XRMResExport::XRMResExport(
297 const OString &rOutputFile, const OString &rFilePath )
298 : XRMResParser(),
299 pResData( NULL ),
300 sPath( rFilePath )
302 pOutputStream.open( rOutputFile, PoOfstream::APP );
303 if (!pOutputStream.isOpen())
305 OString sError( "Unable to open output file: " );
306 sError += rOutputFile;
307 Error( sError );
311 XRMResExport::~XRMResExport()
313 pOutputStream.close();
314 delete pResData;
317 void XRMResExport::Output( const OString& ) {}
319 void XRMResExport::WorkOnDesc(
320 const OString &rOpenTag,
321 OString &rText )
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);
332 file.close();
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,
342 OString &rText )
344 OString sLang( GetAttribute( rOpenTag, sLangAttribute ));
346 if ( !pResData )
348 pResData = new ResData( GetGID() );
350 pResData->sText[sLang] = rText;
353 void XRMResExport::EndOfText(
354 const OString &,
355 const OString & )
357 if ( pResData )
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 );
366 delete pResData;
367 pResData = NULL;
371 // class XRMResMerge
374 XRMResMerge::XRMResMerge(
375 const OString &rMergeSource, const OString &rOutputFile,
376 const OString &rFilename )
377 : XRMResParser(),
378 pMergeDataFile( NULL ),
379 sFilename( rFilename ) ,
380 pResData( NULL )
382 if (!rMergeSource.isEmpty() && sLanguage.equalsIgnoreAsciiCase("ALL"))
384 pMergeDataFile = new MergeDataFile(
385 rMergeSource, sInputFileName, false);
386 aLanguages = pMergeDataFile->GetLanguages();
388 else
389 aLanguages.push_back( sLanguage );
390 pOutputStream.open(
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;
395 Error( sError );
399 XRMResMerge::~XRMResMerge()
401 pOutputStream.close();
402 delete pMergeDataFile;
403 delete pResData;
406 void XRMResMerge::WorkOnDesc(
407 const OString &rOpenTag,
408 OString &rText )
410 WorkOnText( rOpenTag, rText);
411 if ( pMergeDataFile && pResData ) {
412 MergeEntrys *pEntrys = pMergeDataFile->GetMergeEntrys( pResData );
413 if ( pEntrys ) {
414 OString sCur;
415 OString sDescFilename = GetAttribute ( rOpenTag, "xlink:href" );
416 for( unsigned int n = 0; n < aLanguages.size(); n++ ){
417 sCur = aLanguages[ n ];
418 OString sContent;
419 if ( !sCur.equalsIgnoreAsciiCase("en-US") &&
420 ( pEntrys->GetText(
421 sContent, STRING_TYP_TEXT, sCur, true )) &&
422 !sContent.isEmpty())
424 OString sText( sContent );
425 OString sAdditionalLine( "\n " );
426 sAdditionalLine += rOpenTag;
427 OString sSearch = sLangAttribute;
428 sSearch += "=\"";
429 OString sReplace( sSearch );
431 sSearch += GetAttribute( rOpenTag, sLangAttribute );
432 sReplace += sCur;
433 sAdditionalLine = sAdditionalLine.replaceFirst(
434 sSearch, sReplace);
436 sSearch = OString("xlink:href=\"");
437 sReplace = sSearch;
439 OString sLocDescFilename = sDescFilename;
440 sLocDescFilename = sLocDescFilename.replaceFirst(
441 "en-US", sCur);
443 sSearch += sDescFilename;
444 sReplace += sLocDescFilename;
445 sAdditionalLine = sAdditionalLine.replaceFirst(
446 sSearch, sReplace);
448 Output( sAdditionalLine );
450 sal_Int32 i = sOutputFile.lastIndexOf('/');
451 if (i == -1) {
452 std::cerr
453 << "Error: output file " << sOutputFile.getStr()
454 << " does not contain any /\n";
455 throw false; //TODO
457 OString sOutputDescFile(
458 sOutputFile.copy(0, i + 1) + sLocDescFilename);
459 ofstream file(sOutputDescFile.getStr());
460 if (file.is_open()) {
461 file << sText.getStr();
462 file.close();
463 } else {
464 std::cerr
465 << "Error: cannot write "
466 << sOutputDescFile.getStr() << '\n';
467 throw false; //TODO
473 delete pResData;
474 pResData = NULL;
477 void XRMResMerge::WorkOnText(
478 const OString &,
479 OString & )
481 if ( pMergeDataFile ) {
482 if ( !pResData ) {
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 )
500 Output( rCloseTag );
501 if ( pMergeDataFile && pResData ) {
502 MergeEntrys *pEntrys = pMergeDataFile->GetMergeEntrys( pResData );
503 if ( pEntrys ) {
504 OString sCur;
505 for( unsigned int n = 0; n < aLanguages.size(); n++ ){
506 sCur = aLanguages[ n ];
507 OString sContent;
508 if (!sCur.equalsIgnoreAsciiCase("en-US") &&
509 ( pEntrys->GetText(
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;
518 sSearch += "=\"";
519 OString sReplace( sSearch );
521 sSearch += GetAttribute( rOpenTag, sLangAttribute );
522 sReplace += sCur;
524 sAdditionalLine = sAdditionalLine.replaceFirst(
525 sSearch, sReplace);
527 sAdditionalLine += sText;
528 sAdditionalLine += rCloseTag;
530 Output( sAdditionalLine );
535 delete pResData;
536 pResData = NULL;
539 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */