Doxygen XLinks
by
V: 2511R0
Website: doxygen
Loading...
Searching...
No Matches
dxl.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_DOXYGEN_LINKER
10#define HPP_DOXYGEN_LINKER
11#pragma once
12
13
14#include "dxlapp.hpp"
15#include "threadpool.hpp"
16#include "doxyfile.hpp"
17#include "xlink.hpp"
18#include "ALib.ThreadModel.H"
19#include "ALib.Files.H"
20#include "ALib.CLI.H"
21#include "ALib.ThreadModel.H"
23#include "exclamations.hpp"
24
25
26#if defined(__clang__)
27_Pragma("clang diagnostic push")
28_Pragma("clang diagnostic ignored \"-Wheader-hygiene\"")
29#endif
30
31#if !DOXYGEN
32using namespace std::literals::chrono_literals;
33#endif
34
35#if defined(__clang__)
36_Pragma("clang diagnostic pop")
37#endif
38
39/// todox
40namespace dxl {
41class Index;
42class DXLExpression;
43
44// todo
45// [ ] It might be useful to have an option to print out all Records which have never been
46// linked to in the documentation. For this, type Target needs to get a hit-counter.
47
48/// A preprocessor constant defined in file #"F;dxl.hpp".
49#define TEST_CONSTANT "In file dxl.hpp"
50#undef TEST_CONSTANT
51
52/// This is the first definition in this file.
53#define TEST_REDEFINED "ORIGINAL"
54#undef TEST_REDEFINED
55
56/// ...wile this is the second definition in this file.
57#define TEST_REDEFINED "REDEFINED"
58#undef TEST_REDEFINED
59
60/// This type definition is not used in the code.
61/// It is for testing in manual section #"dxl_styling".
63
64/// This union is not used in the code.
65/// It is for testing in manual section #"dxl_styling".
67 int i; ///< In \c int.
68 double d; ///< In \c double.
69};
70
71
72/// This type definition is not used in the code. It is for testing whether \dxl finds members
73/// through chained type definitions.
75
76/// This type is not used in the code. It is for testing whether \dxl finds members
77/// which are inherited through a (chained!) type definition.
79 public:
80 /// This tests if overridden members are still reached directly.
81 /// @return A pointer to the buffer.
82 const alib::character* Buffer() const { return alib::AString::Buffer(); }
83};
84
85/// The possible exit codes of the application. In addition to these, the codes defined with
86/// #"App::BuiltInExitCodes" and #"app::ExitCodes" might occur.
87enum class ExitCodes {
88 OK = 0, ///< All went well.
89 CantOpenDoxyfile = 20, ///< Doxygen INI-file (usually Doxyfile) not found.
90 NoTagfileGeneratedByDoxyfile= 21, ///< Doxygen INI-file entry <b>GENERATE_TAGFILE</b> needs to
91 ///< be set to enable DoxygenXLinks.
92 OtherErrorInDoxyfile = 22, ///< Some other error occurred when parsing the Doxygen
93 ///< INI-file.
94 TagFileNotFound = 23, ///< Doxygen tag-file not created, yet. Needs a second run.
95 NoHTMLFilesFound = 24, ///< HTML files to process not found.
96 CantOpenHMLFile = 25, ///< A HTML file was not found or could not be accessed.
97 CantWriteHMLFile = 26, ///< A HTML file that was read before, could not be written.
98 NoSourceFilesFound = 27, ///< No sources found with the specification given in the Doxyfile.
99 CantOpenSrcFile = 28, ///< A source file was not found or could not be accessed.
100 NoSourceCopiesFound = 29, ///< No sources found with the specification given in the Doxyfile.
101 CantOpenReplSrcFile = 30, ///< A replacement source file was not found or could not be accessed.
102 CantWriteReplSrcFile = 31, ///< A replacement source file was not found or could not be accessed.
103};
104
105/// TODO(251212 17:24): Ich glaube wirklich das kann man löschen und nur noch die
106/// app::App::Exceptions::ControlledEarlyExit werfen!
107/// Zuletzt zumindest alle durchgehen und schauen welche noch benutzt werden
108enum class Exceptions {
109 ErrorOpeningFile = 1, ///< todox
110 UnknownKind = 2, ///< todox
111 XMLSyntaxError = 10, ///< todox
112 NotATagStart = 11, ///< todox
113 UnexpectedXMLTag = 12, ///< todox
114 XMLEndTagNotInSameLine = 13, ///< todox
115 FileNotOnRootLevel = 14, ///< todox
116 DuplicateChildName = 15, ///< todox
117 DuplicateCompound = 16, ///< todox
118 UnexpectedXMLValue = 17, ///< todox
119};
120
121// #################################################################################################
122/// class DoxygenXLinks
123// #################################################################################################
124/// This is the main class of this little project that organizes the pieces and performs
125/// all necessary steps. Method #Run is called in #"App::States::Run"
127 friend void DbgUnitTests(DoxygenXLinks*);
128
129 protected:
130 /// The file tree used for reading the source files.
132
133 /// The file tree used for reading the html files.
135
136 /// Used to optimize logging speed in critical code section.
138
139 public:
140 /// The thread pool used to load and search the HMTL files.
142
143 /// The lock used with the allocator #MA. Locking needs only be performed while the
144 /// threadpool is active.
146
147 /// Our mono allocator.
149
150 /// The Doxyfile to process.
152
153 /// The set of unique \xls found in the source and HTML files.
155 std::hash<alib::String>, std::equal_to<alib::String>,
156 alib::lang::Caching::Enabled,alib::Recycling::None> XLinkMap;
157
158 /// Some statistical data displayed with verbose output option. (todo!)
159 struct Statistics {
160 /// The number of unique XLinks found in HTML files.
161 std::atomic<int> UniqueXLinks = 0;
162
163 /// The number of unresolved XLinks.
164 std::atomic<int> UnresolvedXLinks = 0;
165
166 /// The number of ambiguous XLinks.
167 std::atomic<int> AmbiguousXLinks = 0;
168
169 /// The number of XLinks that have an erroneous specification.
170 std::atomic<int> XLinksWithErrors = 0;
171
172 /// The number of unresolved XLinks.
173 std::atomic<int> XLinksWithWarnings = 0;
174
175 /// The number of HTML files
176 std::atomic<int> HTMLFiles = 0;
177
178 /// The number of HTML file lines
179 std::atomic<int> HTMLFileLines = 0;
180
181 /// The cumulated size of the HTML file lines
182 std::atomic<int> HTMLFileSize = 0;
183
184 /// The number of attributed EL-anchors.
185 std::atomic<int> ELReplacements = 0;
186
187 /// The number of unresolved EL-anchors.
188 std::atomic<int> ELReplacementsUnresolved = 0;
189
190 /// The number of attributed ELREF-anchors.
191 std::atomic<int> ELREFReplacements = 0;
192
193 /// The number of unresolved ELREF-anchors.
194 std::atomic<int> ELREFReplacementsUnresolved = 0;
195
196
197 /// The number of source files
198 std::atomic<int> SourceFiles = 0;
199
200 /// The number of code lines read.
201 std::atomic<int> SourceFileLines = 0;
202
203 /// The cumulated size of the source files
204 std::atomic<int> SourceFileSize = 0;
205
206 /// Duration of reading and writing HTML files.
207 alib::Ticks::Duration TimeHTMLReplacements;
208
209 /// Duration of reading tag-files and sources.
210 alib::Ticks::Duration TimeIndexAndSourceLoading;
211
212 /// The number of replaced source files
213 std::atomic<int> ReplSourceFiles = 0;
214
215 /// The number of code lines read in the replacement source tree.
216 std::atomic<int> ReplSourceFileLines = 0;
217
218 /// The cumulated size of the replaced source files
219 std::atomic<int> ReplSourceFileSize = 0;
220
221 /// Duration of reading and writing the restorable source copies.
222 alib::Ticks::Duration TimeSourceReplacements;
223
224
225};
226
227 /// Statistics collected during the execution and printed when verbose output is requested.
229
230 /// An exclamation file, containing locations in in HTML-files. In rare cases \dxl might
231 /// see an \xl that is not one. Such cases have to be entered in the external exclamation file.
233
234 /// The path to this file. Todo: make configurable and auto-generated from app-name
235 alib::CString ExclamationsPath = "DoxygenXLinks.exclamations.txt";
236
237 /// The vector of #Index objects resulting from doxygen tag-files. (One \b %Index per
238 /// tag-file.)
240
241
242protected:
243 /// Implements a special feature: Files not found in doxygen tag-files, might still have
244 /// an HTML-file containing its source. Such files are named \c "XYZ_source.html".
245 /// This method is called if an \xl to a file cannon not be resolved otherwise.
246 /// @param xLink The \xl with the unresolved target file.
247 void tryResolveHTMLTargetFile(XLink& xLink);
248
249 /// Scans the source files input. This is mainly needed to add "clickable" output on
250 /// erroneous links. But over time, more features started depending on the availability
251 /// of the sources.
252 void scanSrcFiles();
253
254 /// Launches the #"SourceLocationFinder" jobs on the #".fTreeSources;source-file tree".
255 void scheduleSrcScanners();
256
257 /// Scans the HTML input file tree.
258 void scanHTMLFiles();
259
260 /// Launches the #"HTMLReplacer" jobs on the #".fTreeHTML;HTML-file tree".
262
263 /// Scans the replacement-source folders.
264 /// @param folder The directory to search copies of sources.
265 void scanReplSrcFiles(const alib::String& folder);
266
267 /// Launches the #"SourceReplacer" jobs on the #".fTreeSources;source-file tree".
268 /// @param folder The directory to search copies of sources. (Only used for log-output here.)
269 void schduleSourceReplacers(const alib::String& folder);
270
271 /// Writes the non-resolved and ambiguous src links in an ordered fashion.
272 void writeErrors();
273
274 /// Writes links found in sources which were not found in the HTML files.
275 /// This might happen if doxygen was not run properly.
277
278 /// This should not write any output. If so, it indicates that the source and html parsers
279 /// detect different link contents.
281
282 /// Writes some statistics. If \p{verbose} is off, then just one line with the number of
283 /// links in each category is given.
284 /// Reads #"var Variable" <b>STATISTICS</b>
285 void writeStatistics();
286
287 /// Writes all links that are filtered by the given expression.
288 /// @param expressionString The filter expression.
289 /// @param format The output format.
290 void listLinks(const alib::String& expressionString, const alib::String& format);
291
292public:
293 /// Constructor.
295
296 /// Virtual destructor.
298
299 // #############################################################################################
300 // Interface
301 // #############################################################################################
302 /// The main method of this main class of project \dxl.
303 void Run();
304
305 /// This method stores a link in the %XLinkMap but does not resolve it, yet.
306 /// It is called by the #"SourceLocationFinder".
307 /// @param searchString The string found in the HTML file to search for.
308 /// @return The \xl object.
309 XLink* RegisterXLink(alib::String& searchString);
310
311 /// This is the central search method of this project, called by the class #"HTMLReplacer".
312 /// While most of the search-logic is located in the method #"Index::Search",
313 /// this method is responsible for the creation of creating and hashing \xl objects and
314 /// for collecting erroneous links.
315 /// @param searchString The string found in the HTML file to search for.
316 /// @param htmlFile The HTML file where this link is currently found.
317 /// This is used to resolve #"XLink::NextLocal;local versions".
318 /// @return The \xl object. If its method #"link IsResolved" returns \c false,
319 /// no target information is set, and no replacement must happen by the caller.
320 XLink* GetXLink(alib::String& searchString, const alib::files::File& htmlFile);
321
322 /// This is used with HTML-links that are set by \b Doxygen automatically (not explicitly
323 /// by the documentation writer). It is determined which css classes are added to the anchor.
324 /// @param styles The target styles struct to set.
325 /// @param isELREFAnchor Denotes whether an anchor with class "el" or "elref" was found.
326 /// @param elLocation The HTML-file where the EL-anchor was found.
327 /// @param targetFilename The target HTML-file name portion of the anchor.
328 /// @param targetAnchor The anchor portion of anchor.
329 /// @param lineNo The line in \p{elLocation}. (Used for log-output.)
330 /// @param colNo The column in \p{elLocation}. (Used for log-output.)
331 void GetELDecoration( Styles& styles,
332 bool isELREFAnchor,
333 alib::File& elLocation,
334 alib::String targetFilename,
335 alib::String targetAnchor,
336 int lineNo, int colNo );
337
338
339 // #############################################################################################
340 // Other Methods
341 // #############################################################################################
342 /// @return A reference the #"FTree" instance holding the sources.
344
345 /// @return The mutex assigned to the shared #"FTree".
347
348 /// @return A reference the #"FTree" instance holding the HTML-files .
350
351 /// @return The mutex assigned to the shared #"FTree" holding the HTML-files.
353
354 /// This method searches the anchor with the given name in all tag-files and adds the given
355 /// title information.<br>
356 /// One way to receive the title information is described in manual section...
357 /// TODO: also ist das überhaupt noch drin? Jedenfalls funktionierte es ja mit den ALib-macro-groups gar nicht!
358 ///
359 /// Note that all given strings are volatile and must be copied before stored.
360 /// @param anchorName The name of the anchor to receive a title.
361 /// @param anchorTitle The title to set.
362 /// @param sourceHint Information about where the anchor title came from.
363 void AddAnchorTitle( const alib::String& anchorName, const alib::String& anchorTitle,
364 const alib::String& sourceHint );
365}; // class DoxygenXLinks
366
367/// Converts the following HTML-entities to ASCII-code characters in the given string \p{buffer}:
368/// HTML Entity | ASCII Character
369/// -----------------|--------------------------
370/// <c>\&lt;</c> | <c>&lt;</c>
371/// <c>\&gt;</c> | <c>&gt;</c>
372/// <c>\&amp;</c> | <c>&amp;</c>
373/// <c>\&apos;</c> | <c>&apos;</c>
374/// <c>\&lsqb;</c> | <c>[</c>
375/// <c>\&rsqb;</c> | <c>]</c>
376/// <c>\&commat;</c> | <c>\@</c>
377/// <c>\&dollar;</c> | <c>$</c>
378/// <c>\&nbsp;</c> | <c>' '</c>
379///
380/// \note HTML entity <c>"\&quot;"</c> is \b kept in!
381/// @see Function #ConvertASCIItoHTMLEntities which does the opposite.
382/// @param buffer The buffer to search for HTML entities and convert them to ASCII.
384
385/// The counter-function of #ConvertHTMLEntitiesToAscii.
386/// Also converts quotes <c>'\"'</c> to HTML entity <c>"\&quot;"</c> (what the counter-function
387/// does not do).
388/// @param buffer The buffer to search for ASCII characters to be converted to HTML entities.
390
391} //namespace [dxl]
392
393ALIB_CAMP_ENUM( dxl::ExitCodes , cli::ERExitCodeDecl , APPCLI_CAMP , "DLExitCodes" )
394ALIB_CAMP_ENUM( dxl::Exceptions , exceptions::ERException , APPCLI_CAMP , "E" )
395#endif // HPP_DOXYGEN_LINKER
#define ALIB_CAMP_ENUM(T, TRecord, Camp, ResName)
constexpr const TChar * Buffer() const
A customized ALib thread-pool.
const alib::character * Buffer() const
Definition dxl.hpp:82
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
threads::Lock Lock
lox::Verbosity Verbosity
threads::SharedLock SharedLock
strings::TCString< character > CString
files::File File
containers::HashMap< TAllocator, TKey, TMapped, THash, TEqual, THashCaching, TRecycling > HashMap
files::TSharedFTree< SharedLock > SharedFTree
strings::TString< character > String
files::FTree FTree
strings::TAString< character, lang::HeapAllocator > AString
characters::character character
std::vector< T, StdMA< T > > StdVectorMA
todox
Definition doxyfile.cpp:20
Exceptions
Definition dxl.hpp:108
@ DuplicateChildName
todox
Definition dxl.hpp:116
@ XMLEndTagNotInSameLine
todox
Definition dxl.hpp:114
@ UnknownKind
todox
Definition dxl.hpp:110
@ XMLSyntaxError
todox
Definition dxl.hpp:111
@ UnexpectedXMLTag
todox
Definition dxl.hpp:113
@ UnexpectedXMLValue
todox
Definition dxl.hpp:118
@ FileNotOnRootLevel
todox
Definition dxl.hpp:115
@ DuplicateCompound
todox
Definition dxl.hpp:117
@ ErrorOpeningFile
todox
Definition dxl.hpp:109
@ NotATagStart
todox
Definition dxl.hpp:112
dxl::XLink XLinkType
Definition dxl.hpp:62
void ConvertHTMLEntitiesToAscii(alib::AString &buffer)
Definition dxl.cpp:104
void ConvertASCIItoHTMLEntities(alib::AString &buffer)
Definition dxl.cpp:133
alib::AString ChainedAString
Definition dxl.hpp:74
ExitCodes
Definition dxl.hpp:87
@ TagFileNotFound
Doxygen tag-file not created, yet. Needs a second run.
Definition dxl.hpp:94
@ CantOpenHMLFile
A HTML file was not found or could not be accessed.
Definition dxl.hpp:96
@ OtherErrorInDoxyfile
Definition dxl.hpp:92
@ CantOpenSrcFile
A source file was not found or could not be accessed.
Definition dxl.hpp:99
@ NoSourceCopiesFound
No sources found with the specification given in the Doxyfile.
Definition dxl.hpp:100
@ CantOpenDoxyfile
Doxygen INI-file (usually Doxyfile) not found.
Definition dxl.hpp:89
@ NoTagfileGeneratedByDoxyfile
Definition dxl.hpp:90
@ NoSourceFilesFound
No sources found with the specification given in the Doxyfile.
Definition dxl.hpp:98
@ CantOpenReplSrcFile
A replacement source file was not found or could not be accessed.
Definition dxl.hpp:101
@ OK
All went well.
Definition dxl.hpp:88
@ CantWriteHMLFile
A HTML file that was read before, could not be written.
Definition dxl.hpp:97
@ NoHTMLFilesFound
HTML files to process not found.
Definition dxl.hpp:95
@ CantWriteReplSrcFile
A replacement source file was not found or could not be accessed.
Definition dxl.hpp:102
double d
In double.
Definition dxl.hpp:68
int i
In int.
Definition dxl.hpp:67