Doxygen
Loading...
Searching...
No Matches
RequirementManager Class Reference

#include <src/requirement.h>

Classes

class  Private

Public Member Functions

void addRequirement (Entry *e)
void generatePage ()
void writeTagFile (TextStream &tagFile)
void addRequirementRefsForSymbol (const Definition *symbol)
const RequirementIntffind (const QCString &reqId) const
void writeRef (OutputList &ol, const RequirementRef &ref)
RequirementIntfList requirements () const
const PageDefrequirementsPage () const

Static Public Member Functions

static RequirementManagerinstance ()

Private Member Functions

 RequirementManager ()

Private Attributes

std::unique_ptr< Privatep

Detailed Description

Definition at line 74 of file requirement.h.

Constructor & Destructor Documentation

◆ RequirementManager()

RequirementManager::RequirementManager ( )
private

Definition at line 104 of file requirement.cpp.

104 : p(std::make_unique<Private>())
105{
106 p->reqPageDef = addRelatedPage("requirements", // name
107 theTranslator->trRequirements(), // ptitle
108 QCString(), // doc
109 "requirements", // fileName
110 1, // docLine
111 1 // startLine
112 );
113}
std::unique_ptr< Private > p
Definition requirement.h:89
virtual QCString trRequirements()=0
static void addRelatedPage(Entry *root)
Definition doxygen.cpp:329
Translator * theTranslator
Definition language.cpp:71

References addRelatedPage(), p, and theTranslator.

Referenced by instance().

Member Function Documentation

◆ addRequirement()

void RequirementManager::addRequirement ( Entry * e)

Definition at line 120 of file requirement.cpp.

121{
122 //printf("requirement ID=%s title='%s' file=%s line=%d brief='%s' doc='%s'\n",
123 // qPrint(e->name), qPrint(e->type), qPrint(e->fileName), e->startLine, qPrint(e->brief), qPrint(e->doc));
124 QCString tagFile;
125 QCString extPage;
126 QCString title = parseCommentAsText(p->reqPageDef,nullptr,e->type,e->fileName,e->startLine);
127 QCString doc = e->doc;
128 if (e->tagInfo())
129 {
130 //printf("External requirement %s title=%s fileName=%s tagName=%s anchor=%s\n",
131 // qPrint(e->name),qPrint(e->type),qPrint(e->tagInfo()->fileName),qPrint(e->tagInfo()->tagName),qPrint(e->tagInfo()->anchor));
132 tagFile = e->tagInfo()->tagName;
133 extPage = e->tagInfo()->fileName;
134 // register requirement id as anchor; for non-external links this is
135 // done in commentscan.l in the comment block containing the @requirement command
136 SectionManager::instance().add(e->name,"requirements",1,title,SectionType::Anchor,1);
137 }
138 if (!e->brief.isEmpty())
139 {
140 doc.prepend(e->brief+"\n<p>");
141 }
142 p->requirements.add(e->name, e->fileName, e->startLine, title, doc, tagFile, extPage);
143
144 p->reqPageDef->setRefItems(e->sli);
145}
const TagInfo * tagInfo() const
Definition entry.h:178
QCString fileName
file this entry was extracted from
Definition entry.h:224
QCString type
member type
Definition entry.h:174
int startLine
start line of entry in the source
Definition entry.h:225
QCString name
member name
Definition entry.h:175
QCString doc
documentation block (partly parsed)
Definition entry.h:201
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:227
QCString brief
brief description (doc block)
Definition entry.h:204
QCString & prepend(const char *s)
Definition qcstring.h:422
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
SectionInfo * add(const SectionInfo &si)
Definition section.h:138
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:178
static constexpr int Anchor
Definition section.h:40
QCString fileName
Definition entry.h:106
QCString tagName
Definition entry.h:105
QCString parseCommentAsText(const Definition *scope, const MemberDef *md, const QCString &doc, const QCString &fileName, int lineNr)
Definition util.cpp:5349

References SectionManager::add(), SectionType::Anchor, Entry::brief, Entry::doc, Entry::fileName, TagInfo::fileName, SectionManager::instance(), QCString::isEmpty(), Entry::name, p, parseCommentAsText(), QCString::prepend(), Entry::sli, Entry::startLine, Entry::tagInfo(), TagInfo::tagName, and Entry::type.

Referenced by buildRequirementsList().

