108 return p->reqPageDef;
131 if (
p->reqPageDef==
nullptr)
161 p->reqPageDef->setRefItems(e->
sli);
167 return !
p->requirements.empty();
173 for (
const auto &req :
p->requirements)
175 result.push_back(req.get());
182 AUTO_TRACE(
"#requirements={}",
p->requirements.size());
183 if (!
Config_getBool(GENERATE_REQUIREMENTS) ||
p->requirements.empty())
return;
184 std::vector<const SectionInfo*> anchors;
185 std::stable_sort(
p->requirements.begin(),
p->requirements.end(),
186 [](
const auto &left,
const auto &right) { return dstricmp(left->id(),right->id()) < 0; });
187 DString doc =
"<table class=\"doxtable reqlist\">";
193 using RequirementPtrVector = std::vector<const Requirement*>;
194 RequirementPtrVector missingSatisfiedRef, missingVerifiedRef;
195 for (
const auto &req :
p->requirements)
199 anchors.push_back(si);
201 doc +=
"<tr><td valign=\"top\">";
202 doc +=
" \\ifile \""+req->file()+
"\" \\iline "+
DString().
setNum(req->line())+
" ";
206 doc +=
"<span class=\"req_id\">";
207 if (
DString tagFile = req->getTagFile(); !tagFile.
empty())
212 doc +=
"\">"+req->id()+
"</a>";
220 doc +=
"<div class=\"req_title\">"+req->title()+
"</div>";
221 doc +=
"<p/><div class=\"req_docs\">";
223 req->sortReferences();
226 DString symName = sym->qualifiedName();
234 int numSatisfiedBy =
static_cast<int>(req->satisfiedBy().size());
235 if (numSatisfiedBy>0)
237 doc +=
"<p><div class=\"satisfiedby\">";
241 [&symToString, &refs = req->satisfiedBy()](
size_t entryIndex) {
242 return symToString(refs[entryIndex]);
248 missingSatisfiedRef.push_back(req.get());
250 int numVerifiedBy =
static_cast<int>(req->verifiedBy().size());
253 doc +=
"<p><div class=\"verifiedby\">";
257 [&symToString, &refs = req->verifiedBy()](
size_t entryIndex) {
258 return symToString(refs[entryIndex]);
264 missingVerifiedRef.push_back(req.get());
266 doc +=
"\n</div></td></tr>\n";
271 doc +=
" \\ifile \"requirements\" \\iline 1\n";
273 auto writeMissingRef = [&doc,&anchors](
const RequirementPtrVector &reqs,
280 anchors.push_back(si);
281 doc +=
"\\htmlonly <div class=\"missing_";
283 doc +=
"\">\\endhtmlonly\n";
284 doc +=
DString(
"@section missing_")+label+
" "+section+
"\n"+text+
"\n";
285 doc +=
"\\htmlonly </div>\\endhtmlonly\n";
291 int numMissingSatisfied =
static_cast<int>(missingSatisfiedRef.size());
292 if ((traceInfo==REQ_TRACEABILITY_INFO_t::YES || traceInfo==REQ_TRACEABILITY_INFO_t::UNSATISFIED_ONLY) && numMissingSatisfied>0)
294 writeMissingRef(missingSatisfiedRef,
300 [&missingSatisfiedRef](
size_t entryIndex) {
301 DString id = missingSatisfiedRef[entryIndex]->id();
302 return
"@ref "+id +
" \""+id+
"\"";
307 int numMissingVerified =
static_cast<int>(missingVerifiedRef.size());
308 if ((traceInfo==REQ_TRACEABILITY_INFO_t::YES || traceInfo==REQ_TRACEABILITY_INFO_t::UNVERIFIED_ONLY) && numMissingVerified>0)
310 writeMissingRef(missingVerifiedRef,
316 [&missingVerifiedRef](
size_t entryIndex) {
317 DString id = missingVerifiedRef[entryIndex]->id();
318 return
"@ref "+id +
" \""+id+
"\"";
323 p->reqPageDef->setDocumentation(doc,
"requirements",1,
false);
324 p->reqPageDef->addSectionsToDefinition(anchors);
329 return p->requirements.find(reqId);
348 warn(ref.file(),ref.line(),
"Reference to unknown requirement '{}' found",ref.reqId());
367 else if (!req->title().empty())
370 title += req->title();
388 if (!
p->requirements.empty())
390 for (
const auto &req :
p->requirements)
392 tagFile <<
" <compound kind=\"requirement\">\n";
393 tagFile <<
" <id>" << req->id() <<
"</id>\n";
394 tagFile <<
" <title>" <<
convertToXML(req->title()) <<
"</title>\n";
395 DString fn = req->getOutputFileBase();
397 tagFile <<
" <filename>" << fn <<
"</filename>\n";
398 tagFile <<
" </compound>\n";
408 std::stable_sort(uniqueRefs.begin(),uniqueRefs.end(),
409 [](
const auto &left,
const auto &right)
410 { return left.reqId()< right.reqId() ||
411 (left.reqId()==right.reqId() &&
412 dstricmp(left.title(),right.title())<0);
416 auto last = std::unique(uniqueRefs.begin(),uniqueRefs.end(),
417 [](
const auto &left,
const auto &right)
418 { return left.reqId()==right.reqId() &&
419 dstricmp(left.title(),right.title())==0;
423 uniqueRefs.erase(last, uniqueRefs.end());
428 inputReqRefs.begin(),
430 std::back_inserter(satisfiesRefs),
431 std::back_inserter(verifiesRefs),
432 [](
const auto &ref) { return ref.type()==RequirementRefType::Satisfies; }
436 makeUnique(satisfiesRefs);
437 makeUnique(verifiesRefs);
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
DString & setNum(short n)
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
DString & prepend(const char *s)
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
const std::string & str() const
The common base class of all entity definitions found in the sources.
virtual const DString & name() const =0
virtual const RequirementRefs & requirementReferences() const =0
virtual DString qualifiedName() const =0
Represents an unstructured piece of information, about an entity found in the sources.
const TagInfo * tagInfo() const
DString fileName
file this entry was extracted from
DString doc
documentation block (partly parsed)
DString brief
brief description (doc block)
int startLine
start line of entry in the source
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Container class representing a vector of objects with keys.
A model of a class/file/namespace member symbol.
virtual bool isObjCMethod() const =0
virtual bool isFunctionOrSignalSlot() const =0
Class representing a list of output generators that are written to in parallel.
void writeObjectLink(const DString &ref, const DString &file, const DString &anchor, const DString &name)
void docify(const DString &s)
A model of a page symbol.
std::vector< const Definition * > DefinitionVector
LinkedMap< Requirement > requirements
static RequirementManager & instance()
std::unique_ptr< Private > p
bool hasRequirements() const
const RequirementIntf * find(const DString &reqId) const
void writeTagFile(TextStream &tagFile)
void writeRef(OutputList &ol, const RequirementRef &ref)
void addRequirement(Entry *e)
const PageDef * requirementsPage() const
void addRequirementRefsForSymbol(const Definition *symbol)
RequirementIntfList requirements() const
Class to hold requirement reference information.
class that provide information about a section.
singleton class that owns the list of all sections
SectionInfo * add(const SectionInfo &si)
static SectionManager & instance()
returns a reference to the singleton
static constexpr int Anchor
static constexpr int Section
static constexpr int Requirement
Text streaming class that buffers data.
virtual DString trUnsatisfiedRequirements()=0
virtual DString trRequirements()=0
virtual DString trRequirementID()=0
virtual DString trUnverifiedRequirementsText(bool singular, const DString &list)=0
virtual DString trSatisfiedBy(const DString &list)=0
virtual DString trUnsatisfiedRequirementsText(bool singular, const DString &list)=0
virtual DString trVerifiedBy(const DString &list)=0
virtual DString trWriteList(int numEntries)=0
virtual DString trUnverifiedRequirements()=0
#define Config_getBool(name)
#define Config_getEnum(name)
#define AUTO_TRACE_ADD(...)
int dstricmp_sort(const char *str1, const char *str2)
Translator * theTranslator
MemberDef * toMemberDef(Definition *d)
#define warn(file, line, fmt,...)
void splitRequirementRefs(const RequirementRefs &inputReqRefs, RequirementRefs &satisfiesRefs, RequirementRefs &verifiesRefs)
std::vector< const RequirementIntf * > RequirementIntfList
std::vector< RequirementRef > RequirementRefs
List of requirement references.
Requirement(const DString &id_, const DString &file_, int line_, const DString &title_, const DString &doc_, const DString &tagFile_, const DString &extPage_)
DString getTagFile() const override
const DefinitionVector & satisfiedBy() const override
void addSatisfiedBy(const Definition *def)
DString getExtPage() const override
void addVerifiedBy(const Definition *def)
int line() const override
DString file() const override
DString doc() const override
DString id() const override
DefinitionVector m_verifiedBy
DString title() const override
const DefinitionVector & verifiedBy() const override
DString getOutputFileBase() const override
DefinitionVector m_satisfiedBy
DString parseCommentAsText(const Definition *scope, const MemberDef *md, const DString &doc, const DString &fileName, int lineNr)
PageDef * addRelatedPage(const DString &name, const DString &ptitle, const DString &doc, const DString &fileName, int docLine, int startLine, const RefItemVector &sli, GroupDef *gd, const TagInfo *tagInfo, bool xref, SrcLangExt lang)
void addHtmlExtensionIfMissing(DString &fName)
DString createHtmlUrl(const DString &relPath, const DString &ref, bool href, bool isLocalFile, const DString &targetFileName, const DString &anchor)
DString convertToXML(const DString &s, bool keepEntities, const bool citeEntry)
void writeMarkerList(OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
A bunch of utility functions.