LCOV - code coverage report
Current view: top level - l10ntools/source/help - HelpLinker.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 381 529 72.0 %
Date: 2012-08-25 Functions: 19 21 90.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 432 1078 40.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "HelpCompiler.hxx"
      30                 :            : #include "l10ntools/HelpLinker.hxx"
      31                 :            : 
      32                 :            : #include <map>
      33                 :            : 
      34                 :            : #include <string.h>
      35                 :            : #include <limits.h>
      36                 :            : 
      37                 :            : #include <libxslt/xslt.h>
      38                 :            : #include <libxslt/xsltutils.h>
      39                 :            : #include <libxslt/functions.h>
      40                 :            : #include <libxslt/extensions.h>
      41                 :            : 
      42                 :            : #include <sal/main.h>
      43                 :            : #include <sal/types.h>
      44                 :            : #include <osl/time.h>
      45                 :            : #include <rtl/bootstrap.hxx>
      46                 :            : 
      47                 :            : #include <expat.h>
      48                 :            : 
      49                 :         70 : IndexerPreProcessor::IndexerPreProcessor
      50                 :            :     ( const std::string& aModuleName, const fs::path& fsIndexBaseDir,
      51                 :            :       const fs::path& idxCaptionStylesheet, const fs::path& idxContentStylesheet )
      52                 :            :         : m_aModuleName( aModuleName )
      53                 :         70 :         , m_fsIndexBaseDir( fsIndexBaseDir )
      54                 :            : {
      55 [ +  - ][ +  - ]:         70 :     m_fsCaptionFilesDirName = fsIndexBaseDir / "caption";
      56         [ +  - ]:         70 :     fs::create_directory( m_fsCaptionFilesDirName );
      57                 :            : 
      58 [ +  - ][ +  - ]:         70 :     m_fsContentFilesDirName = fsIndexBaseDir / "content";
      59         [ +  - ]:         70 :     fs::create_directory( m_fsContentFilesDirName );
      60                 :            : 
      61                 :            :     m_xsltStylesheetPtrCaption = xsltParseStylesheetFile
      62 [ +  - ][ +  - ]:         70 :         ((const xmlChar *)idxCaptionStylesheet.native_file_string().c_str());
      63                 :            :     m_xsltStylesheetPtrContent = xsltParseStylesheetFile
      64 [ +  - ][ +  - ]:         70 :         ((const xmlChar *)idxContentStylesheet.native_file_string().c_str());
      65                 :         70 : }
      66                 :            : 
      67                 :         70 : IndexerPreProcessor::~IndexerPreProcessor()
      68                 :            : {
      69         [ +  - ]:         70 :     if( m_xsltStylesheetPtrCaption )
      70         [ +  - ]:         70 :         xsltFreeStylesheet( m_xsltStylesheetPtrCaption );
      71         [ +  - ]:         70 :     if( m_xsltStylesheetPtrContent )
      72         [ +  - ]:         70 :         xsltFreeStylesheet( m_xsltStylesheetPtrContent );
      73                 :         70 : }
      74                 :            : 
      75                 :       8981 : std::string getEncodedPath( const std::string& Path )
      76                 :            : {
      77                 :       8981 :     rtl::OString aOStr_Path( Path.c_str() );
      78                 :            :     rtl::OUString aOUStr_Path( rtl::OStringToOUString
      79 [ +  - ][ +  - ]:       8981 :         ( aOStr_Path, fs::getThreadTextEncoding() ) );
      80                 :       8981 :     rtl::OUString aPathURL;
      81         [ +  - ]:       8981 :     osl::File::getFileURLFromSystemPath( aOUStr_Path, aPathURL );
      82                 :            :     rtl::OString aOStr_PathURL( rtl::OUStringToOString
      83 [ +  - ][ +  - ]:       8981 :         ( aPathURL, fs::getThreadTextEncoding() ) );
      84         [ +  - ]:       8981 :     std::string aStdStr_PathURL( aOStr_PathURL.getStr() );
      85                 :       8981 :     return aStdStr_PathURL;
      86                 :            : }
      87                 :            : 
      88                 :       8981 : void IndexerPreProcessor::processDocument
      89                 :            :     ( xmlDocPtr doc, const std::string &EncodedDocPath )
      90                 :            : {
      91         [ +  - ]:       8981 :     std::string aStdStr_EncodedDocPathURL = getEncodedPath( EncodedDocPath );
      92                 :            : 
      93         [ +  - ]:       8981 :     if( m_xsltStylesheetPtrCaption )
      94                 :            :     {
      95         [ +  - ]:       8981 :         xmlDocPtr resCaption = xsltApplyStylesheet( m_xsltStylesheetPtrCaption, doc, NULL );
      96                 :       8981 :         xmlNodePtr pResNodeCaption = resCaption->xmlChildrenNode;
      97         [ +  - ]:       8981 :         if( pResNodeCaption )
      98                 :            :         {
      99         [ +  - ]:       8981 :             fs::path fsCaptionPureTextFile_docURL = m_fsCaptionFilesDirName / aStdStr_EncodedDocPathURL;
     100                 :            : #ifdef WNT     //We need _wfopen to support long file paths on Windows XP
     101                 :            :             FILE* pFile_docURL = _wfopen(
     102                 :            :                 fsCaptionPureTextFile_docURL.native_file_string_w(), L"w" );
     103                 :            : #else
     104                 :            :             FILE* pFile_docURL = fopen(
     105 [ +  - ][ +  - ]:       8981 :                 fsCaptionPureTextFile_docURL.native_file_string().c_str(), "w" );
     106                 :            : #endif
     107         [ +  - ]:       8981 :             if( pFile_docURL )
     108                 :            :             {
     109         [ +  - ]:       8981 :                 fprintf( pFile_docURL, "%s\n", pResNodeCaption->content );
     110         [ +  - ]:       8981 :                 fclose( pFile_docURL );
     111                 :       8981 :             }
     112                 :            :         }
     113         [ +  - ]:       8981 :         xmlFreeDoc(resCaption);
     114                 :            :     }
     115                 :            : 
     116         [ +  - ]:       8981 :     if( m_xsltStylesheetPtrContent )
     117                 :            :     {
     118         [ +  - ]:       8981 :         xmlDocPtr resContent = xsltApplyStylesheet( m_xsltStylesheetPtrContent, doc, NULL );
     119                 :       8981 :         xmlNodePtr pResNodeContent = resContent->xmlChildrenNode;
     120         [ +  + ]:       8981 :         if( pResNodeContent )
     121                 :            :         {
     122         [ +  - ]:       8438 :             fs::path fsContentPureTextFile_docURL = m_fsContentFilesDirName / aStdStr_EncodedDocPathURL;
     123                 :            : #ifdef WNT     //We need _wfopen to support long file paths on Windows XP
     124                 :            :             FILE* pFile_docURL = _wfopen(
     125                 :            :                 fsContentPureTextFile_docURL.native_file_string_w(), L"w" );
     126                 :            : #else
     127                 :            :             FILE* pFile_docURL = fopen(
     128 [ +  - ][ +  - ]:       8438 :                 fsContentPureTextFile_docURL.native_file_string().c_str(), "w" );
     129                 :            : #endif
     130         [ +  - ]:       8438 :             if( pFile_docURL )
     131                 :            :             {
     132         [ +  - ]:       8438 :                 fprintf( pFile_docURL, "%s\n", pResNodeContent->content );
     133         [ +  - ]:       8438 :                 fclose( pFile_docURL );
     134                 :       8438 :             }
     135                 :            :         }
     136         [ +  - ]:       8981 :         xmlFreeDoc(resContent);
     137                 :       8981 :     }
     138                 :       8981 : }
     139                 :            : 
     140                 :      37868 : struct Data
     141                 :            : {
     142                 :            :     std::vector<std::string> _idList;
     143                 :            :     typedef std::vector<std::string>::const_iterator cIter;
     144                 :            : 
     145                 :      18934 :     void append(const std::string &id)
     146                 :            :     {
     147                 :      18934 :         _idList.push_back(id);
     148                 :      18934 :     }
     149                 :            : 
     150                 :      18934 :     std::string getString() const
     151                 :            :     {
     152         [ +  - ]:      18934 :         std::string ret;
     153                 :      18934 :         cIter aEnd = _idList.end();
     154 [ +  - ][ +  + ]:      37868 :         for (cIter aIter = _idList.begin(); aIter != aEnd; ++aIter)
                 [ +  - ]
     155 [ +  - ][ +  - ]:      18934 :             ret += *aIter + ";";
                 [ +  - ]
     156                 :      18934 :         return ret;
     157                 :            :     }
     158                 :            : };
     159                 :            : 
     160                 :     111817 : void writeKeyValue_DBHelp( FILE* pFile, const std::string& aKeyStr, const std::string& aValueStr )
     161                 :            : {
     162         [ -  + ]:     111817 :     if( pFile == NULL )
     163                 :     111817 :         return;
     164                 :     111817 :     char cLF = 10;
     165                 :     111817 :     unsigned int nKeyLen = aKeyStr.length();
     166                 :     111817 :     unsigned int nValueLen = aValueStr.length();
     167                 :     111817 :     fprintf( pFile, "%x ", nKeyLen );
     168         [ +  - ]:     111817 :     if( nKeyLen > 0 )
     169                 :            :     {
     170         [ -  + ]:     111817 :         if (fwrite( aKeyStr.c_str(), 1, nKeyLen, pFile ) != nKeyLen)
     171                 :          0 :             fprintf(stderr, "fwrite to db failed\n");
     172                 :            :     }
     173         [ -  + ]:     111817 :     if (fprintf( pFile, " %x ", nValueLen ) < 0)
     174                 :          0 :         fprintf(stderr, "fwrite to db failed\n");
     175         [ +  + ]:     111817 :     if( nValueLen > 0 )
     176                 :            :     {
     177         [ -  + ]:     111632 :         if (fwrite( aValueStr.c_str(), 1, nValueLen, pFile ) != nValueLen)
     178                 :          0 :             fprintf(stderr, "fwrite to db failed\n");
     179                 :            :     }
     180         [ -  + ]:     111817 :     if (fprintf( pFile, "%c", cLF ) < 0)
     181                 :          0 :         fprintf(stderr, "fwrite to db failed\n");
     182                 :            : }
     183                 :            : 
     184         [ +  - ]:        142 : class HelpKeyword
     185                 :            : {
     186                 :            : private:
     187                 :            :     typedef boost::unordered_map<std::string, Data, pref_hash> DataHashtable;
     188                 :            :     DataHashtable _hash;
     189                 :            : 
     190                 :            : public:
     191                 :      18934 :     void insert(const std::string &key, const std::string &id)
     192                 :            :     {
     193                 :      18934 :         Data &data = _hash[key];
     194                 :      18934 :         data.append(id);
     195                 :      18934 :     }
     196                 :            : 
     197                 :            :     void dump(DB* table)
     198                 :            :     {
     199                 :            :         DataHashtable::const_iterator aEnd = _hash.end();
     200                 :            :         for (DataHashtable::const_iterator aIter = _hash.begin(); aIter != aEnd; ++aIter)
     201                 :            :         {
     202                 :            :             const std::string &keystr = aIter->first;
     203                 :            :             DBT key;
     204                 :            :             memset(&key, 0, sizeof(key));
     205                 :            :             key.data = const_cast<char*>(keystr.c_str());
     206                 :            :             key.size = keystr.length();
     207                 :            : 
     208                 :            :             const Data &data = aIter->second;
     209                 :            :             std::string str = data.getString();
     210                 :            :             DBT value;
     211                 :            :             memset(&value, 0, sizeof(value));
     212                 :            :             value.data = const_cast<char*>(str.c_str());
     213                 :            :             value.size = str.length();
     214                 :            : 
     215                 :            :             table->put(table, NULL, &key, &value, 0);
     216                 :            :         }
     217                 :            :     }
     218                 :            : 
     219                 :         71 :     void dump_DBHelp( const fs::path& rFileName )
     220                 :            :     {
     221                 :            : #ifdef WNT     //We need _wfopen to support long file paths on Windows XP
     222                 :            :         FILE* pFile = _wfopen( rFileName.native_file_string_w(), L"wb" );
     223                 :            : #else
     224 [ +  - ][ +  - ]:         71 :         FILE* pFile = fopen( rFileName.native_file_string().c_str(), "wb" );
     225                 :            : #endif
     226         [ +  - ]:         71 :         if( pFile == NULL )
     227                 :         71 :             return;
     228                 :            : 
     229         [ +  - ]:         71 :         DataHashtable::const_iterator aEnd = _hash.end();
     230 [ +  + ][ +  - ]:      19005 :         for (DataHashtable::const_iterator aIter = _hash.begin(); aIter != aEnd; ++aIter)
     231 [ +  - ][ +  - ]:      18934 :             writeKeyValue_DBHelp( pFile, aIter->first, aIter->second.getString() );
         [ +  - ][ +  - ]
     232                 :            : 
     233         [ +  - ]:         71 :         fclose( pFile );
     234                 :            :     }
     235                 :            : };
     236                 :            : 
     237                 :            : namespace URLEncoder
     238                 :            : {
     239                 :     106121 :     static std::string encode(const std::string &rIn)
     240                 :            :     {
     241                 :     106121 :         const char *good = "!$&'()*+,-.=@_";
     242                 :            :         static const char hex[17] = "0123456789ABCDEF";
     243                 :            : 
     244                 :     106121 :         std::string result;
     245         [ +  + ]:    3672601 :         for (size_t i=0; i < rIn.length(); ++i)
     246                 :            :         {
     247         [ +  - ]:    3566480 :             unsigned char c = rIn[i];
     248 [ +  + ][ +  + ]:    3566480 :             if (isalnum (c) || strchr (good, c))
     249         [ +  - ]:    3365063 :                 result += c;
     250                 :            :             else {
     251         [ +  - ]:     201417 :                 result += '%';
     252         [ +  - ]:     201417 :                 result += hex[c >> 4];
     253         [ +  - ]:     201417 :                 result += hex[c & 0xf];
     254                 :            :             }
     255                 :            :         }
     256                 :     106121 :         return result;
     257                 :            :     }
     258                 :            : }
     259                 :            : 
     260                 :      55582 : void HelpLinker::addBookmark( DB* dbBase, FILE* pFile_DBHelp, std::string thishid,
     261                 :            :         const std::string& fileB, const std::string& anchorB,
     262                 :            :         const std::string& jarfileB, const std::string& titleB)
     263                 :            : {
     264                 :            :     HCDBG(std::cerr << "HelpLinker::addBookmark " << thishid << " " <<
     265                 :            :         fileB << " " << anchorB << " " << jarfileB << " " << titleB << std::endl);
     266                 :            : 
     267 [ +  - ][ +  - ]:      55582 :     thishid = URLEncoder::encode(thishid);
     268                 :            : 
     269                 :            :     DBT key;
     270                 :      55582 :     memset(&key, 0, sizeof(key));
     271                 :      55582 :     key.data = const_cast<char*>(thishid.c_str());
     272                 :      55582 :     key.size = thishid.length();
     273                 :            : 
     274                 :      55582 :     int fileLen = fileB.length();
     275         [ +  + ]:      55582 :     if (!anchorB.empty())
     276                 :      46601 :         fileLen += (1 + anchorB.length());
     277                 :      55582 :     int dataLen = 1 + fileLen + 1 + jarfileB.length() + 1 + titleB.length();
     278                 :            : 
     279         [ +  - ]:      55582 :     std::vector<unsigned char> dataB(dataLen);
     280                 :      55582 :     size_t i = 0;
     281         [ +  - ]:      55582 :     dataB[i++] = static_cast<unsigned char>(fileLen);
     282         [ +  + ]:    1738524 :     for (size_t j = 0; j < fileB.length(); ++j)
     283 [ +  - ][ +  - ]:    1682942 :         dataB[i++] = static_cast<unsigned char>(fileB[j]);
     284         [ +  + ]:      55582 :     if (!anchorB.empty())
     285                 :            :     {
     286         [ +  - ]:      46601 :         dataB[i++] = '#';
     287         [ +  + ]:     617571 :         for (size_t j = 0; j < anchorB.length(); ++j)
     288 [ +  - ][ +  - ]:     570970 :             dataB[i++] = anchorB[j];
     289                 :            :     }
     290         [ +  - ]:      55582 :     dataB[i++] = static_cast<unsigned char>(jarfileB.length());
     291         [ +  + ]:     614312 :     for (size_t j = 0; j < jarfileB.length(); ++j)
     292 [ +  - ][ +  - ]:     558730 :         dataB[i++] = jarfileB[j];
     293                 :            : 
     294         [ +  - ]:      55582 :     dataB[i++] = static_cast<unsigned char>(titleB.length());
     295         [ +  + ]:     890440 :     for (size_t j = 0; j < titleB.length(); ++j)
     296 [ +  - ][ +  - ]:     834858 :         dataB[i++] = titleB[j];
     297                 :            : 
     298                 :            :     DBT data;
     299                 :      55582 :     memset(&data, 0, sizeof(data));
     300         [ +  - ]:      55582 :     data.data = &dataB[0];
     301                 :      55582 :     data.size = dataB.size();
     302                 :            : 
     303         [ -  + ]:      55582 :     if( dbBase != NULL )
     304         [ #  # ]:          0 :         dbBase->put(dbBase, NULL, &key, &data, 0);
     305                 :            : 
     306         [ +  - ]:      55582 :     if( pFile_DBHelp != NULL )
     307                 :            :     {
     308         [ +  - ]:      55582 :         std::string aValueStr( dataB.begin(), dataB.end() );
     309         [ +  - ]:      55582 :         writeKeyValue_DBHelp( pFile_DBHelp, thishid, aValueStr );
     310                 :      55582 :     }
     311                 :      55582 : }
     312                 :            : 
     313                 :         70 : void HelpLinker::initIndexerPreProcessor()
     314                 :            : {
     315         [ -  + ]:         70 :     if( m_pIndexerPreProcessor )
     316 [ #  # ][ #  # ]:          0 :         delete m_pIndexerPreProcessor;
     317         [ +  - ]:         70 :     std::string mod = module;
     318         [ +  - ]:         70 :     std::transform (mod.begin(), mod.end(), mod.begin(), tocharlower);
     319                 :            :     m_pIndexerPreProcessor = new IndexerPreProcessor( mod, indexDirParentName,
     320 [ +  - ][ +  - ]:         70 :          idxCaptionStylesheet, idxContentStylesheet );
     321                 :         70 : }
     322                 :            : 
     323                 :            : /**
     324                 :            : *
     325                 :            : */
     326                 :         71 : void HelpLinker::link() throw( HelpProcessingException )
     327                 :            : {
     328                 :         71 :     bool bIndexForExtension = true;
     329                 :            : 
     330         [ +  + ]:         71 :     if( bExtensionMode )
     331                 :            :     {
     332         [ +  - ]:         62 :         indexDirParentName = extensionDestination;
     333                 :            :     }
     334                 :            :     else
     335                 :            :     {
     336                 :          9 :         indexDirParentName = zipdir;
     337         [ +  - ]:          9 :         fs::create_directory(indexDirParentName);
     338                 :            :     }
     339                 :            : 
     340                 :            : #ifdef CMC_DEBUG
     341                 :            :     std::cerr << "will not delete tmpdir of " << indexDirParentName.native_file_string().c_str() << std::endl;
     342                 :            : #endif
     343                 :            : 
     344         [ +  - ]:         71 :     std::string mod = module;
     345         [ +  - ]:         71 :     std::transform (mod.begin(), mod.end(), mod.begin(), tocharlower);
     346                 :            : 
     347                 :            :     // do the work here
     348                 :            :     // continue with introduction of the overall process thing into the
     349                 :            :     // here all hzip files will be worked on
     350         [ +  - ]:         71 :     std::string appl = mod;
     351 [ +  - ][ +  + ]:         71 :     if (appl[0] == 's')
     352 [ +  - ][ +  - ]:          9 :         appl = appl.substr(1);
     353                 :            : 
     354                 :         71 :     bool bUse_ = true;
     355                 :            : #ifdef DBHELP_ONLY
     356         [ +  + ]:         71 :     if( !bExtensionMode )
     357                 :          9 :         bUse_ = false;
     358                 :            : #endif
     359                 :            : 
     360                 :         71 :     DB* helpText(0);
     361                 :            : #ifndef DBHELP_ONLY
     362                 :            :     fs::path helpTextFileName(indexDirParentName / (mod + ".ht"));
     363                 :            :     db_create(&helpText,0,0);
     364                 :            :     helpText->open(helpText, NULL, helpTextFileName.native_file_string().c_str(), NULL, DB_BTREE,
     365                 :            :         DB_CREATE | DB_TRUNCATE, 0644);
     366                 :            : #endif
     367                 :            : 
     368 [ +  + ][ +  - ]:         71 :     fs::path helpTextFileName_DBHelp(indexDirParentName / (mod + (bUse_ ? ".ht_" : ".ht")));
                 [ +  - ]
     369                 :            : #ifdef WNT
     370                 :            :     //We need _wfopen to support long file paths on Windows XP
     371                 :            :     FILE* pFileHelpText_DBHelp = _wfopen
     372                 :            :         ( helpTextFileName_DBHelp.native_file_string_w(), L"wb" );
     373                 :            : #else
     374                 :            : 
     375                 :            :     FILE* pFileHelpText_DBHelp = fopen
     376 [ +  - ][ +  - ]:         71 :         ( helpTextFileName_DBHelp.native_file_string().c_str(), "wb" );
     377                 :            : #endif
     378                 :         71 :     DB* dbBase(0);
     379                 :            : #ifndef DBHELP_ONLY
     380                 :            :     fs::path dbBaseFileName(indexDirParentName / (mod + ".db"));
     381                 :            :     db_create(&dbBase,0,0);
     382                 :            :     dbBase->open(dbBase, NULL, dbBaseFileName.native_file_string().c_str(), NULL, DB_BTREE,
     383                 :            :         DB_CREATE | DB_TRUNCATE, 0644);
     384                 :            : #endif
     385                 :            : 
     386 [ +  - ][ +  - ]:         71 :     fs::path dbBaseFileName_DBHelp(indexDirParentName / (mod + (bUse_ ? ".db_" : ".db")));
                 [ +  + ]
     387                 :            : #ifdef WNT
     388                 :            :     //We need _wfopen to support long file paths on Windows XP
     389                 :            :     FILE* pFileDbBase_DBHelp = _wfopen
     390                 :            :         ( dbBaseFileName_DBHelp.native_file_string_w(), L"wb" );
     391                 :            : #else
     392                 :            :     FILE* pFileDbBase_DBHelp = fopen
     393 [ +  - ][ +  - ]:         71 :         ( dbBaseFileName_DBHelp.native_file_string().c_str(), "wb" );
     394                 :            : #endif
     395                 :            : 
     396                 :            : #ifndef DBHELP_ONLY
     397                 :            :     DB* keyWord(0);
     398                 :            :     fs::path keyWordFileName(indexDirParentName / (mod + ".key"));
     399                 :            :     db_create(&keyWord,0,0);
     400                 :            :     keyWord->open(keyWord, NULL, keyWordFileName.native_file_string().c_str(), NULL, DB_BTREE,
     401                 :            :         DB_CREATE | DB_TRUNCATE, 0644);
     402                 :            : #endif
     403                 :            : 
     404 [ +  - ][ +  - ]:         71 :     fs::path keyWordFileName_DBHelp(indexDirParentName / (mod + (bUse_ ? ".key_" : ".key")));
                 [ +  + ]
     405                 :            : 
     406         [ +  - ]:         71 :     HelpKeyword helpKeyword;
     407                 :            : 
     408                 :            :     // catch HelpProcessingException to avoid locking data bases
     409                 :            :     try
     410                 :            :     {
     411                 :            : 
     412                 :            :     // lastly, initialize the indexBuilder
     413 [ +  + ][ +  - ]:         71 :     if ( (!bExtensionMode || bIndexForExtension) && !helpFiles.empty())
         [ +  + ][ +  + ]
     414         [ +  - ]:         70 :         initIndexerPreProcessor();
     415                 :            : 
     416                 :            :     // here we start our loop over the hzip files.
     417                 :         71 :     HashSet::iterator end = helpFiles.end();
     418 [ +  - ][ +  - ]:       9052 :     for (HashSet::iterator iter = helpFiles.begin(); iter != end; ++iter)
                 [ +  + ]
     419                 :            :     {
     420                 :            :         // process one file
     421                 :            :         // streamTable contains the streams in the hzip file
     422         [ +  - ]:       8981 :         StreamTable streamTable;
     423         [ +  - ]:       8981 :         const std::string &xhpFileName = *iter;
     424                 :            : 
     425 [ +  + ][ +  - ]:       8981 :         if (!bExtensionMode && xhpFileName.rfind(".xhp") != xhpFileName.length()-4)
         [ -  + ][ -  + ]
     426                 :            :         {
     427                 :            :             // only work on .xhp - files
     428                 :            :             SAL_WARN("l10ntools",
     429                 :            :                 "ERROR: input list entry '"
     430                 :            :                     << xhpFileName
     431                 :            :                     << "' has the wrong extension (only files with extension .xhp "
     432                 :            :                     << "are accepted)");
     433                 :            : 
     434                 :          0 :             continue;
     435                 :            :         }
     436                 :            : 
     437                 :       8981 :         fs::path langsourceRoot(sourceRoot);
     438                 :       8981 :         fs::path xhpFile;
     439                 :            : 
     440         [ +  + ]:       8981 :         if( bExtensionMode )
     441                 :            :         {
     442                 :            :             // langsourceRoot == sourceRoot for extensions
     443         [ +  - ]:         62 :             std::string xhpFileNameComplete( extensionPath );
     444 [ +  - ][ +  - ]:         62 :             xhpFileNameComplete.append( '/' + xhpFileName );
     445         [ +  - ]:         62 :             xhpFile = fs::path( xhpFileNameComplete );
     446                 :            :         }
     447                 :            :         else
     448                 :            :         {
     449 [ +  - ][ +  - ]:       8919 :             langsourceRoot.append('/' + lang + '/');
                 [ +  - ]
     450         [ +  - ]:       8919 :             xhpFile = fs::path(xhpFileName, fs::native);
     451                 :            :         }
     452                 :            : 
     453                 :            :         HelpCompiler hc( streamTable, xhpFile, langsourceRoot,
     454         [ +  - ]:       8981 :             embeddStylesheet, module, lang, bExtensionMode );
     455                 :            : 
     456                 :            :         HCDBG(std::cerr << "before compile of " << xhpFileName << std::endl);
     457         [ +  - ]:       8981 :         bool success = hc.compile();
     458                 :            :         HCDBG(std::cerr << "after compile of " << xhpFileName << std::endl);
     459                 :            : 
     460 [ -  + ][ #  # ]:       8981 :         if (!success && !bExtensionMode)
     461                 :            :         {
     462         [ #  # ]:          0 :             std::stringstream aStrStream;
     463                 :            :             aStrStream <<
     464         [ #  # ]:          0 :                 "\nERROR: compiling help particle '"
     465         [ #  # ]:          0 :                     << xhpFileName
     466         [ #  # ]:          0 :                     << "' for language '"
     467         [ #  # ]:          0 :                     << lang
     468         [ #  # ]:          0 :                     << "' failed!";
     469 [ #  # ][ #  # ]:          0 :             throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     470                 :            :         }
     471                 :            : 
     472         [ +  - ]:       8981 :         std::string documentPath = streamTable.document_path;
     473 [ +  - ][ +  - ]:       8981 :         if (documentPath.find("/") == 0)
     474 [ +  - ][ +  - ]:       8981 :             documentPath = documentPath.substr(1);
     475                 :            : 
     476         [ +  - ]:       8981 :         std::string documentJarfile = streamTable.document_module + ".jar";
     477                 :            : 
     478         [ +  - ]:       8981 :         std::string documentTitle = streamTable.document_title;
     479         [ -  + ]:       8981 :         if (documentTitle.empty())
     480         [ #  # ]:          0 :             documentTitle = "<notitle>";
     481                 :            : 
     482                 :       8981 :         const std::string& fileB = documentPath;
     483                 :       8981 :         const std::string& jarfileB = documentJarfile;
     484                 :       8981 :         std::string& titleB = documentTitle;
     485                 :            : 
     486                 :            :         // add once this as its own id.
     487 [ +  - ][ +  - ]:       8981 :         addBookmark(dbBase, pFileDbBase_DBHelp, documentPath, fileB, std::string(), jarfileB, titleB);
                 [ +  - ]
     488                 :            : 
     489                 :            :         // first the database *.db
     490                 :            :         // ByteArrayInputStream bais = null;
     491                 :            :         // ObjectInputStream ois = null;
     492                 :            : 
     493                 :       8981 :         const HashSet *hidlist = streamTable.appl_hidlist;
     494         [ -  + ]:       8981 :         if (!hidlist)
     495                 :          0 :             hidlist = streamTable.default_hidlist;
     496 [ +  - ][ +  + ]:       8981 :         if (hidlist && !hidlist->empty())
                 [ +  + ]
     497                 :            :         {
     498                 :            :             // now iterate over all elements of the hidlist
     499                 :       6096 :             HashSet::const_iterator aEnd = hidlist->end();
     500 [ +  - ][ +  + ]:      47791 :             for (HashSet::const_iterator hidListIter = hidlist->begin();
                 [ +  - ]
     501                 :            :                 hidListIter != aEnd; ++hidListIter)
     502                 :            :             {
     503 [ +  - ][ +  - ]:      41695 :                 std::string thishid = *hidListIter;
     504                 :            : 
     505         [ +  - ]:      41695 :                 std::string anchorB;
     506                 :      41695 :                 size_t index = thishid.rfind('#');
     507         [ +  - ]:      41695 :                 if (index != std::string::npos)
     508                 :            :                 {
     509 [ +  - ][ +  - ]:      41695 :                     anchorB = thishid.substr(1 + index);
     510 [ +  - ][ +  - ]:      41695 :                     thishid = thishid.substr(0, index);
     511                 :            :                 }
     512 [ +  - ][ +  - ]:      41695 :                 addBookmark(dbBase, pFileDbBase_DBHelp, thishid, fileB, anchorB, jarfileB, titleB);
     513                 :      41695 :             }
     514                 :            :         }
     515                 :            : 
     516                 :            :         // now the keywords
     517                 :       8981 :         const Hashtable *anchorToLL = streamTable.appl_keywords;
     518         [ -  + ]:       8981 :         if (!anchorToLL)
     519                 :          0 :             anchorToLL = streamTable.default_keywords;
     520 [ +  - ][ +  + ]:       8981 :         if (anchorToLL && !anchorToLL->empty())
                 [ +  + ]
     521                 :            :         {
     522         [ +  - ]:       4257 :             std::string fakedHid = URLEncoder::encode(documentPath);
     523         [ +  - ]:       4257 :             Hashtable::const_iterator aEnd = anchorToLL->end();
     524 [ +  - ][ +  + ]:       9163 :             for (Hashtable::const_iterator enumer = anchorToLL->begin();
     525                 :            :                 enumer != aEnd; ++enumer)
     526                 :            :             {
     527         [ +  - ]:       4906 :                 const std::string &anchor = enumer->first;
     528                 :            :                 addBookmark(dbBase, pFileDbBase_DBHelp, documentPath, fileB,
     529 [ +  - ][ +  - ]:       4906 :                     anchor, jarfileB, titleB);
     530 [ +  - ][ +  - ]:       4906 :                 std::string totalId = fakedHid + "#" + anchor;
     531                 :            :                 // std::cerr << hzipFileName << std::endl;
     532         [ +  - ]:       4906 :                 const LinkedList& ll = enumer->second;
     533                 :       4906 :                 LinkedList::const_iterator aOtherEnd = ll.end();
     534 [ +  - ][ +  - ]:      23840 :                 for (LinkedList::const_iterator llIter = ll.begin();
                 [ +  + ]
     535                 :            :                     llIter != aOtherEnd; ++llIter)
     536                 :            :                 {
     537 [ +  - ][ +  - ]:      18934 :                         helpKeyword.insert(*llIter, totalId);
     538                 :            :                 }
     539                 :       9163 :             }
     540                 :            : 
     541                 :            :         }
     542                 :            : 
     543                 :            :         // and last the helptexts
     544                 :       8981 :         const Stringtable *helpTextHash = streamTable.appl_helptexts;
     545         [ -  + ]:       8981 :         if (!helpTextHash)
     546                 :          0 :             helpTextHash = streamTable.default_helptexts;
     547 [ +  - ][ +  + ]:       8981 :         if (helpTextHash && !helpTextHash->empty())
                 [ +  + ]
     548                 :            :         {
     549         [ +  - ]:       5909 :             Stringtable::const_iterator aEnd = helpTextHash->end();
     550 [ +  - ][ +  + ]:      43210 :             for (Stringtable::const_iterator helpTextIter = helpTextHash->begin();
     551                 :            :                 helpTextIter != aEnd; ++helpTextIter)
     552                 :            :             {
     553 [ +  - ][ +  - ]:      37301 :                 std::string helpTextId = helpTextIter->first;
     554         [ +  - ]:      37301 :                 const std::string& helpTextText = helpTextIter->second;
     555                 :            : 
     556 [ +  - ][ +  - ]:      37301 :                 helpTextId = URLEncoder::encode(helpTextId);
     557                 :            : 
     558                 :            :                 DBT keyDbt;
     559                 :      37301 :                 memset(&keyDbt, 0, sizeof(keyDbt));
     560                 :      37301 :                 keyDbt.data = const_cast<char*>(helpTextId.c_str());
     561                 :      37301 :                 keyDbt.size = helpTextId.length();
     562                 :            : 
     563                 :            :                 DBT textDbt;
     564                 :      37301 :                 memset(&textDbt, 0, sizeof(textDbt));
     565                 :      37301 :                 textDbt.data = const_cast<char*>(helpTextText.c_str());
     566                 :      37301 :                 textDbt.size = helpTextText.length();
     567                 :            : 
     568         [ -  + ]:      37301 :                 if( helpText != NULL )
     569         [ #  # ]:          0 :                     helpText->put(helpText, NULL, &keyDbt, &textDbt, 0);
     570                 :            : 
     571         [ +  - ]:      37301 :                 if( pFileHelpText_DBHelp != NULL )
     572         [ +  - ]:      37301 :                     writeKeyValue_DBHelp( pFileHelpText_DBHelp, helpTextId, helpTextText );
     573                 :      37301 :             }
     574                 :            :         }
     575                 :            : 
     576                 :            :         //IndexerPreProcessor
     577 [ +  + ][ +  - ]:       8981 :         if( !bExtensionMode || bIndexForExtension )
     578                 :            :         {
     579                 :            :             // now the indexing
     580                 :       8981 :             xmlDocPtr document = streamTable.appl_doc;
     581         [ -  + ]:       8981 :             if (!document)
     582                 :          0 :                 document = streamTable.default_doc;
     583         [ +  - ]:       8981 :             if (document)
     584                 :            :             {
     585         [ +  - ]:       8981 :                 std::string temp = module;
     586         [ +  - ]:       8981 :                 std::transform (temp.begin(), temp.end(), temp.begin(), tocharlower);
     587 [ +  - ][ +  - ]:       8981 :                 m_pIndexerPreProcessor->processDocument(document, URLEncoder::encode(documentPath) );
     588                 :            :             }
     589                 :            :         }
     590                 :            : 
     591 [ +  - ][ +  - ]:       8981 :     } // while loop over hzip files ending
     592                 :            : 
     593                 :            :     } // try
     594         [ #  # ]:          0 :     catch( const HelpProcessingException& )
     595                 :            :     {
     596                 :            :         // catch HelpProcessingException to avoid locking data bases
     597                 :            : #ifndef DBHELP_ONLY
     598                 :            :         helpText->close(helpText, 0);
     599                 :            :         dbBase->close(dbBase, 0);
     600                 :            :         keyWord->close(keyWord, 0);
     601                 :            : #endif
     602         [ #  # ]:          0 :         if( pFileHelpText_DBHelp != NULL )
     603         [ #  # ]:          0 :             fclose( pFileHelpText_DBHelp );
     604         [ #  # ]:          0 :         if( pFileDbBase_DBHelp != NULL )
     605         [ #  # ]:          0 :             fclose( pFileDbBase_DBHelp );
     606                 :          0 :         throw;
     607                 :            :     }
     608                 :            : 
     609                 :            : #ifndef DBHELP_ONLY
     610                 :            :     helpText->close(helpText, 0);
     611                 :            :     dbBase->close(dbBase, 0);
     612                 :            :     helpKeyword.dump(keyWord);
     613                 :            :     keyWord->close(keyWord, 0);
     614                 :            : #endif
     615         [ +  - ]:         71 :     if( pFileHelpText_DBHelp != NULL )
     616         [ +  - ]:         71 :         fclose( pFileHelpText_DBHelp );
     617         [ +  - ]:         71 :     if( pFileDbBase_DBHelp != NULL )
     618         [ +  - ]:         71 :         fclose( pFileDbBase_DBHelp );
     619                 :            : 
     620         [ +  - ]:         71 :     helpKeyword.dump_DBHelp( keyWordFileName_DBHelp);
     621                 :            : 
     622         [ +  + ]:         71 :     if( !bExtensionMode )
     623                 :            :     {
     624                 :            :         // New index
     625         [ +  - ]:          9 :         Stringtable::iterator aEnd = additionalFiles.end();
     626 [ +  - ][ +  + ]:         39 :         for (Stringtable::iterator enumer = additionalFiles.begin(); enumer != aEnd;
     627                 :            :             ++enumer)
     628                 :            :         {
     629         [ +  - ]:         30 :             const std::string &additionalFileName = enumer->second;
     630         [ +  - ]:         30 :             const std::string &additionalFileKey = enumer->first;
     631                 :            : 
     632         [ +  - ]:         30 :             fs::path fsAdditionalFileName( additionalFileName, fs::native );
     633                 :            :             HCDBG({
     634                 :            :                     std::string aNativeStr = fsAdditionalFileName.native_file_string();
     635                 :            :                     const char* pStr = aNativeStr.c_str();
     636                 :            :                     std::cerr << pStr << std::endl;
     637                 :            :             });
     638                 :            : 
     639         [ +  - ]:         30 :             fs::path fsTargetName( indexDirParentName / additionalFileKey );
     640                 :            : 
     641         [ +  - ]:         30 :             fs::copy( fsAdditionalFileName, fsTargetName );
     642                 :         30 :         }
     643         [ +  - ]:         71 :     }
     644                 :         71 : }
     645                 :            : 
     646                 :            : 
     647                 :         71 : void HelpLinker::main( std::vector<std::string> &args,
     648                 :            :                        std::string* pExtensionPath, std::string* pDestination,
     649                 :            :                        const rtl::OUString* pOfficeHelpPath )
     650                 :            :     throw( HelpProcessingException )
     651                 :            : {
     652                 :         71 :     bExtensionMode = false;
     653                 :         71 :     helpFiles.clear();
     654                 :            : 
     655 [ +  + ][ +  + ]:         71 :     if ((!args.empty()) && args[0][0] == '@')
                 [ +  - ]
     656                 :            :     {
     657         [ +  - ]:          9 :         std::vector<std::string> stringList;
     658 [ +  - ][ +  - ]:          9 :         std::ifstream fileReader(args[0].substr(1).c_str());
                 [ +  - ]
     659                 :            : 
     660 [ +  - ][ +  + ]:       9171 :         while (fileReader)
     661                 :            :         {
     662         [ +  - ]:       9162 :             std::string token;
     663         [ +  - ]:       9162 :             fileReader >> token;
     664         [ +  + ]:       9162 :             if (!token.empty())
     665         [ +  - ]:       9153 :                 stringList.push_back(token);
     666                 :       9162 :         }
     667         [ +  - ]:          9 :         fileReader.close();
     668                 :            : 
     669 [ +  - ][ +  - ]:          9 :         args = stringList;
     670                 :            :     }
     671                 :            : 
     672                 :         71 :     size_t i = 0;
     673                 :         71 :     bool bSrcOption = false;
     674         [ +  + ]:       9216 :     while (i < args.size())
     675                 :            :     {
     676         [ -  + ]:       9145 :         if (args[i].compare("-extlangsrc") == 0)
     677                 :            :         {
     678                 :          0 :             ++i;
     679         [ #  # ]:          0 :             if (i >= args.size())
     680                 :            :             {
     681         [ #  # ]:          0 :                 std::stringstream aStrStream;
     682 [ #  # ][ #  # ]:          0 :                 aStrStream << "extension source missing" << std::endl;
     683 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     684                 :            :             }
     685                 :          0 :             extsource = args[i];
     686                 :            :         }
     687         [ -  + ]:       9145 :         else if (args[i].compare("-extlangdest") == 0)
     688                 :            :         {
     689                 :            :             //If this argument is not provided then the location provided in -extsource will
     690                 :            :             //also be the destination
     691                 :          0 :             ++i;
     692         [ #  # ]:          0 :             if (i >= args.size())
     693                 :            :             {
     694         [ #  # ]:          0 :                 std::stringstream aStrStream;
     695 [ #  # ][ #  # ]:          0 :                 aStrStream << "extension destination missing" << std::endl;
     696 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     697                 :            :             }
     698                 :          0 :             extdestination = args[i];
     699                 :            :         }
     700         [ +  + ]:       9145 :         else if (args[i].compare("-src") == 0)
     701                 :            :         {
     702                 :          9 :             ++i;
     703         [ -  + ]:          9 :             if (i >= args.size())
     704                 :            :             {
     705         [ #  # ]:          0 :                 std::stringstream aStrStream;
     706 [ #  # ][ #  # ]:          0 :                 aStrStream << "sourceroot missing" << std::endl;
     707 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     708                 :            :             }
     709                 :          9 :             bSrcOption = true;
     710                 :          9 :             sourceRoot = fs::path(args[i], fs::native);
     711                 :            :         }
     712         [ +  + ]:       9136 :         else if (args[i].compare("-sty") == 0)
     713                 :            :         {
     714                 :          9 :             ++i;
     715         [ -  + ]:          9 :             if (i >= args.size())
     716                 :            :             {
     717         [ #  # ]:          0 :                 std::stringstream aStrStream;
     718 [ #  # ][ #  # ]:          0 :                 aStrStream << "embeddingStylesheet missing" << std::endl;
     719 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     720                 :            :             }
     721                 :            : 
     722                 :          9 :             embeddStylesheet = fs::path(args[i], fs::native);
     723                 :            :         }
     724         [ +  + ]:       9127 :         else if (args[i].compare("-zipdir") == 0)
     725                 :            :         {
     726                 :          9 :             ++i;
     727         [ -  + ]:          9 :             if (i >= args.size())
     728                 :            :             {
     729         [ #  # ]:          0 :                 std::stringstream aStrStream;
     730 [ #  # ][ #  # ]:          0 :                 aStrStream << "idxtemp missing" << std::endl;
     731 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     732                 :            :             }
     733                 :            : 
     734                 :          9 :             zipdir = fs::path(args[i], fs::native);
     735                 :            :         }
     736         [ +  + ]:       9118 :         else if (args[i].compare("-idxcaption") == 0)
     737                 :            :         {
     738                 :          9 :             ++i;
     739         [ -  + ]:          9 :             if (i >= args.size())
     740                 :            :             {
     741         [ #  # ]:          0 :                 std::stringstream aStrStream;
     742 [ #  # ][ #  # ]:          0 :                 aStrStream << "idxcaption stylesheet missing" << std::endl;
     743 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     744                 :            :             }
     745                 :            : 
     746                 :          9 :             idxCaptionStylesheet = fs::path(args[i], fs::native);
     747                 :            :         }
     748         [ +  + ]:       9109 :         else if (args[i].compare("-idxcontent") == 0)
     749                 :            :         {
     750                 :          9 :             ++i;
     751         [ -  + ]:          9 :             if (i >= args.size())
     752                 :            :             {
     753         [ #  # ]:          0 :                 std::stringstream aStrStream;
     754 [ #  # ][ #  # ]:          0 :                 aStrStream << "idxcontent stylesheet missing" << std::endl;
     755 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     756                 :            :             }
     757                 :            : 
     758                 :          9 :             idxContentStylesheet = fs::path(args[i], fs::native);
     759                 :            :         }
     760         [ +  + ]:       9100 :         else if (args[i].compare("-o") == 0)
     761                 :            :         {
     762                 :          9 :             ++i;
     763         [ -  + ]:          9 :             if (i >= args.size())
     764                 :            :             {
     765         [ #  # ]:          0 :                 std::stringstream aStrStream;
     766 [ #  # ][ #  # ]:          0 :                 aStrStream << "outputfilename missing" << std::endl;
     767 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     768                 :            :             }
     769                 :            : 
     770                 :          9 :             outputFile = fs::path(args[i], fs::native);
     771                 :            :         }
     772         [ +  + ]:       9091 :         else if (args[i].compare("-mod") == 0)
     773                 :            :         {
     774                 :         71 :             ++i;
     775         [ -  + ]:         71 :             if (i >= args.size())
     776                 :            :             {
     777         [ #  # ]:          0 :                 std::stringstream aStrStream;
     778 [ #  # ][ #  # ]:          0 :                 aStrStream << "module name missing" << std::endl;
     779 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     780                 :            :             }
     781                 :            : 
     782                 :         71 :             module = args[i];
     783                 :            :         }
     784         [ +  + ]:       9020 :         else if (args[i].compare("-lang") == 0)
     785                 :            :         {
     786                 :          9 :             ++i;
     787         [ -  + ]:          9 :             if (i >= args.size())
     788                 :            :             {
     789         [ #  # ]:          0 :                 std::stringstream aStrStream;
     790 [ #  # ][ #  # ]:          0 :                 aStrStream << "language name missing" << std::endl;
     791 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     792                 :            :             }
     793                 :            : 
     794                 :          9 :             lang = args[i];
     795                 :            :         }
     796         [ -  + ]:       9011 :         else if (args[i].compare("-hid") == 0)
     797                 :            :         {
     798                 :          0 :             ++i;
     799 [ #  # ][ #  # ]:          0 :             throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, "obsolete -hid argument used" );
     800                 :            :         }
     801         [ +  + ]:       9011 :         else if (args[i].compare("-add") == 0)
     802                 :            :         {
     803 [ +  - ][ +  - ]:         30 :             std::string addFile, addFileUnderPath;
     804                 :         30 :             ++i;
     805         [ -  + ]:         30 :             if (i >= args.size())
     806                 :            :             {
     807         [ #  # ]:          0 :                 std::stringstream aStrStream;
     808 [ #  # ][ #  # ]:          0 :                 aStrStream << "pathname missing" << std::endl;
     809 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     810                 :            :             }
     811                 :            : 
     812 [ +  - ][ +  - ]:         30 :             addFileUnderPath = args[i];
     813                 :         30 :             ++i;
     814         [ -  + ]:         30 :             if (i >= args.size())
     815                 :            :             {
     816         [ #  # ]:          0 :                 std::stringstream aStrStream;
     817 [ #  # ][ #  # ]:          0 :                 aStrStream << "pathname missing" << std::endl;
     818 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     819                 :            :             }
     820 [ +  - ][ +  - ]:         30 :             addFile = args[i];
     821 [ +  - ][ +  - ]:         30 :             if (!addFileUnderPath.empty() && !addFile.empty())
                 [ +  - ]
     822 [ +  - ][ +  - ]:         30 :                 additionalFiles[addFileUnderPath] = addFile;
     823                 :            :         }
     824                 :            :         else
     825                 :       8981 :             helpFiles.push_back(args[i]);
     826                 :       9145 :         ++i;
     827                 :            :     }
     828                 :            : 
     829                 :            :     //We can be called from the helplinker executable or the extension manager
     830                 :            :     //In the latter case extsource is not used.
     831 [ +  + ][ +  - ]:         80 :     if( (pExtensionPath && pExtensionPath->length() > 0 && pOfficeHelpPath)
           [ -  +  -  + ]
                 [ +  + ]
     832                 :          9 :         || !extsource.empty())
     833                 :            :     {
     834                 :         62 :         bExtensionMode = true;
     835         [ -  + ]:         62 :         if (!extsource.empty())
     836                 :            :         {
     837                 :            :             //called from helplinker.exe, pExtensionPath and pOfficeHelpPath
     838                 :            :             //should be NULL
     839                 :          0 :             sourceRoot = fs::path(extsource, fs::native);
     840         [ #  # ]:          0 :             extensionPath = sourceRoot.toUTF8();
     841                 :            : 
     842         [ #  # ]:          0 :             if (extdestination.empty())
     843                 :            :             {
     844         [ #  # ]:          0 :                 std::stringstream aStrStream;
     845 [ #  # ][ #  # ]:          0 :                 aStrStream << "-extlangdest is missing" << std::endl;
     846 [ #  # ][ #  # ]:          0 :                 throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     847                 :            :             }
     848                 :            :             else
     849                 :            :             {
     850                 :            :                 //Convert from system path to file URL!!!
     851         [ #  # ]:          0 :                 fs::path p(extdestination, fs::native);
     852 [ #  # ][ #  # ]:          0 :                 extensionDestination = p.toUTF8();
     853                 :            :             }
     854                 :            :         }
     855                 :            :         else
     856                 :            :         { //called from extension manager
     857                 :         62 :             extensionPath = *pExtensionPath;
     858                 :         62 :             sourceRoot = fs::path(extensionPath);
     859                 :         62 :             extensionDestination = *pDestination;
     860                 :            :         }
     861                 :            :         //check if -src option was used. This option must not be used
     862                 :            :         //when extension help is compiled.
     863         [ -  + ]:         62 :         if (bSrcOption)
     864                 :            :         {
     865         [ #  # ]:          0 :             std::stringstream aStrStream;
     866 [ #  # ][ #  # ]:          0 :             aStrStream << "-src must not be used together with -extsource missing" << std::endl;
     867 [ #  # ][ #  # ]:          0 :             throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     868                 :            :         }
     869                 :            :     }
     870                 :            : 
     871 [ +  + ][ -  + ]:         71 :     if (!bExtensionMode && zipdir.empty())
                 [ -  + ]
     872                 :            :     {
     873         [ #  # ]:          0 :         std::stringstream aStrStream;
     874 [ #  # ][ #  # ]:          0 :         aStrStream << "no index dir given" << std::endl;
     875 [ #  # ][ #  # ]:          0 :         throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     876                 :            :     }
     877                 :            : 
     878 [ +  + ][ +  -  :        142 :     if ( (!bExtensionMode && idxCaptionStylesheet.empty())
             -  +  #  # ]
                 [ -  + ]
     879                 :         71 :         || (!extsource.empty() && idxCaptionStylesheet.empty()) )
     880                 :            :     {
     881                 :            :         //No extension mode and extension mode using commandline
     882                 :            :         //!extsource.empty indicates extension mode using commandline
     883                 :            :         // -idxcaption paramter is required
     884         [ #  # ]:          0 :         std::stringstream aStrStream;
     885 [ #  # ][ #  # ]:          0 :         aStrStream << "no index caption stylesheet given" << std::endl;
     886 [ #  # ][ #  # ]:          0 :         throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     887                 :            :     }
     888 [ +  + ][ +  - ]:         71 :     else if ( bExtensionMode &&  extsource.empty())
                 [ +  + ]
     889                 :            :     {
     890                 :            :         //This part is used when compileExtensionHelp is called from the extensions manager.
     891                 :            :         //If extension help is compiled using helplinker in the build process
     892                 :         62 :         rtl::OUString aIdxCaptionPathFileURL( *pOfficeHelpPath );
     893                 :         62 :         aIdxCaptionPathFileURL += rtl::OUString("/idxcaption.xsl");
     894                 :            : 
     895                 :            :         rtl::OString aOStr_IdxCaptionPathFileURL( rtl::OUStringToOString
     896 [ +  - ][ +  - ]:         62 :             ( aIdxCaptionPathFileURL, fs::getThreadTextEncoding() ) );
     897         [ +  - ]:         62 :         std::string aStdStr_IdxCaptionPathFileURL( aOStr_IdxCaptionPathFileURL.getStr() );
     898                 :            : 
     899         [ +  - ]:         62 :         idxCaptionStylesheet = fs::path( aStdStr_IdxCaptionPathFileURL );
     900                 :            :     }
     901                 :            : 
     902 [ +  + ][ +  -  :        142 :     if ( (!bExtensionMode && idxContentStylesheet.empty())
             -  +  #  # ]
                 [ -  + ]
     903                 :         71 :         || (!extsource.empty() && idxContentStylesheet.empty()) )
     904                 :            :     {
     905                 :            :         //No extension mode and extension mode using commandline
     906                 :            :         //!extsource.empty indicates extension mode using commandline
     907                 :            :         // -idxcontent paramter is required
     908         [ #  # ]:          0 :         std::stringstream aStrStream;
     909 [ #  # ][ #  # ]:          0 :         aStrStream << "no index content stylesheet given" << std::endl;
     910 [ #  # ][ #  # ]:          0 :         throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     911                 :            :     }
     912 [ +  + ][ +  - ]:         71 :     else if ( bExtensionMode && extsource.empty())
                 [ +  + ]
     913                 :            :     {
     914                 :            :         //If extension help is compiled using helplinker in the build process
     915                 :            :         //then  -idxcontent must be supplied
     916                 :            :         //This part is used when compileExtensionHelp is called from the extensions manager.
     917                 :         62 :         rtl::OUString aIdxContentPathFileURL( *pOfficeHelpPath );
     918                 :         62 :         aIdxContentPathFileURL += rtl::OUString("/idxcontent.xsl");
     919                 :            : 
     920                 :            :         rtl::OString aOStr_IdxContentPathFileURL( rtl::OUStringToOString
     921 [ +  - ][ +  - ]:         62 :             ( aIdxContentPathFileURL, fs::getThreadTextEncoding() ) );
     922         [ +  - ]:         62 :         std::string aStdStr_IdxContentPathFileURL( aOStr_IdxContentPathFileURL.getStr() );
     923                 :            : 
     924         [ +  - ]:         62 :         idxContentStylesheet = fs::path( aStdStr_IdxContentPathFileURL );
     925                 :            :     }
     926 [ +  + ][ -  + ]:         71 :     if (!bExtensionMode && embeddStylesheet.empty())
                 [ -  + ]
     927                 :            :     {
     928         [ #  # ]:          0 :         std::stringstream aStrStream;
     929 [ #  # ][ #  # ]:          0 :         aStrStream << "no embedding resolving file given" << std::endl;
     930 [ #  # ][ #  # ]:          0 :         throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     931                 :            :     }
     932         [ -  + ]:         71 :     if (sourceRoot.empty())
     933                 :            :     {
     934         [ #  # ]:          0 :         std::stringstream aStrStream;
     935 [ #  # ][ #  # ]:          0 :         aStrStream << "no sourceroot given" << std::endl;
     936 [ #  # ][ #  # ]:          0 :         throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     937                 :            :     }
     938 [ +  + ][ -  + ]:         71 :     if (!bExtensionMode && outputFile.empty())
                 [ -  + ]
     939                 :            :     {
     940         [ #  # ]:          0 :         std::stringstream aStrStream;
     941 [ #  # ][ #  # ]:          0 :         aStrStream << "no output file given" << std::endl;
     942 [ #  # ][ #  # ]:          0 :         throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     943                 :            :     }
     944         [ -  + ]:         71 :     if (module.empty())
     945                 :            :     {
     946         [ #  # ]:          0 :         std::stringstream aStrStream;
     947 [ #  # ][ #  # ]:          0 :         aStrStream << "module missing" << std::endl;
     948 [ #  # ][ #  # ]:          0 :         throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     949                 :            :     }
     950 [ +  + ][ -  + ]:         71 :     if (!bExtensionMode && lang.empty())
                 [ -  + ]
     951                 :            :     {
     952         [ #  # ]:          0 :         std::stringstream aStrStream;
     953 [ #  # ][ #  # ]:          0 :         aStrStream << "language missing" << std::endl;
     954 [ #  # ][ #  # ]:          0 :         throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
     955                 :            :     }
     956                 :         71 :     link();
     957                 :         71 : }
     958                 :            : 
     959                 :            : // Variable to set an exception in "C" StructuredXMLErrorFunction
     960                 :            : static const HelpProcessingException* GpXMLParsingException = NULL;
     961                 :            : 
     962                 :          0 : extern "C" void StructuredXMLErrorFunction(void *userData, xmlErrorPtr error)
     963                 :            : {
     964                 :            :     (void)userData;
     965                 :            :     (void)error;
     966                 :            : 
     967         [ #  # ]:          0 :     std::string aErrorMsg = error->message;
     968         [ #  # ]:          0 :     std::string aXMLParsingFile;
     969         [ #  # ]:          0 :     if( error->file != NULL )
     970         [ #  # ]:          0 :         aXMLParsingFile = error->file;
     971                 :          0 :     int nXMLParsingLine = error->line;
     972 [ #  # ][ #  # ]:          0 :     HelpProcessingException* pException = new HelpProcessingException( aErrorMsg, aXMLParsingFile, nXMLParsingLine );
     973                 :          0 :     GpXMLParsingException = pException;
     974                 :            : 
     975                 :            :     // Reset error handler
     976         [ #  # ]:          0 :     xmlSetStructuredErrorFunc( NULL, NULL );
     977                 :          0 : }
     978                 :            : 
     979                 :          0 : HelpProcessingErrorInfo& HelpProcessingErrorInfo::operator=( const struct HelpProcessingException& e )
     980                 :            : {
     981                 :          0 :     m_eErrorClass = e.m_eErrorClass;
     982                 :          0 :     rtl::OString tmpErrorMsg( e.m_aErrorMsg.c_str() );
     983 [ #  # ][ #  # ]:          0 :     m_aErrorMsg = rtl::OStringToOUString( tmpErrorMsg, fs::getThreadTextEncoding() );
     984                 :          0 :     rtl::OString tmpXMLParsingFile( e.m_aXMLParsingFile.c_str() );
     985 [ #  # ][ #  # ]:          0 :     m_aXMLParsingFile = rtl::OStringToOUString( tmpXMLParsingFile, fs::getThreadTextEncoding() );
     986                 :          0 :     m_nXMLParsingLine = e.m_nXMLParsingLine;
     987                 :          0 :     return *this;
     988                 :            : }
     989                 :            : 
     990                 :            : 
     991                 :            : // Returns true in case of success, false in case of error
     992                 :         62 : HELPLINKER_DLLPUBLIC bool compileExtensionHelp
     993                 :            : (
     994                 :            :     const rtl::OUString& aOfficeHelpPath,
     995                 :            :     const rtl::OUString& aExtensionName,
     996                 :            :     const rtl::OUString& aExtensionLanguageRoot,
     997                 :            :     sal_Int32 nXhpFileCount, const rtl::OUString* pXhpFiles,
     998                 :            :     const rtl::OUString& aDestination,
     999                 :            :     HelpProcessingErrorInfo& o_rHelpProcessingErrorInfo
    1000                 :            : )
    1001                 :            : {
    1002                 :         62 :     bool bSuccess = true;
    1003                 :            : 
    1004         [ +  - ]:         62 :     std::vector<std::string> args;
    1005         [ +  - ]:         62 :     args.reserve(nXhpFileCount + 2);
    1006 [ +  - ][ +  - ]:         62 :     args.push_back(std::string("-mod"));
    1007 [ +  - ][ +  - ]:         62 :     rtl::OString aOExtensionName = rtl::OUStringToOString( aExtensionName, fs::getThreadTextEncoding() );
    1008 [ +  - ][ +  - ]:         62 :     args.push_back(std::string(aOExtensionName.getStr()));
    1009                 :            : 
    1010         [ +  + ]:        124 :     for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp )
    1011                 :            :     {
    1012                 :         62 :         rtl::OUString aXhpFile = pXhpFiles[iXhp];
    1013                 :            : 
    1014 [ +  - ][ +  - ]:         62 :         rtl::OString aOXhpFile = rtl::OUStringToOString( aXhpFile, fs::getThreadTextEncoding() );
    1015 [ +  - ][ +  - ]:         62 :         args.push_back(std::string(aOXhpFile.getStr()));
    1016                 :         62 :     }
    1017                 :            : 
    1018 [ +  - ][ +  - ]:         62 :     rtl::OString aOExtensionLanguageRoot = rtl::OUStringToOString( aExtensionLanguageRoot, fs::getThreadTextEncoding() );
    1019                 :         62 :     const char* pExtensionPath = aOExtensionLanguageRoot.getStr();
    1020         [ +  - ]:         62 :     std::string aStdStrExtensionPath = pExtensionPath;
    1021 [ +  - ][ +  - ]:         62 :     rtl::OString aODestination = rtl::OUStringToOString(aDestination, fs::getThreadTextEncoding());
    1022                 :         62 :     const char* pDestination = aODestination.getStr();
    1023         [ +  - ]:         62 :     std::string aStdStrDestination = pDestination;
    1024                 :            : 
    1025                 :            :     // Set error handler
    1026         [ +  - ]:         62 :     xmlSetStructuredErrorFunc( NULL, (xmlStructuredErrorFunc)StructuredXMLErrorFunction );
    1027                 :            :     try
    1028                 :            :     {
    1029 [ +  - ][ +  - ]:         62 :         HelpLinker* pHelpLinker = new HelpLinker();
    1030         [ +  - ]:         62 :         pHelpLinker->main( args, &aStdStrExtensionPath, &aStdStrDestination, &aOfficeHelpPath );
    1031 [ +  - ][ +  - ]:         62 :         delete pHelpLinker;
    1032                 :            :     }
    1033         [ #  # ]:          0 :     catch( const HelpProcessingException& e )
    1034                 :            :     {
    1035         [ #  # ]:          0 :         if( GpXMLParsingException != NULL )
    1036                 :            :         {
    1037         [ #  # ]:          0 :             o_rHelpProcessingErrorInfo = *GpXMLParsingException;
    1038         [ #  # ]:          0 :             delete GpXMLParsingException;
    1039                 :          0 :             GpXMLParsingException = NULL;
    1040                 :            :         }
    1041                 :            :         else
    1042                 :            :         {
    1043         [ #  # ]:          0 :             o_rHelpProcessingErrorInfo = e;
    1044                 :            :         }
    1045                 :          0 :         bSuccess = false;
    1046                 :            :     }
    1047                 :            :     // Reset error handler
    1048         [ +  - ]:         62 :     xmlSetStructuredErrorFunc( NULL, NULL );
    1049                 :            : 
    1050                 :            :     // i83624: Tree files
    1051                 :         62 :     ::rtl::OUString aTreeFileURL = aExtensionLanguageRoot;
    1052                 :         62 :     aTreeFileURL += rtl::OUString("/help.tree");
    1053                 :         62 :     osl::DirectoryItem aTreeFileItem;
    1054         [ +  - ]:         62 :     osl::FileBase::RC rcGet = osl::DirectoryItem::get( aTreeFileURL, aTreeFileItem );
    1055                 :         62 :     osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileSize );
    1056   [ #  #  #  # ]:         62 :     if( rcGet == osl::FileBase::E_None &&
         [ -  + ][ -  + ]
    1057         [ #  # ]:          0 :         aTreeFileItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None &&
    1058                 :          0 :         aFileStatus.isValid( osl_FileStatus_Mask_FileSize ) )
    1059                 :            :     {
    1060         [ #  # ]:          0 :         sal_uInt64 ret, len = aFileStatus.getFileSize();
    1061         [ #  # ]:          0 :         char* s = new char[ int(len) ];  // the buffer to hold the installed files
    1062                 :          0 :         osl::File aFile( aTreeFileURL );
    1063         [ #  # ]:          0 :         aFile.open( osl_File_OpenFlag_Read );
    1064         [ #  # ]:          0 :         aFile.read( s, len, ret );
    1065         [ #  # ]:          0 :         aFile.close();
    1066                 :            : 
    1067         [ #  # ]:          0 :         XML_Parser parser = XML_ParserCreate( 0 );
    1068         [ #  # ]:          0 :         XML_Status parsed = XML_Parse( parser, s, int( len ), true );
    1069                 :            : 
    1070         [ #  # ]:          0 :         if (XML_STATUS_ERROR == parsed)
    1071                 :            :         {
    1072         [ #  # ]:          0 :             XML_Error nError = XML_GetErrorCode( parser );
    1073                 :          0 :             o_rHelpProcessingErrorInfo.m_eErrorClass = HELPPROCESSING_XMLPARSING_ERROR;
    1074         [ #  # ]:          0 :             o_rHelpProcessingErrorInfo.m_aErrorMsg = rtl::OUString::createFromAscii( XML_ErrorString( nError ) );;
    1075                 :          0 :             o_rHelpProcessingErrorInfo.m_aXMLParsingFile = aTreeFileURL;
    1076                 :            :             // CRAHSES!!! o_rHelpProcessingErrorInfo.m_nXMLParsingLine = XML_GetCurrentLineNumber( parser );
    1077                 :          0 :             bSuccess = false;
    1078                 :            :         }
    1079                 :            : 
    1080         [ #  # ]:          0 :         XML_ParserFree( parser );
    1081 [ #  # ][ #  # ]:          0 :         delete[] s;
    1082                 :            :     }
    1083                 :            : 
    1084         [ +  - ]:         62 :     return bSuccess;
    1085                 :            : }
    1086                 :            : 
    1087                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10