Doxygen XLinks
by
V: 2511R0
Website: doxygen
Loading...
Searching...
No Matches
xlink.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of \dxl - A doxygen post-processor that allows to define smarter
4/// <b>Doxygen</b>-links.
5///
6/// \emoji :copyright: 2025-2026 A-Worx GmbH, Germany.
7/// Published under \ref mainpage_license "Boost Software License".
8//==================================================================================================
9#ifndef HPP_DXL_XLINK
10#define HPP_DXL_XLINK
11#pragma once
12#include "target.hpp"
13#include "styles.hpp"
14#include "index.hpp"
15#include "ALib.FileTree.H"
16#include "dxl.hpp"
17
18namespace dxl {
19class XLink;
20class DoxygenXLinks;
21
22/// A location of an XLink in a source or HTML file.
23struct Location {
24 alib::filetree::FTFile File; ///< The file's node, either in #"fTreeSources;2" or
25 ///< #"fTreeHTML;2".
26 int Line; ///< The line number of the XLink.
27 int Column; ///< The column in the #Line.
28};
29
30
31/// Entries of a list of XLink instances found in a source file.
32/// Instances represent an XLink to a doxygen #"dxl Target" as given by the user.
34 XLink* XL; ///< The corresponding XLink.
35 int Line; ///< The line number of the XLink.
36 int Column; ///< The column in the #Line.
37};
38
39/// This type is #"FTFile::AttachCustomData;attached" to file tree nodes of source files.
40/// It lists all places of links in the file.
42
43//##################################################################################################
44/// Encapsulates the information given with the links that this whole project was created for.
45/// Instances represent an XLink to a doxygen #"dxl Target" as given by the user.
46//##################################################################################################
47class XLink {
48 public:
49 #if ALIB_DEBUG
50 friend void DbgUnitTests(DoxygenXLinks*);
51 #endif
52
53
54 /// The maximum number of scope hints and parents.
55 static constexpr int MAX_SCOPE_DEPTH= 20;
56
57 /// Possible results when parsing source links.
58 enum class Errors {
59 OK = 0, ///< No error or warning.
60 TooManyParentsRequested = 1, ///< Warning: The display requested more parents to include
61 ///< than available.
62 AnchorHasNoTitle = 2, ///< Warning: An anchor without a title was used without
63 ///< providing a user-defined display string. \dxl inserts
64 ///< the anchor name in this case.
65 InappropriateDisplayTweak= 3, ///< A display tweak was given that is not applicable to the
66 ///< resolved target type.
67
68 WARNINGMARKER = 4, ///< This is a marker-element that separates warnings from
69 ///< Errors.
70
71 Empty = 5, ///< The search string was empty (apart from possible
72 ///< whitespaces).
73 NoTargetNameGiven = 6, ///< No target identifier was given.
74 TooManyScopeHints = 7, ///< Too many scope-hints (words separated with spaces) were
75 ///< given.
76 ScopeTooDeep = 8, ///< The number of nested scope (namespaces/compounds) is too
77 ///< huge.
78 UnknownUnderlyingType = 9, ///< The underlying type requested with '^' was not found.
79 IllegalTargetKind =10, ///< The target kind specification must be "!k " with k being a
80 ///< valid kind identification-character and a space following.
81 LocalLinkWithScopeHints =11, ///< A local XLink (aka the identifier section starts with
82 ///< \c '.') must not have scope hints.
83 ///
84 /// This error occurs with the command line option <c>--doxyfy</c>.
85 /// As explained in the chapter #"dxl_manual_addfeat_doxyfication", certain local links
86 /// cannot be restored back to \b Doxygen's <c>\\ref</c> command if they occur in different
87 /// HTML files.
89
90 /// This error occurs with the command line option <c>--doxyfy</c>.
91 /// It is issued when a local XLink is found in the source-copy to be restored, which has
92 /// not been found in the HTML files. This usually indicates a wrong setup of the
93 /// documentation build steps.
95
96 /// This error occurs with local links that appear in HTML-files that are not found in
97 /// the index (tag-file). For example, if a local link is used in the short description
98 /// of a class and this class then appears in "hierarchy.html"
100
101 };
102
103 /// The mono allocator used to create the members of the class.
105
106 /// The lock protecting the creation phase and as well allocator access.
108
109 protected:
110 /// An array of identifiers listed in the source XLink. The first members of the list are
111 /// 'hints' given by the user separated by spaces. Those hints are used with a substring search
112 /// in a component path.<br>
113 /// The rest of the list represents fully-named parents and finally the component itself.
114 /// The separation and length of the list is given with the fields #scopeHintsSize and
115 /// #scopeSize.
117
118 /// The number of strings in the array #scope that are only hints.
120
121 /// The number of strings in the array #scope. Up to index #scopeHintsSize <c> - 1</c>
122 /// the strings are only hints. The remaining represent full parent paths.
123 int scopeSize =0;
124
125 /// Inner main method of #"AssembleDisplay()".
126 void assembleDisplay();
127
128 public:
129 /// The original source string.
131
132 /// Function arguments provided with the source XLink.
134
135 /// Template arguments provided at the beginning of the source XLink, before path hints and
136 /// the path, optionally introduced by the keyword \c template.
138
139 /// Template arguments provided at the end of the source XLink, before the optional display,
140 /// hence after the entity name.
142
143 /// Function qualifiers like \c const, or \c nothrow provided with the source XLink.
145
146 /// A variable subscript provided by the source XLink.
148
149 /// An XLink to the parent scope. Created with #GetLinkToParent in the case a parent scope was
150 /// given and some search results are not found in this %XLink directly.
152
153 /// The name of the entity to find (namespace, record, variable, function, enumeration element,
154 /// type definition, etc).<br>
155 /// If <b>"*"</b> is given, the following rules apply:
156 /// - Besides the entity name, the given parent paths is displayed (not the path hints).
157 /// - In case of a function, all parameters are appended.
158 /// - In case of a template type, the keyword <c>typename<...></c> with the list of
159 /// all template parameters is prepended. <- This is a TODO(251221 08:27):
160 /// - In case of a template specialization, the list of specialization types <c><...></c>
161 /// is appended. <- This is a TODO(251221 08:27):
163
164 /// Same as #Display but #"ConvertASCIItoHTMLEntities;HTML-encoded".
166
167 /// The position of the display string in the original search string.
168 /// Note: This information is solely needed for implementing the
169 /// #"alib_mod_expressions;ALib expression" function #"DXLExpression;LinkDisplay"
171
172 /// This is a list of HTML styles to apply to the link. The list is created in the method
173 /// #AssembleDisplay.
175
176 /// The list of results. Only when this list contains exactly one element, the XLink was
177 /// successfully resolved.
179
180 /// A list of copies of this link, which is filled when disambiguation was (only) possible
181 /// through the link's HTML file name. In this case, the same link, for example, "Size"
182 /// can be dissolved into various different targets.
183 /// This whole concept makes things a little complicated but allows easy linking to
184 /// local members!
185 XLink* NextLocal =nullptr;
186
187 /// The tree node of the HTML file that created this copy of the originally given local \xl.
188 alib::filetree::FTree::ConstCursorHandle HTMLFileOfLocalLink = 0;
189
190 /// The entity in the string tree that corresponds to the HTML file given with
191 /// the field #".HTMLFileOfLocalLink".
192 Index::ConstCursorHandle LocalLinkEntity = 0;
193
194 /// List of nodes pointing to inherited base types. This is used to find inherited members.
195 /// Created only if this XLink includes a parent specification and if during the search potential
196 /// results come up that may be inherited, while no other results exist, yet.
198
199 /// List of nodes pointing to type definition targets. This is used to find members which
200 /// were addressed through type definitions.
202
203 /// A list of target nodes with the same name.
205
206 /// A list of functions matching by name but not by parameters. Filled per Index only in case
207 /// a function was searched (parameter hints given in the XLink) and no match was found.
208 /// But even if filled, a different index might provide a hit.
210
211 /// The (non-specialized) template type that matches an XLink, but either the link has
212 /// different template parameters or a specialization was searched but not found.
214
215 /// A list of entries that are variables, while the \xl's subscript does not match.
217
218 /// A list of entries that are not templates, while a template type was searched.
220
221 /// A list of specializations whose paths were matching the search pattern, but the
222 /// specialization parameters did not fit. Also, non-specialized types that fit are put here.
224
225 /// The list of locations in source files. This list is unsorted as it is collected by
226 /// the thread pool workers.
228
229 /// The list of locations in HTML files. This list is unsorted as it is collected by
230 /// the thread pool workers.
231 alib::StdVectorMA<Location> HTMLLocations; // todo: die landen nun teilweise in den local links
232
233 /// Possible errors that occured during parsing the search string given by the user.
235
236 /// Function arguments provided with the source XLink.
238
239
240 /// This flag is set when the specified link identifier starts with a dot character <c>'.'</c>.
241 /// In this case, the \xl processing is changed in various ways.
242 bool IsLocal =false;
243
244 /// This flag is set when the specified link identifier was not found in the HTML files.
245 bool NotFoundInHTML =false;
246
247 /// This flag is set if <c>"^"</c> is given at the start of the XLink which suppresses
248 /// warnings if linking indirectly through base types or type definitions (or both).
250
251 /// This flag is set if <c>"^"</c> is given at the start of the XLink and the target is
252 /// a type definition and it's parent is not a record (or the parent was not given).<br>
253 /// Note that this flag is set only after the link is resolved in the method #"GetXLink".
254 /// Before (namely after parsing the link and during the search and disambiguation process)
255 /// instead the flag #NoIndirectionWarning is set. The latter then is cleared.
257
258 /// This flag is used with the final output generation to prevent double printing when
259 /// walking through the source file tree and the file's list of XLink-locations.
260 bool WasPrinted =false;
261
262 /// Helper that searches the target of a type definition. Supports:
263 /// - chained type definitions, and
264 /// - type definitions whose target type is local to the namespace of the type definition.
265 /// @param startCursor A reference to the cursor that points to the type definition.
266 /// @param origSearchString The original search string. This is used for log-output only.
267 /// @return The target cursor. On failure, this will be a root cursor.
268 static
269 Index::Node ResolveTypeDef( const Index::Node& startCursor,
270 const alib::String& origSearchString );
271
272 /// Recursive helper used by #"Index::Search" to find inherited parents.
273 /// @param bases The list of base types.
274 void findInherited( const decltype(TGTRecord::BaseTypes)& bases);
275
276 /// Constructor. Parses the given \p{searchString} and allocates the fields in the \p{ma}.
278 : MA(ALIB_DBG("DLXLink",) 1 ) // todo: Check if 1 is enough. Should be!
279 , Targets {MA}
286 , HTMLLocations {MA} { ALIB_DBG( MA.DbgCriticalSectionsPH->DCSLock= &Lock); }
287
288 /// This method is need for the unit-tests and available only with debug-compilations.
289 void DbgReset() {
291 new (this) XLink();
292 ALIB_DBG(MA.DbgCriticalSectionsPH.Construct(nullptr));
293 }
294
295 /// Parses the given \p{searchString} and allocates the fields in the #MA.
296 void Parse();
297
298 /// Creates (once) and returns an XLink targeting the parent-scope of this XLink.
299 /// The returned XLink is already resolved and its #Targets can be iterated.<br>
300 /// This function is used to find inherited- and type-definition-members.
301 /// It furthermore creates and fills the field #BaseTypes.
302 ///
303 /// This function will be called by #"Index::Search" only in the case that this XLink contains a
304 /// parent specification.
305 /// @return The requested XLink.
307
308 /// @return The number of strings in the array #scope that are only hints.
309 int HintsSize() const { return scopeHintsSize; }
310
311 /// The number of strings in the array #scope. Up to index <c>scopeHintsSize - 1</c>
312 /// the strings are only hints. The remaining represent full parent paths.
313 /// @return The number of strings in the array #scope.
314 int ScopeSize() const { return scopeSize - scopeHintsSize -1; }
315
316 /// @return A scope-parent specified in this XLink.
317 /// @param n The number of the parent to get.
318 const alib::String& Scope(int n) const
319 { ALIB_ASSERT(n >= 0 && n < ScopeSize(), "DXL/XLINK") return scope[scopeHintsSize + n]; }
320
321 /// @return A scope-hint specified in this XLink.
322 /// @param n The number of the hint to get.
323 const alib::String& Hint(int n) const
324 { ALIB_ASSERT(n >= 0 && n < HintsSize(), "DXL/XLINK") return scope[n]; }
325
326 /// @return The last component of the given path.
327 alib::String& Name() const { ALIB_ASSERT(scopeSize>0, "DXL/XLINK") return scope[scopeSize - 1];}
328
329 /// @returns \c true, if this link was not only registered, but also parsed.
330 bool IsParsed() const { return scopeSize > 0 || Error!= Errors::OK; }
331
332 /// @returns \c true, if exactly one match was found, \c false otherwise.
333 bool IsResolved() const { return Targets.size() == 1; }
334
335 /// @returns \c true, if this links has errors (other than not resolved or ambiguous).
336 bool HasErrors() const { return Error > Errors::WARNINGMARKER; }
337
338 /// @param ignoreIndirects If \c true is given, indirect links which are not marked as such,
339 /// are not listed in the error/warning output.
340 /// @returns \c true, if this link has warnings.
341 bool HasWarnings(bool ignoreIndirects) {
342 return ( Error != Errors::OK
344 || ( !ignoreIndirects
345 && !IsLocal
349 ) );
350 }
351 /// @param ignoreIndirects Passed to internally used method #".HasWarnings".
352 /// @returns \c true, if exactly one match was found, \c false otherwise.
353 bool IsGood(bool ignoreIndirects) {
354 return IsResolved() && !HasErrors() && !HasWarnings(ignoreIndirects);
355 }
356
357 /// @returns The result if #IsResolved returns \c true. Otherwise, this is undefined behavior.
358 /// In debug-builds, an #"Raise;ALib assertion" is raised, if #IsResolved is \c false.
360 ALIB_ASSERT_ERROR(IsResolved(), "DXL/XLINK",
361 "XLink is not resolved. Method Result() must not be invoked.")
362 return Targets.front();
363 }
364
365 /// @returns The result if #IsResolved returns \c true. Otherwise, this is undefined behavior.
366 /// In debug-builds, an #"Raise;ALib assertion" is raised, if #IsResolved is \c false.
368 ALIB_ASSERT_ERROR(IsResolved(), "DXL/XLINK",
369 "XLink is not resolved. Method Result() must not be invoked.")
370 return Targets.front();
371 }
372
373 /// Assembles the display string #Display, if not already set.
374 /// Called when an XLink was successfully resolved (size in #Targets is 1).
379 else {
380 alib::String2K htmlDisplay;
382 DisplayHTMLEncoded= alib::String(MA, htmlDisplay );
383 }
384 }
385
386 /// Writes a human-readable message on unresolved or ambiguous links.
387 /// @param out The target output paragraph formatter.
388 /// @param linkString The original XLink string found in the output (and sources).
389 /// @param suppressHints If given as \c true, no hints are printed.
390 void PrintError(alib::Paragraphs& out, const alib::String& linkString,
391 bool suppressHints= false);
392
393 /// Returns this or a new \xl instance, with the given file attached.
394 /// New copies are attached to the pointer #".NextLocal", which implements a forward list.
395 /// @param htmlFile The file that the local link was found in.
396 /// @return An \xl with the given \p{htmlFile} set.
397 std::pair<XLink*,bool> GetLocalCopy(const alib::filetree::FTFile& htmlFile);
398
399 /// Returns the number of local copies, hence the number of different HTML-files that this
400 /// local link appeared in.
401 /// @return The number of local copies.
403 if( !HTMLFileOfLocalLink.IsValid())
404 return 0;
405 int n= 1;
406 XLink* l= this;
407 while((l= l->NextLocal))
408 ++n;
409 return n;
410 }
411
412};
413
414} //namespace [dxl]
415
416
417#endif // HPP_DXL_XLINK
#define ALIB_ASSERT(cond, domain)
#define ALIB_DBG(...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
Kinds
Enumerates the kinds of compounds found in a the Doxygen tagfile.
Definition target.hpp:28
@ UNSPECIFIED
Used with the field #"XLink::KindSpec;2".
Definition target.hpp:57
void Destruct(T &object)
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
threads::Lock Lock
containers::List< T, MonoAllocator, TRecycling > ListMA
lang::integer integer
strings::TString< character > String
LocalString< 2048 > String2K
format::Paragraphs Paragraphs
std::vector< T, StdMA< T > > StdVectorMA
todox
Definition doxyfile.cpp:20
void ConvertASCIItoHTMLEntities(const alib::String &src, alib::AString &dest)
Definition dxl.cpp:130
bool NeedsHTMLConversion(const String &asciiString)
Definition dxl.cpp:138
alib::StdVectorMA< ResolvedLocation > XLinkList
Definition xlink.hpp:41
The cursor type of the #"StringTree".
Definition index.hpp:105
bool IsIndirectLinkToScannedHTMLSourceFile
Set if the method DoxygenXLinks::tryResolveHTMLTargetFile" is needed and succeeds.
Definition index.hpp:425
bool IsIndirectByInheritance
Set if a member was found in a base type and not in the originally given one.
Definition index.hpp:411
A location of an XLink in a source or HTML file.
Definition xlink.hpp:23
int Line
The line number of the XLink.
Definition xlink.hpp:26
int Column
The column in the Line.
Definition xlink.hpp:27
alib::filetree::FTFile File
#"fTreeHTML;2".
Definition xlink.hpp:24
int Line
The line number of the XLink.
Definition xlink.hpp:35
int Column
The column in the Line.
Definition xlink.hpp:36
XLink * XL
The corresponding XLink.
Definition xlink.hpp:34
alib::ListMA< alib::String > BaseTypes
The base type of the record.
Definition target.hpp:359