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

Generated by: LCOV version 1.10