◆ addRequirementRefsForSymbol()

void RequirementManager::addRequirementRefsForSymbol ( const Definition * symbol)

Definition at line 306 of file requirement.cpp.

307{
308 for (const auto &ref : symbol->requirementReferences())
309 {
310 Requirement *req = p->requirements.find(ref.reqId());
311 if (req)
312 {
313 //printf("adding reference from %s to requirement %s\n",qPrint(symbol->name()),qPrint(ref.reqId()));
314 switch (ref.type())
315 {
316 case RequirementRefType::Satisfies: req->addSatisfiedBy(symbol); break;
317 case RequirementRefType::Verifies: req->addVerifiedBy(symbol); break;
318 }
319 }
320 else
321 {
322 warn(ref.file(),ref.line(),"Reference to unknown requirement '{}' found",ref.reqId());
323 // invalid reference (file, and line needed)
324 }
325 }
326}
virtual const RequirementRefs & requirementReferences() const =0
#define warn(file, line, fmt,...)
Definition message.h:97
void addSatisfiedBy(const Definition *def)
void addVerifiedBy(const Definition *def)

References Requirement::addSatisfiedBy(), Requirement::addVerifiedBy(), p, Definition::requirementReferences(), Satisfies, Verifies, and warn.

Referenced by ClassDefImpl::addRequirementReferences(), ConceptDefImpl::addRequirementReferences(), DirDefImpl::addRequirementReferences(), FileDefImpl::addRequirementReferences(), GroupDefImpl::addRequirementReferences(), MemberDefImpl::addRequirementReferences(), ModuleDefImpl::addRequirementReferences(), NamespaceDefImpl::addRequirementReferences(), and PageDefImpl::addRequirementReferences().

◆ find()

const RequirementIntf * RequirementManager::find ( const QCString & reqId) const

Definition at line 301 of file requirement.cpp.

302{
303 return p->requirements.find(reqId);
304}

References p.

Referenced by generatePage(), and writeRef().

◆ generatePage()

void RequirementManager::generatePage ( )

Definition at line 157 of file requirement.cpp.

