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