Doxygen XLinks
by
V: 2511R0
Website: doxygen
Loading...
Searching...
No Matches
expressions.cpp
1//==================================================================================================
2// This implementation-file is part of DoxygenXLinks - A doxygen post-processor that allows to
3// define smarter <b>Doxygen</b>-links.
4//
5// \emoji :copyright: 2025-2026 A-Worx GmbH, Germany.
6// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8#include "expressions.hpp"
10using namespace alib;
11using namespace alib::expressions;
12
13namespace dxl {
14//==================================================================================================
15//=== Anonymous expression functions and constant objects
16//==================================================================================================
18namespace {
19#define ES expressions::Scope
20#define DS dynamic_cast<DXLScope&>(scope)
21#define AI ArgIterator
22#define VAL (*DS.Xlink)
23#define NODE VAL.Result().Node
24#define INTARG0 int(begin->Unbox<integer>())
25Box linkString(ES& scope, AI, AI) { return DS.Xlink->LinkString; }
26Box display (ES& scope, AI, AI) { return DS.Xlink->Display; }
27Box linkDisplay(ES& scope, AI, AI) { return DS.Xlink->DisplayOriginalPos
28 ? DS.Xlink->LinkString.Substring(DS.Xlink->DisplayOriginalPos)
29 : EMPTY_STRING; }
30Box linkTarget(ES& scope, AI, AI) { return DS.Xlink->DisplayOriginalPos
31 ? DS.Xlink->LinkString.Substring(0, DS.Xlink->DisplayOriginalPos-1)
32 : DS.Xlink->LinkString; }
33
34Box kind (ES& scope, AI, AI) { return VAL.IsResolved() ? NODE.Kind() : Target::UNRESOLVED; }
35Box kindSpec (ES& scope, AI, AI) { return VAL.KindSpec; }
36
37Box target (ES& scope, AI,AI) {
38 return DS.Xlink->IsResolved() ? DS.Xlink->Result().Node
39 : Index::Node();
40}
41
42Box isScannedFile(ES& scope, AI,AI) { return VAL.IsResolved() && DS.Xlink->Result().LinksToAScannedHTMLFile; }
43Box isIndSource (ES& scope, AI,AI) { return VAL.IsResolved() && DS.Xlink->Result().IsIndirectLinkToScannedHTMLSourceFile; }
44Box isIndInherit (ES& scope, AI,AI) { return VAL.IsResolved() && DS.Xlink->Result().IsIndirectByInheritance; }
45Box isIndTDMem (ES& scope, AI,AI) { return VAL.IsResolved() && DS.Xlink->Result().IsIndirectByTypeDef; }
46Box isIndTypeDef (ES& scope, AI,AI) { return VAL.IsResolved() && DS.Xlink->Result().IsResolvedTypeDef; }
47
48Box name(ES& scope, AI begin, AI end) {
49 Index::Node node;
50 // called without parameter
51 if ( begin == end ) {
52 if ( DS.Xlink->IsResolved())
53 node= DS.Xlink->Result().Node;
54 }
55 else
56 node= begin->Unbox<Index::Node>();
57
58 if (node.IsInvalid() || node.IsRoot() )
59 return EMPTY_STRING;
60 return node.Name();
61}
62
63Box path (ES& scope, AI begin, AI end) {
64
65 // without parameter: get the path of the xlink's node once
66 if ( begin == end ) {
67 if ( DS.Path.IsNull() ) {
68 if (!VAL.IsResolved() )
69 return EMPTY_STRING;
70 String256 path;
71 auto& node= NODE;
72 ALIB_LOCK_SHARED_WITH(node.Index().SLock)
73 node.Path(path);
74 DS.Path = String(scope.Allocator, path);
75 }
76 return DS.Path;
77 }
78
79 // with parameter: we just allocate the path and don't care how often the same is requested
80 auto node= begin->Unbox<Index::Node>();
81 if (node.IsInvalid() || node.IsRoot() )
82 return EMPTY_STRING;
83 String256 path;
84 ALIB_LOCK_SHARED_WITH(node.Index().SLock)
85 node.Path(path);
86 return String(scope.Allocator, path);
87}
88
89Box parent (ES& scope, AI begin, AI end) {
90 // called without parameter
91 if ( begin == end ) {
92 if ( !DS.Xlink->IsResolved())
93 return Index::Node();
94 return DS.Xlink->Result().Node.Parent();
95 }
96
97 // called with node given
98 if ( begin->IsType<Index::Node>()) {
99 auto node= begin->Unbox<Index::Node>();
100 if (node.IsInvalid() || node.IsRoot() )
101 return Index::Node();
102 return node.Parent();
103 }
104
105 // called with integer given
106 if ( !DS.Xlink->IsResolved())
107 return Index::Node();
108 auto depth= INTARG0;
109 auto node = DS.Xlink->Result().Node;
110 while (depth>0 && !node.IsRoot()) {
111 node= node.Parent();
112 --depth;
113 }
114 return node;
115}
116
117Box isGood (ES& scope, AI,AI) { return DS.Xlink->IsGood (false); }
118Box isResolved(ES& scope, AI,AI) { return DS.Xlink->IsResolved (); }
119Box hasError (ES& scope, AI,AI) { return DS.Xlink->HasErrors (); }
120Box hasWarning(ES& scope, AI,AI) { return DS.Xlink->HasWarnings(false); }
121Box errorCode (ES& scope, AI,AI) { return DS.Xlink->Error; }
122
123Box countSrcLocs( ES& scope, AI,AI) { return integer(DS.Xlink->SourceLocations.size()); }
124Box countHTMLLocs(ES& scope, AI,AI) { return integer(DS.Xlink->HTMLLocations .size()); }
125
126Box countScpHnts (ES& scope, AI,AI) { return DS.Xlink->HintsSize(); }
127Box scopeHint (ES& scope, AI begin,AI) {
128 int idx= INTARG0;
129 return idx>= 0 && idx< DS.Xlink->HintsSize() ? DS.Xlink->Hint(idx)
130 : EMPTY_STRING;
131}
132Box countScope (ES& scope, AI,AI) { return DS.Xlink->ScopeSize() - 1; }
133Box scope (ES& scope, AI begin,AI) {
134 int idx= INTARG0;
135 return idx>= 0 && idx< DS.Xlink->ScopeSize() ? DS.Xlink->Scope( DS.Xlink->ScopeSize() - idx - 1)
136 : EMPTY_STRING;
137}
138Box identifier (ES& scope, AI,AI) {
139 return DS.Xlink->ScopeSize() > 0 ? DS.Xlink->Scope( DS.Xlink->ScopeSize() - 1)
140 : EMPTY_STRING;
141}
142
143Box countParams (ES& scope, AI begin,AI end) {
144 if ( begin == end )
145 return DS.Xlink->Args ? DS.Xlink->Args->Count : -1;
146 auto node= begin->Unbox<Index::Node>();
147 if ( node.IsInvalid() || !node.IsA(Target::Function) )
148 return -1;
149 auto* args= Cast<TGTFunction,NC>(node)->Args;
150 return args ? args->Count : -1;
151}
152
153Box params (ES& scope, AI begin,AI end) {
154 Target::FunctionArguments* args= nullptr;
155 if ( begin == end ) {
156 args= DS.Xlink->Args;
157 }
158 else {
159 auto node= begin->Unbox<Index::Node>();
160 if ( node.IsInvalid() || !node.IsA(Target::Function) )
161 return EMPTY_STRING;
162 args= Cast<TGTFunction,NC>(node)->Args;
163 }
164 if (!args) return EMPTY_STRING;
165 String256 buf;
166 args->Print(buf);
167 return String(scope.Allocator, buf);
168}
169
170Box countTParams (ES& scope, AI begin,AI end) {
171 if ( begin == end )
172 return DS.Xlink->TemplateArgs ? DS.Xlink->TemplateArgs->Count : -1;
173 auto node= begin->Unbox<Index::Node>();
174 if ( node.IsInvalid() || !node.IsA(Target::RECORD) )
175 return -1;
176 auto* args= Cast<TGTRecord,NC>(node)->TemplateArgs;
177 return args ? args->Count : -1;
178}
179
180Box tParams (ES& scope, AI begin,AI end) {
181 Target::TemplateArguments* args= nullptr;
182 if ( begin == end ) {
183 args= DS.Xlink->TemplateArgs;
184 }
185 else {
186 auto node= begin->Unbox<Index::Node>();
187 if ( node.IsInvalid() || !node.IsA(Target::RECORD) )
188 return EMPTY_STRING;
189 args= Cast<TGTRecord,NC>(node)->TemplateArgs;
190 }
191 if (!args) return EMPTY_STRING;
192 String256 buf;
193 args->Print(buf);
194 return String(scope.Allocator, buf);
195}
196
197Box countTSParams (ES& scope, AI begin,AI end) {
198 if ( begin == end )
199 return DS.Xlink->SpecializationArgs ? DS.Xlink->SpecializationArgs->Count : -1;
200 auto node= begin->Unbox<Index::Node>();
201 if ( node.IsInvalid() || !node.IsA(Target::RECORD) )
202 return -1;
203 auto* args= Cast<TGTRecord,NC>(node)->SpecializationArgs;
204 return args ? args->Count : -1;
205}
206
207Box tSParams (ES& scope, AI begin,AI end) {
208 Target::TemplateArguments* args= nullptr;
209 if ( begin == end ) {
210 args= DS.Xlink->SpecializationArgs;
211 }
212 else {
213 auto node= begin->Unbox<Index::Node>();
214 if ( node.IsInvalid() || !node.IsA(Target::RECORD) )
215 return EMPTY_STRING;
216 args= Cast<TGTRecord,NC>(node)->SpecializationArgs;
217 }
218 if (!args) return EMPTY_STRING;
219 String256 buf;
220 args->Print(buf);
221 return String(scope.Allocator, buf);
222}
223
224Box depth (ES& scope, AI begin,AI end) {
225 Index::Node node;
226 if ( begin == end ) {
227 if ( !DS.Xlink->IsResolved())
228 return -1;
229 node= DS.Xlink->Result().Node;
230 }
231 else {
232 node= begin->Unbox<Index::Node>();
233 if (node.IsInvalid() || node.IsRoot() )
234 return -1;
235 }
236 ALIB_LOCK_SHARED_WITH(node.Index().SLock)
237 return node.AsCursor().Depth();
238}
239
240Box tagFilePath (ES& scope, AI begin,AI end) {
241 Index::Node node;
242 if ( begin == end ) {
243 if ( !DS.Xlink->IsResolved())
244 return EMPTY_STRING;
245 node= DS.Xlink->Result().Node;
246 }
247 else {
248 node= begin->Unbox<Index::Node>();
249 if (node.IsInvalid() || node.IsRoot() )
250 return EMPTY_STRING;
251 }
252 return node.Index().FilePath;
253}
254
255Box tagFileName (ES& scope, AI begin,AI end) {
256 Index::Node node;
257 if ( begin == end ) {
258 if ( !DS.Xlink->IsResolved())
259 return EMPTY_STRING;
260 node= DS.Xlink->Result().Node;
261 }
262 else {
263 node= begin->Unbox<Index::Node>();
264 if (node.IsInvalid() || node.IsRoot() )
265 return EMPTY_STRING;
266 }
267 return node.Index().FileName;
268}
269
270Box tagFileLine (ES& scope, AI begin,AI end) {
271 Index::Node node;
272 if ( begin == end ) {
273 if ( !DS.Xlink->IsResolved())
274 return -1;
275 node= DS.Xlink->Result().Node;
276 }
277 else {
278 node= begin->Unbox<Index::Node>();
279 if (node.IsInvalid() || node.IsRoot() )
280 return -1;
281 }
282 return node.LineNo();
283}
284
285Box htmlFile (ES& scope, AI begin,AI end) {
286 Index::Node node;
287 if ( begin == end ) {
288 if ( !DS.Xlink->IsResolved())
289 return EMPTY_STRING;
290 node= DS.Xlink->Result().Node;
291 }
292 else {
293 node= begin->Unbox<Index::Node>();
294 if (node.IsInvalid() || node.IsRoot() )
295 return EMPTY_STRING;
296 }
297 return node.HTMLFile();
298
299}
300Box htmlAnchor (ES& scope, AI begin,AI end) {
301 Index::Node node;
302 if ( begin == end ) {
303 if ( !DS.Xlink->IsResolved())
304 return EMPTY_STRING;
305 node= DS.Xlink->Result().Node;
306 }
307 else {
308 node= begin->Unbox<Index::Node>();
309 if (node.IsInvalid() || node.IsRoot() )
310 return EMPTY_STRING;
311 }
312 if (!node.IsA(Target::MEMBER))
313 return EMPTY_STRING;
314 return Cast<TGTMember,NC>(node)->Anchor;
315}
316
317#undef ES
318#undef FS
319#undef AI
320#undef NODE
321#undef VAL
322#undef INTARG0
323#include "ALib.Lang.CIMethods.H"
324
325extern Box constDir ; Box constDir ;
326extern Box constFile ; Box constFile ;
327extern Box constPage ; Box constPage ;
328extern Box constGroup ; Box constGroup ;
329extern Box constDocAnchor ; Box constDocAnchor ;
330extern Box constNameSpace ; Box constNameSpace ;
331extern Box constStruct ; Box constStruct ;
332extern Box constClass ; Box constClass ;
333extern Box constUnion ; Box constUnion ;
334extern Box constConcept ; Box constConcept ;
335extern Box constMacro ; Box constMacro ;
336extern Box constTypedef ; Box constTypedef ;
337extern Box constVariable ; Box constVariable ;
338extern Box constFunction ; Box constFunction ;
339extern Box constEnumeration ; Box constEnumeration ;
340extern Box constEnumElement ; Box constEnumElement ;
341extern Box constGenericMember ; Box constGenericMember ;
342extern Box constRecord ; Box constRecord ;
343extern Box constUnspecified ; Box constUnspecified ;
344
345extern Box TypeNode ; Box TypeNode ;
346extern Box TypeKind ; Box TypeKind ;
347
348extern Box* SigNode[1] ; Box* SigNode[1]= { &TypeNode };
349
350
351//================================================================================================
352//=== The compiler plugin
353//================================================================================================
354/// The internal compiler plug-in which adds file-related functions to the expression
355/// compiler as documented with the outer class.
356struct Plugin : plugins::Calculus {
357 /// Constructor
358 /// @param compiler The compiler that this plugin will be attached to.
359 Plugin( Compiler& compiler )
360 : Calculus( "DXL Plug-in", compiler, CompilePriorities::Custom ) {
361 // Initialize constant static boxes. This must not be done in the C++ bootstrap code.
362 constDir = Target::Dir ;
363 constFile = Target::File ;
364 constPage = Target::Page ;
365 constGroup = Target::Group ;
366 constDocAnchor = Target::DocAnchor ;
367 constNameSpace = Target::Namespace ;
368 constStruct = Target::Struct ;
369 constClass = Target::Class ;
370 constUnion = Target::Union ;
371 constConcept = Target::Concept ;
372 constMacro = Target::Macro ;
373 constTypedef = Target::Typedef ;
374 constVariable = Target::Variable ;
375 constFunction = Target::Function ;
376 constEnumeration = Target::Enumeration ;
377 constEnumElement = Target::EnumElement ;
378 constGenericMember= Target::GenericMember;
379 constRecord = Target::RECORD ;
380 constUnspecified = Target::UNSPECIFIED ;
381
382 TypeNode = Index::Node();
383
385
386 compiler.AddType(TypeKind , APPCLI_CAMP.GetResource("TKINDS"));
387 compiler.AddType(TypeNode , APPCLI_CAMP.GetResource("TNODE"));
388
389 // load identifier/function names from resources
390 constexpr int tableSize= 58;
391 Token functionNames[tableSize];
392 strings::util::LoadResourcedTokens( APPCLI_CAMP, "EID", functionNames ALIB_DBG(,tableSize) );
393
394 Token* descriptor= functionNames;
395
396 // Constant identifiers
397 ConstantIdentifiers= {
398 { *descriptor++, constDir },
399 { *descriptor++, constFile },
400 { *descriptor++, constPage },
401 { *descriptor++, constGroup },
402 { *descriptor++, constDocAnchor },
403 { *descriptor++, constNameSpace },
404 { *descriptor++, constStruct },
405 { *descriptor++, constClass },
406 { *descriptor++, constUnion },
407 { *descriptor++, constConcept },
408 { *descriptor++, constMacro },
409 { *descriptor++, constTypedef },
410 { *descriptor++, constVariable },
411 { *descriptor++, constFunction },
412 { *descriptor++, constEnumeration },
413 { *descriptor++, constEnumElement },
414 { *descriptor++, constGenericMember },
415 { *descriptor++, constRecord },
416 { *descriptor++, constUnspecified },
417 };
418
419 Functions= {
420 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(linkString ), &Types::String , ETI },
421 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(display ), &Types::String , ETI },
422 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(kind ), &TypeKind , ETI },
423 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(target ), &TypeNode , ETI },
424 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(name ), &Types::String , ETI },
425 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(name ), &Types::String , ETI },
426 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(path ), &Types::String , ETI },
427 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(path ), &Types::String , ETI },
428 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(parent ), &TypeNode , ETI },
429 { *descriptor , CALCULUS_SIGNATURE(Signatures::I), CALCULUS_CALLBACK(parent ), &TypeNode , ETI },
430 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(parent ), &TypeNode , ETI },
431 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(isGood ), &Types::Boolean, ETI },
432 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(isResolved ), &Types::Boolean, ETI },
433 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(hasError ), &Types::Boolean, ETI },
434 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(hasWarning ), &Types::Boolean, ETI },
435 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(errorCode ), &Types::Integer, ETI },
436 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(countScpHnts ), &Types::Integer, ETI },
437 { *descriptor++, CALCULUS_SIGNATURE(Signatures::I), CALCULUS_CALLBACK(scopeHint ), &Types::String , ETI },
438 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(countScope ), &Types::Integer, ETI },
439 { *descriptor++, CALCULUS_SIGNATURE(Signatures::I), CALCULUS_CALLBACK(scope ), &Types::String , ETI },
440 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(identifier ), &Types::String , ETI },
441
442 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(countParams ), &Types::Integer, ETI },
443 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(countParams ), &Types::Integer, ETI },
444 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(params ), &Types::String , ETI },
445 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(params ), &Types::String , ETI },
446 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(countTParams ), &Types::Integer, ETI },
447 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(countTParams ), &Types::Integer, ETI },
448 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(tParams ), &Types::String , ETI },
449 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(tParams ), &Types::String , ETI },
450 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(countTSParams), &Types::Integer, ETI },
451 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(countTSParams), &Types::Integer, ETI },
452 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(tSParams ), &Types::String , ETI },
453 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(tSParams ), &Types::String , ETI },
454 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(linkDisplay ), &Types::String , ETI },
455 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(linkTarget ), &Types::String , ETI },
456 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(kindSpec ), &TypeKind , ETI },
457 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(depth ), &Types::Integer , ETI },
458 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(depth ), &Types::Integer , ETI },
459
460 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(tagFilePath ), &Types::String , ETI },
461 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(tagFilePath ), &Types::String , ETI },
462 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(tagFileName ), &Types::String , ETI },
463 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(tagFileName ), &Types::String , ETI },
464 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(tagFileLine ), &Types::Integer, ETI },
465 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(tagFileLine ), &Types::Integer, ETI },
466 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(htmlFile ), &Types::String, ETI },
467 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(htmlFile ), &Types::String, ETI },
468 { *descriptor , CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(htmlAnchor ), &Types::String, ETI },
469 { *descriptor++, CALCULUS_SIGNATURE(SigNode) , CALCULUS_CALLBACK(htmlAnchor ), &Types::String, ETI },
470 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(countSrcLocs ), &Types::Integer, ETI },
471 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(countHTMLLocs), &Types::Integer, ETI },
472
473 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(isScannedFile), &Types::Boolean, ETI },
474 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(isIndSource ), &Types::Boolean, ETI },
475 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(isIndInherit ), &Types::Boolean, ETI },
476 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(isIndTDMem ), &Types::Boolean, ETI },
477 { *descriptor++, CALCULUS_SIGNATURE(nullptr) , CALCULUS_CALLBACK(isIndTypeDef ), &Types::Boolean, ETI },
478 };
479
480 AutoCasts= {
481 { constDir , nullptr, nullptr, CALCULUS_DEFAULT_AUTOCAST , nullptr , nullptr },
482 };
483
484 } // FileExpressions::Plugin constructor
485};
486
487expressions::Compiler* theCompiler= nullptr;
488Plugin* thePlugin= nullptr;
489
490} // anonymous namespace
491
492DXLScope::DXLScope() : Scope{ theCompiler->CfgFormatter } {}
493
495: ExpressionFormatter { formatString, theCompiler } {}
496
497
498//==================================================================================================
499//=== DXLExpression
500//==================================================================================================
502
503 // create compiler once
504 if (!theCompiler) {
505 theCompiler = new Compiler();
506 thePlugin = new Plugin(*theCompiler);
507 theCompiler->SetupDefaults();
508 theCompiler->InsertPlugin( thePlugin );
509 }
510
511 // compile the expression
512 expression= theCompiler->Compile( expressionString );
513
514 // create the scope
515 scope= new DXLScope();
516}
518 delete scope;
519 expression= nullptr;
520}
521
522
524 scope->Xlink = xLink;
525 Box result= expression->Evaluate( *scope );
526 return result.IsType<bool>() ? result.Unbox<bool>()
527 : result.Unbox<integer>() != 0;
528 }
529
530
531} // namespace [alib::files]
532
533
#define ALIB_LOCK_SHARED_WITH(lock)
#define ALIB_DBG(...)
bool IsType() const
void AddType(Type sample, const NString &name)
ExpressionFormatter(const String &formatString, Compiler *compiler, SPFormatter formatter=nullptr, character separatorChar='@')
const String & GetResource(const NString &name)
DXLScope * scope
The scope used with this filter.
~DXLExpression()
Destructor.
bool Includes(XLink *xLink)
DXLExpression(const alib::String &expressionString)
alib::expressions::Expression expression
The compiled expression.
alib::system::PathString FileName
The base name component of FilePath.
Definition index.hpp:230
@ Struct
Denotes a struct.
Definition target.hpp:37
@ Function
Denotes a namespace- or member-function.
Definition target.hpp:46
@ Variable
Denotes a namespace- or member-variable.
Definition target.hpp:45
@ UNSPECIFIED
Used with the field #"XLink::KindSpec;2".
Definition target.hpp:56
@ Union
Denotes a union.
Definition target.hpp:39
@ Class
Denotes a class.
Definition target.hpp:38
@ Typedef
Denotes a type definition.
Definition target.hpp:44
@ File
Denotes a source file.
Definition target.hpp:31
@ EnumElement
Denotes an enumeration element.
Definition target.hpp:48
@ UNRESOLVED
The kind attached to the root node of the tree.
Definition target.hpp:60
@ Concept
Denotes a C++20 concept.
Definition target.hpp:40
@ Macro
Denotes a preprocessor definition.
Definition target.hpp:43
@ GenericMember
An unknown or uninteresting group member type.
Definition target.hpp:49
@ Dir
Denotes a source folder.
Definition target.hpp:30
@ Page
Denotes a page.
Definition target.hpp:32
@ Group
Denotes a group.
Definition target.hpp:33
@ Enumeration
Denotes an enumeration.
Definition target.hpp:47
@ Namespace
Denotes a namespace.
Definition target.hpp:36
@ DocAnchor
Denotes a preprocessor definition.
Definition target.hpp:34
@ RECORD
Mask to identify records types.
Definition target.hpp:67
#define CALCULUS_DEFAULT_AUTOCAST
#define CALCULUS_CALLBACK(func)
#define CALCULUS_SIGNATURE(BoxPointerArray)
void LoadResourcedTokens(camp::Camp &module, const NString &resourceName, strings::util::Token *target, int dbgSizeVerifier, character outerSeparator=',', character innerSeparator=' ')
constexpr const String EMPTY_STRING
lang::integer integer
boxing::Box Box
expressions::Compiler Compiler
strings::TString< character > String
app::AppCliCamp APPCLI_CAMP
system::Path Path
LocalString< 256 > String256
strings::util::Token Token
expressions::plugins::Calculus Calculus
todox
Definition doxyfile.cpp:20
const TGT * Cast(const Index::Node &node)
Definition index.hpp:544
Scope(const Scope &)=delete
DXLExpressionFormatter(const alib::String &formatString)
The cursor type of the #"StringTree".
Definition index.hpp:105
const alib::String & HTMLFile() const
Definition index.hpp:187
Index & Index() const
Definition index.hpp:173
int LineNo() const
Definition index.hpp:183