Doxygen
Loading...
Searching...
No Matches
searchindex_js.cpp File Reference
#include <utility>
#include <algorithm>
#include <cassert>
#include "searchindex_js.h"
#include "doxygen.h"
#include "groupdef.h"
#include "pagedef.h"
#include "namespacedef.h"
#include "classdef.h"
#include "classlist.h"
#include "membername.h"
#include "filename.h"
#include "language.h"
#include "textstream.h"
#include "util.h"
#include "version.h"
#include "message.h"
#include "resourcemgr.h"
#include "indexlist.h"
#include "portable.h"
#include "threadpool.h"
#include "moduledef.h"
#include "section.h"
Include dependency graph for searchindex_js.cpp:

Go to the source code of this file.

Macros

#define SEARCH_INDEX_ALL   0
#define SEARCH_INDEX_CLASSES   1
#define SEARCH_INDEX_INTERFACES   2
#define SEARCH_INDEX_STRUCTS   3
#define SEARCH_INDEX_EXCEPTIONS   4
#define SEARCH_INDEX_NAMESPACES   5
#define SEARCH_INDEX_FILES   6
#define SEARCH_INDEX_FUNCTIONS   7
#define SEARCH_INDEX_VARIABLES   8
#define SEARCH_INDEX_TYPEDEFS   9
#define SEARCH_INDEX_SEQUENCES   10
#define SEARCH_INDEX_DICTIONARIES   11
#define SEARCH_INDEX_ENUMS   12
#define SEARCH_INDEX_ENUMVALUES   13
#define SEARCH_INDEX_PROPERTIES   14
#define SEARCH_INDEX_EVENTS   15
#define SEARCH_INDEX_RELATED   16
#define SEARCH_INDEX_DEFINES   17
#define SEARCH_INDEX_GROUPS   18
#define SEARCH_INDEX_PAGES   19
#define SEARCH_INDEX_CONCEPTS   20
#define SEARCH_INDEX_MODULES   21

Functions

static void splitSearchTokens (QCString &title, IntVector &indices)
static void addMemberToSearchIndex (const MemberDef *md)
void createJavaScriptSearchIndex ()
static void writeJavascriptSearchData (const QCString &searchDirName)
static void writeJavasScriptSearchDataPage (const QCString &baseName, const QCString &dataFileName, const SearchIndexList &list)
void writeJavaScriptSearchIndex ()
const std::array< SearchIndexInfo, NUM_SEARCH_INDICES > & getSearchIndices ()

Variables

static std::array< SearchIndexInfo, NUM_SEARCH_INDICESg_searchIndexInfo

Macro Definition Documentation

◆ SEARCH_INDEX_ALL

#define SEARCH_INDEX_ALL   0

Definition at line 157 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex(), and createJavaScriptSearchIndex().

◆ SEARCH_INDEX_CLASSES

#define SEARCH_INDEX_CLASSES   1

Definition at line 158 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_CONCEPTS

#define SEARCH_INDEX_CONCEPTS   20

Definition at line 177 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_DEFINES

#define SEARCH_INDEX_DEFINES   17

Definition at line 174 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_DICTIONARIES

#define SEARCH_INDEX_DICTIONARIES   11

Definition at line 168 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_ENUMS

#define SEARCH_INDEX_ENUMS   12

Definition at line 169 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_ENUMVALUES

#define SEARCH_INDEX_ENUMVALUES   13

Definition at line 170 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_EVENTS

#define SEARCH_INDEX_EVENTS   15

Definition at line 172 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_EXCEPTIONS

#define SEARCH_INDEX_EXCEPTIONS   4

Definition at line 161 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_FILES

#define SEARCH_INDEX_FILES   6

Definition at line 163 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_FUNCTIONS

#define SEARCH_INDEX_FUNCTIONS   7

Definition at line 164 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_GROUPS

#define SEARCH_INDEX_GROUPS   18

Definition at line 175 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_INTERFACES

#define SEARCH_INDEX_INTERFACES   2

Definition at line 159 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_MODULES

#define SEARCH_INDEX_MODULES   21

Definition at line 178 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_NAMESPACES

#define SEARCH_INDEX_NAMESPACES   5

Definition at line 162 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_PAGES

#define SEARCH_INDEX_PAGES   19

Definition at line 176 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_PROPERTIES

#define SEARCH_INDEX_PROPERTIES   14

Definition at line 171 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_RELATED

#define SEARCH_INDEX_RELATED   16

Definition at line 173 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_SEQUENCES

#define SEARCH_INDEX_SEQUENCES   10

Definition at line 167 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_STRUCTS

#define SEARCH_INDEX_STRUCTS   3

Definition at line 160 of file searchindex_js.cpp.

Referenced by createJavaScriptSearchIndex().

◆ SEARCH_INDEX_TYPEDEFS

#define SEARCH_INDEX_TYPEDEFS   9

Definition at line 166 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

◆ SEARCH_INDEX_VARIABLES

#define SEARCH_INDEX_VARIABLES   8

Definition at line 165 of file searchindex_js.cpp.

