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

Generated by: LCOV version 1.10