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

Generated by: LCOV version 1.10