Referenced by addMemberToSearchIndex().

Function Documentation

◆ addMemberToSearchIndex()

void addMemberToSearchIndex ( const MemberDef * md)
static

Definition at line 213 of file searchindex_js.cpp.

214{
215 bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
216 bool isLinkable = md->isLinkable();
217 const ClassDef *cd=nullptr;
218 const NamespaceDef *nd=nullptr;
219 const FileDef *fd=nullptr;
220 const GroupDef *gd=nullptr;
221 if (isLinkable &&
222 (
223 ((cd=md->getClassDef()) && cd->isLinkable() && !cd->isImplicitTemplateInstance()) ||
224 ((gd=md->getGroupDef()) && gd->isLinkable())
225 )
226 )
227 {
228 const QCString &n = md->name();
229 if (!n.isEmpty())
230 {
231 bool isFriendToHide = hideFriendCompounds &&
232 (md->typeString()=="friend class" ||
233 md->typeString()=="friend struct" ||
234 md->typeString()=="friend union");
235 if (!(md->isFriend() && isFriendToHide))
236 {
238 }
239 if (md->isFunction() || md->isSlot() || md->isSignal())
240 {
242 }
243 else if (md->isVariable())
244 {
246 }
247 else if (md->isSequence())
248 {
250 }
251 else if (md->isDictionary())
252 {
254 }
255 else if (md->isTypedef())
256 {
258 }
259 else if (md->isEnumerate())
260 {
262 }
263 else if (md->isEnumValue())
264 {
266 }
267 else if (md->isProperty())
268 {
270 }
271 else if (md->isEvent())
272 {
274 }
275 else if (md->isRelated() || md->isForeign() ||
276 (md->isFriend() && !isFriendToHide))
277 {
279 }
280 }
281 }
282 else if (isLinkable &&
283 (((nd=md->getNamespaceDef()) && nd->isLinkable()) ||
284 ((fd=md->getFileDef()) && fd->isLinkable())
285 )
286 )
287 {
288 const QCString &n = md->name();
289 if (!n.isEmpty())
290 {
292
293 if (md->isFunction())
294 {
296 }
297 else if (md->isVariable())
298 {
300 }
301 else if (md->isSequence())
302 {
304 }
305 else if (md->isDictionary())
306 {
308 }
309 else if (md->isTypedef())
310 {
312 }
313 else if (md->isEnumerate())
314 {
316 }
317 else if (md->isEnumValue())
318 {
320 }
321 else if (md->isDefine())
322 {
324 }
325 }
326 }
327}
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual bool isImplicitTemplateInstance() const =0
virtual bool isLinkable() const =0
virtual const QCString & name() const =0
A model of a file symbol.
Definition filedef.h:99
A model of a group of symbols.
Definition groupdef.h:52
virtual QCString typeString() const =0
virtual bool isSignal() const =0
virtual bool isFriend() const =0
virtual bool isForeign() const =0
virtual bool isRelated() const =0
virtual bool isSequence() const =0
virtual const ClassDef * getClassDef() const =0
virtual GroupDef * getGroupDef()=0
virtual bool isTypedef() const =0
virtual bool isSlot() const =0
virtual const FileDef * getFileDef() const =0
virtual bool isEvent() const =0
virtual bool isFunction() const =0
virtual bool isDictionary() const =0
virtual bool isDefine() const =0
virtual const NamespaceDef * getNamespaceDef() const =0
virtual bool isEnumerate() const =0
virtual bool isVariable() const =0
virtual bool isEnumValue() const =0
virtual bool isProperty() const =0
An abstract interface of a namespace symbol.
This is an alternative implementation of QCString.
Definition qcstring.h:101
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
#define Config_getBool(name)
Definition config.h:33
#define SEARCH_INDEX_TYPEDEFS
#define SEARCH_INDEX_EVENTS
static std::array< SearchIndexInfo, NUM_SEARCH_INDICES > g_searchIndexInfo
#define SEARCH_INDEX_DEFINES
#define SEARCH_INDEX_ENUMS
#define SEARCH_INDEX_DICTIONARIES
#define SEARCH_INDEX_ALL
#define SEARCH_INDEX_SEQUENCES
#define SEARCH_INDEX_PROPERTIES
#define SEARCH_INDEX_ENUMVALUES
#define SEARCH_INDEX_FUNCTIONS
#define SEARCH_INDEX_VARIABLES
#define SEARCH_INDEX_RELATED
Searchable term.