158{
159 if (p->requirements.empty()) return;
160 std::vector<const SectionInfo*> anchors;
161 std::stable_sort(p->requirements.begin(),p->requirements.end(),
162 [](const auto &left,const auto &right) { return qstricmp(left->id(),right->id()) < 0; });
163 QCString doc = "<table class=\"doxtable reqlist\">";
164 doc.reserve(10*1024); // prevent too many reallocs
165 doc += "<tr><th>";
167 doc += "</th><th>";
168 doc += "</th>";
169 using RequirementPtrVector = std::vector<const Requirement*>;
170 RequirementPtrVector missingSatisfiedRef, missingVerifiedRef;
171 for (const auto &req : p->requirements) // TODO: filter out external references?
172 {
173 if (const SectionInfo *si = SectionManager::instance().find(req->id()); si!=nullptr)
174 {
175 anchors.push_back(si);
176 }
177 doc += "<tr><td valign=\"top\">";
178 doc += " \\ifile \""+req->file()+"\" \\iline "+QCString().setNum(req->line())+" ";
179 doc += "\\anchor ";
180 doc += req->id();
181 doc += " ";
182 doc += "<span class=\"req_id\">";
183 if (QCString tagFile = req->getTagFile(); !tagFile.isEmpty())
184 {
185 //printf("tagFile=%s extPage=%s\n",qPrint(tagFile),qPrint(req->getExtPage()));
186 doc += "<a href=\"";
187 doc += createHtmlUrl(QCString(),tagFile,true,false,req->getExtPage(),req->id());
188 doc +="\">"+req->id()+"</a>";
189 }
190 else
191 {
192 doc += req->id();
193 }
194 doc += "</span> ";
195 doc += "</td><td>";
196 doc += "<div class=\"req_title\">"+req->title()+"</div>";
197 doc += "<div class=\"req_docs\">";
198 doc += req->doc();
199 req->sortReferences();
200 auto symToString = [](const Definition *sym)
201 {
202 QCString symName = sym->qualifiedName();
203 if (sym->definitionType()==Definition::TypeMember)
204 {
205 const MemberDef *md = toMemberDef(sym);
206 if (!md->isObjCMethod() && md->isFunctionOrSignalSlot()) symName += "()";
207 }
208 return symName;
209 };
210 int numSatisfiedBy = static_cast<int>(req->satisfiedBy().size());
211 if (numSatisfiedBy>0)
212 {
213 doc += "<p><div class=\"satisfiedby\">";
215 writeMarkerList(theTranslator->trWriteList(numSatisfiedBy).str(),
216 numSatisfiedBy,
217 [&symToString, &refs = req->satisfiedBy()](size_t entryIndex) {
218 return symToString(refs[entryIndex]);
219 }));
220 doc += "</div></p>";
221 }
222 else
223 {
224 missingSatisfiedRef.push_back(req.get());
225 }
226 int numVerifiedBy = static_cast<int>(req->verifiedBy().size());
227 if (numVerifiedBy>0)
228 {
229 doc += "<p><div class=\"verifiedby\">";
232 numVerifiedBy,
233 [&symToString, &refs = req->verifiedBy()](size_t entryIndex) {
234 return symToString(refs[entryIndex]);
235 }));
236 doc += "</div></p>";
237 }
238 else
239 {
240 missingVerifiedRef.push_back(req.get());
241 }
242 doc += "</div></td></tr>\n";
243 }
244 doc += "</table>\n";
245
246 //------------
247 doc += " \\ifile \"requirements\" \\iline 1\n";
248
249 auto writeMissingRef = [&doc,&anchors](const RequirementPtrVector &reqs,
250 const char *label,const QCString &section,const QCString &text)
251 {
252 if (!reqs.empty())
253 {
254 SectionManager &sm = SectionManager::instance();
255 const SectionInfo *si = sm.add(QCString("missing_")+label,"requirements",1,section,SectionType::Section,1);
256 anchors.push_back(si);
257 doc += "\\htmlonly <div class=\"missing_req\">\\endhtmlonly\n";
258 doc += QCString("@section missing_")+label+" "+section+"\n"+text+"\n";
259 doc += "\\htmlonly </div>\\endhtmlonly\n";
260 }
261 };
262
263 // write list of requirements that do not have a satisfies relation
264 auto traceInfo = Config_getEnum(REQ_TRACEABILITY_INFO);
265 int numMissingSatisfied = static_cast<int>(missingSatisfiedRef.size());
266 if ((traceInfo==REQ_TRACEABILITY_INFO_t::YES || traceInfo==REQ_TRACEABILITY_INFO_t::SATISFIES_ONLY) && numMissingSatisfied>0)
267 {
268 writeMissingRef(missingSatisfiedRef,
269 "satisfies",
271 theTranslator->trUnsatisfiedRequirementsText(numMissingSatisfied==1,
272 writeMarkerList(theTranslator->trWriteList(numMissingSatisfied).str(),
273 numMissingSatisfied,
274 [&missingSatisfiedRef](size_t entryIndex) {
275 QCString id = missingSatisfiedRef[entryIndex]->id();
276 return "@ref "+id + " \""+id+"\"";
277 })));
278 }
279
280 // write list of requirements that do not have a verifies relation
281 int numMissingVerified = static_cast<int>(missingVerifiedRef.size());
282 if ((traceInfo==REQ_TRACEABILITY_INFO_t::YES || traceInfo==REQ_TRACEABILITY_INFO_t::VERIFIES_ONLY) && numMissingVerified>0)
283 {
284 writeMissingRef(missingVerifiedRef,
285 "verifies",
287 theTranslator->trUnverifiedRequirementsText(numMissingVerified==1,
288 writeMarkerList(theTranslator->trWriteList(numMissingVerified).str(),
289 numMissingVerified,
290 [&missingVerifiedRef](size_t entryIndex) {
291 QCString id = missingVerifiedRef[entryIndex]->id();
292 return "@ref "+id + " \""+id+"\"";
293 })));
294 }
295
296 //printf("doc=[[\n%s\n]]\n",qPrint(doc));
297 p->reqPageDef->setDocumentation(doc,"requirements",1,false);
298 p->reqPageDef->addSectionsToDefinition(anchors);
299}
virtual bool isObjCMethod() const =0
virtual bool isFunctionOrSignalSlot() const =0
const std::string & str() const
Definition qcstring.h:552
QCString & setNum(short n)
Definition qcstring.h:459
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition qcstring.h:185
const RequirementIntf * find(const QCString &reqId) const
static constexpr int Section
Definition section.h:33
virtual QCString trUnverifiedRequirements()=0
virtual QCString trSatisfiedBy(const QCString &list)=0
virtual QCString trUnsatisfiedRequirements()=0
virtual QCString trWriteList(int numEntries)=0
virtual QCString trRequirementID()=0
virtual QCString trUnsatisfiedRequirementsText(bool singular, const QCString &list)=0
virtual QCString trVerifiedBy(const QCString &list)=0
virtual QCString trUnverifiedRequirementsText(bool singular, const QCString &list)=0
#define Config_getEnum(name)
Definition config.h:35
MemberDef * toMemberDef(Definition *d)
void writeMarkerList(OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
Definition util.cpp:1106
QCString createHtmlUrl(const QCString &relPath, const QCString &ref, bool href, bool isLocalFile, const QCString &targetFileName, const QCString &anchor)
Definition util.cpp:5716

References SectionManager::add(), Config_getEnum, createHtmlUrl(), find(), SectionManager::instance(), QCString::isEmpty(), MemberDef::isFunctionOrSignalSlot(), MemberDef::isObjCMethod(), p, QCString::reserve(), SectionType::Section, QCString::setNum(), theTranslator, toMemberDef(), Definition::TypeMember, and writeMarkerList().

Referenced by parseInput().

◆ instance()

◆ requirements()

RequirementIntfList RequirementManager::requirements ( ) const

Definition at line 147 of file requirement.cpp.

148{
149 RequirementIntfList result;
150 for (const auto &req : p->requirements)
151 {
152 result.push_back(req.get());
153 }
154 return result;
155}
std::vector< const RequirementIntf * > RequirementIntfList
Definition requirement.h:72

References p.

◆ requirementsPage()

const PageDef * RequirementManager::requirementsPage ( ) const

Definition at line 115 of file requirement.cpp.

116{
117 return p->reqPageDef;
118}

References p.

◆ writeRef()

void RequirementManager::writeRef ( OutputList & ol,
const RequirementRef & ref )

Definition at line 329 of file requirement.cpp.

330{
331 if (const RequirementIntf *req = RequirementManager::instance().find(ref.reqId()); req!=nullptr)
332 {
333 QCString title = ref.reqId();
334 if (!ref.title().isEmpty())
335 {
336 title +=" (";
337 title += parseCommentAsText(p->reqPageDef,nullptr,ref.title(),ref.file(),ref.line());
338 title +=")";
339 }
340 else if (!req->title().isEmpty())
341 {
342 title += " (";
343 title += req->title();
344 title += ")";
345 }
346 else
347 {
348 title = ref.reqId();
349 }
350 ol.writeObjectLink(QCString(),req->getOutputFileBase(),ref.reqId(),title);
351 }
352 else
353 {
354 ol.docify(ref.reqId());
355 }
356}
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:439
void docify(const QCString &s)
Definition outputlist.h:437
static RequirementManager & instance()
QCString title() const
Definition requirement.h:43
QCString reqId() const
Definition requirement.h:42
QCString file() const
Definition requirement.h:44
int line() const
Definition requirement.h:45

References OutputList::docify(), RequirementRef::file(), find(), instance(), QCString::isEmpty(), RequirementRef::line(), p, parseCommentAsText(), RequirementRef::reqId(), RequirementRef::title(), and OutputList::writeObjectLink().

◆ writeTagFile()

void RequirementManager::writeTagFile ( TextStream & tagFile)

Definition at line 358 of file requirement.cpp.

359{
360 if (!p->requirements.empty())
361 {
362 for (const auto &req : p->requirements)
363 {
364 tagFile << " <compound kind=\"requirement\">\n";
365 tagFile << " <id>" << req->id() << "</id>\n";
366 tagFile << " <title>" << convertToXML(req->title()) << "</title>\n";
367 QCString fn = req->getOutputFileBase();
369 tagFile << " <filename>" << fn << "</filename>\n";
370 tagFile << " </compound>\n";
371 }
372 }
373}
QCString convertToXML(const QCString &s, bool keepEntities)
Definition util.cpp:3893
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4902

References addHtmlExtensionIfMissing(), convertToXML(), and p.

Referenced by writeTagFile().

Member Data Documentation

◆ p

std::unique_ptr<Private> RequirementManager::p
private

The documentation for this class was generated from the following files: