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

#include <src/commentscan.h>

Classes

struct  Private

Public Member Functions

 CommentScanner ()
 ~CommentScanner ()
bool parseCommentBlock (OutlineParserInterface *parser, Entry *curEntry, const DString &comment, const DString &fileName, int &lineNr, bool isBrief, bool isJavadocStyle, bool isInbody, Protection &prot, int &position, bool &newEntryNeeded, bool markdownEnabled, GuardedSectionStack *guards)
 Invokes the comment block parser with the request to parse a single comment block.
void initGroupInfo (Entry *entry)
void enterFile (const DString &fileName, int lineNr)
void leaveFile (const DString &fileName, int lineNr)
void enterCompound (const DString &fileName, int line, const DString &name)
void leaveCompound (const DString &fileName, int line, const DString &name)
void open (Entry *e, const DString &fileName, int line, bool implicit=false)
void close (Entry *e, const DString &fileName, int line, bool foundInline, bool implicit=false)
void addDeprecatedDocs (Entry *current, const DString &fileName, int line, OutlineParserInterface *parser)

Static Public Member Functions

static bool isCommand (const DString &cmdName)

Private Attributes

std::unique_ptr< Privatep

Detailed Description

Definition at line 53 of file commentscan.h.

Constructor & Destructor Documentation

◆ CommentScanner()

CommentScanner::CommentScanner ( )

Definition at line 4970 of file commentscan.l.

4970 : p(std::make_unique<Private>())
4971{
4972 commentscanYYlex_init_extra(&p->extra,&p->yyscanner);
4973#ifdef FLEX_DEBUG
4974 commentscanYYset_debug(Debug::isFlagSet(Debug::Lex_commentscan)?1:0,p->yyscanner);
4975#endif
4976}
std::unique_ptr< Private > p
@ Lex_commentscan
Definition debug.h:56
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132

References Debug::isFlagSet(), Debug::Lex_commentscan, and p.

◆ ~CommentScanner()

CommentScanner::~CommentScanner ( )

Definition at line 4978 of file commentscan.l.

4979{
4980 commentscanYYlex_destroy(p->yyscanner);
4981}

References p.

Member Function Documentation

◆ addDeprecatedDocs()

void CommentScanner::addDeprecatedDocs ( Entry * current,
const DString & fileName,
int line,
OutlineParserInterface * parser )

Definition at line 5212 of file commentscan.l.

5213{
5214 static reg::Ex deprecated_re(R"(deprecated\s*(\‍(\s*\"([^\"]*)\"\s*\))?)");
5215 reg::Match match;
5216 std::string attr = current->attributes.str();
5217 if (reg::search(attr,match,deprecated_re))
5218 {
5219 DString docs;
5220 if (match.size()==3) // deprecated attribute with documentation
5221 {
5222 Markdown markdown(fileName,line);
5223 DString rawDoc = match[2].str();
5224 DString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(rawDoc,line) : rawDoc;
5225 std::shared_ptr<Entry> docEntry = std::make_shared<Entry>();
5226 GuardedSectionStack guards;
5227 bool newEntryNeeded = false;
5228 Protection prot = Protection::Public;
5229 int position=0;
5230 parseCommentBlock(parser,
5231 docEntry.get(),
5232 processedDoc,
5233 fileName,
5234 line,
5235 false, // isBrief
5236 false, // isAutoBriefOn
5237 false, // isInbody
5238 prot,
5239 position,
5240 newEntryNeeded,
5241 Config_getBool(MARKDOWN_SUPPORT), // markdownSupport
5242 &guards);
5243 docs = docEntry->doc;
5244 //printf("rawDoc='%s' processedDoc='%s' docs='%s'\n",qPrint(rawDoc),qPrint(processedDoc),qPrint(docs));
5245 }
5246 else // deprecated attribute without documentation
5247 {
5248 current->spec.setDeprAttr(true);
5249 }
5250 if (!docs.empty() || !current->spec.isDeprDoc()) // attribute has docs
5251 // or no @deprecated command found in comment yet
5252 {
5253 // add new deprecated xref item to the documentation of this entry
5254 addXRefItemToEntry(current,
5255 docs,
5256 "deprecated",
5259 false, // append
5260 false, // inBody
5261 line);
5262 }
5263 }
5264 else
5265 {
5266 //printf("no match in attributes='%s'\n",qPrint(attr));
5267 }
5268}
bool parseCommentBlock(OutlineParserInterface *parser, Entry *curEntry, const DString &comment, const DString &fileName, int &lineNr, bool isBrief, bool isJavadocStyle, bool isInbody, Protection &prot, int &position, bool &newEntryNeeded, bool markdownEnabled, GuardedSectionStack *guards)
Invokes the comment block parser with the request to parse a single comment block.
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
const std::string & str() const
Definition dstring.h:645
DString attributes
member's attributes (e.g. [[nodiscard]])
Definition entry.h:193
TypeSpecifier spec
class/member specifiers
Definition entry.h:181
virtual DString trDeprecatedList()=0
virtual DString trDeprecated()=0
std::stack< GuardedSection > GuardedSectionStack
Definition commentscan.h:48
static void addXRefItemToEntry(Entry *current, const DString &docs, const DString &baseName, const DString &itemTitle, const DString &listTitle, bool append, bool inBody, int lineNr)
#define Config_getBool(name)
Definition config.h:33
Translator * theTranslator
Definition language.cpp:76
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition regex.cpp:850
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:861
Protection
Definition types.h:32