References Config_getBool, g_searchIndexInfo, MemberDef::getClassDef(), MemberDef::getFileDef(), MemberDef::getGroupDef(), MemberDef::getNamespaceDef(), MemberDef::isDefine(), MemberDef::isDictionary(), QCString::isEmpty(), MemberDef::isEnumerate(), MemberDef::isEnumValue(), MemberDef::isEvent(), MemberDef::isForeign(), MemberDef::isFriend(), MemberDef::isFunction(), ClassDef::isImplicitTemplateInstance(), Definition::isLinkable(), MemberDef::isProperty(), MemberDef::isRelated(), MemberDef::isSequence(), MemberDef::isSignal(), MemberDef::isSlot(), MemberDef::isTypedef(), MemberDef::isVariable(), Definition::name(), SEARCH_INDEX_ALL, SEARCH_INDEX_DEFINES, SEARCH_INDEX_DICTIONARIES, SEARCH_INDEX_ENUMS, SEARCH_INDEX_ENUMVALUES, SEARCH_INDEX_EVENTS, SEARCH_INDEX_FUNCTIONS, SEARCH_INDEX_PROPERTIES, SEARCH_INDEX_RELATED, SEARCH_INDEX_SEQUENCES, SEARCH_INDEX_TYPEDEFS, SEARCH_INDEX_VARIABLES, and MemberDef::typeString().

Referenced by addToIndices(), and createJavaScriptSearchIndex().

◆ createJavaScriptSearchIndex()

void createJavaScriptSearchIndex ( )

Definition at line 331 of file searchindex_js.cpp.

332{
333 // index classes
334 for (const auto &cd : *Doxygen::classLinkedMap)
335 {
336 if (cd->isLinkable())
337 {
338 QCString n = cd->localName();
340 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
341 {
342 if (cd->compoundType()==ClassDef::Interface)
343 {
345 }
346 else if (cd->compoundType()==ClassDef::Struct)
347 {
349 }
350 else if (cd->compoundType()==ClassDef::Exception)
351 {
353 }
354 else // cd->compoundType()==ClassDef::Class
355 {
357 }
358 }
359 else // non slice optimization: group all types under classes
360 {
362 }
363 }
364 }
365
366 // index namespaces
367 for (const auto &nd : *Doxygen::namespaceLinkedMap)
368 {
369 if (nd->isLinkable())
370 {
371 QCString n = nd->name();
374 }
375 }
376
377 // index concepts
378 for (const auto &cd : *Doxygen::conceptLinkedMap)
379 {
380 if (cd->isLinkable())
381 {
382 QCString n = cd->localName();
385 }
386 }
387
388 // index modules
389 for (const auto &mod : ModuleManager::instance().modules())
390 {
391 if (mod->isLinkable() && mod->isPrimaryInterface())
392 {
393 QCString n = mod->name();
396 }
397 }
398
399 // index files
400 for (const auto &fn : *Doxygen::inputNameLinkedMap)
401 {
402 for (const auto &fd : *fn)
403 {
404 QCString n = fd->name();
405 if (fd->isLinkable())
406 {
409 }
410 }
411 }
412
413 // index class members
414 {
415 // for each member name
416 for (const auto &mn : *Doxygen::memberNameLinkedMap)
417 {
418 // for each member definition
419 for (const auto &md : *mn)
420 {
421 addMemberToSearchIndex(md.get());
422 }
423 }
424 }
425
426 // index file/namespace members
427 {
428 // for each member name
429 for (const auto &mn : *Doxygen::functionNameLinkedMap)
430 {
431 // for each member definition
432 for (const auto &md : *mn)
433 {
434 addMemberToSearchIndex(md.get());
435 }
436 }
437 }
438
439 // index groups
440 for (const auto &gd : *Doxygen::groupLinkedMap)
441 {
442 if (gd->isLinkable())
443 {
444 QCString title(filterTitle(gd->groupTitle()).str());
445 IntVector tokenIndices;
446 splitSearchTokens(title,tokenIndices);
447 for (int index : tokenIndices)
448 {
449 g_searchIndexInfo[SEARCH_INDEX_ALL].add(SearchTerm(title.mid(index),gd.get()));
450 g_searchIndexInfo[SEARCH_INDEX_GROUPS].add(SearchTerm(title.mid(index),gd.get()));
451 }
452 }
453 }
454
455 // index pages
456 for (const auto &pd : *Doxygen::pageLinkedMap)
457 {
458 if (pd->isLinkable())
459 {
460 QCString title(filterTitle(pd->title()).str());
461 IntVector tokenIndices;
462 splitSearchTokens(title,tokenIndices);
463 for (int index : tokenIndices)
464 {
465 g_searchIndexInfo[SEARCH_INDEX_ALL].add(SearchTerm(title.mid(index),pd.get()));
466 g_searchIndexInfo[SEARCH_INDEX_PAGES].add(SearchTerm(title.mid(index),pd.get()));
467 }
468 }
469 }
470
471 // main page
473 {
474 QCString title(filterTitle(Doxygen::mainPage->title()).str());
475 IntVector tokenIndices;
476 splitSearchTokens(title,tokenIndices);
477 for (int index : tokenIndices)
478 {
481 }
482 }
483
484 // sections
485 const auto &sm = SectionManager::instance();
486 for (const auto &sectionInfo : sm)
487 {
488 if (sectionInfo->level()>0) // level 0 is for page titles
489 {
490 QCString title = filterTitle(sectionInfo->title());
491 IntVector tokenIndices;
492 splitSearchTokens(title,tokenIndices);
493 //printf("split(%s)=(%s) %zu\n",qPrint(sectionInfo->title()),qPrint(title),tokenIndices.size());
494 for (int index : tokenIndices)
495 {
496 g_searchIndexInfo[SEARCH_INDEX_ALL].add(SearchTerm(title.mid(index),sectionInfo.get()));
497 g_searchIndexInfo[SEARCH_INDEX_PAGES].add(SearchTerm(title.mid(index),sectionInfo.get()));
498 }
499 }
500 }
501
502 // sort all lists
503 for (auto &sii : g_searchIndexInfo) // for each index
504 {
505 for (auto &[name,symList] : sii.symbolMap) // for each symbol in the index
506 {
507 // sort the symbols (first on search term, and then on full name)
508 //
509 // `std::stable_sort` is used here due to reproducibility issues
510 // on key collisions
511 // https://github.com/doxygen/doxygen/issues/10445
512 std::stable_sort(symList.begin(),
513 symList.end(),
514 [](const auto &t1,const auto &t2)
515 {
516 int eq = qstricmp_sort(t1.word,t2.word); // search term first
517 return eq==0 ? qstricmp_sort(t1.title,t2.title)<0 : eq<0; // then full title
518 });
519 }
520 }
521}
@ Interface
Definition classdef.h:112
@ Exception
Definition classdef.h:115
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:97
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:100
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:104
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:95
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:112
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:99
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:111
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
static ModuleManager & instance()
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:241
const std::string & str() const
Definition qcstring.h:552
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:179
std::vector< int > IntVector
Definition containers.h:38
static void addMemberToSearchIndex(const MemberDef *md)
#define SEARCH_INDEX_STRUCTS
static void splitSearchTokens(QCString &title, IntVector &indices)
#define SEARCH_INDEX_NAMESPACES
#define SEARCH_INDEX_CONCEPTS
#define SEARCH_INDEX_FILES
#define SEARCH_INDEX_PAGES
#define SEARCH_INDEX_GROUPS
#define SEARCH_INDEX_INTERFACES
#define SEARCH_INDEX_MODULES
#define SEARCH_INDEX_CLASSES
#define SEARCH_INDEX_EXCEPTIONS
QCString filterTitle(const QCString &title)
Definition util.cpp:5650

