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 );
270c01398f2SHerbert 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)298c01398f2SHerbert 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.
498c01398f2SHerbert 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 }
519c01398f2SHerbert 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;
535c01398f2SHerbert 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
868*a893be29SPedro Giffuni // -idxcaption parameter 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
892*a893be29SPedro Giffuni // -idxcontent parameter 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