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