References addMemberToSearchIndex(), Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Config_getBool, ClassDef::Exception, filterTitle(), Doxygen::functionNameLinkedMap, g_searchIndexInfo, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), SectionManager::instance(), ClassDef::Interface, Doxygen::mainPage, Doxygen::memberNameLinkedMap, QCString::mid(), Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, SEARCH_INDEX_ALL, SEARCH_INDEX_CLASSES, SEARCH_INDEX_CONCEPTS, SEARCH_INDEX_EXCEPTIONS, SEARCH_INDEX_FILES, SEARCH_INDEX_GROUPS, SEARCH_INDEX_INTERFACES, SEARCH_INDEX_MODULES, SEARCH_INDEX_NAMESPACES, SEARCH_INDEX_PAGES, SEARCH_INDEX_STRUCTS, splitSearchTokens(), QCString::str(), and ClassDef::Struct.

Referenced by generateOutput().

◆ getSearchIndices()

const std::array< SearchIndexInfo, NUM_SEARCH_INDICES > & getSearchIndices ( )

Definition at line 867 of file searchindex_js.cpp.

868{
869 return g_searchIndexInfo;
870}

References g_searchIndexInfo.

◆ splitSearchTokens()

void splitSearchTokens ( QCString & title,
IntVector & indices )
static

helper function to simplify the given title string, and fill a list of start positions for the start of each word in the simplified title string.

Definition at line 89 of file searchindex_js.cpp.

90{
91 if (title.isEmpty()) return;
92
93 // simplify title to contain only words with single space as separator
94 size_t di=0;
95 bool lastIsSpace=true;
96 for (size_t si=0; si<title.length(); si++)
97 {
98 char c = title.at(si);
99 if (c=='@' || c=='\\') // skip over special commands
100 {
101 title.at(di)=' ';
102 if (si<title.length()-1)
103 {
104 c = title.at(++si);
105 while (si<title.length() && (isId(c) || c==':')) c = title.at(++si);
106 --si;
107 }
108 }
109 else if (c=='<') // skip over html tags
110 {
111 if (si<title.length()-1)
112 {
113 for (size_t tsi = si; tsi<title.length(); ++tsi)
114 {
115 if (title.at(tsi)=='>')
116 {
117 si=tsi;
118 break;
119 }
120 }
121 }
122 }
123 else if (isId(c) || c==':') // add "word" character
124 {
125 title.at(di)=c;
126 di++;
127 lastIsSpace=false;
128 }
129 else if (!lastIsSpace) // add one separator as space
130 {
131 title.at(di)=' ';
132 di++;
133 lastIsSpace=true;
134 }
135 }
136 if (di>0 && title.at(di-1)==' ') di--; // strip trailing whitespace
137 title.resize(di);
138
139 // create a list of start positions within title for
140 // each unique word in order of appearance
141 int p=0,i=0;
142 while ((i=title.find(' ',p))!=-1)
143 {
144 std::string word = title.mid(p,i-p).str();
145 indices.push_back(p);
146 p = i+1;
147 }
148 if (p<static_cast<int>(title.length()))
149 {
150 std::string word = title.mid(p).str();
151 indices.push_back(p);
152 }
153}
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:166
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:593
void resize(size_t newlen)
Definition qcstring.h:180
bool isId(int c)
Definition util.h:256