References addXRefItemToEntry(), Entry::attributes, Config_getBool, DString::empty(), parseCommentBlock(), Markdown::process(), reg::search(), Entry::spec, DString::str(), theTranslator, Translator::trDeprecated(), and Translator::trDeprecatedList().

◆ close()

void CommentScanner::close ( Entry * e,
const DString & fileName,
int line,
bool foundInline,
bool implicit = false )

Definition at line 5201 of file commentscan.l.

5202{
5203 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
5204 yyextra->docGroup.close(e,fileName,lineNr,foundInline,implicit);
5205}

References p.

◆ enterCompound()

void CommentScanner::enterCompound ( const DString & fileName,
int line,
const DString & name )

Definition at line 5183 of file commentscan.l.

5184{
5185 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
5186 yyextra->docGroup.enterCompound(fileName,lineNr,name);
5187}

References p.

◆ enterFile()

void CommentScanner::enterFile ( const DString & fileName,
int lineNr )

Definition at line 5171 of file commentscan.l.

5172{
5173 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
5174 yyextra->docGroup.enterFile(fileName,lineNr);
5175}

References p.

Referenced by generateHtmlForComment().

◆ initGroupInfo()

void CommentScanner::initGroupInfo ( Entry * entry)

Definition at line 5165 of file commentscan.l.

5166{
5167 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
5168 yyextra->docGroup.initGroupInfo(entry);
5169}

References p.

◆ isCommand()

bool CommentScanner::isCommand ( const DString & cmdName)
static

Definition at line 5207 of file commentscan.l.

5208{
5209 return (docCmdMap.find(cmdName.str()) != docCmdMap.end());
5210}
static const std::unordered_map< std::string, DocCmdMap > docCmdMap

References docCmdMap, and DString::str().

Referenced by Markdown::Private::processLink().

◆ leaveCompound()

void CommentScanner::leaveCompound ( const DString & fileName,
int line,
const DString & name )

Definition at line 5189 of file commentscan.l.

5190{
5191 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
5192 yyextra->docGroup.leaveCompound(fileName,lineNr,name);
5193}

References p.

◆ leaveFile()

void CommentScanner::leaveFile ( const DString & fileName,
int lineNr )

Definition at line 5177 of file commentscan.l.

5178{
5179 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
5180 yyextra->docGroup.leaveFile(fileName,lineNr);
5181}

References p.

Referenced by generateHtmlForComment().

◆ open()

void CommentScanner::open ( Entry * e,
const DString & fileName,
int line,
bool implicit = false )

Definition at line 5195 of file commentscan.l.

5196{
5197 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
5198 yyextra->docGroup.open(e,fileName,lineNr,implicit);
5199}

References p.

◆ parseCommentBlock()

bool CommentScanner::parseCommentBlock ( OutlineParserInterface * parser,
Entry * curEntry,
const DString & comment,
const DString & fileName,
int & lineNr,
bool isBrief,
bool isJavadocStyle,
bool isInbody,
Protection & prot,
int & position,
bool & newEntryNeeded,
bool markdownEnabled,
GuardedSectionStack * guards )

Invokes the comment block parser with the request to parse a single comment block.

