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