References QCString::at(), QCString::find(), QCString::isEmpty(), isId(), QCString::length(), QCString::mid(), QCString::resize(), and QCString::str().

Referenced by createJavaScriptSearchIndex().

◆ writeJavascriptSearchData()

void writeJavascriptSearchData ( const QCString & searchDirName)
static

Definition at line 523 of file searchindex_js.cpp.

524{
525 std::ofstream t = Portable::openOutputStream(searchDirName+"/searchdata.js");
526 if (t.is_open())
527 {
528 t << "var indexSectionsWithContent =\n";
529 t << "{\n";
530 int j=0;
531 for (const auto &sii : g_searchIndexInfo)
532 {
533 if (!sii.symbolMap.empty())
534 {
535 if (j>0) t << ",\n";
536 t << " " << j << ": \"";
537
538 std::string previous_letter; // start with value that does not exist in the map
539 for (const auto &[letter,list] : sii.symbolMap)
540 {
541 if (letter != previous_letter)
542 {
543 if ( letter == "\"" ) t << "\\"; // add escape for backslash
544 t << letter;
545 previous_letter = letter;
546 }
547 }
548 t << "\"";
549 j++;
550 }
551 }
552 if (j>0) t << "\n";
553 t << "};\n\n";
554 t << "var indexSectionNames =\n";
555 t << "{\n";
556 j=0;
557 for (const auto &sii : g_searchIndexInfo)
558 {
559 if (!sii.symbolMap.empty())
560 {
561 if (j>0) t << ",\n";
562 t << " " << j << ": \"" << convertToJSString(sii.name,true,false) << "\"";
563 j++;
564 }
565 }
566 if (j>0) t << "\n";
567 t << "};\n\n";
568 t << "var indexSectionLabels =\n";
569 t << "{\n";
570 j=0;
571 for (const auto &sii : g_searchIndexInfo)
572 {
573 if (!sii.symbolMap.empty())
574 {
575 if (j>0) t << ",\n";
576 t << " " << j << ": \"" << convertToJSString(convertToXML(sii.getText()),true,false) << "\"";
577 j++;
578 }
579 }
580 if (j>0) t << "\n";
581 t << "};\n\n";
582 }
583}
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:648
QCString convertToJSString(const QCString &s, bool keepEntities, bool singleQuotes)
Definition util.cpp:4044
QCString convertToXML(const QCString &s, bool keepEntities)
Definition util.cpp:3933

References convertToJSString(), convertToXML(), g_searchIndexInfo, and Portable::openOutputStream().

Referenced by writeJavaScriptSearchIndex().

◆ writeJavaScriptSearchIndex()

void writeJavaScriptSearchIndex ( )

Definition at line 796 of file searchindex_js.cpp.

797{
798 // write index files
799 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
800
801 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
802 if (numThreads>1) // multi threaded version
803 {
804 ThreadPool threadPool(numThreads);
805 std::vector< std::future<int> > results;
806 for (auto &sii : g_searchIndexInfo)
807 {
808 int p=0;
809 for (const auto &[letter,symList] : sii.symbolMap)
810 {
811 QCString baseName;
812 baseName.sprintf("%s_%x",sii.name.data(),p);
813 QCString dataFileName = searchDirName + "/"+baseName+".js";
814 auto &list = symList;
815 auto processFile = [p,baseName,dataFileName,&list]()
816 {
817 writeJavasScriptSearchDataPage(baseName,dataFileName,list);
818 return p;
819 };
820 results.emplace_back(threadPool.queue(processFile));
821 p++;
822 }
823 }
824 // wait for the results
825 for (auto &f : results) f.get();
826 }
827 else // single threaded version
828 {
829 for (auto &sii : g_searchIndexInfo)
830 {
831 int p=0;
832 for (const auto &[letter,symList] : sii.symbolMap)
833 {
834 QCString baseName;
835 baseName.sprintf("%s_%x",sii.name.data(),p);
836 QCString dataFileName = searchDirName + "/"+baseName+".js";
837 writeJavasScriptSearchDataPage(baseName,dataFileName,symList);
838 p++;
839 }
840 }
841 }
842
843 writeJavascriptSearchData(searchDirName);
844 auto &mgr = ResourceMgr::instance();
845 {
846 std::ofstream fn = Portable::openOutputStream(searchDirName+"/search.js");
847 if (fn.is_open())
848 {
849 TextStream t(&fn);
850 t << substitute(mgr.getAsString("search.js"),"$PROJECTID",getProjectId());
851 }
852 }
853
854 Doxygen::indexList->addStyleSheetFile("search/searchdata.js");
855 Doxygen::indexList->addStyleSheetFile("search/search.js");
856}
static IndexList * indexList
Definition doxygen.h:132
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
static ResourceMgr & instance()
Returns the one and only instance of this class.
Text streaming class that buffers data.
Definition textstream.h:36
Class managing a pool of worker threads.
Definition threadpool.h:48
#define Config_getInt(name)
Definition config.h:34
#define Config_getString(name)
Definition config.h:32
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:571
static void writeJavasScriptSearchDataPage(const QCString &baseName, const QCString &dataFileName, const SearchIndexList &list)
static void writeJavascriptSearchData(const QCString &searchDirName)
QCString getProjectId()
Definition util.cpp:6829

