LCOV - code coverage report
Current view: top level - rsc/source/rsc - rsc.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 409 484 84.5 %
Date: 2015-06-13 12:38:46 Functions: 16 16 100.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 <stdlib.h>
      21             : #include <stdio.h>
      22             : #include <fcntl.h>
      23             : 
      24             : #ifdef UNX
      25             : #include <unistd.h>
      26             : #include <sys/wait.h>
      27             : #include <sys/stat.h>
      28             : #else
      29             : #include <io.h>
      30             : #include <process.h>
      31             : #include <direct.h>
      32             : #endif
      33             : 
      34             : #include <string.h>
      35             : #include <ctype.h>
      36             : #include <errno.h>
      37             : 
      38             : #include <tools/stream.hxx>
      39             : #include <rscerror.h>
      40             : #include <rsctop.hxx>
      41             : #include <rscdb.hxx>
      42             : #include <rscpar.hxx>
      43             : #include <rscrsc.hxx>
      44             : #include <rschash.hxx>
      45             : 
      46             : #include <osl/file.h>
      47             : #include <osl/file.hxx>
      48             : #include <osl/process.h>
      49             : #include <rtl/strbuf.hxx>
      50             : #include <rtl/tencinfo.h>
      51             : #include <rtl/textenc.h>
      52             : #include <comphelper/string.hxx>
      53             : 
      54             : #include <vector>
      55             : #include <algorithm>
      56             : 
      57             : using comphelper::string::getTokenCount;
      58             : 
      59             : OString*  pStdParType  = NULL;
      60             : OString*  pStdPar1     = NULL;
      61             : OString*  pStdPar2     = NULL;
      62             : OString*  pWinParType  = NULL;
      63             : OString*  pWinPar1     = NULL;
      64             : OString*  pWinPar2     = NULL;
      65             : sal_uInt32      nRefDeep     = 10;
      66             : AtomContainer*  pHS          = NULL;
      67             : 
      68             : 
      69         417 : void RscCmdLine::Init()
      70             : {
      71         417 :     nCommands       = 0;
      72         417 :     nByteOrder      = RSC_BIGENDIAN;
      73             : 
      74         417 :     aPath = OString(".");
      75         417 :     m_aOutputFiles.clear();
      76         417 :     m_aOutputFiles.push_back( OutputFile() );
      77         417 : }
      78             : 
      79         417 : RscCmdLine::RscCmdLine( int argc, char ** argv, RscError * pEH )
      80             : {
      81             :     char *          pStr;
      82             :     char **         ppStr;
      83         417 :     RscPtrPtr       aCmdLine;
      84             :     sal_uInt32      i;
      85         417 :     bool            bOutputSrsIsSet = false;
      86             : 
      87         417 :     Init();
      88             : 
      89         417 :     pStr = ::ResponseFile( &aCmdLine, argv, argc );
      90         417 :     if( pStr )
      91           0 :         pEH->FatalError( ERR_OPENFILE, RscId(), pStr );
      92             : 
      93             :     /* check the inputted switches       */
      94         417 :     ppStr  = reinterpret_cast<char **>(aCmdLine.GetBlock());
      95         417 :     ppStr++;
      96         417 :     i = 1;
      97       10763 :     while( ppStr && i < (aCmdLine.GetCount() -1) )
      98             :     {
      99             : #if OSL_DEBUG_LEVEL > 1
     100             :         fprintf( stderr, "CmdLineArg: \"%s\"\n", *ppStr );
     101             : #endif
     102        9929 :         if (strcmp(*ppStr, "-isystem") == 0)
     103             :         {
     104             :             // ignore "-isystem" and following arg
     105           0 :             if (i < aCmdLine.GetCount() - 1)
     106             :             {
     107           0 :                 ++ppStr;
     108           0 :                 ++i;
     109             :             }
     110             :         }
     111        9929 :         else if (strncmp(*ppStr, "-isystem", strlen("-isystem")) == 0)
     112             :         {
     113             :             // ignore args starting with "-isystem"
     114             :         }
     115        9929 :         else if( '-' == **ppStr )
     116             :         {
     117       19024 :             if( !rsc_stricmp( (*ppStr) + 1, "h" )
     118        9512 :               || !strcmp( (*ppStr) + 1, "?" ) )
     119             :             { // Write help to standard output
     120           0 :                 nCommands |= HELP_FLAG;
     121             :             }
     122        9512 :             else if( !rsc_stricmp( (*ppStr) + 1, "p" ) )
     123             :             { // No preprocessor
     124          56 :                 nCommands |= NOPREPRO_FLAG;
     125             :             }
     126        9456 :             else if( !rsc_stricmp( (*ppStr) + 1, "s" ) )
     127             :             { // Syntax analysis, creates .srs file
     128         361 :                 nCommands |= NOLINK_FLAG;
     129             :             }
     130        9095 :             else if( !rsc_stricmp( (*ppStr) + 1, "l" ) )
     131             :             { // Linken, keine Syntax und kein Prepro
     132           0 :                 nCommands |= NOPREPRO_FLAG;
     133           0 :                 nCommands |= NOSYNTAX_FLAG;
     134             :             }
     135        9095 :             else if( !rsc_stricmp( (*ppStr) + 1, "r" ) )
     136             :             { // erzeugt kein .res-file
     137           0 :                 nCommands |= NORESFILE_FLAG;
     138             :             }
     139        9095 :             else if( !rsc_strnicmp( (*ppStr) + 1, "sub", 3 ) )
     140             :             {
     141             :                 const char* pEqual;
     142         112 :                 for( pEqual = (*ppStr)+4; *pEqual && *pEqual != '='; ++pEqual )
     143             :                     ;
     144         112 :                 if( *pEqual )
     145             :                 {
     146         112 :                     m_aReplacements.push_back( std::pair< OString, OString >( OString( (*ppStr)+4, pEqual - *ppStr - 4 ),
     147         224 :                         OString( pEqual + 1 ) ) );
     148             :                 }
     149             :             }
     150        8983 :             else if( !rsc_stricmp( (*ppStr) + 1, "PreLoad" ) )
     151             :             { // Alle Resourcen mit Preload
     152           0 :                 nCommands |= PRELOAD_FLAG;
     153             :             }
     154        8983 :             else if( !rsc_stricmp( (*ppStr) + 1, "LITTLEENDIAN" ) )
     155             :             { // Byte Ordnung beim Schreiben
     156           0 :                 nByteOrder = RSC_LITTLEENDIAN;
     157             :             }
     158        8983 :             else if( !rsc_stricmp( (*ppStr) + 1, "BIGENDIAN" ) )
     159             :             { // Byte Ordnung beim Schreiben
     160           0 :                 nByteOrder = RSC_BIGENDIAN;
     161             :             }
     162        8983 :             else if( !rsc_strnicmp( (*ppStr) + 1, "d", 1 ) )
     163             :             { // Symbole definieren
     164        3610 :                 nCommands |= DEFINE_FLAG;
     165             :             }
     166        5373 :             else if( !rsc_strnicmp( (*ppStr) + 1, "i", 1 ) )
     167             :             { // define include path
     168        4340 :                 nCommands |= INCLUDE_FLAG;
     169        4340 :                 OStringBuffer aBuffer(aPath);
     170        4340 :                 if (!aBuffer.isEmpty())
     171        4340 :                     aBuffer.append(SAL_PATHSEPARATOR);
     172        4340 :                 aBuffer.append((*ppStr) + 2);
     173        4340 :                 aPath = aBuffer.makeStringAndClear();
     174             :             }
     175        1033 :             else if( !rsc_strnicmp( (*ppStr) + 1, "fs=", 3 ) )
     176             :             { // define name of .res file
     177          56 :                 if( m_aOutputFiles.back().aOutputRc.getLength() )
     178           0 :                     m_aOutputFiles.push_back( OutputFile() );
     179          56 :                 m_aOutputFiles.back().aOutputRc = (*ppStr) + 4;
     180             :             }
     181         977 :             else if( !rsc_strnicmp( (*ppStr) + 1, "lip=", 4 ) )
     182             :             {  // additional language specific include for system dependent files
     183         448 :                 const OString aSysSearchDir( (*ppStr)+5 );
     184             : 
     185             :                 // ignore empty -lip= arguments that we get lots of these days
     186         448 :                 if (!aSysSearchDir.isEmpty())
     187             :                 {
     188         448 :                     m_aOutputFiles.back().aSysSearchDirs.push_back(aSysSearchDir);
     189         448 :                     OString aLangSearchPath = m_aOutputFiles.back().aLangSearchPath;
     190         448 :                     if( !aLangSearchPath.isEmpty() )
     191             :                     {
     192         392 :                         aLangSearchPath = aLangSearchPath + OString( SAL_PATHSEPARATOR );
     193             :                     }
     194         448 :                     aLangSearchPath = aLangSearchPath + aSysSearchDir;
     195             : 
     196         448 :                     m_aOutputFiles.back().aLangSearchPath = aLangSearchPath;
     197         448 :                 }
     198             :             }
     199         529 :             else if( !rsc_strnicmp( (*ppStr) + 1, "fp=", 3 ) )
     200             :             { // define name of .srs file
     201         417 :                 aOutputSrs = (*ppStr) + 4;
     202         417 :                 bOutputSrsIsSet = true;
     203             :             }
     204         112 :             else if( !rsc_strnicmp( (*ppStr) + 1, "oil=", 4 ) )
     205             :             {
     206          56 :                 aILDir = (*ppStr) + 5;
     207             :             }
     208          56 :             else if( !rsc_stricmp( (*ppStr) + 1, "NoSysResTest" ) )
     209             :             { // Bitmap, Pointers, Icons nicht ueberpruefen
     210           0 :                 nCommands |= NOSYSRESTEST_FLAG;
     211             :             }
     212          56 :             else if( !rsc_stricmp( (*ppStr) + 1, "SrsDefault" ) )
     213             :             { // Only write one language to srs file
     214           0 :                 nCommands |= SRSDEFAULT_FLAG;
     215             :             }
     216          56 :             else if( !rsc_stricmp( (*ppStr) + 1, "lg" ) )
     217             :             {
     218           0 :                 m_aOutputFiles.back().aLangName.clear();
     219             :             }
     220          56 :             else if( !rsc_strnicmp( (*ppStr) + 1, "lg", 2 ) )
     221             :             {
     222          56 :                 if( !m_aOutputFiles.back().aLangName.isEmpty() )
     223           0 :                     m_aOutputFiles.push_back( OutputFile() );
     224          56 :                 m_aOutputFiles.back().aLangName = OString((*ppStr)+3);
     225             :             }
     226             :             else
     227           0 :                 pEH->FatalError( ERR_UNKNOWNSW, RscId(), *ppStr );
     228             :         }
     229             :         else
     230             :         {
     231             :             // Eingabedatei
     232         417 :             aInputList.push_back( new OString(*ppStr) );
     233             :         }
     234        9929 :         ppStr++;
     235        9929 :         i++;
     236             :     }
     237             : 
     238         417 :     if( nCommands & HELP_FLAG )
     239           0 :         pEH->FatalError( ERR_USAGE, RscId() );
     240             :     // was an inputted file specified
     241         417 :     else if( !aInputList.empty() )
     242             :     {
     243         417 :         ::std::list<OutputFile>::iterator it;
     244         834 :         for( it = m_aOutputFiles.begin(); it != m_aOutputFiles.end(); ++it )
     245             :         {
     246         417 :             if( it->aOutputRc.isEmpty() )
     247         361 :                 it->aOutputRc  = ::OutputFile( *aInputList.front(), "rc"  );
     248             :         }
     249         417 :         if( ! bOutputSrsIsSet )
     250           0 :             aOutputSrs = ::OutputFile( *aInputList.front(), "srs" );
     251             :     }
     252             :     else
     253           0 :         pEH->FatalError( ERR_NOINPUT, RscId() );
     254         417 : }
     255             : 
     256         834 : RscCmdLine::~RscCmdLine()
     257             : {
     258         834 :     for ( size_t i = 0, n = aInputList.size(); i < n; ++i )
     259         417 :         delete aInputList[ i ];
     260         417 :     aInputList.clear();
     261         417 : }
     262             : 
     263        1548 : OString RscCmdLine::substitutePaths( const OString& rIn )
     264             : {
     265             :     // prepare return value
     266        1548 :     OStringBuffer aRet( 256 );
     267        1548 :     std::list< std::pair< OString, OString > >::const_iterator last_match = m_aReplacements.end();
     268             : 
     269             :     // search for longest replacement match
     270        4644 :     for( std::list< std::pair< OString, OString > >::const_iterator repl = m_aReplacements.begin(); repl != m_aReplacements.end(); ++repl )
     271             :     {
     272        3096 :         if( rIn.startsWith( repl->second ) ) // path matches
     273             :         {
     274        1919 :             if( last_match == m_aReplacements.end() || last_match->second.getLength() < repl->second.getLength() )
     275        1919 :                 last_match = repl;
     276             :         }
     277             :     }
     278             : 
     279             :     // copy replacement found and rest of rIn
     280        1548 :     sal_Int32 nIndex = 0;
     281        1548 :     if( last_match != m_aReplacements.end() )
     282             :     {
     283        1548 :         aRet.append( "%" );
     284        1548 :         aRet.append( last_match->first );
     285        1548 :         aRet.append( "%" );
     286        1548 :         nIndex = last_match->second.getLength();
     287             :     }
     288             : 
     289        1548 :     if( rIn.match( "/", nIndex ) )
     290         371 :         aRet.append( rIn.copy( nIndex ) );
     291             :     else
     292        1177 :         aRet.append( rIn.copy( nIndex - 1 ) );
     293             : 
     294        1548 :     return aRet.makeStringAndClear();
     295             : }
     296             : 
     297         417 : RscCompiler::RscCompiler( RscCmdLine * pLine, RscTypCont * pTypCont )
     298             : {
     299         417 :     fListing      = NULL;
     300         417 :     fExitFile     = NULL;
     301             : 
     302             :     //Set Command Line, set Type Container
     303         417 :     pCL = pLine;
     304         417 :     pTC = pTypCont;
     305         417 : }
     306             : 
     307         417 : RscCompiler::~RscCompiler()
     308             : {
     309         417 :     pTC->pEH->SetListFile( NULL );
     310             : 
     311         417 :     if( fListing )
     312           0 :         fclose( fListing );
     313             : 
     314         417 :     if( fExitFile )
     315           0 :         fclose( fExitFile );
     316         417 : }
     317             : 
     318         417 : ERRTYPE RscCompiler::Start()
     319             : {
     320         417 :     ERRTYPE         aError;
     321             :     RscFile*        pFName;
     322             : 
     323         417 :     if( pCL->aInputList.empty() )
     324           0 :         pTC->pEH->FatalError( ERR_NOINPUT, RscId() );
     325             : 
     326         834 :     for( size_t i = 0, n = pCL->aInputList.size(); i < n; ++i )
     327         417 :         pTC->aFileTab.NewCodeFile( *pCL->aInputList[ i ] );
     328             : 
     329         417 :     if( !(pCL->nCommands & NOSYNTAX_FLAG) )
     330             :     {
     331         417 :         if( pCL->nCommands & NOPREPRO_FLAG )
     332             :         {
     333             : 
     334          56 :             pTC->pEH->SetListFile( NULL );
     335             : 
     336          56 :             sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
     337         168 :             while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && aError.IsOk() )
     338             :             {
     339          56 :                 pFName = pTC->aFileTab.Get( aIndex );
     340          56 :                 if( !pFName->bScanned && !pFName->IsIncFile() )
     341             :                 {
     342          56 :                     aError = IncludeParser( aIndex );
     343             :                     // Currentzeiger richtig setzen
     344          56 :                     aIndex = pTC->aFileTab.GetIndexOf( pFName );
     345             :                 }
     346          56 :                 aIndex = pTC->aFileTab.NextIndex( aIndex );
     347             :             }
     348             : 
     349          56 :             pTC->pEH->SetListFile( fListing );
     350             :         }
     351             :     }
     352             : 
     353         417 :     if ( pTC->pEH->GetVerbosity() >= RscVerbosityVerbose )
     354             :     {
     355           0 :         pTC->pEH->StdOut( "Files: " );
     356           0 :         sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
     357           0 :         while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
     358             :         {
     359           0 :             pFName = pTC->aFileTab.Get( aIndex );
     360           0 :             pTC->pEH->StdOut( pFName->aFileName.getStr() );
     361           0 :             pTC->pEH->StdOut( " " );
     362           0 :             aIndex = pTC->aFileTab.NextIndex( aIndex );
     363             :         }
     364           0 :         pTC->pEH->StdOut( "\n" );
     365             :     }
     366             : 
     367         417 :     if( aError.IsOk() )
     368         417 :         aError = Link();
     369             : 
     370         417 :     if( aError.IsOk() )
     371         417 :         EndCompile();
     372             : 
     373         417 :     if( aError.IsError() )
     374           0 :         pTC->pEH->Error( ERR_ERROR, NULL, RscId() );
     375             : 
     376         417 :     return aError;
     377             : }
     378             : 
     379         417 : void RscCompiler::EndCompile()
     380             : {
     381         417 :     if( !pCL->aOutputSrs.isEmpty() && (pCL->nCommands & NOLINK_FLAG) )
     382             :     {
     383         361 :         pTC->pEH->StdOut( "Writing file ", RscVerbosityVerbose );
     384         361 :         pTC->pEH->StdOut( pCL->aOutputSrs.getStr(), RscVerbosityVerbose );
     385         361 :         pTC->pEH->StdOut( ".\n", RscVerbosityVerbose );
     386             : 
     387             :         // kopiere von TMP auf richtigen Namen
     388         361 :         unlink( pCL->aOutputSrs.getStr() );   // Zieldatei loeschen
     389         361 :         if( !(pCL->nCommands & NOSYNTAX_FLAG) )
     390             :         {
     391             :             FILE        * foutput;
     392             : 
     393         361 :             if( NULL == (foutput = fopen( pCL->aOutputSrs.getStr(), "w" )) )
     394           0 :                 pTC->pEH->FatalError( ERR_OPENFILE, RscId(), pCL->aOutputSrs.getStr() );
     395             :             else
     396             :             {
     397             :                 // Schreibe Datei
     398         361 :                 sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
     399         722 :                 while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
     400             :                 {
     401         361 :                     RscFile* pFN = pTC->aFileTab.Get( aIndex );
     402         361 :                     if( !pFN->IsIncFile() )
     403             :                     {
     404         361 :                         pTC->WriteSrc( foutput, NOFILE_INDEX, false );
     405         361 :                         break; // ?T 281091MM nur eine Src-Datei
     406             :                     }
     407             :                 }
     408             : 
     409         361 :                 fclose( foutput );
     410             :             }
     411             :         }
     412             :     }
     413         417 : }
     414             : 
     415          56 : ERRTYPE RscCompiler :: IncludeParser( sal_uLong lFileKey )
     416             : {
     417             :     FILE            * finput;
     418             :     RscFile         * pFName;
     419          56 :     ERRTYPE           aError;
     420             : 
     421          56 :     pFName = pTC->aFileTab.Get( lFileKey );
     422          56 :     if( !pFName )
     423           0 :         aError = ERR_ERROR;
     424          56 :     else if( !pFName->bScanned )
     425             :     {
     426          56 :         finput = fopen( pFName->aPathName.getStr(), "r" );
     427          56 :         if( !finput )
     428             :         {
     429           0 :             aError = ERR_OPENFILE;
     430             :             pTC->pEH->Error( aError, NULL, RscId(),
     431           0 :                              pFName->aPathName.getStr() );
     432             :         }
     433             :         else
     434             :         {
     435          56 :             RscFileInst       aFileInst( pTC, lFileKey, lFileKey, finput );
     436             : 
     437          56 :             pFName->bScanned = true;
     438          56 :             ::IncludeParser( &aFileInst );
     439          56 :             fclose( finput );
     440             : 
     441             :             // Include-Pfad durchsuchen
     442         112 :             for ( size_t i = 0, n = pFName->aDepLst.size(); i < n; ++i )
     443             :             {
     444          56 :                 RscDepend       * pDep = pFName->aDepLst[ i ];
     445          56 :                 RscFile         * pFNTmp = pTC->aFileTab.GetFile( pDep->GetFileKey() );
     446             :                 // Kein Pfad und Include Datei
     447          56 :                 if( pFNTmp && !pFNTmp->bLoaded )
     448             :                 {
     449          56 :                    pFNTmp->aPathName = pFNTmp->aFileName;
     450             :                 }
     451          56 :             };
     452             :         };
     453             :     };
     454             : 
     455          56 :     return aError;
     456             : }
     457             : 
     458        1196 : ERRTYPE RscCompiler :: ParseOneFile( sal_uLong lFileKey,
     459             :                                      const RscCmdLine::OutputFile* pOutputFile,
     460             :                                      const WriteRcContext* pContext )
     461             : {
     462        1196 :     FILE *     finput = NULL;
     463        1196 :     ERRTYPE    aError;
     464             :     RscFile *  pFName;
     465             : 
     466        1196 :     pFName = pTC->aFileTab.Get( lFileKey );
     467        1196 :     if( !pFName )
     468           0 :         aError = ERR_ERROR;
     469        1196 :     else if( !pFName->bLoaded )
     470             :     {
     471             : 
     472             :         //Include-Dateien vorher lesen
     473         417 :         pFName->bLoaded = true; //Endlos Rekursion vermeiden
     474             : 
     475         834 :         for ( size_t i = 0; i < pFName->aDepLst.size() && aError.IsOk(); ++i )
     476             :         {
     477         417 :             RscDepend* pDep = pFName->aDepLst[ i ];
     478         417 :             aError = ParseOneFile( pDep->GetFileKey(), pOutputFile, pContext );
     479             :         }
     480             : 
     481         417 :         if( aError.IsError() )
     482           0 :             pFName->bLoaded = false; //bei Fehler nicht geladenen
     483             :         else
     484             :         {
     485         417 :             OUString aTmpPath;
     486         834 :             OUString aSrsPath = OStringToOUString( pFName->aPathName, RTL_TEXTENCODING_ASCII_US );
     487             : 
     488         417 :             osl::FileBase::createTempFile( 0, 0, &aTmpPath );
     489         417 :             osl::FileBase::getFileURLFromSystemPath( aSrsPath, aSrsPath );
     490             : 
     491         417 :             if( pContext && pOutputFile )
     492          56 :                 PreprocessSrsFile( *pOutputFile, *pContext, aSrsPath, aTmpPath );
     493             :             else
     494         361 :                 osl::File::copy( aSrsPath, aTmpPath );
     495             : 
     496         834 :             OUString aParseFile;
     497         417 :             osl::FileBase::getSystemPathFromFileURL( aTmpPath, aParseFile );
     498         417 :             finput = fopen(OUStringToOString(aParseFile, RTL_TEXTENCODING_ASCII_US).getStr(), "r");
     499             : 
     500         417 :             if( !finput )
     501             :             {
     502           0 :                 pTC->pEH->Error( ERR_OPENFILE, NULL, RscId(), pFName->aPathName.getStr() );
     503           0 :                 aError = ERR_OPENFILE;
     504             :             }
     505             :             else
     506             :             {
     507         417 :                 RscFileInst aFileInst( pTC, lFileKey, lFileKey, finput );
     508             : 
     509         417 :                 pTC->pEH->StdOut( "reading file ", RscVerbosityVerbose );
     510         417 :                 pTC->pEH->StdOut( OUStringToOString(aParseFile, RTL_TEXTENCODING_ASCII_US).getStr(), RscVerbosityVerbose );
     511         417 :                 pTC->pEH->StdOut( " ", RscVerbosityVerbose );
     512             : 
     513         417 :                 aError = ::parser( &aFileInst );
     514         417 :                 if( aError.IsError() )
     515           0 :                     pTC->Delete( lFileKey );//Resourceobjekte loeschen
     516         417 :                 pTC->pEH->StdOut( "\n", RscVerbosityVerbose );
     517         417 :                 fclose( finput );
     518             :             };
     519             : 
     520         834 :             osl::File::remove( aTmpPath );
     521             :         };
     522             :     };
     523             : 
     524        1196 :     return aError;
     525             : }
     526             : 
     527             : namespace
     528             : {
     529             :     using namespace ::osl;
     530             :     class RscIoError { };
     531             : 
     532         168 :     static inline OUString lcl_getAbsoluteUrl(const OUString& i_sBaseUrl, const OString& i_sPath)
     533             :     {
     534         168 :         OUString sRelUrl, sAbsUrl;
     535         168 :         if(FileBase::getFileURLFromSystemPath(OStringToOUString(i_sPath, RTL_TEXTENCODING_MS_1252), sRelUrl) != FileBase::E_None)
     536           0 :             throw RscIoError();
     537         168 :         if(FileBase::getAbsoluteFileURL(i_sBaseUrl, sRelUrl, sAbsUrl) != FileBase::E_None)
     538           0 :             throw RscIoError();
     539         168 :         return sAbsUrl;
     540             :     };
     541             : 
     542         168 :     static inline OString lcl_getSystemPath(const OUString& i_sUrl)
     543             :     {
     544         168 :         OUString sSys;
     545         168 :         if(FileBase::getSystemPathFromFileURL(i_sUrl, sSys) != FileBase::E_None)
     546           0 :             throw RscIoError();
     547             :         OSL_TRACE("temporary file: %s", OUStringToOString(sSys, RTL_TEXTENCODING_UTF8).getStr());
     548         168 :         return OUStringToOString(sSys, RTL_TEXTENCODING_MS_1252);
     549             :     };
     550             : 
     551         112 :     static inline OString lcl_getTempFile(OUString& sTempDirUrl)
     552             :     {
     553             :         // get a temp file name for the rc file
     554         112 :         OUString sTempUrl;
     555         112 :         if(FileBase::createTempFile(&sTempDirUrl, NULL, &sTempUrl) != FileBase::E_None)
     556           0 :             throw RscIoError();
     557             :         OSL_TRACE("temporary url: %s", OUStringToOString(sTempUrl, RTL_TEXTENCODING_UTF8).getStr());
     558         112 :         return lcl_getSystemPath(sTempUrl);
     559             :     };
     560             : }
     561             : 
     562         417 : ERRTYPE RscCompiler::Link()
     563             : {
     564             :     FILE *      foutput;
     565         417 :     ERRTYPE     aError;
     566             :     RscFile*    pFName;
     567             : 
     568         417 :     if( !(pCL->nCommands & NOLINK_FLAG) )
     569             :     {
     570          56 :         ::std::list<RscCmdLine::OutputFile>::const_iterator it;
     571             : 
     572         112 :         for( it = pCL->m_aOutputFiles.begin(); it != pCL->m_aOutputFiles.end(); ++it )
     573             :         {
     574             :             // cleanup nodes
     575         224 :             for( sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
     576         112 :                  aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && aError.IsOk();
     577          56 :                  aIndex = pTC->aFileTab.NextIndex( aIndex ) )
     578             :             {
     579          56 :                 pFName = pTC->aFileTab.Get( aIndex );
     580          56 :                 if( !pFName->IsIncFile() )
     581             :                 {
     582          56 :                     pTC->Delete( aIndex );
     583          56 :                     aIndex = pTC->aFileTab.GetIndexOf( pFName );
     584          56 :                     pFName->bLoaded = false;
     585             :                 }
     586             :             }
     587             : 
     588             : 
     589             :             // get two temp file urls
     590         112 :             OString aRcTmp, aSysListTmp, aSysList;
     591             :             try
     592             :             {
     593          56 :                 OUString sPwdUrl;
     594          56 :                 osl_getProcessWorkingDir( &sPwdUrl.pData );
     595         112 :                 OUString sRcUrl = lcl_getAbsoluteUrl(sPwdUrl, it->aOutputRc);
     596             :                 // TempDir is either the directory where the rc file is located or pwd
     597         112 :                 OUString sTempDirUrl = sRcUrl.copy(0,sRcUrl.lastIndexOf('/'));
     598             :                 OSL_TRACE("rc directory URL: %s", OUStringToOString(sTempDirUrl, RTL_TEXTENCODING_UTF8).getStr());
     599             : 
     600          56 :                 aRcTmp = lcl_getTempFile(sTempDirUrl);
     601             :                 OSL_TRACE("temporary rc file: %s", aRcTmp.getStr());
     602             : 
     603         112 :                 OUString sOilDirUrl;
     604          56 :                 if(!pCL->aILDir.isEmpty())
     605          56 :                     sOilDirUrl = lcl_getAbsoluteUrl(sPwdUrl, pCL->aILDir);
     606             :                 else
     607           0 :                     sOilDirUrl = sTempDirUrl;
     608             :                 OSL_TRACE("ilst directory URL: %s", OUStringToOString(sOilDirUrl, RTL_TEXTENCODING_UTF8).getStr());
     609             : 
     610          56 :                 aSysListTmp = lcl_getTempFile(sOilDirUrl);
     611             :                 OSL_TRACE("temporary ilst file: %s", aSysListTmp.getStr());
     612             : 
     613         112 :                 OUString sIlstUrl;
     614          56 :                 sIlstUrl = sRcUrl.copy(sRcUrl.lastIndexOf('/')+1);
     615          56 :                 sIlstUrl = sIlstUrl.copy(0,sIlstUrl.lastIndexOf('.'));
     616          56 :                 sIlstUrl += ".ilst";
     617          56 :                 sIlstUrl = lcl_getAbsoluteUrl(sOilDirUrl, OUStringToOString(sIlstUrl, RTL_TEXTENCODING_UTF8));
     618             : 
     619          56 :                 aSysList = lcl_getSystemPath(sIlstUrl);
     620          56 :                 OSL_TRACE("ilst file: %s", aSysList.getStr());
     621             :             }
     622           0 :             catch (RscIoError&)
     623             :             {
     624           0 :                 OString sMsg("Error with paths:\n");
     625           0 :                 sMsg += "temporary rc file: " + aRcTmp + "\n";
     626           0 :                 sMsg += "temporary ilst file: " + aSysListTmp + "\n";
     627           0 :                 sMsg += "ilst file: " + aSysList + "\n";
     628           0 :                 pTC->pEH->FatalError(ERR_OPENFILE, RscId(), sMsg.getStr());
     629             :             }
     630          56 :             if ( NULL == (fExitFile = foutput = fopen( aRcTmp.getStr(), "wb" )) )
     631           0 :                 pTC->pEH->FatalError( ERR_OPENFILE, RscId(), aRcTmp.getStr() );
     632             : 
     633             :             // Schreibe Datei
     634          56 :             sal_Char cSearchDelim = SAL_PATHSEPARATOR;
     635          56 :             sal_Char cAccessDelim = SAL_PATHDELIMITER;
     636          56 :             pTC->ChangeLanguage( it->aLangName );
     637          56 :             pTC->SetSourceCharSet( RTL_TEXTENCODING_UTF8 );
     638          56 :             pTC->ClearSysNames();
     639         112 :             OStringBuffer aSysSearchPath(it->aLangSearchPath);
     640          56 :             sal_Int32 nIndex = 0;
     641         112 :             OString aSearchPath = pTC->GetSearchPath();
     642          56 :             do
     643             :             {
     644          56 :                 OString aToken = aSearchPath.getToken( 0, cSearchDelim, nIndex );
     645          56 :                 if (!aSysSearchPath.isEmpty())
     646          56 :                     aSysSearchPath.append(cSearchDelim);
     647          56 :                 aSysSearchPath.append(aToken);
     648          56 :                 aSysSearchPath.append(cAccessDelim);
     649          56 :                 aSysSearchPath.append(it->aLangName);
     650          56 :                 aSysSearchPath.append(cSearchDelim);
     651          56 :                 aSysSearchPath.append(aToken);
     652             :             }
     653          56 :             while ( nIndex >= 0 );
     654             :             OSL_TRACE( "setting search path for language %s: %s", it->aLangName.getStr(), aSysSearchPath.getStr() );
     655          56 :             pTC->SetSysSearchPath(aSysSearchPath.makeStringAndClear());
     656             : 
     657         112 :             WriteRcContext  aContext;
     658             : 
     659          56 :             aContext.fOutput = foutput;
     660          56 :             aContext.aOutputRc = it->aOutputRc;
     661          56 :             aContext.aOutputSysList = aSysListTmp;
     662          56 :             aContext.pCmdLine = pCL;
     663             : 
     664             :             // create empty sys list
     665          56 :             if( !aContext.aOutputSysList.isEmpty() )
     666             :             {
     667          56 :                 FILE* pSysListFile = fopen( aContext.aOutputSysList.getStr(), "wb" );
     668             : 
     669          56 :                 if( !pSysListFile )
     670           0 :                     pTC->pEH->FatalError( ERR_OPENFILE, RscId(), aContext.aOutputSysList.getStr() );
     671             :                 else
     672          56 :                     fclose( pSysListFile );
     673             :             }
     674             : 
     675             :             // parse files for specific language
     676         224 :             for( sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
     677         112 :                  aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && aError.IsOk();
     678          56 :                  aIndex = pTC->aFileTab.NextIndex( aIndex ) )
     679             :             {
     680          56 :                 pFName = pTC->aFileTab.Get( aIndex );
     681          56 :                 if( !pFName->IsIncFile() )
     682             :                 {
     683          56 :                     aError = ParseOneFile( aIndex, &*it, &aContext );
     684          56 :                     aIndex = pTC->aFileTab.GetIndexOf( pFName );
     685             :                 }
     686             :             };
     687             : 
     688          56 :             aError = pTC->WriteRc( aContext );
     689             : 
     690          56 :             fclose( foutput );
     691          56 :             fExitFile = NULL;
     692          56 :             unlink( it->aOutputRc.getStr() );
     693          56 :             if( rename( aRcTmp.getStr(), it->aOutputRc.getStr() ) )
     694             :             {
     695           0 :                 OStringBuffer aBuf;
     696           0 :                 aBuf.append( aRcTmp );
     697           0 :                 aBuf.append( " -> " );
     698           0 :                 aBuf.append( it->aOutputRc );
     699           0 :                 pTC->pEH->FatalError( ERR_RENAMEFILE, RscId(), aBuf.getStr() );
     700             :             }
     701             :             else
     702             :             {
     703             : #ifdef UNX
     704          56 :                 (void)chmod( it->aOutputRc.getStr(), S_IRWXU | S_IRWXG | S_IROTH );
     705             : #endif
     706             :             }
     707             : 
     708          56 :             unlink( aSysList.getStr() );
     709          56 :             if( rename( aSysListTmp.getStr(), aSysList.getStr() ) )
     710             :             {
     711           0 :                 OStringBuffer aBuf;
     712           0 :                 aBuf.append( aSysListTmp );
     713           0 :                 aBuf.append( " -> " );
     714           0 :                 aBuf.append( aSysList );
     715           0 :                 pTC->pEH->FatalError( ERR_RENAMEFILE, RscId(), aBuf.getStr() );
     716             :             }
     717             :             else
     718             :             {
     719             : #ifdef UNX
     720          56 :                 (void)chmod( aSysList.getStr(), S_IRWXU | S_IRWXG | S_IROTH );
     721             : #endif
     722             :             }
     723          56 :         }
     724             :     }
     725             :     else
     726             :     {
     727             :         // parse files
     728        2168 :         for( sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
     729        1084 :              aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && aError.IsOk();
     730         723 :              aIndex = pTC->aFileTab.NextIndex( aIndex ) )
     731             :         {
     732         723 :             pFName = pTC->aFileTab.Get( aIndex );
     733         723 :             if( !pFName->IsIncFile() )
     734             :             {
     735         723 :                 aError = ParseOneFile( aIndex, NULL, NULL );
     736         723 :                 aIndex = pTC->aFileTab.GetIndexOf( pFName );
     737             :             }
     738             :         };
     739             :     }
     740             : 
     741         417 :     return aError;
     742             : }
     743             : 
     744        1548 : bool RscCompiler::GetImageFilePath( const RscCmdLine::OutputFile& rOutputFile,
     745             :                                     const WriteRcContext& rContext,
     746             :                                     const OString& rBaseFileName,
     747             :                                     OString& rImagePath,
     748             :                                     FILE* pSysListFile )
     749             : {
     750        1548 :     ::std::list< OString >  aFileNames;
     751        1548 :     bool bFound = false;
     752             : 
     753        1548 :     aFileNames.push_back( rBaseFileName + OString(".png") );
     754        1548 :     aFileNames.push_back( rBaseFileName + OString(".bmp") );
     755             : 
     756        1548 :     ::std::list< OString >::iterator aFileIter( aFileNames.begin() );
     757             : 
     758        4648 :     while( ( aFileIter != aFileNames.end() ) && !bFound )
     759             :     {
     760        1552 :         ::std::list< OString >::const_iterator aDirIter( rOutputFile.aSysSearchDirs.begin() );
     761             : 
     762       11744 :         while( ( aDirIter != rOutputFile.aSysSearchDirs.end() ) && !bFound )
     763             :         {
     764        8640 :             const OString aSysPath = *aDirIter + "/" + *aFileIter;
     765       17280 :             OUString aAbsPath = OStringToOUString( aSysPath, RTL_TEXTENCODING_ASCII_US );
     766             : 
     767             : 
     768        8640 :             osl::FileBase::getFileURLFromSystemPath( aAbsPath, aAbsPath );
     769       17280 :             osl::DirectoryItem aDirectoryItem;
     770        8640 :             bool bFile = false;
     771        8640 :             if (osl::DirectoryItem::E_None == osl::DirectoryItem::get( aAbsPath, aDirectoryItem ))
     772             :             {
     773        1548 :                 osl::FileStatus aFS(osl_FileStatus_Mask_Type);
     774        1548 :                 if (osl::DirectoryItem::E_None == aDirectoryItem.getFileStatus( aFS ))
     775        1548 :                     bFile = aFS.isRegular();
     776             :             }
     777             : 
     778             : #if OSL_DEBUG_LEVEL > 1
     779             :             fprintf( stderr, "Searching image: %s\n", aSysPath.getStr() );
     780             : #endif
     781             : 
     782        8640 :             if( bFile )
     783             :             {
     784        1548 :                 std::list< std::pair< OString, OString > >::const_iterator  aReplIter( rContext.pCmdLine->m_aReplacements.begin() );
     785        1548 :                 OString aRelPathStr( aSysPath );
     786             : 
     787        4644 :                 while( ( aReplIter != rContext.pCmdLine->m_aReplacements.end() ) && !bFound )
     788             :                 {
     789        1548 :                     OString aSearch(aReplIter->second.toAsciiLowerCase());
     790        3096 :                     OString aSearchIn(aRelPathStr.toAsciiLowerCase());
     791        1548 :                     if( aSearchIn.startsWith(aSearch) )
     792             :                     {
     793        1548 :                         sal_Int32       nCopyPos = aReplIter->second.getLength(), nLength = aRelPathStr.getLength();
     794        1548 :                         const sal_Char* pChars = aRelPathStr.getStr();
     795             : 
     796        3096 :                         while( ( nCopyPos < nLength ) && ( pChars[ nCopyPos ] == '/' || pChars[ nCopyPos ] == '\\' || pChars[ nCopyPos ] == ':' ) )
     797             :                         {
     798           0 :                             ++nCopyPos;
     799             :                         }
     800             : 
     801        1548 :                         if( nCopyPos < nLength )
     802        1548 :                             rImagePath = aRelPathStr.copy( nCopyPos ).replace( '\\', '/' );
     803             : 
     804        1548 :                         bFound = true;
     805             :                     }
     806             : 
     807        1548 :                     ++aReplIter;
     808        1548 :                 }
     809             : 
     810        1548 :                 if( bFound && pSysListFile )
     811             :                 {
     812        1548 :                     fprintf( pSysListFile, "%s\n", rContext.pCmdLine->substitutePaths( aSysPath ).getStr() );
     813        1548 :                 }
     814             : 
     815             : #if OSL_DEBUG_LEVEL > 1
     816             :                 fprintf( stderr, "ImagePath to add: %s\n", rImagePath.getStr() );
     817             : #endif
     818             :             }
     819             : 
     820        8640 :             ++aDirIter;
     821        8640 :         }
     822             : 
     823        1552 :         ++aFileIter;
     824             :     }
     825             : 
     826        1548 :     return bFound;
     827             : }
     828             : 
     829          56 : void RscCompiler::PreprocessSrsFile( const RscCmdLine::OutputFile& rOutputFile,
     830             :                                      const WriteRcContext& rContext,
     831             :                                      const OUString& rSrsInPath,
     832             :                                      const OUString& rSrsOutPath )
     833             : {
     834          56 :     SvFileStream                aIStm( rSrsInPath, StreamMode::READ );
     835         112 :     SvFileStream                aOStm( rSrsOutPath, StreamMode::WRITE | StreamMode::TRUNC );
     836         112 :     ::std::vector< OString > aMissingImages;
     837          56 :     FILE*                       pSysListFile = rContext.aOutputSysList.isEmpty() ? NULL : fopen( rContext.aOutputSysList.getStr(), "ab" );
     838             : 
     839          56 :     if( !aIStm.GetError() && !aOStm.GetError() )
     840             :     {
     841          56 :         OString aLine;
     842         112 :         OString aFilePath;
     843             : 
     844      113709 :         while( aIStm.ReadLine( aLine ) )
     845             :         {
     846      384693 :             if( ( getTokenCount(aLine, '=') == 2 ) &&
     847      245303 :                 ( aLine.getToken(0, '=').indexOf("File") != -1 ) )
     848             :             {
     849         941 :                 OString aBaseFileName( aLine.getToken(1, '"').getToken(0, '.') );
     850             : 
     851         941 :                 if( GetImageFilePath( rOutputFile, rContext, aBaseFileName, aFilePath, pSysListFile ) )
     852             :                 {
     853        1882 :                     aLine = OStringBuffer("File = \"").
     854        1882 :                         append(aFilePath).append("\";").
     855         941 :                         makeStringAndClear();
     856             :                 }
     857             :                 else
     858           0 :                     aMissingImages.push_back( aBaseFileName );
     859             : 
     860         941 :                 aOStm.WriteLine(aLine);
     861             :             }
     862      112656 :             else if (aLine.indexOf("ImageList") != -1)
     863             :             {
     864          50 :                 ::std::vector< ::std::pair< OString, sal_Int32 > > aEntryVector;
     865             : 
     866          50 :                 aOStm.WriteLine(aLine);
     867             : 
     868          50 :                 if (aLine.indexOf(';') == -1)
     869             :                 {
     870          49 :                     const sal_Size nImgListStartPos = aIStm.Tell();
     871             : 
     872         126 :                     do
     873             :                     {
     874         126 :                         if( !aIStm.ReadLine(aLine) )
     875           0 :                             break;
     876             :                     }
     877         126 :                     while (aLine.indexOf("Prefix") == -1);
     878             : 
     879          49 :                     const OString aPrefix( aLine.getToken(1, '"') );
     880          49 :                     aIStm.Seek( nImgListStartPos );
     881             : 
     882         420 :                     do
     883             :                     {
     884         420 :                         if (!aIStm.ReadLine(aLine) )
     885           0 :                             break;
     886             :                     }
     887         420 :                     while (aLine.indexOf("IdList") == -1);
     888             : 
     889             :                     // scan all ids and collect images
     890         803 :                     while (aLine.indexOf('}') == -1)
     891             :                     {
     892         705 :                         if( !aIStm.ReadLine(aLine) )
     893           0 :                             break;
     894             : 
     895         705 :                         aLine = comphelper::string::stripStart(aLine, ' ');
     896         705 :                         aLine = comphelper::string::stripStart(aLine, '\t');
     897         705 :                         aLine = comphelper::string::remove(aLine, ';');
     898             : 
     899         705 :                         if (comphelper::string::isdigitAsciiString(aLine))
     900             :                         {
     901         607 :                             sal_Int32 nNumber = atoi(aLine.getStr());
     902             : 
     903         607 :                             OStringBuffer aBuf(aPrefix);
     904         607 :                             if( nNumber < 10000 )
     905         282 :                                 aBuf.append('0');
     906         607 :                             aBuf.append(aLine);
     907        1214 :                             OString aBaseFileName = aBuf.makeStringAndClear();
     908             : 
     909         607 :                             if( GetImageFilePath( rOutputFile, rContext, aBaseFileName, aFilePath, pSysListFile ) )
     910         607 :                                 aEntryVector.push_back( ::std::pair< OString, sal_Int32 >( aFilePath, nNumber ) );
     911             :                             else
     912         607 :                                 aMissingImages.push_back( aBaseFileName );
     913             :                         }
     914             :                     }
     915             : 
     916          49 :                     const sal_Size nImgListEndPos = aIStm.Tell();
     917          49 :                     aIStm.Seek( nImgListStartPos );
     918         518 :                     while( aIStm.Tell() < nImgListEndPos )
     919             :                     {
     920         420 :                         aIStm.ReadLine( aLine );
     921             : 
     922         420 :                         if (aLine.indexOf("IdList") != -1)
     923             :                         {
     924         803 :                             while (aLine.indexOf('}') == -1)
     925         705 :                                 aIStm.ReadLine(aLine);
     926             :                         }
     927             :                         else
     928         371 :                             aOStm.WriteLine(aLine);
     929             :                     }
     930             : 
     931          49 :                     aOStm.WriteLine(OString("FileList = {"));
     932             : 
     933         656 :                     for( size_t i = 0; i < aEntryVector.size(); ++i )
     934             :                     {
     935         607 :                         OStringBuffer aEntryString("< \"");
     936             : 
     937         607 :                         aEntryString.append(aEntryVector[i].first);
     938         607 :                         aEntryString.append("\"; ");
     939         607 :                         aEntryString.append(static_cast<sal_Int32>(aEntryVector[ i ].second));
     940         607 :                         aEntryString.append("; >;");
     941             : 
     942         607 :                         aOStm.WriteLine(aEntryString.makeStringAndClear());
     943         607 :                     }
     944             : 
     945          49 :                     aOStm.WriteLine(OString("};"));
     946             :                 }
     947             :                 else
     948           1 :                     aOStm.WriteLine(aLine);
     949             :             }
     950             :             else
     951      112606 :                 aOStm.WriteLine(aLine);
     952          56 :         }
     953             :     }
     954             : 
     955          56 :     if( aMissingImages.size() > 0 )
     956             :     {
     957           0 :         OStringBuffer aImagesStr;
     958             : 
     959           0 :         for( size_t i = 0; i < aMissingImages.size(); ++i )
     960             :         {
     961           0 :             if( i )
     962           0 :                 aImagesStr.append(' ');
     963             : 
     964           0 :             aImagesStr.append(aMissingImages[i]);
     965             :         }
     966             : 
     967           0 :         pTC->pEH->FatalError( ERR_NOIMAGE, RscId(), aImagesStr.getStr() );
     968             :     }
     969             : 
     970          56 :     if( pSysListFile )
     971         112 :         fclose( pSysListFile );
     972          56 : }
     973             : 
     974             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11