LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/l10ntools/source - cfgmerge.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 254 0.0 %
Date: 2013-07-09 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include "common.hxx"
      21             : #include "sal/config.h"
      22             : 
      23             : #include <cstdio>
      24             : #include <cstdlib>
      25             : #include <cstring>
      26             : 
      27             : #include "boost/scoped_ptr.hpp"
      28             : #include "rtl/strbuf.hxx"
      29             : 
      30             : #include "helper.hxx"
      31             : #include "export.hxx"
      32             : #include "cfgmerge.hxx"
      33             : #include "tokens.h"
      34             : 
      35             : void yyerror(char const *);
      36             : 
      37             : namespace {
      38             : 
      39             : namespace global {
      40             : 
      41           0 : OString inputPathname;
      42           0 : boost::scoped_ptr< CfgParser > parser;
      43             : 
      44             : }
      45             : }
      46             : 
      47             : extern "C" {
      48             : 
      49           0 : FILE * init(int argc, char ** argv) {
      50             : 
      51           0 :     common::HandledArgs aArgs;
      52           0 :     if ( !common::handleArguments(argc, argv, aArgs) )
      53             :     {
      54           0 :         common::writeUsage("cfgex","*.xcu");
      55           0 :         std::exit(EXIT_FAILURE);
      56             :     }
      57           0 :     global::inputPathname = aArgs.m_sInputFile;
      58             : 
      59           0 :     FILE * pFile = std::fopen(global::inputPathname.getStr(), "r");
      60           0 :     if (pFile == 0) {
      61             :         std::fprintf(
      62             :             stderr, "Error: Cannot open file \"%s\"\n",
      63           0 :             global::inputPathname.getStr() );
      64           0 :         std::exit(EXIT_FAILURE);
      65             :     }
      66             : 
      67           0 :     if (aArgs.m_bMergeMode) {
      68             :         global::parser.reset(
      69             :             new CfgMerge(
      70             :                 aArgs.m_sMergeSrc, aArgs.m_sOutputFile,
      71           0 :                 global::inputPathname, aArgs.m_sLanguage ));
      72             :     } else {
      73             :         global::parser.reset(
      74             :             new CfgExport(
      75           0 :                 aArgs.m_sOutputFile, global::inputPathname ));
      76             :     }
      77             : 
      78           0 :     return pFile;
      79             : }
      80             : 
      81           0 : void workOnTokenSet(int nTyp, char * pTokenText) {
      82           0 :     global::parser->Execute( nTyp, pTokenText );
      83           0 : }
      84             : 
      85             : }
      86             : 
      87             : //
      88             : // class CfgStackData
      89             : //
      90             : 
      91           0 : CfgStackData* CfgStack::Push(const OString &rTag, const OString &rId)
      92             : {
      93           0 :     CfgStackData *pD = new CfgStackData( rTag, rId );
      94           0 :     maList.push_back( pD );
      95           0 :     return pD;
      96             : }
      97             : 
      98             : //
      99             : // class CfgStack
     100             : //
     101             : 
     102           0 : CfgStack::~CfgStack()
     103             : {
     104           0 :     for ( size_t i = 0, n = maList.size(); i < n; i++ )
     105           0 :         delete maList[ i ];
     106           0 :     maList.clear();
     107           0 : }
     108             : 
     109           0 : OString CfgStack::GetAccessPath( size_t nPos )
     110             : {
     111           0 :     OStringBuffer sReturn;
     112           0 :     for (size_t i = 0; i <= nPos; ++i)
     113             :     {
     114           0 :         if (i)
     115           0 :             sReturn.append('.');
     116           0 :         sReturn.append(maList[i]->GetIdentifier());
     117             :     }
     118             : 
     119           0 :     return sReturn.makeStringAndClear();
     120             : }
     121             : 
     122           0 : CfgStackData *CfgStack::GetStackData()
     123             : {
     124           0 :     if (!maList.empty())
     125           0 :         return maList[maList.size() - 1];
     126             :     else
     127           0 :         return 0;
     128             : }
     129             : 
     130             : //
     131             : // class CfgParser
     132             : //
     133             : 
     134           0 : CfgParser::CfgParser()
     135             :                 : pStackData( NULL ),
     136           0 :                 bLocalize( sal_False )
     137             : {
     138           0 : }
     139             : 
     140           0 : CfgParser::~CfgParser()
     141             : {
     142           0 : }
     143             : 
     144           0 : sal_Bool CfgParser::IsTokenClosed(const OString &rToken)
     145             : {
     146           0 :     return rToken[rToken.getLength() - 2] == '/';
     147             : }
     148             : 
     149           0 : void CfgParser::AddText(
     150             :     OString &rText,
     151             :     const OString &rIsoLang,
     152             :     const OString &rResTyp )
     153             : {
     154           0 :     rText = rText.replaceAll(OString('\n'), OString()).
     155             :         replaceAll(OString('\r'), OString()).
     156           0 :         replaceAll(OString('\t'), OString());
     157           0 :     pStackData->sResTyp = rResTyp;
     158           0 :     WorkOnText( rText, rIsoLang );
     159           0 :     pStackData->sText[ rIsoLang ] = rText;
     160           0 : }
     161             : 
     162           0 : int CfgParser::ExecuteAnalyzedToken( int nToken, char *pToken )
     163             : {
     164           0 :     OString sToken( pToken );
     165             : 
     166           0 :     if ( sToken == " " || sToken == "\t" )
     167           0 :         sLastWhitespace += sToken;
     168             : 
     169           0 :     OString sTokenName;
     170           0 :     OString sTokenId;
     171             : 
     172           0 :     sal_Bool bOutput = sal_True;
     173             : 
     174           0 :     switch ( nToken ) {
     175             :         case CFG_TOKEN_PACKAGE:
     176             :         case CFG_TOKEN_COMPONENT:
     177             :         case CFG_TOKEN_TEMPLATE:
     178             :         case CFG_TOKEN_CONFIGNAME:
     179             :         case CFG_TOKEN_OORNAME:
     180             :         case CFG_TOKEN_OORVALUE:
     181             :         case CFG_TAG:
     182             :         case ANYTOKEN:
     183             :         case CFG_TEXT_START:
     184             :         {
     185           0 :             sTokenName = sToken.getToken(1, '<').getToken(0, '>').
     186           0 :                 getToken(0, ' ');
     187             : 
     188           0 :               if ( !IsTokenClosed( sToken )) {
     189           0 :                 OString sSearch;
     190           0 :                 switch ( nToken ) {
     191             :                     case CFG_TOKEN_PACKAGE:
     192           0 :                         sSearch = "package-id=";
     193           0 :                     break;
     194             :                     case CFG_TOKEN_COMPONENT:
     195           0 :                         sSearch = "component-id=";
     196           0 :                     break;
     197             :                     case CFG_TOKEN_TEMPLATE:
     198           0 :                         sSearch = "template-id=";
     199           0 :                     break;
     200             :                     case CFG_TOKEN_CONFIGNAME:
     201           0 :                         sSearch = "cfg:name=";
     202           0 :                     break;
     203             :                     case CFG_TOKEN_OORNAME:
     204           0 :                         sSearch = "oor:name=";
     205           0 :                         bLocalize = sal_True;
     206           0 :                     break;
     207             :                     case CFG_TOKEN_OORVALUE:
     208           0 :                         sSearch = "oor:value=";
     209           0 :                     break;
     210             :                     case CFG_TEXT_START: {
     211           0 :                         if ( sCurrentResTyp != sTokenName ) {
     212           0 :                             WorkOnResourceEnd();
     213             :                          }
     214           0 :                         sCurrentResTyp = sTokenName;
     215             : 
     216           0 :                         OString sTemp = sToken.copy( sToken.indexOf( "xml:lang=" ));
     217           0 :                         sCurrentIsoLang = sTemp.getToken(1, '"');
     218             : 
     219           0 :                         if ( sCurrentIsoLang == NO_TRANSLATE_ISO )
     220           0 :                             bLocalize = sal_False;
     221             : 
     222           0 :                         pStackData->sTextTag = sToken;
     223             : 
     224           0 :                         sCurrentText = "";
     225             :                     }
     226           0 :                     break;
     227             :                 }
     228           0 :                 if ( !sSearch.isEmpty())
     229             :                 {
     230           0 :                     OString sTemp = sToken.copy( sToken.indexOf( sSearch ));
     231           0 :                     sTokenId = sTemp.getToken(1, '"');
     232             :                 }
     233           0 :                 pStackData = aStack.Push( sTokenName, sTokenId );
     234             : 
     235           0 :                 if ( sSearch == "cfg:name=" ) {
     236           0 :                     OString sTemp( sToken.toAsciiUpperCase() );
     237           0 :                     bLocalize = (( sTemp.indexOf( "CFG:TYPE=\"STRING\"" ) != -1 ) &&
     238           0 :                         ( sTemp.indexOf( "CFG:LOCALIZED=\"sal_True\"" ) != -1 ));
     239           0 :                 }
     240             :             }
     241           0 :             else if ( sTokenName == "label" ) {
     242           0 :                 if ( sCurrentResTyp != sTokenName ) {
     243           0 :                     WorkOnResourceEnd();
     244             :                 }
     245           0 :                 sCurrentResTyp = sTokenName;
     246             :             }
     247             :         }
     248           0 :         break;
     249             :         case CFG_CLOSETAG:
     250             :         {
     251           0 :             sTokenName = sToken.getToken(1, '/').getToken(0, '>').
     252           0 :                 getToken(0, ' ');
     253           0 :             if ( aStack.GetStackData() && ( aStack.GetStackData()->GetTagType() == sTokenName ))
     254             :             {
     255           0 :                 if (sCurrentText.isEmpty())
     256           0 :                     WorkOnResourceEnd();
     257           0 :                 aStack.Pop();
     258           0 :                 pStackData = aStack.GetStackData();
     259             :             }
     260             :             else
     261             :             {
     262           0 :                 OString sError( "Misplaced close tag: " );
     263           0 :                 OString sInFile(" in file ");
     264           0 :                 sError += sToken;
     265           0 :                 sError += sInFile;
     266           0 :                 sError += global::inputPathname;
     267           0 :                 Error( sError );
     268           0 :                 std::exit(EXIT_FAILURE);
     269             :             }
     270             :         }
     271           0 :         break;
     272             : 
     273             :         case CFG_TEXTCHAR:
     274           0 :             sCurrentText += sToken;
     275           0 :             bOutput = sal_False;
     276           0 :         break;
     277             : 
     278             :         case CFG_TOKEN_NO_TRANSLATE:
     279           0 :             bLocalize = sal_False;
     280           0 :         break;
     281             :     }
     282             : 
     283           0 :     if ( !sCurrentText.isEmpty() && nToken != CFG_TEXTCHAR )
     284             :     {
     285           0 :         AddText( sCurrentText, sCurrentIsoLang, sCurrentResTyp );
     286           0 :         Output( sCurrentText );
     287           0 :         sCurrentText = OString();
     288           0 :         pStackData->sEndTextTag = sToken;
     289             :     }
     290             : 
     291           0 :     if ( bOutput )
     292           0 :         Output( sToken );
     293             : 
     294           0 :     if ( sToken != " " && sToken != "\t" )
     295           0 :         sLastWhitespace = "";
     296             : 
     297           0 :     return 1;
     298             : }
     299             : 
     300           0 : void CfgExport::Output(const OString&)
     301             : {
     302           0 : }
     303             : 
     304           0 : int CfgParser::Execute( int nToken, char * pToken )
     305             : {
     306           0 :     OString sToken( pToken );
     307             : 
     308           0 :     switch ( nToken ) {
     309             :         case CFG_TAG:
     310           0 :             if ( sToken.indexOf( "package-id=" ) != -1 )
     311           0 :                 return ExecuteAnalyzedToken( CFG_TOKEN_PACKAGE, pToken );
     312           0 :             else if ( sToken.indexOf( "component-id=" ) != -1 )
     313           0 :                 return ExecuteAnalyzedToken( CFG_TOKEN_COMPONENT, pToken );
     314           0 :             else if ( sToken.indexOf( "template-id=" ) != -1 )
     315           0 :                 return ExecuteAnalyzedToken( CFG_TOKEN_TEMPLATE, pToken );
     316           0 :             else if ( sToken.indexOf( "cfg:name=" ) != -1 )
     317           0 :                 return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken );
     318           0 :             else if ( sToken.indexOf( "oor:name=" ) != -1 )
     319           0 :                 return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken );
     320           0 :             else if ( sToken.indexOf( "oor:value=" ) != -1 )
     321           0 :                 return ExecuteAnalyzedToken( CFG_TOKEN_OORVALUE, pToken );
     322           0 :         break;
     323             :     }
     324           0 :     return ExecuteAnalyzedToken( nToken, pToken );
     325             : }
     326             : 
     327           0 : void CfgParser::Error(const OString& rError)
     328             : {
     329           0 :     yyerror(rError.getStr());
     330           0 : }
     331             : 
     332             : //
     333             : // class CfgExport
     334             : //
     335             : 
     336           0 : CfgExport::CfgExport(
     337             :         const OString &rOutputFile,
     338             :         const OString &rFilePath )
     339             : 
     340           0 :                 : sPath( rFilePath )
     341             : {
     342           0 :     pOutputStream.open( rOutputFile, PoOfstream::APP );
     343           0 :     if (!pOutputStream.isOpen())
     344             :     {
     345           0 :         std::cerr << "ERROR: Unable to open output file: " << rOutputFile << "\n";
     346           0 :         std::exit(EXIT_FAILURE);
     347             :     }
     348           0 : }
     349             : 
     350           0 : CfgExport::~CfgExport()
     351             : {
     352           0 :     pOutputStream.close();
     353           0 : }
     354             : 
     355             : 
     356           0 : void CfgExport::WorkOnResourceEnd()
     357             : {
     358           0 :     if ( bLocalize ) {
     359           0 :     if ( !pStackData->sText["en-US"].isEmpty() )
     360             :         {
     361           0 :             OString sXComment = pStackData->sText[OString(RTL_CONSTASCII_STRINGPARAM("x-comment"))];
     362           0 :             OString sLocalId = pStackData->sIdentifier;
     363           0 :             OString sGroupId;
     364           0 :             if ( aStack.size() == 1 ) {
     365           0 :                 sGroupId = sLocalId;
     366           0 :                 sLocalId = "";
     367             :             }
     368             :             else {
     369           0 :                 sGroupId = aStack.GetAccessPath( aStack.size() - 2 );
     370             :             }
     371             : 
     372             : 
     373           0 :             OString sText = pStackData->sText[ "en-US" ];
     374           0 :             sText = helper::UnQuotHTML( sText );
     375             : 
     376             :             common::writePoEntry(
     377             :                 "Cfgex", pOutputStream, sPath, pStackData->sResTyp,
     378           0 :                 sGroupId, sLocalId, sXComment, sText);
     379             :         }
     380             :     }
     381           0 : }
     382             : 
     383           0 : void CfgExport::WorkOnText(
     384             :     OString &rText,
     385             :     const OString &rIsoLang
     386             : )
     387             : {
     388           0 :     if( !rIsoLang.isEmpty() ) rText = helper::UnQuotHTML( rText );
     389           0 : }
     390             : 
     391             : 
     392             : //
     393             : // class CfgMerge
     394             : //
     395             : 
     396           0 : CfgMerge::CfgMerge(
     397             :     const OString &rMergeSource, const OString &rOutputFile,
     398             :     const OString &rFilename, const OString &rLanguage )
     399             :                 : pMergeDataFile( NULL ),
     400             :                 pResData( NULL ),
     401             :                 sFilename( rFilename ),
     402           0 :                 bEnglish( sal_False )
     403             : {
     404             :     pOutputStream.open(
     405           0 :         rOutputFile.getStr(), std::ios_base::out | std::ios_base::trunc);
     406           0 :     if (!pOutputStream.is_open())
     407             :     {
     408           0 :         std::cerr << "ERROR: Unable to open output file: " << rOutputFile << "\n";
     409           0 :         std::exit(EXIT_FAILURE);
     410             :     }
     411             : 
     412           0 :     if (!rMergeSource.isEmpty())
     413             :     {
     414             :         pMergeDataFile = new MergeDataFile(
     415           0 :             rMergeSource, global::inputPathname, true );
     416           0 :         if (rLanguage.equalsIgnoreAsciiCase("ALL") )
     417             :         {
     418           0 :             aLanguages = pMergeDataFile->GetLanguages();
     419             :         }
     420           0 :         else aLanguages.push_back(rLanguage);
     421             :     }
     422             :     else
     423           0 :         aLanguages.push_back(rLanguage);
     424           0 : }
     425             : 
     426           0 : CfgMerge::~CfgMerge()
     427             : {
     428           0 :     pOutputStream.close();
     429           0 :     delete pMergeDataFile;
     430           0 :     delete pResData;
     431           0 : }
     432             : 
     433           0 : void CfgMerge::WorkOnText(OString &, const OString& rLangIndex)
     434             : {
     435             : 
     436           0 :     if ( pMergeDataFile && bLocalize ) {
     437           0 :         if ( !pResData ) {
     438           0 :             OString sLocalId = pStackData->sIdentifier;
     439           0 :             OString sGroupId;
     440           0 :             if ( aStack.size() == 1 ) {
     441           0 :                 sGroupId = sLocalId;
     442           0 :                 sLocalId = OString();
     443             :             }
     444             :             else {
     445           0 :                 sGroupId = aStack.GetAccessPath( aStack.size() - 2 );
     446             :             }
     447             : 
     448           0 :             pResData = new ResData( sGroupId, sFilename );
     449           0 :             pResData->sId = sLocalId;
     450           0 :             pResData->sResTyp = pStackData->sResTyp;
     451             :         }
     452             : 
     453           0 :         if (rLangIndex.equalsIgnoreAsciiCase("en-US"))
     454           0 :             bEnglish = sal_True;
     455             :     }
     456           0 : }
     457             : 
     458           0 : void CfgMerge::Output(const OString& rOutput)
     459             : {
     460           0 :     pOutputStream << rOutput.getStr();
     461           0 : }
     462             : 
     463           0 : void CfgMerge::WorkOnResourceEnd()
     464             : {
     465             : 
     466           0 :     if ( pMergeDataFile && pResData && bLocalize && bEnglish ) {
     467           0 :         MergeEntrys *pEntrys = pMergeDataFile->GetMergeEntrysCaseSensitive( pResData );
     468           0 :         if ( pEntrys ) {
     469           0 :             OString sCur;
     470             : 
     471           0 :             for( unsigned int i = 0; i < aLanguages.size(); ++i ){
     472           0 :                 sCur = aLanguages[ i ];
     473             : 
     474           0 :                 OString sContent;
     475           0 :                 pEntrys->GetText( sContent, STRING_TYP_TEXT, sCur , sal_True );
     476           0 :                 if (
     477           0 :                     ( !sCur.equalsIgnoreAsciiCase("en-US") ) && !sContent.isEmpty())
     478             :                 {
     479             : 
     480           0 :                     OString sText = helper::QuotHTML( sContent);
     481             : 
     482           0 :                     OString sAdditionalLine( "\t" );
     483             : 
     484           0 :                     OString sTextTag = pStackData->sTextTag;
     485           0 :                     OString sTemp = sTextTag.copy( sTextTag.indexOf( "xml:lang=" ));
     486             : 
     487           0 :                     sal_Int32 n = 0;
     488           0 :                     OString sSearch = sTemp.getToken(0, '"', n);
     489           0 :                     sSearch += "\"";
     490           0 :                     sSearch += sTemp.getToken(0, '"', n);
     491           0 :                     sSearch += "\"";
     492             : 
     493           0 :                     OString sReplace = sTemp.getToken(0, '"');
     494           0 :                     sReplace += "\"";
     495           0 :                     sReplace += sCur;
     496           0 :                     sReplace += "\"";
     497             : 
     498           0 :                     sTextTag = sTextTag.replaceFirst(sSearch, sReplace);
     499             : 
     500           0 :                     sAdditionalLine += sTextTag;
     501           0 :                     sAdditionalLine += sText;
     502           0 :                     sAdditionalLine += pStackData->sEndTextTag;
     503             : 
     504           0 :                     sAdditionalLine += "\n";
     505           0 :                     sAdditionalLine += sLastWhitespace;
     506             : 
     507           0 :                     Output( sAdditionalLine );
     508             :                 }
     509           0 :             }
     510             :         }
     511             :     }
     512           0 :     delete pResData;
     513           0 :     pResData = NULL;
     514           0 :     bEnglish = sal_False;
     515           0 : }
     516             : 
     517             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10