Parameters
[in]parserThe language parse that invoked this function. The comment block parse may invoke ParserInterface::parsePrototype() in order to parse the argument of a @fn command.
[in]curEntryThe Entry to which the comment block belongs. Any information (like documentation) that is found in the comment block will be stored in this entry.
[in]commentA string representing the actual comment block. Note that leading *'s are already stripped from the comment block.
[in]fileNameThe name of the file in which the comment is found. Mainly used for producing warnings.
[in,out]lineNrThe line number at which the comment block was found. When the function returns it will be set to the last line parsed.
[in]isBrieftrue iff this comment block represents a brief description.
[in]isJavadocStyletrue iff this comment block is in "Javadoc" style. This means that it starts as a brief description until the end of the sentences is found and then proceeds as a detailed description.
[in]isInbodytrue iff this comment block is located in the body of a function.
[in,out]protThe protection level in which this comment block was found. Commands in the comment block may override this.
[in,out]positionThe character position within comment where the comment block starts. Typically used in case the comment block contains multiple structural commands.
[out]newEntryNeededBoolean that is true if the comment block parser finds that a the comment block finishes the entry and a new one needs to be started.
[in]markdownEnabledIndicates if markdown specific processing should be done.
[in,out]guardsTracks nested conditional sections (if,ifnot,..)
Returns
true if the comment requires further processing. The parameter newEntryNeeded will typically be true in this case and position will indicate the offset inside the comment string where to proceed parsing. false indicates no further processing is needed.

Definition at line 4983 of file commentscan.l.

