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