References Config_getInt, Config_getString, g_searchIndexInfo, getProjectId(), Doxygen::indexList, ResourceMgr::instance(), Portable::openOutputStream(), ThreadPool::queue(), QCString::sprintf(), substitute(), writeJavascriptSearchData(), and writeJavasScriptSearchDataPage().

Referenced by generateOutput().

◆ writeJavasScriptSearchDataPage()

void writeJavasScriptSearchDataPage ( const QCString & baseName,
const QCString & dataFileName,
const SearchIndexList & list )
static

Definition at line 585 of file searchindex_js.cpp.

586{
587 auto isDef = [](const SearchTerm::LinkInfo &info)
588 {
589 return std::holds_alternative<const Definition *>(info);
590 };
591 auto getDef = [&isDef](const SearchTerm::LinkInfo &info)
592 {
593 return isDef(info) ? std::get<const Definition *>(info) : nullptr;
594 };
595 auto isSection = [](const SearchTerm::LinkInfo &info)
596 {
597 return std::holds_alternative<const SectionInfo *>(info);
598 };
599 auto getSection = [&isSection](const SearchTerm::LinkInfo &info)
600 {
601 return isSection(info) ? std::get<const SectionInfo *>(info) : nullptr;
602 };
603
604 int cnt = 0;
605 std::ofstream ti = Portable::openOutputStream(dataFileName);
606 if (!ti.is_open())
607 {
608 err("Failed to open file '{}' for writing...\n",dataFileName);
609 return;
610 }
611
612 ti << "var searchData=\n";
613 // format
614 // searchData[] = array of items
615 // searchData[x][0] = id
616 // searchData[x][1] = [ name + child1 + child2 + .. ]
617 // searchData[x][1][0] = name as shown
618 // searchData[x][1][y+1] = info for child y
619 // searchData[x][1][y+1][0] = url
620 // searchData[x][1][y+1][1] = 1 => target="_parent"
621 // searchData[x][1][y+1][1] = 0 => target="_blank"
622 // searchData[x][1][y+1][2] = scope
623
624 ti << "[\n";
625 bool firstEntry=TRUE;
626
627 int childCount=0;
628 QCString lastWord;
629 const Definition *prevScope = nullptr;
630 for (auto it = list.begin(); it!=list.end();)
631 {
632 const SearchTerm &term = *it;
633 const SearchTerm::LinkInfo info = term.info;
634 const Definition *d = getDef(info);
635 const SectionInfo *si = getSection(info);
636 assert(d || si); // either d or si should be valid
637 QCString word = term.word;
638 QCString id = term.termEncoded();
639 ++it;
640 const Definition *scope = d ? d->getOuterScope() : nullptr;
641 const SearchTerm::LinkInfo next = it!=list.end() ? it->info : SearchTerm::LinkInfo();
642 const Definition *nextScope = isDef(next) ? getDef(next)->getOuterScope() : nullptr;
643 const MemberDef *md = toMemberDef(d);
644 QCString anchor = d ? d->anchor() : si ? si->label() : QCString();
645
646 if (word!=lastWord) // this item has a different search word
647 {
648 if (!firstEntry)
649 {
650 ti << "]]]";
651 ti << ",\n";
652 }
653 firstEntry=FALSE;
654 ti << " ['" << id << "_" << cnt++ << "',['";
655 if (next==SearchTerm::LinkInfo() || it->word!=word) // unique result, show title
656 {
657 ti << convertToJSString(convertToXML(term.title),true,true);
658 }
659 else // multiple results, show matching word only, expanded list will show title
660 {
661 ti << convertToJSString(convertToXML(term.word),true,true);
662 }
663 ti << "',[";
664 childCount=0;
665 prevScope=nullptr;
666 }
667
668 if (childCount>0)
669 {
670 ti << "],[";
671 }
672 QCString fn = d ? d->getOutputFileBase() : si ? si->fileName() : QCString();
673 QCString ref = d ? d->getReference() : si ? si->ref() : QCString();
675 QCString extRef = externalRef("../",ref,true)+fn;
676 if (!anchor.isEmpty())
677 {
678 extRef+="#"+anchor;
679 }
680 ti << "'" << convertToJSString(extRef,true,true) << "',";
681
682 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
683 if (!extLinksInWindow || ref.isEmpty())
684 {
685 ti << "1,";
686 }
687 else
688 {
689 ti << "0,";
690 }
691
692 if (lastWord!=word && (next==SearchTerm::LinkInfo() || it->word!=word)) // unique search result
693 {
694 if (d && d->getOuterScope()!=Doxygen::globalScope)
695 {
696 ti << "'" << convertToJSString(convertToXML(d->getOuterScope()->name()),true,true) << "'";
697 }
698 else if (md)
699 {
700 const FileDef *fd = md->getBodyDef();
701 if (fd==nullptr) fd = md->getFileDef();
702 if (fd)
703 {
704 ti << "'" << convertToJSString(convertToXML(fd->localName()),true,true) << "'";
705 }
706 }
707 else
708 {
709 ti << "''";
710 }
711 }
712 else // multiple entries with the same name
713 {
714 bool found=FALSE;
715 bool overloadedFunction = ((prevScope!=nullptr && scope==prevScope) || (scope && scope==nextScope)) &&
716 md && md->isCallable();
718 if (md) prefix=convertToXML(md->localName());
719 if (overloadedFunction) // overloaded member function
720 {
722 // show argument list to disambiguate overloaded functions
723 }
724 else if (md && md->isCallable()) // unique member function
725 {
726 prefix+="()"; // only to show it is a callable symbol
727 }
728 QCString name;
729 if (d)
730 {
731 switch (d->definitionType())
732 {
733 case Definition::TypeClass: name = convertToXML((toClassDef(d))->displayName()); found=true; break;
734 case Definition::TypeNamespace: name = convertToXML((toNamespaceDef(d))->displayName()); found=true; break;
735 case Definition::TypeModule: name = convertToXML(d->name()+" "+theTranslator->trModule(false,true)); found=true; break;
736 case Definition::TypePage: name = convertToXML(filterTitle(toPageDef(d)->title())); found=true; break;
737 case Definition::TypeGroup: name = convertToXML(filterTitle(toGroupDef(d)->groupTitle())); found=true; break;
738 default:
739 if (scope==nullptr || scope==Doxygen::globalScope) // in global scope
740 {
741 if (md)
742 {
743 const FileDef *fd = md->getBodyDef();
744 if (fd==nullptr) fd = md->resolveAlias()->getFileDef();
745 if (fd)
746 {
747 if (!prefix.isEmpty()) prefix+=":&#160;";
748 name = prefix + convertToXML(fd->localName());
749 found = true;
750 }
751 }
752 }
753 else if (md && (md->resolveAlias()->getClassDef() || md->resolveAlias()->getNamespaceDef()))
754 // member in class or namespace scope
755 {
756 SrcLangExt lang = md->getLanguage();
758 name = convertToXML(d->getOuterScope()->qualifiedName()) + sep + prefix;
759 found = true;
760 }
761 else if (scope) // some thing else? -> show scope
762 {
763 name = prefix + convertToXML(scope->name());
764 found = true;
765 }
766 break;
767 }
768 }
769 else if (si)
770 {
771 name = parseCommentAsHtml(si->definition(),nullptr,si->title(),si->fileName(),si->lineNr());
772 name = convertToXML(name);
773 found = true;
774 }
775 if (!found) // fallback
776 {
777 name = prefix + "("+theTranslator->trGlobalNamespace()+")";
778 }
779
780 ti << "'" << convertToJSString(name,true,true) << "'";
781
782 prevScope = scope;
783 childCount++;
784 }
785 lastWord = word;
786 }
787 if (!firstEntry)
788 {
789 ti << "]]]\n";
790 }
791 ti << "];\n";
792 Doxygen::indexList->addStyleSheetFile(("search/"+baseName+".js").data());
793}
constexpr auto prefix
Definition anchor.cpp:44
The common base class of all entity definitions found in the sources.
Definition definition.h:77
virtual const QCString & localName() const =0
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual DefType definitionType() const =0
virtual QCString anchor() const =0
virtual const FileDef * getBodyDef() const =0
virtual QCString getReference() const =0
virtual QCString qualifiedName() const =0
virtual QCString getOutputFileBase() const =0
virtual Definition * getOuterScope() const =0
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
virtual MemberDef * resolveAlias()=0
virtual QCString argsString() const =0
virtual bool isCallable() const =0
class that provide information about a section.
Definition section.h:58
QCString label() const
Definition section.h:69
Definition * definition() const
Definition section.h:77
QCString ref() const
Definition section.h:72
QCString fileName() const
Definition section.h:74
int lineNr() const
Definition section.h:73
QCString title() const
Definition section.h:70
ClassDef * toClassDef(Definition *d)
GroupDef * toGroupDef(Definition *d)
Translator * theTranslator
Definition language.cpp:71
MemberDef * toMemberDef(Definition *d)
#define err(fmt,...)
Definition message.h:127
#define term(fmt,...)
Definition message.h:137
NamespaceDef * toNamespaceDef(Definition *d)
PageDef * toPageDef(Definition *d)
Definition pagedef.cpp:502
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
std::variant< std::monostate, const Definition *, const SectionInfo * > LinkInfo
SrcLangExt
Definition types.h:207
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:5793
QCString parseCommentAsHtml(const Definition *scope, const MemberDef *member, const QCString &doc, const QCString &fileName, int lineNr)
Definition util.cpp:5445
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:5915
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4942