4997{
4998 AUTO_TRACE("comment='{}' fileName={} lineNr={} isBrief={} isAutoBriefOn={} inInbody={}"
4999 " prot={} markdownSupport={}",Trace::trunc(comment),fileName,lineNr,isBrief,
5000 isAutoBriefOn,isInbody,prot,markdownSupport);
5001 yyscan_t yyscanner = p->yyscanner;
5002 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
5003
5004 initParser(yyscanner);
5005 yyextra->guards = guards;
5006 yyextra->langParser = parser;
5007 yyextra->current = curEntry;
5008 yyextra->current->docLine = (lineNr > 1 ? lineNr : 1);
5009 if (comment.empty()) return false; // avoid empty strings
5010 yyextra->inputString = comment;
5011 yyextra->inputString.append(" ");
5012 yyextra->inputPosition = position;
5013 yyextra->lineNr = lineNr;
5014 yyextra->fileName = fileName;
5015 yyextra->protection = prot;
5016 yyextra->needNewEntry = false;
5017 yyextra->xrefKind = XRef_None;
5018 yyextra->xrefAppendFlag = false;
5019 yyextra->insidePre = false;
5020 yyextra->parseMore = false;
5021 yyextra->inBody = isInbody;
5022 yyextra->markdownSupport= markdownSupport;
5023 yyextra->outputXRef.clear();
5024 if (!isBrief && !isAutoBriefOn && !yyextra->current->doc.empty())
5025 { // add newline separator between detailed comment blocks
5026 yyextra->current->doc += '\n';
5027 }
5028 setOutput(yyscanner, isBrief || isAutoBriefOn ? OutputBrief : OutputDoc );
5029 yyextra->briefEndsAtDot = isAutoBriefOn;
5030 yyextra->condCount = 0;
5031 yyextra->sectionLevel = 0;
5032 yyextra->spaceBeforeCmd.clear();
5033 yyextra->spaceBeforeIf.clear();
5034 yyextra->htmlContextStack.clear();
5035
5036 DebugLex debugLex(Debug::Lex_commentscan, __FILE__, !fileName.empty() ? qPrint(fileName): nullptr);
5037 if (!yyextra->current->inbodyDocs.empty() && isInbody) // separate in body fragments
5038 {
5039 char cmd[30];
5040 snprintf(cmd,30,"\n\n\\iline %d \\ilinebr ",lineNr);
5041 yyextra->current->inbodyDocs+=cmd;
5042 }
5043
5044 Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: {}:{}\n"
5045 "input=[\n{}]\n",fileName,lineNr,yyextra->inputString
5046 );
5047
5048 commentscanYYrestart( nullptr, yyscanner );
5049 BEGIN( Comment );
5050 commentscanYYlex(yyscanner);
5051 setOutput(yyscanner, OutputDoc );
5052
5053 if (YY_START==OverloadParam) // comment ended with \overload
5054 {
5056 }
5057
5058 if (yyextra->insideParBlock)
5059 {
5060 warn(yyextra->fileName,yyextra->lineNr,
5061 "Documentation block ended while inside a \\parblock. Missing \\endparblock");
5062 }
5063
5064 yyextra->current->doc=stripLeadingAndTrailingEmptyLines(yyextra->current->doc,yyextra->current->docLine);
5065 yyextra->current->brief=stripLeadingAndTrailingEmptyLines(yyextra->current->brief,yyextra->current->docLine);
5066
5067 if (yyextra->current->section.isFileDoc() && yyextra->current->doc.empty())
5068 {
5069 // to allow a comment block with just a @file command.
5070 yyextra->current->doc="\n\n";
5071 }
5072
5073 if (yyextra->current->section.isMemberGrp() &&
5074 yyextra->docGroup.empty()) // @name section but no group started yet
5075 {
5076 yyextra->docGroup.open(yyextra->current,yyextra->fileName,yyextra->lineNr,true);
5077 }
5078
5079 Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: {}:{}\noutput=[\n"
5080 "brief=[line={}\n{}]\ndocs=[line={}\n{}]\ninbody=[line={}\n{}]\n]\n===========\n",
5081 fileName,lineNr,
5082 yyextra->current->briefLine,yyextra->current->brief,
5083 yyextra->current->docLine,yyextra->current->doc,
5084 yyextra->current->inbodyLine,yyextra->current->inbodyDocs
5085 );
5086
5087 checkFormula(yyscanner);
5088 prot = yyextra->protection;
5089
5090 yyextra->docGroup.addDocs(curEntry);
5091
5092 newEntryNeeded = yyextra->needNewEntry;
5093
5094 // if we did not proceed during this call, it does not make
5095 // sense to continue, since we get stuck. See bug 567346 for situations
5096 // were this happens
5097 if (yyextra->parseMore && position==yyextra->inputPosition) yyextra->parseMore=false;
5098
5099 if (!yyextra->parseMore && !yyextra->guards->empty())
5100 {
5101 warn(yyextra->fileName,yyextra->lineNr,"Documentation block ended in the middle of a conditional section!");
5102 }
5103
5104 if (yyextra->parseMore) position=yyextra->inputPosition; else position=0;
5105
5106 lineNr = yyextra->lineNr;
5107 AUTO_TRACE_EXIT("position={} parseMore={} newEntryNeeded={}",
5108 position,yyextra->parseMore,newEntryNeeded);
5109
5110 return yyextra->parseMore;
5111}
void clear()
Definition dstring.h:214
DString & append(char c)
Definition dstring.h:489
@ CommentScan
Definition debug.h:33
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:78
int docLine
line number at which the documentation was found
Definition entry.h:201
virtual DString trOverloadText()=0
yyguts_t * yyscan_t
Definition code.l:24
@ XRef_None
static void setOutput(yyscan_t yyscanner, OutputContext ctx)
static void initParser(yyscan_t yyscanner)
static void addOutput(yyscan_t yyscanner, const char *s)
@ OutputDoc
@ OutputBrief
static void checkFormula(yyscan_t yyscanner)
#define AUTO_TRACE(...)
Definition docnode.cpp:53
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:55
const char * qPrint(const char *s)
Definition dstring.h:783
#define warn(file, line, fmt,...)
Definition message.h:97
DString trunc(const DString &s, size_t numChars=15)
Definition trace.h:56
DString stripLeadingAndTrailingEmptyLines(const DString &s, int &docLine)
Special version of DString::stripWhiteSpace() that only strips completely blank lines.
Definition util.cpp:3987

References addOutput(), DString::append(), AUTO_TRACE, AUTO_TRACE_EXIT, checkFormula(), Debug::CommentScan, Entry::docLine, DString::empty(), initParser(), Debug::Lex_commentscan, OutputBrief, OutputDoc, p, Debug::print(), qPrint(), setOutput(), stripLeadingAndTrailingEmptyLines(), theTranslator, Translator::trOverloadText(), Trace::trunc(), warn, and XRef_None.

Referenced by addDeprecatedDocs(), generateHtmlForComment(), and CitationManager::generatePage().

Member Data Documentation

◆ p

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

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