LCOV - code coverage report
Current view: top level - idlc/source - idlccompile.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 130 169 76.9 %
Date: 2012-08-25 Functions: 8 8 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 111 270 41.1 %

           Branch data     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 <idlc/idlc.hxx>
      21                 :            : #include <rtl/ustring.hxx>
      22                 :            : #include <rtl/strbuf.hxx>
      23                 :            : #include <osl/process.h>
      24                 :            : #include <osl/diagnose.h>
      25                 :            : #include <osl/thread.h>
      26                 :            : #include <osl/file.hxx>
      27                 :            : 
      28                 :            : #if defined(SAL_W32)
      29                 :            : #include <io.h>
      30                 :            : #endif
      31                 :            : 
      32                 :            : #ifdef  SAL_UNX
      33                 :            : #include <errno.h>
      34                 :            : #include <unistd.h>
      35                 :            : #if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) || \
      36                 :            :     defined(AIX) || defined(OPENBSD) || defined(DRAGONFLY)
      37                 :            : #include <sys/wait.h>
      38                 :            : #else
      39                 :            : #include <wait.h>
      40                 :            : #endif
      41                 :            : #endif
      42                 :            : 
      43                 :            : #include <string.h>
      44                 :            : 
      45                 :            : using namespace ::rtl;
      46                 :            : using namespace ::osl;
      47                 :            : 
      48                 :            : extern int yyparse();
      49                 :            : extern FILE* yyin;
      50                 :            : extern int yydebug;
      51                 :            : 
      52                 :            : sal_Int32 lineNumber = 1;
      53                 :            : 
      54                 :            : 
      55                 :        166 : static OUString TMP(RTL_CONSTASCII_USTRINGPARAM("TMP"));
      56                 :        166 : static OUString TEMP(RTL_CONSTASCII_USTRINGPARAM("TEMP"));
      57                 :            : static sal_Char tmpFilePattern[512];
      58                 :            : 
      59                 :      47821 : sal_Bool isFileUrl(const OString& fileName)
      60                 :            : {
      61         [ +  + ]:      47821 :     if (fileName.indexOf("file://") == 0 )
      62                 :      17933 :         return sal_True;
      63                 :      47821 :     return sal_False;
      64                 :            : }
      65                 :            : 
      66                 :      29888 : OString convertToAbsoluteSystemPath(const OString& fileName)
      67                 :            : {
      68                 :      29888 :     OUString uSysFileName;
      69 [ +  - ][ +  - ]:      29888 :     OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
      70 [ +  - ][ +  + ]:      29888 :     if ( isFileUrl(fileName) )
      71                 :            :     {
      72         [ +  - ]:      11955 :         if (FileBase::getSystemPathFromFileURL(uFileName, uSysFileName)
      73                 :            :             != FileBase::E_None)
      74                 :            :         {
      75                 :            :             OSL_ASSERT(false);
      76                 :            :         }
      77                 :            :     } else
      78                 :            :     {
      79                 :      17933 :         OUString uWorkingDir, uUrlFileName, uTmp;
      80         [ +  - ]:      17933 :         if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None)
      81                 :            :         {
      82                 :            :             OSL_ASSERT(false);
      83                 :            :         }
      84         [ +  - ]:      17933 :         if (FileBase::getFileURLFromSystemPath(uFileName, uTmp)
      85                 :            :             != FileBase::E_None)
      86                 :            :         {
      87                 :            :             OSL_ASSERT(false);
      88                 :            :         }
      89         [ +  - ]:      17933 :         if (FileBase::getAbsoluteFileURL(uWorkingDir, uTmp, uUrlFileName)
      90                 :            :             != FileBase::E_None)
      91                 :            :         {
      92                 :            :             OSL_ASSERT(false);
      93                 :            :         }
      94         [ +  - ]:      17933 :         if (FileBase::getSystemPathFromFileURL(uUrlFileName, uSysFileName)
      95                 :            :             != FileBase::E_None)
      96                 :            :         {
      97                 :            :             OSL_ASSERT(false);
      98                 :      17933 :         }
      99                 :            :     }
     100                 :            : 
     101 [ +  - ][ +  - ]:      29888 :     return OUStringToOString(uSysFileName, osl_getThreadTextEncoding());
     102                 :            : }
     103                 :            : 
     104                 :      17933 : OString convertToFileUrl(const OString& fileName)
     105                 :            : {
     106         [ +  + ]:      17933 :     if ( !isFileUrl(fileName) )
     107                 :            :     {
     108         [ +  - ]:      11955 :         OString tmp = convertToAbsoluteSystemPath(fileName);
     109 [ +  - ][ +  - ]:      11955 :         OUString uFileName(tmp.getStr(), tmp.getLength(), osl_getThreadTextEncoding());
     110                 :      11955 :         OUString uUrlFileName;
     111         [ +  - ]:      11955 :         if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName)
     112                 :            :             != FileBase::E_None)
     113                 :            :         {
     114                 :            :             OSL_ASSERT(false);
     115                 :            :         }
     116 [ +  - ][ +  - ]:      11955 :         return OUStringToOString(uUrlFileName, osl_getThreadTextEncoding());
     117                 :            :     }
     118                 :            : 
     119                 :      17933 :     return fileName;
     120                 :            : }
     121                 :            : 
     122                 :      11956 : OString makeTempName(const OString& prefix)
     123                 :            : {
     124                 :      11956 :     OUString uTmpPath;
     125                 :      11956 :     OString tmpPath;
     126                 :            : 
     127 [ +  - ][ +  - ]:      11956 :     if ( osl_getEnvironment(TMP.pData, &uTmpPath.pData) != osl_Process_E_None )
     128                 :            :     {
     129 [ +  - ][ +  - ]:      11956 :         if ( osl_getEnvironment(TEMP.pData, &uTmpPath.pData) != osl_Process_E_None )
     130                 :            :         {
     131                 :            : #if defined(SAL_W32)
     132                 :            :             tmpPath = OString("c:\\temp");
     133                 :            : #else
     134                 :      11956 :             tmpPath = OString("/tmp");
     135                 :            : #endif
     136                 :            :         }
     137                 :            :     }
     138                 :            : 
     139         [ -  + ]:      11956 :     if ( !uTmpPath.isEmpty() )
     140         [ #  # ]:          0 :         tmpPath = OUStringToOString(uTmpPath, RTL_TEXTENCODING_UTF8);
     141                 :            : 
     142                 :            : #if defined(SAL_W32) || defined(SAL_UNX)
     143                 :            : 
     144                 :            :     OSL_ASSERT( sizeof(tmpFilePattern) >
     145                 :            :                 (size_t) ( tmpPath.getLength()
     146                 :            :                            + RTL_CONSTASCII_LENGTH( PATH_SEPARATOR )
     147                 :            :                            + prefix.getLength()
     148                 :            :                            + RTL_CONSTASCII_LENGTH( "XXXXXX") ) );
     149                 :            : 
     150                 :      11956 :     tmpFilePattern[ sizeof(tmpFilePattern)-1 ] = '\0';
     151                 :      11956 :     strncpy(tmpFilePattern, tmpPath.getStr(), sizeof(tmpFilePattern)-1);
     152                 :      11956 :     strncat(tmpFilePattern, PATH_SEPARATOR, sizeof(tmpFilePattern)-1-strlen(tmpFilePattern));
     153                 :      11956 :     strncat(tmpFilePattern, prefix.getStr(), sizeof(tmpFilePattern)-1-strlen(tmpFilePattern));
     154                 :      11956 :     strncat(tmpFilePattern, "XXXXXX", sizeof(tmpFilePattern)-1-strlen(tmpFilePattern));
     155                 :            : 
     156                 :            : #ifdef SAL_UNX
     157         [ +  - ]:      11956 :     int nDescriptor = mkstemp(tmpFilePattern);
     158         [ -  + ]:      11956 :     if( -1 == nDescriptor )
     159                 :            :     {
     160         [ #  # ]:          0 :         fprintf(stderr, "idlc: mkstemp(\"%s\") failed: %s\n", tmpFilePattern, strerror(errno));
     161                 :          0 :         exit( 1 );
     162                 :            :     }
     163                 :            :     // the file shall later be reopened by stdio functions
     164         [ +  - ]:      11956 :     close( nDescriptor );
     165                 :            : #else
     166                 :            :     (void) mktemp(tmpFilePattern);
     167                 :            : #endif
     168                 :            : #endif
     169                 :            : 
     170                 :      11956 :     return OString(tmpFilePattern);
     171                 :            : }
     172                 :            : 
     173                 :       5978 : sal_Bool copyFile(const OString* source, const OString& target)
     174                 :            : {
     175                 :       5978 :     sal_Bool bRet = sal_True;
     176                 :            : 
     177 [ +  - ][ +  - ]:       5978 :     FILE* pSource = source == 0 ? stdin : fopen(source->getStr(), "rb");
     178         [ -  + ]:       5978 :     if ( !pSource )
     179                 :          0 :         return sal_False;
     180                 :            : 
     181         [ +  - ]:       5978 :     FILE* pTarget = fopen(target.getStr(), "wb");
     182         [ -  + ]:       5978 :     if ( !pTarget )
     183                 :            :     {
     184         [ #  # ]:          0 :         fclose(pSource);
     185                 :          0 :         return sal_False;
     186                 :            :     }
     187                 :            : 
     188                 :       5978 :     size_t totalSize = 512;
     189                 :       5978 :     size_t readSize  = 0;
     190                 :            :     char   pBuffer[513];
     191                 :            : 
     192         [ +  + ]:      37937 :     while ( !feof(pSource) )
     193                 :            :     {
     194 [ +  - ][ +  + ]:      31959 :         if ( (readSize = fread(pBuffer, 1, totalSize, pSource)) > 0 && !ferror(pSource) )
         [ +  - ][ +  + ]
     195                 :            :         {
     196 [ +  - ][ +  - ]:      31952 :             if ( (fwrite(pBuffer, 1, readSize, pTarget)) != readSize || ferror(pTarget) )
         [ -  + ][ -  + ]
     197                 :            :             {
     198         [ #  # ]:          0 :                 if (source != 0) {
     199         [ #  # ]:          0 :                     fclose(pSource);
     200                 :            :                 }
     201         [ #  # ]:          0 :                 fclose(pTarget);
     202                 :          0 :                 return sal_False;
     203                 :            :             }
     204                 :            :         }
     205                 :            :     }
     206                 :            : 
     207         [ +  - ]:       5978 :     if (source != 0) {
     208         [ +  - ]:       5978 :         fclose(pSource);
     209                 :            :     }
     210 [ +  - ][ -  + ]:       5978 :     if ( fflush(pTarget) )
     211                 :          0 :         bRet = sal_False;
     212         [ +  - ]:       5978 :     fclose(pTarget);
     213                 :            : 
     214                 :       5978 :     return bRet;
     215                 :            : }
     216                 :            : 
     217                 :       5978 : sal_Int32 compileFile(const OString * pathname)
     218                 :            : {
     219                 :            :     // preprocess input file
     220         [ +  - ]:       5978 :     OString tmpFile = makeTempName(OString("idli_"));
     221         [ +  - ]:       5978 :     OString preprocFile = makeTempName(OString("idlf_"));
     222                 :            : 
     223                 :       5978 :     OString fileName;
     224         [ -  + ]:       5978 :     if (pathname == 0) {
     225                 :          0 :         fileName = "stdin";
     226                 :            :     } else {
     227                 :       5978 :         fileName = *pathname;
     228                 :            :     }
     229                 :            : 
     230 [ +  - ][ -  + ]:       5978 :     if ( !copyFile(pathname, tmpFile) )
     231                 :            :     {
     232                 :            :           fprintf(stderr, "%s: could not copy %s%s to %s\n",
     233 [ #  # ][ #  # ]:          0 :                 idlc()->getOptions()->getProgramName().getStr(),
     234                 :            :                 pathname == 0 ? "" : "file ", fileName.getStr(),
     235 [ #  # ][ #  # ]:          0 :                 tmpFile.getStr());
     236                 :          0 :           exit(99);
     237                 :            :     }
     238                 :            : 
     239 [ +  - ][ +  - ]:       5978 :     idlc()->setFileName(fileName);
     240         [ +  - ]:       5978 :     idlc()->setMainFileName(fileName);
     241         [ +  - ]:       5978 :     idlc()->setRealFileName(tmpFile);
     242                 :            : 
     243         [ +  - ]:       5978 :     ::std::vector< ::rtl::OUString> lCppArgs;
     244         [ +  - ]:       5978 :     lCppArgs.push_back("-DIDL");
     245         [ +  - ]:       5978 :     lCppArgs.push_back("-C");
     246         [ +  - ]:       5978 :     lCppArgs.push_back("-zI");
     247                 :            : 
     248                 :       5978 :     OStringBuffer cppArgs(256);
     249         [ +  - ]:       5978 :     Options* pOptions = idlc()->getOptions();
     250                 :            : 
     251                 :       5978 :     OString filePath;
     252                 :       5978 :     sal_Int32 index = fileName.lastIndexOf(SEPARATOR);
     253                 :            : 
     254         [ +  - ]:       5978 :     if ( index > 0)
     255                 :            :     {
     256                 :       5978 :         filePath = fileName.copy(0, index);
     257                 :            : 
     258         [ +  - ]:       5978 :         if ( !filePath.isEmpty() )
     259                 :            :         {
     260         [ +  - ]:       5978 :             cppArgs.append("-I");
     261         [ +  - ]:       5978 :             cppArgs.append(filePath);
     262                 :            :             lCppArgs.push_back(rtl::OStringToOUString(
     263                 :            :                 cppArgs.makeStringAndClear().replace('\\', '/'),
     264 [ +  - ][ +  - ]:       5978 :                 RTL_TEXTENCODING_UTF8));
     265                 :            :         }
     266                 :            :     }
     267                 :            : 
     268 [ +  - ][ -  + ]:       5978 :     if ( pOptions->isValid("-D") )
     269                 :            :     {
     270         [ #  # ]:          0 :         OString token, dOpt = pOptions->getOption("-D");
     271                 :          0 :         sal_Int32 nIndex = 0;
     272         [ #  # ]:          0 :         do
     273                 :            :         {
     274                 :          0 :             token = dOpt.getToken( 0, ' ', nIndex );
     275         [ #  # ]:          0 :             if (token.getLength())
     276 [ #  # ][ #  # ]:          0 :                 lCppArgs.push_back(rtl::OStringToOUString("-D" + token, RTL_TEXTENCODING_UTF8));
     277                 :          0 :         } while( nIndex != -1 );
     278                 :            :     }
     279                 :            : 
     280 [ +  - ][ +  - ]:       5978 :         if ( pOptions->isValid("-I") )
     281                 :            :     {
     282         [ +  - ]:       5978 :         OString token, incOpt = pOptions->getOption("-I");
     283                 :       5978 :         sal_Int32 nIndex = 0;
     284         [ +  + ]:      11951 :         do
     285                 :            :         {
     286                 :      11951 :             token = incOpt.getToken( 0, ' ', nIndex );
     287         [ +  - ]:      11951 :             if (token.getLength())
     288 [ +  - ][ +  - ]:      11951 :                 lCppArgs.push_back(rtl::OStringToOUString("-I" + token, RTL_TEXTENCODING_UTF8));
     289                 :       5978 :         } while( nIndex != -1 );
     290                 :            :     }
     291                 :            : 
     292 [ +  - ][ +  - ]:       5978 :     lCppArgs.push_back(OUString(RTL_CONSTASCII_USTRINGPARAM("-o")));
     293                 :            : 
     294         [ +  - ]:       5978 :         cppArgs.append(preprocFile);
     295 [ +  - ][ +  - ]:       5978 :     lCppArgs.push_back(OStringToOUString(cppArgs.makeStringAndClear(), RTL_TEXTENCODING_UTF8));
     296                 :            : 
     297         [ +  - ]:       5978 :     cppArgs.append(tmpFile);
     298 [ +  - ][ +  - ]:       5978 :     lCppArgs.push_back(OStringToOUString(cppArgs.makeStringAndClear(), RTL_TEXTENCODING_UTF8));
     299                 :            : 
     300                 :       5978 :     OUString cpp;
     301                 :       5978 :     OUString startDir;
     302         [ +  - ]:       5978 :     if (osl_getExecutableFile(&cpp.pData) != osl_Process_E_None) {
     303                 :            :         OSL_ASSERT(false);
     304                 :            :     }
     305                 :            : 
     306                 :       5978 :     sal_Int32 idx= cpp.lastIndexOf("idlc");
     307                 :       5978 :     cpp = cpp.copy(0, idx);
     308                 :            : 
     309                 :            : #if defined(SAL_W32)
     310                 :            :     cpp += OUString( RTL_CONSTASCII_USTRINGPARAM("ucpp.exe"));
     311                 :            : #else
     312         [ +  - ]:       5978 :     cpp += OUString( RTL_CONSTASCII_USTRINGPARAM("ucpp"));
     313                 :            : #endif
     314                 :            : 
     315                 :       5978 :     oslProcess      hProcess = NULL;
     316                 :       5978 :     oslProcessError procError = osl_Process_E_None;
     317                 :            : 
     318                 :       5978 :     const int nCmdArgs = lCppArgs.size();
     319                 :       5978 :     rtl_uString** pCmdArgs = 0;
     320                 :       5978 :     pCmdArgs = (rtl_uString**)rtl_allocateZeroMemory(nCmdArgs * sizeof(rtl_uString*));
     321                 :            : 
     322                 :       5978 :     ::std::vector< ::rtl::OUString >::iterator iter = lCppArgs.begin();
     323                 :       5978 :     ::std::vector< ::rtl::OUString >::iterator end = lCppArgs.end();
     324                 :       5978 :     int i = 0;
     325 [ +  - ][ +  + ]:      59775 :         while ( iter != end ) {
     326                 :      53797 :         pCmdArgs[i++] = (*iter).pData;
     327                 :      53797 :         ++iter;
     328                 :            :     }
     329                 :            : 
     330                 :            :         procError = osl_executeProcess( cpp.pData, pCmdArgs, nCmdArgs, osl_Process_WAIT,
     331         [ +  - ]:       5978 :                                     0, startDir.pData, 0, 0, &hProcess );
     332                 :            : 
     333                 :            :     oslProcessInfo hInfo;
     334                 :       5978 :     hInfo.Size = (sal_uInt32)(sizeof(oslProcessInfo));
     335         [ +  - ]:       5978 :     if (osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &hInfo)
     336                 :            :         != osl_Process_E_None)
     337                 :            :     {
     338                 :            :         OSL_ASSERT(false);
     339                 :            :     }
     340                 :            : 
     341 [ +  - ][ -  + ]:       5978 :     if ( procError || (hInfo.Code != 0) )
     342                 :            :     {
     343         [ #  # ]:          0 :         if ( procError != osl_Process_E_None )
     344 [ #  # ][ #  # ]:          0 :             fprintf(stderr, "%s: starting preprocessor failed\n", pOptions->getProgramName().getStr());
     345                 :            :         else
     346                 :            :             fprintf(stderr, "%s: preprocessing %s%s failed\n",
     347         [ #  # ]:          0 :                     pOptions->getProgramName().getStr(),
     348 [ #  # ][ #  # ]:          0 :                     pathname == 0 ? "" : "file ", fileName.getStr());
     349                 :            : 
     350         [ #  # ]:          0 :         osl_freeProcessHandle(hProcess);
     351                 :          0 :         rtl_freeMemory(pCmdArgs);
     352         [ #  # ]:          0 :         exit(hInfo.Code ? hInfo.Code : 99);
     353                 :            :     }
     354         [ +  - ]:       5978 :     osl_freeProcessHandle(hProcess);
     355                 :       5978 :     rtl_freeMemory(pCmdArgs);
     356                 :            : 
     357         [ -  + ]:       5978 :     if (unlink(tmpFile.getStr()) != 0)
     358                 :            :     {
     359                 :            :         fprintf(stderr, "%s: Could not remove cpp input file %s\n",
     360 [ #  # ][ #  # ]:          0 :                  pOptions->getProgramName().getStr(), tmpFile.getStr());
     361                 :          0 :         exit(99);
     362                 :            :     }
     363                 :            : 
     364 [ +  - ][ -  + ]:       5978 :     if ( pOptions->isValid("-E") )
     365                 :            :     {
     366         [ #  # ]:          0 :         if (unlink(preprocFile.getStr()) != 0)
     367                 :            :         {
     368                 :            :             fprintf(stderr, "%s: Could not remove parser input file %s\n",
     369 [ #  # ][ #  # ]:          0 :                        pOptions->getProgramName().getStr(), preprocFile.getStr());
     370                 :          0 :             exit(99);
     371                 :            :         }
     372                 :          0 :         exit(0);
     373                 :            :     }
     374                 :            : 
     375                 :            :     // parse file
     376         [ +  - ]:       5978 :     yyin = fopen(preprocFile.getStr(), "r");
     377         [ -  + ]:       5978 :     if (yyin == NULL)
     378                 :            :     {
     379                 :            :         fprintf(stderr, "%s: Could not open cpp output file %s\n",
     380 [ #  # ][ #  # ]:          0 :                    pOptions->getProgramName().getStr(), preprocFile.getStr());
     381                 :          0 :         exit(99);
     382                 :            :     }
     383                 :            : 
     384                 :            :     //yydebug = 0 no trace information
     385                 :            :     //yydebug = 1 parser produce trace information
     386                 :       5978 :     yydebug = 0;
     387                 :            : 
     388         [ +  - ]:       5978 :     sal_Int32 nErrors = yyparse();
     389         [ +  - ]:       5978 :     nErrors = idlc()->getErrorCount();
     390                 :            : 
     391         [ +  - ]:       5978 :     fclose(yyin);
     392         [ -  + ]:       5978 :     if (unlink(preprocFile.getStr()) != 0)
     393                 :            :     {
     394                 :            :         fprintf(stderr, "%s: Could not remove parser input file %s\n",
     395 [ #  # ][ #  # ]:          0 :                 pOptions->getProgramName().getStr(), preprocFile.getStr());
     396                 :          0 :         exit(99);
     397                 :            :     }
     398                 :            : 
     399                 :       5978 :     return nErrors;
     400 [ +  - ][ +  - ]:        498 : }
     401                 :            : 
     402                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10