Doxygen
Loading...
Searching...
No Matches
htmlhelp.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2020 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 * The original version of this file is largely based on a contribution from
15 * Harm van der Heijden.
16 */
17
18#include <algorithm>
19
20#include <stdio.h>
21#include <stdlib.h>
22
23#include "htmlhelp.h"
24#include "config.h"
25#include "message.h"
26#include "doxygen.h"
27#include "language.h"
28#include "portable.h"
29#include "groupdef.h"
30#include "memberdef.h"
31#include "filedef.h"
32#include "util.h"
33#include "linkedmap.h"
34#include "regex.h"
35#include "fileinfo.h"
36
37//----------------------------------------------------------------------------
38
39/** Helper class to deal with recoding the UTF8 encoded text back to the native encoding
40 * specified by CHM_INDEX_ENCODING.
41 */
43{
44 public:
48
50 {
51 QCString str = Config_getString(CHM_INDEX_ENCODING);
52 if (str.isEmpty()) str = "CP1250"; // use safe and likely default
53 m_fromUtf8 = portable_iconv_open(str.data(),"UTF-8");
55 {
56 term("unsupported character conversion for CHM_INDEX_ENCODING: '%s'->'UTF-8'\n", qPrint(str));
57 }
58 }
67
69 {
70 size_t iSize = s.length();
71 size_t oSize = iSize*4;
72 QCString output(oSize, QCString::ExplicitSize);
73 size_t iLeft = iSize;
74 size_t oLeft = oSize;
75 const char *iPtr = s.data();
76 char *oPtr = output.rawData();
77 if (!portable_iconv(m_fromUtf8,&iPtr,&iLeft,&oPtr,&oLeft))
78 {
79 oSize -= oLeft;
80 output.resize(oSize);
81 output.at(oSize)='\0';
82 return output;
83 }
84 else
85 {
86 return s;
87 }
88 }
89 private:
90 void *m_iconv_null = reinterpret_cast<void*>(-1);
92
93};
94
95//----------------------------------------------------------------------------
96
97/** Class representing a field in the HTML help index. */
99{
100 IndexField(const QCString &k,const QCString &n,const QCString &u,const QCString &a,bool l,bool r) :
101 key(k), name(n), url(u), anchor(a), link(l), reversed(r) {}
106 bool link;
108};
109
110/** A helper class for HtmlHelp that manages a two level index in
111 * alphabetical order.
112 */
114{
115 public:
119 void addItem(const QCString &first,const QCString &second,
120 const QCString &url, const QCString &anchor,
121 bool hasLink,bool reversed);
122 void writeFields(std::ostream &t);
123 size_t size() const { return m_map.size(); }
124 private:
127};
128
129/*! Constructs a new HtmlHelp index */
133
134/*! Destroys the HtmlHelp index */
136
137
138/*! Stores an item in the index if it is not already present.
139 * Items are stored in alphabetical order, by sorting on the
140 * concatenation of \a level1 and \a level2 (if present).
141 *
142 * \param level1 the string at level 1 in the index.
143 * \param level2 the string at level 2 in the index (or 0 if not applicable).
144 * \param url the url of the documentation (without .html extension).
145 * \param anchor the anchor of the documentation within the page.
146 * \param hasLink if true, the url (without anchor) can be used in the
147 * level1 item, when writing the header of a list of level2 items.
148 * \param reversed TRUE if level1 is the member name and level2 the compound
149 * name.
150 */
151void HtmlHelpIndex::addItem(const QCString &level1,const QCString &level2,
152 const QCString &url,const QCString &anchor,bool hasLink,
153 bool reversed)
154{
155 static const reg::Ex re(R"(@\d+)");
156 std::string key = substitute(level1,"?","&quest;").str();
157 if (!level2.isEmpty()) key+= std::string("?") + substitute(level2,"?","&quest;").str();
158 if (reg::search(key,re)) // skip anonymous stuff
159 {
160 return;
161 }
162 std::string key_anchor;
163 if (!anchor.isEmpty())
164 {
165 key_anchor = key+anchor.str();
166 }
167 else
168 {
169 key_anchor = key;
170 }
171 m_map.add(key_anchor.c_str(),key.c_str(),url,anchor,hasLink,reversed);
172}
173
174static QCString field2URL(const IndexField *f,bool checkReversed)
175{
176 QCString result = f->url;
178 if (!f->anchor.isEmpty() && (!checkReversed || f->reversed))
179 {
180 result+="#"+f->anchor;
181 }
182 return result;
183}
184
186{
187 /* to prevent
188 * Warning: Keyword string:
189 * ...
190 * is too long. The maximum size is 488 characters.
191 */
192 int maxLen = 400;
193 size_t maxExpandedLen = maxLen+50;
194 QCString result = convertToHtml(s,true);
195 if (result.length()>maxExpandedLen) // we need to truncate the string
196 {
197 // in the unlikely case that the string after conversion grows from maxLen to maxExpandedLen, we try smaller parts
198 // until we end up below the limit
199 while (maxLen>0 && result.length()>maxExpandedLen)
200 {
201 result = convertToHtml(s.left(maxLen));
202 maxLen-=20;
203 }
204 return result+"...";
205 }
206 else
207 {
208 return result;
209 }
210}
211
212/*! Writes the sorted list of index items into a html like list.
213 *
214 * An list of calls with <code>name = level1,level2</code> as follows:
215 * <pre>
216 * a1,b1
217 * a1,b2
218 * a2,b1
219 * a2,b2
220 * a3
221 * a4,b1
222 * </pre>
223 *
224 * Will result in the following list:
225 *
226 * <pre>
227 * a1 -> link to url if hasLink==TRUE
228 * b1 -> link to url#anchor
229 * b2 -> link to url#anchor
230 * a2 -> link to url if hasLink==TRUE
231 * b1 -> link to url#anchor
232 * b2 -> link to url#anchor
233 * a3 -> link to url if hasLink==TRUE
234 * a4 -> link to url if hasLink==TRUE
235 * b1 -> link to url#anchor
236 * </pre>
237 */
238void HtmlHelpIndex::writeFields(std::ostream &t)
239{
240 std::stable_sort(std::begin(m_map),
241 std::end(m_map),
242 [](const auto &e1,const auto &e2) { return qstricmp_sort(e1->name,e2->name)<0; }
243 );
244 QCString prevLevel1;
245 bool level2Started=FALSE;
246 for (auto it = std::begin(m_map); it!=std::end(m_map); ++it)
247 {
248 auto &f = *it;
249 QCString level1,level2;
250 int i = f->name.find('?');
251 if (i!=-1)
252 {
253 level1 = f->name.left(i);
254 level2 = f->name.right(f->name.length()-i-1);
255 }
256 else
257 {
258 level1 = f->name;
259 }
260
261 { // finish old list at level 2
262 if (level2Started) t << " </UL>\n";
263 level2Started=FALSE;
264
265 // <Antony>
266 // Added this code so that an item with only one subitem is written
267 // without any subitem.
268 // For example:
269 // a1, b1 -> will create only a1, not separate subitem for b1
270 // a2, b2
271 // a2, b3
272 QCString nextLevel1;
273 auto it_next = std::next(it);
274 if (it_next!=std::end(m_map))
275 {
276 auto &fnext = *it_next;
277 int j = fnext->name.find('?');
278 if (j<0) j=0;
279 nextLevel1 = fnext->name.left(j);
280 }
281 if (!(level1 == prevLevel1 || level1 == nextLevel1))
282 {
283 level2 = "";
284 }
285 prevLevel1 = level1;
286 // </Antony>
287
288 if (level2.isEmpty())
289 {
290 t << " <LI><OBJECT type=\"text/sitemap\">";
291 t << "<param name=\"Local\" value=\"" << field2URL(f.get(),FALSE);
292 t << "\">";
293 t << "<param name=\"Name\" value=\"" << convertToHtmlAndTruncate(m_recoder.recode(level1)) << "\">"
294 "</OBJECT>\n";
295 }
296 else
297 {
298 if (f->link)
299 {
300 t << " <LI><OBJECT type=\"text/sitemap\">";
301 t << "<param name=\"Local\" value=\"" << field2URL(f.get(),TRUE);
302 t << "\">";
303 t << "<param name=\"Name\" value=\"" << convertToHtmlAndTruncate(m_recoder.recode(level1)) << "\">"
304 "</OBJECT>\n";
305 }
306 else
307 {
308 t << " <LI><OBJECT type=\"text/sitemap\">";
309 t << "<param name=\"See Also\" value=\"" << convertToHtml(m_recoder.recode(level1)) << "\">";
310 t << "<param name=\"Name\" value=\"" << convertToHtmlAndTruncate(m_recoder.recode(level1)) << "\">"
311 "</OBJECT>\n";
312 }
313 }
314 }
315 if (!level2Started && !level2.isEmpty())
316 { // start new list at level 2
317 t << " <UL>\n";
318 level2Started=TRUE;
319 }
320 else if (level2Started && level2.isEmpty())
321 { // end list at level 2
322 t << " </UL>\n";
323 level2Started=FALSE;
324 }
325 if (level2Started)
326 {
327 t << " <LI><OBJECT type=\"text/sitemap\">";
328 t << "<param name=\"Local\" value=\"" << field2URL(f.get(),FALSE);
329 t << "\">";
330 t << "<param name=\"Name\" value=\"" << convertToHtmlAndTruncate(m_recoder.recode(level2)) << "\">"
331 "</OBJECT>\n";
332 }
333 }
334 if (level2Started) t << " </UL>\n";
335}
336
337//----------------------------------------------------------------------------
338//
355
356
357/*! Constructs an html object.
358 * The object has to be \link initialize() initialized\endlink before it can
359 * be used.
360 */
361HtmlHelp::HtmlHelp() : p(std::make_unique<Private>()) {}
362HtmlHelp::~HtmlHelp() = default;
363
364/*! This will create a contents file (index.hhc) and a index file (index.hhk)
365 * and write the header of those files.
366 * It also creates a project file (index.hhp)
367 * \sa finalize()
368 */
370{
371 p->recoder.initialize();
372
373 /* open the contents file */
374 QCString fName = Config_getString(HTML_OUTPUT) + "/" + hhcFileName;
375 p->cts = Portable::openOutputStream(fName);
376 if (!p->cts.is_open())
377 {
378 term("Could not open file %s for writing\n",qPrint(fName));
379 }
380 /* Write the header of the contents file */
381 p->cts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
382 "<HTML><HEAD></HEAD><BODY>\n"
383 "<OBJECT type=\"text/site properties\">\n"
384 "<param name=\"FrameName\" value=\"right\">\n"
385 "</OBJECT>\n"
386 "<UL>\n";
387
388 /* open the index file */
389 fName = Config_getString(HTML_OUTPUT) + "/" + hhkFileName;
390 p->kts = Portable::openOutputStream(fName);
391 if (!p->kts.is_open())
392 {
393 term("Could not open file %s for writing\n",qPrint(fName));
394 }
395 /* Write the header of the contents file */
396 p->kts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
397 "<HTML><HEAD></HEAD><BODY>\n"
398 "<OBJECT type=\"text/site properties\">\n"
399 "<param name=\"FrameName\" value=\"right\">\n"
400 "</OBJECT>\n"
401 "<UL>\n";
402
403}
404
406{
407 /* Write the project file */
408 QCString fName = Config_getString(HTML_OUTPUT) + "/" + hhpFileName;
409 std::ofstream t = Portable::openOutputStream(fName);
410 if (t.is_open())
411 {
412 QCString hhcFile = "\"" + hhcFileName + "\"";
413 QCString hhkFile = "\"" + hhkFileName + "\"";
414 bool hhkPresent = index.size()>0;
415 if (!ctsItemPresent) hhcFile = "";
416 if (!hhkPresent) hhkFile = "";
417
418 QCString indexName="index"+Doxygen::htmlFileExtension;
419 t << "[OPTIONS]\n";
420 if (!Config_getString(CHM_FILE).isEmpty())
421 {
422 t << "Compiled file=" << Config_getString(CHM_FILE) << "\n";
423 }
424 else
425 {
426 t << "Compiled file=index.chm\n";
427 }
428 t << "Compatibility=1.1\n"
429 "Full-text search=Yes\n";
430 if (ctsItemPresent) t << "Contents file=" + hhcFileName + "\n";
431 t << "Default Window=main\n"
432 "Default topic=" << indexName << "\n";
433 if (hhkPresent) t << "Index file=" + hhkFileName + "\n";
434 t << "Language=" << theTranslator->getLanguageString() << "\n";
435 if (Config_getBool(BINARY_TOC)) t << "Binary TOC=YES\n";
436 if (Config_getBool(GENERATE_CHI)) t << "Create CHI file=YES\n";
437 t << "Title=" << recoder.recode(Config_getString(PROJECT_NAME)) << "\n\n";
438
439 t << "[WINDOWS]\n";
440
441 // NOTE: the 0x10387e number is a set of bits specifying the buttons
442 // which should appear in the CHM viewer; that specific value
443 // means "show all buttons including the font-size one";
444 // the font-size one is not normally settable by the HTML Help Workshop
445 // utility but the way to set it is described here:
446 // http://support.microsoft.com/?scid=kb%3Ben-us%3B240062&x=17&y=18
447 // NOTE: the 0x70387e number in addition to the above the Next and Prev button
448 // are shown. They can only be shown in case of a binary toc.
449 // dee http://www.mif2go.com/xhtml/htmlhelp_0016_943addingtabsandtoolbarbuttonstohtmlhelp.htm#Rz108x95873
450 // Value has been taken from htmlhelp.h file of the HTML Help Workshop
451 if (Config_getBool(BINARY_TOC))
452 {
453 t << "main=\"" << recoder.recode(Config_getString(PROJECT_NAME)) << "\"," << hhcFile << ","
454 << hhkFile << ",\"" << indexName << "\",\"" <<
455 indexName << "\",,,,,0x23520,,0x70387e,,,,,,,,0\n\n";
456 }
457 else
458 {
459 t << "main=\"" << recoder.recode(Config_getString(PROJECT_NAME)) << "\"," << hhcFile << ","
460 << hhkFile << ",\"" << indexName << "\",\"" <<
461 indexName << "\",,,,,0x23520,,0x10387e,,,,,,,,0\n\n";
462 }
463
464 t << "[FILES]\n";
465 for (auto &s : indexFiles)
466 {
467 t << s.c_str() << "\n";
468 }
469 for (auto &s : imageFiles)
470 {
471 t << s.c_str() << "\n";
472 }
473 for (auto &s : styleFiles)
474 {
475 t << s.c_str() << "\n";
476 }
477 t.close();
478 }
479 else
480 {
481 err("Could not open file %s for writing\n",qPrint(fName));
482 }
483}
484
486{
487 p->indexFiles.insert(s.str());
488}
489
490/*! Finalizes the HTML help. This will finish and close the
491 * htmlhelp contents file and the htmlhelp index file.
492 * \sa initialize()
493 */
495{
496 // end the contents file
497 p->cts << "</UL>\n";
498 p->cts << "</BODY>\n";
499 p->cts << "</HTML>\n";
500 p->cts.close();
501
502 p->index.writeFields(p->kts);
503
504 // end the index file
505 p->kts << "</UL>\n";
506 p->kts << "</BODY>\n";
507 p->kts << "</HTML>\n";
508 p->kts.close();
509
510 p->createProjectFile();
511
512 p->recoder.finalize();
513}
514
515/*! Increase the level of the contents hierarchy.
516 * This will start a new unnumbered HTML list in contents file.
517 * \sa decContentsDepth()
518 */
520{
521 for (int i=0; i<p->dc+1; i++) p->cts << " ";
522 p->cts << "<UL>\n";
523 ++p->dc;
524}
525
526/*! Decrease the level of the contents hierarchy.
527 * This will end the unnumber HTML list.
528 * \sa incContentsDepth()
529 */
531{
532 for (int i=0; i<p->dc; i++) p->cts << " ";
533 p->cts << "</UL>\n";
534 --p->dc;
535}
536
537/*! Add an list item to the contents file.
538 * \param isDir boolean indicating if this is a dir or file entry
539 * \param name the name of the item.
540 * \param ref the URL of to the item.
541 * \param file the file in which the item is defined.
542 * \param anchor the anchor of the item.
543 * \param separateIndex not used.
544 * \param addToNavIndex not used.
545 * \param def not used.
546 */
548 const QCString &name,
549 const QCString &ref,
550 const QCString &file,
551 const QCString &anchor,
552 bool /* separateIndex */,
553 bool /* addToNavIndex */,
554 const Definition * /* def */)
555{
556 p->ctsItemPresent = true;
557 for (int i=0; i<p->dc; i++) p->cts << " ";
558 p->cts << "<LI><OBJECT type=\"text/sitemap\">";
559 p->cts << "<param name=\"Name\" value=\"" << convertToHtml(p->recoder.recode(name),TRUE) << "\">";
560 if (!file.isEmpty()) // made file optional param - KPW
561 {
562 if (file[0]=='!' || file[0]=='^') // special markers for user defined URLs
563 {
564 p->cts << "<param name=\"";
565 if (file[0]=='^') p->cts << "URL"; else p->cts << "Local";
566 p->cts << "\" value=\"";
567 p->cts << &file[1];
568 p->cts << "\">";
569 }
570 else
571 {
572 QCString currFile = file;
574 QCString currAnc = anchor;
575 p->cts << "<param name=\"Local\" value=\"";
576 if (!ref.isEmpty()) p->cts << externalRef("",ref,true);
577 p->cts << currFile;
578 if (p->prevFile == currFile && p->prevAnc.isEmpty() && currAnc.isEmpty())
579 {
580 currAnc = "top";
581 }
582 if (!currAnc.isEmpty()) p->cts << "#" << currAnc;
583 p->cts << "\">";
584 p->prevFile = currFile;
585 p->prevAnc = currAnc;
586 }
587 }
588 p->cts << "<param name=\"ImageNumber\" value=\"";
589 if (isDir) // added - KPW
590 {
591 p->cts << static_cast<int>(BOOK_CLOSED);
592 }
593 else
594 {
595 p->cts << static_cast<int>(TEXT);
596 }
597 p->cts << "\">";
598 p->cts << "</OBJECT>\n";
599}
600
601
602void HtmlHelp::addIndexItem(const Definition *context,const MemberDef *md,
603 const QCString &sectionAnchor,const QCString &word)
604{
605 if (context && md)
606 {
607 QCString cfname = md->getOutputFileBase();
608 QCString argStr = md->argsString();
609 QCString level1 = context->name();
610 QCString level2 = md->name() + argStr;
611 QCString anchor = !sectionAnchor.isEmpty() ? sectionAnchor : md->anchor();
612 p->index.addItem(level1,level2,cfname,anchor,TRUE,FALSE);
613 p->index.addItem(level2,level1,cfname,anchor,TRUE,TRUE);
614 }
615 else if (context)
616 {
617 QCString level1 = !word.isEmpty() ? word : context->name();
618 p->index.addItem(level1,QCString(),context->getOutputFileBase(),sectionAnchor,TRUE,FALSE);
619 }
620}
621
623{
624 p->styleFiles.insert(fileName.str());
625}
626
627void HtmlHelp::addImageFile(const QCString &fileName)
628{
629 p->imageFiles.insert(fileName.str());
630}
631
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
virtual const QCString & name() const =0
static QCString htmlFileExtension
Definition doxygen.h:122
StringSet indexFiles
Definition htmlhelp.cpp:349
StringSet imageFiles
Definition htmlhelp.cpp:350
HtmlHelpRecoder recoder
Definition htmlhelp.cpp:352
void createProjectFile()
Definition htmlhelp.cpp:405
HtmlHelpIndex index
Definition htmlhelp.cpp:353
std::ofstream kts
Definition htmlhelp.cpp:344
std::ofstream cts
Definition htmlhelp.cpp:344
StringSet styleFiles
Definition htmlhelp.cpp:351
void addImageFile(const QCString &)
Definition htmlhelp.cpp:627
void addIndexFile(const QCString &name)
Definition htmlhelp.cpp:485
static const QCString hhkFileName
Definition htmlhelp.h:87
void addIndexItem(const Definition *context, const MemberDef *md, const QCString &sectionAnchor, const QCString &title)
Definition htmlhelp.cpp:602
static const QCString hhpFileName
Definition htmlhelp.h:88
std::unique_ptr< Private > p
Definition htmlhelp.h:91
void finalize()
Definition htmlhelp.cpp:494
void addContentsItem(bool isDir, const QCString &name, const QCString &ref, const QCString &file, const QCString &anchor, bool separateIndex, bool addToNavIndex, const Definition *def)
Definition htmlhelp.cpp:547
@ BOOK_CLOSED
Definition htmlhelp.h:41
void addStyleSheetFile(const QCString &)
Definition htmlhelp.cpp:622
void incContentsDepth()
Definition htmlhelp.cpp:519
void initialize()
Definition htmlhelp.cpp:369
void decContentsDepth()
Definition htmlhelp.cpp:530
static const QCString hhcFileName
Definition htmlhelp.h:86
A helper class for HtmlHelp that manages a two level index in alphabetical order.
Definition htmlhelp.cpp:114
size_t size() const
Definition htmlhelp.cpp:123
HtmlHelpRecoder & m_recoder
Definition htmlhelp.cpp:126
void addItem(const QCString &first, const QCString &second, const QCString &url, const QCString &anchor, bool hasLink, bool reversed)
Definition htmlhelp.cpp:151
void writeFields(std::ostream &t)
Definition htmlhelp.cpp:238
HtmlHelpIndex(HtmlHelpRecoder &recoder)
Definition htmlhelp.cpp:130
LinkedMap< IndexField > m_map
Definition htmlhelp.cpp:125
Helper class to deal with recoding the UTF8 encoded text back to the native encoding specified by CHM...
Definition htmlhelp.cpp:43
void * m_fromUtf8
Definition htmlhelp.cpp:91
QCString recode(const QCString &s)
Definition htmlhelp.cpp:68
void * m_iconv_null
Definition htmlhelp.cpp:90
void initialize()
Definition htmlhelp.cpp:49
Container class representing a vector of objects with keys.
Definition linkedmap.h:36
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
virtual QCString argsString() const =0
This is an alternative implementation of QCString.
Definition qcstring.h:101
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:578
char * rawData()
Returns a writable pointer to the data.
Definition qcstring.h:165
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
void resize(size_t newlen)
Definition qcstring.h:167
const std::string & str() const
Definition qcstring.h:537
QCString right(size_t len) const
Definition qcstring.h:219
@ ExplicitSize
Definition qcstring.h:133
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
QCString left(size_t len) const
Definition qcstring.h:214
Class representing a regular expression.
Definition regex.h:39
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
#define NON_COPYABLE(cls)
Macro to help implementing the rule of 5 for a non-copyable & movable class.
Definition construct.h:37
std::set< std::string > StringSet
Definition containers.h:31
static QCString convertToHtmlAndTruncate(const QCString &s)
Definition htmlhelp.cpp:185
static QCString field2URL(const IndexField *f, bool checkReversed)
Definition htmlhelp.cpp:174
Translator * theTranslator
Definition language.cpp:71
#define err(fmt,...)
Definition message.h:84
#define term(fmt,...)
Definition message.h:94
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition regex.cpp:748
Portable versions of functions that are platform dependent.
int portable_iconv_close(void *cd)
size_t portable_iconv(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
void * portable_iconv_open(const char *tocode, const char *fromcode)
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
int qstricmp_sort(const char *str1, const char *str2)
Definition qcstring.h:86
const char * qPrint(const char *s)
Definition qcstring.h:672
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
Class representing a field in the HTML help index.
Definition htmlhelp.cpp:99
bool reversed
Definition htmlhelp.cpp:107
QCString anchor
Definition htmlhelp.cpp:105
QCString url
Definition htmlhelp.cpp:104
IndexField(const QCString &k, const QCString &n, const QCString &u, const QCString &a, bool l, bool r)
Definition htmlhelp.cpp:100
QCString key
Definition htmlhelp.cpp:102
QCString name
Definition htmlhelp.cpp:103
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:6066
QCString convertToHtml(const QCString &s, bool keepEntities)
Definition util.cpp:4317
std::string_view word
Definition util.cpp:980
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5243
A bunch of utility functions.