33 #if ALIB_DEBUG_CRITICAL_SECTIONS
58 backwardsParser= backwardsParser.
Substring(0, dotPos);
63 #if ALIB_DEBUG_CRITICAL_SECTIONS
88 while (entityIterator.
IsValid()) {
90 entityIterator.
Next();
96 int expectedFileMapSize = 0;
97 int expectedAnchorMapSize= 0;
115 fileMap .Reserve(expectedFileMapSize , lang::ValueReference::Absolute );
116 anchorMap .Reserve(expectedAnchorMapSize , lang::ValueReference::Absolute );
122 while (entityIterator.
IsValid()) {
135 auto result=
anchorMap.InsertIfNotExistent(
137 entityIterator.
Node().Export() );
138 if ( !result.second ) {
139 Lox_Info(
"In HTML file {!Q}, the anchor {!Q} already exists. (Skipped)\n"
140 " Previous anchor: {}:{} Kind: {:10} FileName: {}\n"
141 " New anchor: {}:{} Kind: {:10} FileName: {}"
145 ,
ImportNode(result.first.Mapped()).HTMLFile()
152 auto result=
anchorMap.InsertIfNotExistent(
154 entityIterator.
Node().Export() );
155 if ( !result.second ) {
156 Lox_Warning(
"In HTML file {!Q}, the DocAnchor {!Q} already exists. (Skipped)\n"
157 " Previous anchor: {}:{} Kind: {:10} FileName: {}\n"
158 " New anchor: {}:{} Kind: {:10} FileName: {}"
162 ,
ImportNode(result.first.Mapped()).HTMLFile()
170 if ( scu->SpecializationArgs ) {
178 "Parse error (only specialization args should appear in the name and those "
179 "have been removed already.")
185 || mf->Qualifiers.IsNotEmpty() ) {
193 entityIterator.
Next();
197 "Expected size of entityMap {} != {} real size.",
Size() ,
entityMap.Size())
200 "Expected size of fileMap {} != {} real size.", expectedFileMapSize ,
fileMap.Size())
203 "Expected size of anchorMap {} < {} real size.", expectedAnchorMapSize,
anchorMap.Size())
211 auto it=
fileMap.Find(htmlFile.Name());
213 Lox_Warning(
"HTML-File {!Q} not found in index: ", htmlFile.Name() )
214 return CursorHandle(0);
228 buffer.
Delete(startPos, 1);
242 auto parent= entry.
Parent();
243 while (!parent.IsRoot()) {
244 pathNameStack[stackSize++]= parent.Name();
245 parent= parent.Parent();
257 pathNameStack[stackSize++]= tagFileName;
260 pathNameStack[stackSize++]= tagFileName.
Substring(dotPos + 1);
261 tagFileName= tagFileName.
Substring(0, dotPos);
267 int stackPointer= stackSize-1;
271 pos= pathNameStack[stackPointer].
IndexOf<
CHK, lang::Case::Ignore>(
272 searchLink.
Hint(hintNo), pos );
280 if ( --stackPointer < 0)
290 range.first!=range.second ;
304 bool foundParentScope=
true;
305 for (
int i= xLink.
ScopeSize() - 1; i>= 0 ; --i) {
307 if ( !parent.IsValid() || !parent.Name().Equals(componentName) ) {
308 foundParentScope=
false;
314 if (!foundParentScope)
335 ,
false,
false,
false,
false,
false,
false,
false
346 bool isIndirectByInheritance,
bool isIndirectByTypeDef ) {
361 if (var->Subscript.IndexOf(xLink.
Subscript) < 0) {
375 if (!rec->TemplateArgs) {
396 if (!rec->SpecializationArgs) {
411 bool skipThis=
false;
413 for (
auto& it : xLink.
Targets ) {
417 while (parent.IsValid()) {
418 if (parent == node.
Parent()) {
427 if ( skipThis )
return;
431 std::erase_if(xLink.
Targets, [&](
const auto& it) {
432 if ( !it.Node.IsA(Target::Typedef) )
434 Node parent = node.Parent();
435 while (parent.IsValid()) {
436 if ( parent == it.Node.Parent())
438 parent= parent.Parent();
446 std::erase_if(xLink.Targets, [&,node](
const auto& it) {
447 Node parent = it.Node.Parent();
448 while (parent.IsValid()) {
451 parent = parent.Parent();
457 for (
auto& it : xLink.Targets) {
458 Node parent = node.Parent();
459 while (parent.IsValid()) {
460 if (parent == it.Node) {
464 parent= parent.Parent();
468 if (skipThis)
return;
473 if ( target->IsA(Target::Function | Target::Macro) ) {
475 if ( target->IsA(Target::Function) )
476 funcArgMatch= Target::FunctionArguments::MATCH( xLink.Args,
477 Cast<TGTFunction,NC>(target)->Args );
482 auto* targetArgs= Cast<TGTMacro,NC>(target)->Args;
483 if ( xLink.Args && !targetArgs)
486 funcArgMatch= Target::FunctionArguments::MATCH(xLink.Args, targetArgs);
489 if ( funcArgMatch == 0)
493 bool hasBetterMatch=
false;
494 std::erase_if(xLink.Targets, [&](
const auto& it) {
495 if ( it.FunctionArgumentMatch < funcArgMatch)
497 if ( it.FunctionArgumentMatch > funcArgMatch)
498 hasBetterMatch= true;
507 bool qualifiersHintMatch=
false;
508 if (xLink.Qualifiers.IsNotNull()) {
509 if ( !target->IsA(Target::Function)
510 || Cast<TGTFunction,NC>(target)->Qualifiers.IndexOf(xLink.Qualifiers) < 0)
512 qualifiersHintMatch=
true;
515 std::erase_if(xLink.Targets, [&,node](
const auto& it) {
516 return it.Node.IsA(Target::Function)
517 && Cast<TGTFunction,NC>(it.Node)->Qualifiers.IsEmpty();
521 if (
auto* func= Cast<TGTFunction>(target); func ) {
522 if ( func->Qualifiers.IsNotEmpty()) {
523 bool hasBetterMatch=
false;
524 for (
auto& it : xLink.Targets) {
525 if (
auto* f= Cast<TGTFunction>(it.Node); f ) {
526 hasBetterMatch= f->Qualifiers.IsEmpty();
536 std::erase_if(xLink.Targets, [&,node](
const auto& it) {
537 return it.Node.IsA(Target::Function)
538 && Cast<TGTFunction,NC>(it.Node)->Qualifiers.IsNotEmpty();
546 std::erase_if(xLink.Targets, [&](
const auto& it) {
549 if ( it.Node.Parent() == node.Parent() ) {
550 if (target->IsA(Target::RECORD)) {
551 if ( it.Node.IsA(Target::Function)
552 && xLink.Args==nullptr)
563 xLink.Targets.push_back({ node
566 , target->IsA(Target::MEMBER) ? Cast<TGTMember ,NC>(target)->Anchor
567 : target->IsA(Target::DocAnchor) ? Cast<TGTDocAnchor,NC>(target)->Name
571 ,isIndirectByInheritance
594 results.reserve(1024/
sizeof(CursorHandle) - 4);
596 for (
auto range=
entityMap.EqualRange( xLink.
Name()) ; range.first!=range.second ; ++range.first)
597 results.push_back(range.first->second);
600 for (
auto handle : results ) {
617 bool scopeMatches=
true;
623 int fileNameComponentIdx= -1;
624 for (
int i= xLink.
ScopeSize() - 1; i>= 0 ; --i) {
627 if ( templatePos > 0 )
628 componentName= componentName.
Substring(0, templatePos);
630 if ( !parent.IsRoot() ) {
631 if ( !componentName.
Equals( parent.Name() ) ) {
645 if ( scopeMatches && xLink.
IsLocal)
646 scopeMatches &= (parent.Export().value == xLink.
LocalLinkEntity.value);
668 for (
auto cursorHandle : results ) {
674 if (inheritanceParent == node.
Parent())
681 if (typeDefTarget == node.
Parent() )
695 bool hasNonGroupResults=
false;
696 for (
auto& it : targets)
697 if ( it.Node.Parent().IsRoot()
699 hasNonGroupResults=
true;
702 if ( hasNonGroupResults)
703 std::erase_if(targets, [](
const auto& it) {
704 return !it.Node.Parent().IsRoot()
#define ALIB_LOCK_SHARED_WITH(lock)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define ALIB_LOCK_WITH(lock)
void Initialize(CursorType startNode, lang::Inclusion includeStartNode)
void SetPathGeneration(lang::Switch pathGeneration)
constexpr CharacterType Separator() const noexcept
void ConstructRootValue(TArgs &&... args)
TAString & Delete(integer regionStart, integer regionLength=MAX_LEN)
integer SearchAndReplace(const TString< TChar > &needle, const TString< TChar > &replacement, integer startIdx=0, integer maxReplacements=strings::MAX_LEN, lang::Case sensitivity=lang::Case::Sensitive, integer endIdx=strings::MAX_LEN)
constexpr integer Length() const
TChar CharAt(integer idx) const
integer IndexOf(const TString &needle, integer startIdx=0, integer endIdx=strings::MAX_LEN) const
integer LastIndexOf(TChar needle, integer startIndex=MAX_LEN) const
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
bool Equals(const TString< TChar > &rhs) const
TSubstring & TrimEnd(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
alib::system::PathString FilePath
The path to the doxygenTagFile.
ConstCursorHandle GetHTMLFileEntity(const alib::File &htmlFile)
alib::MonoAllocator ma
The allocator used for the parent #"StringTree" and for the hashtable in the field map.
void dedupGroupEntries(alib::StdVectorMA< SearchResult > &targets)
void Search(XLink &xLink)
alib::Ticks::Duration LoadTime
A timestamp set when loaded.
alib::containers::HashMap< alib::MonoAllocator, const alib::String &, CursorHandle, std::hash< alib::String >, std::equal_to< const alib::String >, alib::lang::Caching::Disabled, alib::Recycling::None > fileMap
Maps HTML-files found to their corresponding tree nodes.
const alib::String & BaseURL
The URL of the HTML-output created with this tag-file.
int fileNameDotComponentsSize
The number of components in fileNameDotComponents.
alib::system::PathString FileName
The base name component of FilePath.
void Load()
Loads the tag-file and creates the index.
void ReplaceToTreeSeparator(alib::AString &buffer, Target::Kinds kind, alib::integer startPos=0)
alib::containers::HashMap< alib::MonoAllocator, AnchorKey, CursorHandle, AnchorKey::Hash, std::equal_to< AnchorKey >, alib::lang::Caching::Enabled > anchorMap
Maps HTML-files found to their corresponding tree nodes.
void ReplaceFromTreeSeparator(alib::AString &buffer, Target::Kinds kind, alib::integer startPos=0)
void searchFile(XLink &xLink)
void evaluateEntity(XLink &xLink, Node node, bool isIndirectByInheritance, bool isIndirectByTypeDef)
void loadTagFile()
Loads the tag-file. This is called by Load.
Node ImportNode(CursorHandle handle)
alib::containers::HashMap< alib::MonoAllocator, alib::String, CursorHandle > entityMap
bool ScopeHintMatch(Node entry, XLink &searchLink)
Target::KindStats KindStats
Statistics on the number of entities found per kind in #"Target::Kinds;2".
StringTree TreeType
The type of the string tree that holds the tag-file.
Index(const alib::system::PathString &tagFilePath, const alib::String &baseURL, bool isMainTagFile)
alib::String fileNameDotComponents[10]
static Target * GetRootNodeTarget()
bool IsA(Kinds aKind) const
alib::String HTMLFile
The HTML file that this target links to (or into).
Kinds
Enumerates the kinds of compounds found in a the Doxygen tagfile.
@ Struct
Denotes a struct.
@ Function
Denotes a namespace- or member-function.
@ Variable
Denotes a namespace- or member-variable.
@ UNSPECIFIED
Used with the field #"XLink::KindSpec;2".
@ Typedef
Denotes a type definition.
@ File
Denotes a source file.
@ EnumElement
Denotes an enumeration element.
@ Concept
Denotes a C++20 concept.
@ Macro
Denotes a preprocessor definition.
@ Dir
Denotes a source folder.
@ Enumeration
Denotes an enumeration.
@ FILEPATH_COMPONENT
A node of a file path (not a doxygen kind).
@ Namespace
Denotes a namespace.
@ DocAnchor
Denotes a preprocessor definition.
@ RECORD
Mask to identify records types.
int LineNo
The line number in the Doxygen tag-file where this entity is defined.
alib::String & Name() const
Index::Node DidYouMeanTemplateType
alib::StdVectorMA< Index::Node > DidYouMeanSameName
A list of target nodes with the same name.
alib::StdVectorMA< Index::Node > DidYouMeanNotATemplate
A list of entries that are not templates, while a template type was searched.
alib::ListMA< Index::Node > * TypeDefinitionTargets
const alib::String & Scope(int n) const
Target::FunctionArguments * Args
Function arguments provided with the source XLink.
const alib::String & Hint(int n) const
Target::TemplateArguments * TemplateArgs
alib::StdVectorMA< Index::SearchResult > Targets
alib::ListMA< Index::Node > * BaseTypes
alib::String Subscript
A variable subscript provided by the source XLink.
alib::StdVectorMA< Index::Node > DidYouMeanSpecializations
Index::ConstCursorHandle LocalLinkEntity
XLink * GetLinkToParent()
alib::StdVectorMA< Index::Node > DidYouMeanVariable
A list of entries that are variables, while the XLink's subscript does not match.
Target::Kinds KindSpec
Function arguments provided with the source XLink.
Target::TemplateArguments * SpecializationArgs
alib::StdVectorMA< Index::Node > DidYouMeanFunctionOverload
bool NoIndirectionWarning
strings::TString< PathCharType > PathString
constexpr PathCharType DIRECTORY_SEPARATOR
monomem::TLocalAllocator< 1 > LocalAllocator1K
constexpr const String EMPTY_STRING
strings::TString< character > String
strings::TSubstring< character > Substring
strings::TAString< character, lang::HeapAllocator > AString
std::vector< T, StdMA< T > > StdVectorMA
containers::StringTreeIterator< TTree > StringTreeIterator
const TGT * Cast(const Index::Node &node)
HashTable< TAllocator, typename NodeKey::ValueDescriptor, typename NodeKey::Hash, typename NodeKey::EqualTo, lang::Caching::Enabled, TRecycling > nodeTable
Index & index
The index to load.
A pod-like struct providing the key for the hash table found in the field #"Index::anchorMap;2".
The cursor type of the #"StringTree".
const alib::String & HTMLFile() const
const Target * Target() const
bool IsA(Target::Kinds kind) const
Target::Kinds Kind() const
Node()=default
Defaulted default constructor. Creates an invalid node.
int Match(TemplateArguments &target)