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