References addHtmlExtensionIfMissing(), Definition::anchor(), MemberDef::argsString(), Config_getBool, convertToJSString(), convertToXML(), SectionInfo::definition(), Definition::definitionType(), err, externalRef(), FALSE, SectionInfo::fileName(), filterTitle(), Definition::getBodyDef(), MemberDef::getClassDef(), MemberDef::getFileDef(), Definition::getLanguage(), getLanguageSpecificSeparator(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), Definition::getOutputFileBase(), Definition::getReference(), Doxygen::globalScope, Doxygen::indexList, MemberDef::isCallable(), QCString::isEmpty(), SectionInfo::label(), SectionInfo::lineNr(), Definition::localName(), Definition::name(), Portable::openOutputStream(), parseCommentAsHtml(), prefix, Definition::qualifiedName(), SectionInfo::ref(), MemberDef::resolveAlias(), term, theTranslator, SectionInfo::title(), toClassDef(), toGroupDef(), toMemberDef(), toNamespaceDef(), toPageDef(), TRUE, Definition::TypeClass, Definition::TypeGroup, Definition::TypeModule, Definition::TypeNamespace, and Definition::TypePage.

Referenced by writeJavaScriptSearchIndex().

Variable Documentation

◆ g_searchIndexInfo

std::array<SearchIndexInfo,NUM_SEARCH_INDICES> g_searchIndexInfo
static

Definition at line 180 of file searchindex_js.cpp.

180 { {
181 // index name getText symbolList
182 { /* SEARCH_INDEX_ALL */ "all" , []() { return theTranslator->trAll(); }, {} },
183 { /* SEARCH_INDEX_CLASSES */ "classes" , []() { return theTranslator->trClasses(); }, {} },
184 { /* SEARCH_INDEX_INTERFACES */ "interfaces" , []() { return theTranslator->trSliceInterfaces(); }, {} },
185 { /* SEARCH_INDEX_STRUCTS */ "structs" , []() { return theTranslator->trStructs(); }, {} },
186 { /* SEARCH_INDEX_EXCEPTIONS */ "exceptions" , []() { return theTranslator->trExceptions(); }, {} },
187 { /* SEARCH_INDEX_NAMESPACES */ "namespaces" , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
188 theTranslator->trModules() :
189 theTranslator->trNamespace(TRUE,FALSE); }, {} },
190 { /* SEARCH_INDEX_FILES */ "files" , []() { return theTranslator->trFile(TRUE,FALSE); }, {} },
191 { /* SEARCH_INDEX_FUNCTIONS */ "functions" , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
192 theTranslator->trOperations() :
193 theTranslator->trFunctions(); }, {} },
194 { /* SEARCH_INDEX_VARIABLES */ "variables" , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
195 theTranslator->trConstants() :
196 theTranslator->trVariables(); }, {} },
197 { /* SEARCH_INDEX_TYPEDEFS */ "typedefs" , []() { return theTranslator->trTypedefs(); }, {} },
198 { /* SEARCH_INDEX_SEQUENCES */ "sequences" , []() { return theTranslator->trSequences(); }, {} },
199 { /* SEARCH_INDEX_DICTIONARIES */ "dictionaries", []() { return theTranslator->trDictionaries(); }, {} },
200 { /* SEARCH_INDEX_ENUMS */ "enums" , []() { return theTranslator->trEnumerations(); }, {} },
201 { /* SEARCH_INDEX_ENUMVALUES */ "enumvalues" , []() { return theTranslator->trEnumerationValues(); }, {} },
202 { /* SEARCH_INDEX_PROPERTIES */ "properties" , []() { return theTranslator->trProperties(); }, {} },
203 { /* SEARCH_INDEX_EVENTS */ "events" , []() { return theTranslator->trEvents(); }, {} },
204 { /* SEARCH_INDEX_RELATED */ "related" , []() { return theTranslator->trFriends(); }, {} },
205 { /* SEARCH_INDEX_DEFINES */ "defines" , []() { return theTranslator->trDefines(); }, {} },
206 { /* SEARCH_INDEX_GROUPS */ "groups" , []() { return theTranslator->trGroup(TRUE,FALSE); }, {} },
207 { /* SEARCH_INDEX_PAGES */ "pages" , []() { return theTranslator->trPage(TRUE,FALSE); }, {} },
208 { /* SEARCH_INDEX_CONCEPTS */ "concepts" , []() { return theTranslator->trConcept(true,false); }, {} },
209 { /* SEARCH_INDEX_MODULES */ "modules" , []() { return theTranslator->trModule(true,false); }, {} }
210} };

Referenced by addMemberToSearchIndex(), createJavaScriptSearchIndex(), getSearchIndices(), writeJavascriptSearchData(), and writeJavaScriptSearchIndex().