Doxygen
Loading...
Searching...
No Matches
DocParser Class Referencefinal

#include <src/docparser_p.h>

Inheritance diagram for DocParser:
Collaboration diagram for DocParser:

Classes

class  AutoSaveContext

Public Member Functions

void handleImg (DocNodeVariant *parent, DocNodeList &children, const HtmlAttribList &tagHtmlAttribs)
Token internalValidatingParseDoc (DocNodeVariant *parent, DocNodeList &children, const DString &doc)
DString processCopyDoc (const char *data, size_t &len)
DString findAndCopyImage (const DString &fileName, DocImage::Type type, bool doWarn=true)
void checkArgumentName ()
void checkRetvalName ()
void checkUnOrMultipleDocumentedParams ()
bool findDocsForMemberOrCompound (const DString &commandName, DString *pDoc, DString *pBrief, const Definition **pDef)
bool defaultHandleToken (DocNodeVariant *parent, Token &tok, DocNodeList &children, bool handleWord=true)
void errorHandleDefaultToken (DocNodeVariant *parent, Token tok, DocNodeList &children, const DString &txt)
void defaultHandleTitleAndSize (const CommandType cmd, DocNodeVariant *parent, DocNodeList &children, DString &width, DString &height)
Token handleStyleArgument (DocNodeVariant *parent, DocNodeList &children, const DString &cmdName)
void handleStyleEnter (DocNodeVariant *parent, DocNodeList &children, DocStyleChange::Style s, const DString &tagName, const HtmlAttribList *attribs)
void handleStyleLeave (DocNodeVariant *parent, DocNodeList &children, DocStyleChange::Style s, const DString &tagName)
void handlePendingStyleCommands (DocNodeVariant *parent, DocNodeList &children, size_t numberOfElementsToClose=0)
void handleInitialStyleCommands (DocNodeVariant *parent, DocNodeList &children)
Token handleAHref (DocNodeVariant *parent, DocNodeList &children, const HtmlAttribList &tagHtmlAttribs)
void handleUnclosedStyleCommands ()
void handleLinkedWord (DocNodeVariant *parent, DocNodeList &children, bool ignoreAutoLinkFlag=false, bool typeLinkOnly=false)
void handleParameterType (DocNodeVariant *parent, DocNodeList &children, const DString &paramTypes)
void handleInternalRef (DocNodeVariant *parent, DocNodeList &children)
void handleAnchor (DocNodeVariant *parent, DocNodeList &children)
void handleCite (DocNodeVariant *parent, DocNodeList &children)
void handlePrefix (DocNodeVariant *parent, DocNodeList &children)
void handleImage (DocNodeVariant *parent, DocNodeList &children)
void handleRef (DocNodeVariant *parent, DocNodeList &children, char cmdChar, const DString &cmdName)
void handleIFile (char cmdChar, const DString &cmdName)
void handleILine (char cmdChar, const DString &cmdName)
void readTextFileByName (const DString &file, DString &text)

Public Attributes

std::stack< DocParserContextcontextStack
DocParserContext context
DocTokenizer tokenizer

Private Member Functions

void pushContext ()
void popContext ()

Detailed Description

Definition at line 101 of file docparser_p.h.

Member Function Documentation

◆ checkArgumentName()

void DocParser::checkArgumentName ( )

Collects the parameters found with @param command in a list context.paramsFound. If the parameter is not an actual parameter of the current member context.memberDef, then a warning is raised (unless warnings are disabled altogether).

Definition at line 209 of file docparser.cpp.

210{
211 if (!(Config_getBool(WARN_IF_DOC_ERROR) || Config_getBool(WARN_IF_INCOMPLETE_DOC))) return;
212 if (context.memberDef==nullptr) return; // not a member
213 std::string name = context.token->name.str();
214 const ArgumentList &al=context.memberDef->isDocsForDefinition() ?
218 context.numParameters = static_cast<int>(al.size());
219 //printf("isDocsForDefinition()=%d\n",context.memberDef->isDocsForDefinition());
220 if (al.empty()) return; // no argument list
221
222 static const reg::Ex re(R"(\$?\w+\.*)");
223 static const reg::Ex re_digits(R"(\d+)");
224 reg::Iterator it(name,re);
225 reg::Iterator end;
226 for (; it!=end ; ++it)
227 {
228 const auto &match = *it;
229 DString aName=match.str();
230 int number = reg::match(aName.view(),re_digits) ? std::atoi(aName.data()) : -1;
231 if (lang==SrcLangExt::Fortran) aName=aName.lower();
232 //printf("aName='%s'\n",qPrint(aName));
233 bool found=false;
234 int position=1;
235 for (const Argument &a : al)
236 {
237 DString argName = context.memberDef->isDefine() ? a.type : a.name;
238 if (lang==SrcLangExt::Fortran) argName=argName.lower();
239 argName=argName.stripWhiteSpace();
240 //printf("argName='%s' aName=%s\n",qPrint(argName),qPrint(aName));
241 if (argName.endsWith("...")) argName=argName.left(argName.length()-3);
242 bool sameName = aName==argName;
243 bool samePosition = position==number;
244 if (samePosition || sameName) // @param <number> or @param name
245 {
246 if (!sameName) // replace positional argument with real name or -
247 {
248 context.token->name = argName.empty() ? "-" : argName;
249 }
250 context.paramsFound.insert(aName.str());
251 found=true;
252 break;
253 }
254 else if (aName==".") // replace . by - in the output
255 {
256 context.token->name = "-";
257 }
258 position++;
259 }
260 if (!found)
261 {
262 //printf("member type=%d\n",context.memberDef->memberType());
263 DString scope=context.memberDef->getScopeString();
264 if (!scope.empty()) scope+="::"; else scope="";
265 DString inheritedFrom = "";
266 DString docFile = context.memberDef->docFile();
267 int docLine = context.memberDef->docLine();
268 const MemberDef *inheritedMd = context.memberDef->inheritsDocsFrom();
269 if (inheritedMd) // documentation was inherited
270 {
271 inheritedFrom.sprintf(" inherited from member %s at line "
272 "%d in file %s",qPrint(inheritedMd->name()),
273 inheritedMd->docLine(),qPrint(inheritedMd->docFile()));
274 docFile = context.memberDef->getDefFileName();
275 docLine = context.memberDef->getDefLine();
276 }
277 DString alStr = argListToString(al);
278 if (number==0)
279 {
280 warn_doc_error(docFile,docLine,
281 "positional argument with value '0' of command @param "
282 "is invalid, first parameter has index '1' for {}{}{}{}",
283 scope, context.memberDef->name(),
284 alStr, inheritedFrom);
285 context.token->name = "-";
286 }
287 else if (number>0)
288 {
289 warn_doc_error(docFile,docLine,
290 "positional argument '{}' of command @param "
291 "is larger than the number of parameters ({}) for {}{}{}{}",
292 number, al.size(), scope, context.memberDef->name(),
293 alStr, inheritedFrom);
294 context.token->name = "-";
295 }
296 else
297 {
298 warn_doc_error(docFile,docLine,
299 "argument '{}' of command @param "
300 "is not found in the argument list of {}{}{}{}",
301 aName, scope, context.memberDef->name(),
302 alStr, inheritedFrom);
303 }
304 }
305 }
306}
size_t size() const
Definition arguments.h:100
bool empty() const
Definition arguments.h:99
DString lower() const
Definition dstring.h:331
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:153
std::string_view view() const
Definition dstring.h:167
DString & sprintf(const char *format,...)
Definition dstring.cpp:29
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:342
DString left(size_t len) const
Definition dstring.h:311
const std::string & str() const
Definition dstring.h:634
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition dstring.h:162
bool endsWith(const char *s) const
Definition dstring.h:606
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:156
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual int docLine() const =0
virtual DString getDefFileName() const =0
virtual int getDefLine() const =0
virtual const DString & name() const =0
virtual DString docFile() const =0
DocParserContext context
virtual const MemberDef * inheritsDocsFrom() const =0
virtual const ArgumentList & argumentList() const =0
virtual bool isDocsForDefinition() const =0
virtual bool isDefine() const =0
virtual DString getScopeString() const =0
virtual const ArgumentList & declArgumentList() const =0
#define Config_getBool(name)
Definition config.h:33
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:175
const char * qPrint(const char *s)
Definition dstring.h:769
#define warn_doc_error(file, line, fmt,...)
Definition message.h:112
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:858
StringMultiSet paramsFound
Definition docparser_p.h:77
TokenInfo * token
Definition docparser_p.h:95
const MemberDef * memberDef
Definition docparser_p.h:80
DString name
SrcLangExt
Definition types.h:207
DString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1253

References argListToString(), MemberDef::argumentList(), Config_getBool, context, DString::data(), MemberDef::declArgumentList(), Definition::docFile(), Definition::docLine(), ArgumentList::empty(), DString::empty(), end(), DString::endsWith(), Definition::getDefFileName(), Definition::getDefLine(), Definition::getLanguage(), MemberDef::getScopeString(), MemberDef::inheritsDocsFrom(), MemberDef::isDefine(), MemberDef::isDocsForDefinition(), DString::left(), DString::length(), DString::lower(), reg::match(), DocParserContext::memberDef, Definition::name(), TokenInfo::name, DocParserContext::numParameters, DocParserContext::paramsFound, qPrint(), ArgumentList::size(), DString::size(), DString::sprintf(), DString::str(), DString::stripWhiteSpace(), DocParserContext::token, DString::view(), and warn_doc_error.

Referenced by DocParamList::parse(), and DocParamList::parseXml().

◆ checkRetvalName()

void DocParser::checkRetvalName ( )

Collects the return values found with @retval command in a global list g_parserContext.retvalsFound.

Definition at line 310 of file docparser.cpp.

311{
312 DString name = context.token->name;
313 if (!Config_getBool(WARN_IF_DOC_ERROR)) return;
314 if (context.memberDef==nullptr || name.empty()) return; // not a member or no valid name
315 if (context.retvalsFound.count(name.str())==1) // only report the first double entry
316 {
319 "return value '{}' of {} has multiple documentation sections",
321 }
322 context.retvalsFound.insert(name.str());
323}
virtual DString qualifiedName() const =0
StringMultiSet retvalsFound
Definition docparser_p.h:76

References Config_getBool, context, DString::empty(), Definition::getDefFileName(), Definition::getDefLine(), DocParserContext::memberDef, TokenInfo::name, Definition::qualifiedName(), DocParserContext::retvalsFound, DString::str(), DocParserContext::token, and warn_doc_error.

Referenced by DocParamList::parse(), and DocParamList::parseXml().

◆ checkUnOrMultipleDocumentedParams()

void DocParser::checkUnOrMultipleDocumentedParams ( )

Checks if the parameters that have been specified using @param are indeed all parameters and that a parameter does not have multiple @param blocks. Must be called after checkArgumentName() has been called for each argument.

Definition at line 331 of file docparser.cpp.

332{
334 {
335 const ArgumentList &al=context.memberDef->isDocsForDefinition() ?
339 if (!al.empty())
340 {
341 ArgumentList undocParams;
342 int position = 1;
343 for (const Argument &a: al)
344 {
345 DString argName = context.memberDef->isDefine() ? a.type : a.name;
346 if (lang==SrcLangExt::Fortran) argName = argName.lower();
347 argName=argName.stripWhiteSpace();
348 DString aName = argName;
349 if (argName.endsWith("...")) argName=argName.left(argName.length()-3);
350 if (lang==SrcLangExt::Python && (argName=="self" || argName=="cls"))
351 {
352 // allow undocumented self / cls parameter for Python
353 }
354 else if (lang==SrcLangExt::Cpp && (a.type=="this" || a.type.startsWith("this ")))
355 {
356 // allow undocumented this (for C++23 deducing this), see issue #11123
357 }
358 else if (!argName.empty())
359 {
360 size_t count_named = context.paramsFound.count(argName.str());
361 size_t count_positional = context.paramsFound.count(std::to_string(position));
362 if (count_named==0 && count_positional==0 && a.docs.empty())
363 {
364 undocParams.push_back(a);
365 }
366 else if (count_named==1 && count_positional==1 && Config_getBool(WARN_IF_DOC_ERROR))
367 {
370 "argument {} from the argument list of {} has both named and positional @param documentation sections",
372 }
373 else if (count_named+count_positional>1 && Config_getBool(WARN_IF_DOC_ERROR))
374 {
377 "argument {} from the argument list of {} has multiple @param documentation sections",
379 }
380 }
381 position++;
382 }
383 if (!undocParams.empty() && Config_getBool(WARN_IF_INCOMPLETE_DOC))
384 {
385 bool first=true;
386 DString errMsg = "The following parameter";
387 if (undocParams.size()>1) errMsg+="s";
388 errMsg+=DString(" of ")+
390 argListToString(al) +
391 (undocParams.size()>1 ? " are" : " is") + " not documented:\n";
392 for (const Argument &a : undocParams)
393 {
394 DString argName = context.memberDef->isDefine() ? a.type : a.name;
395 if (lang==SrcLangExt::Fortran) argName = argName.lower();
396 argName=argName.stripWhiteSpace();
397 if (!first) errMsg+="\n";
398 first=false;
399 errMsg+=" parameter '"+argName+"'";
400 }
402 }
403
404 if (Config_getBool(WARN_IF_DOC_ERROR) && context.paramPosition-1 > context.numParameters)
405 {
408 "too many @param commands for function {}. Found {} while function has {} parameter{}",
410 }
411 }
412 else
413 {
414 if (context.paramsFound.empty() && Config_getBool(WARN_IF_DOC_ERROR))
415 {
418 "{} has @param documentation sections but no arguments",
420 }
421 }
422 }
423}
void push_back(const Argument &a)
Definition arguments.h:102
DString()=default
#define warn_incomplete_doc(file, line, fmt,...)
Definition message.h:107

References argListToString(), MemberDef::argumentList(), Config_getBool, context, MemberDef::declArgumentList(), Definition::docFile(), Definition::docLine(), DString::DString(), ArgumentList::empty(), DString::empty(), DString::endsWith(), Definition::getLanguage(), DocParserContext::hasParamCommand, MemberDef::isDefine(), MemberDef::isDocsForDefinition(), DString::left(), DString::length(), DString::lower(), DocParserContext::memberDef, DocParserContext::numParameters, DocParserContext::paramPosition, DocParserContext::paramsFound, ArgumentList::push_back(), Definition::qualifiedName(), ArgumentList::size(), DString::str(), DString::stripWhiteSpace(), warn_doc_error, and warn_incomplete_doc.

Referenced by validatingParseDoc().

◆ defaultHandleTitleAndSize()

void DocParser::defaultHandleTitleAndSize ( const CommandType cmd,
DocNodeVariant * parent,
DocNodeList & children,
DString & width,
DString & height )

Definition at line 1209 of file docparser.cpp.

1210{
1211 AUTO_TRACE();
1212 auto ns = AutoNodeStack(this,parent);
1213
1214 // parse title
1216 Token tok = tokenizer.lex();
1217 while (!tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1218 {
1219 if (tok.is(TokenRetval::TK_WORD) && (context.token->name=="width=" || context.token->name=="height="))
1220 {
1221 // special case: no title, but we do have a size indicator
1222 break;
1223 }
1224 else if (tok.is(TokenRetval::TK_HTMLTAG))
1225 {
1227 break;
1228 }
1229 if (!defaultHandleToken(parent,tok,children))
1230 {
1231 errorHandleDefaultToken(parent,tok,children,Mappers::cmdMapper->find(cmd));
1232 }
1233 tok = tokenizer.lex();
1234 }
1235 // parse size attributes
1236 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1237 {
1238 tok=tokenizer.lex();
1239 }
1240 while (tok.is_any_of(TokenRetval::TK_WHITESPACE,TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG)) // there are values following the title
1241 {
1242 if (tok.is(TokenRetval::TK_WORD))
1243 {
1244 if (context.token->name=="width=" || context.token->name=="height=")
1245 {
1248 }
1249
1250 if (context.token->name=="width")
1251 {
1252 width = context.token->chars;
1253 }
1254 else if (context.token->name=="height")
1255 {
1256 height = context.token->chars;
1257 }
1258 else // other text after the title -> treat as normal text
1259 {
1261 //warn_doc_error(context.fileName,tokenizer.getLineNr(),"Unknown option '{}' after \\{} command, expected 'width' or 'height'",
1262 // context.token->name, Mappers::cmdMapper->find(cmd));
1263 break;
1264 }
1265 }
1266
1267 tok=tokenizer.lex();
1268 // if we found something we did not expect, push it back to the stream
1269 // so it can still be processed
1270 if (tok.is_any_of(TokenRetval::TK_COMMAND_AT,TokenRetval::TK_COMMAND_BS))
1271 {
1273 tokenizer.unputString(tok.is(TokenRetval::TK_COMMAND_AT) ? "@" : "\\");
1274 break;
1275 }
1276 else if (tok.is(TokenRetval::TK_SYMBOL))
1277 {
1279 break;
1280 }
1281 else if (tok.is(TokenRetval::TK_HTMLTAG))
1282 {
1284 break;
1285 }
1286 }
1288
1290 AUTO_TRACE_EXIT("width={} height={}",width,height);
1291}
AutoNodeStack(DocParser *parser, DocNodeVariant *node)
void handlePendingStyleCommands(DocNodeVariant *parent, DocNodeList &children, size_t numberOfElementsToClose=0)
DocTokenizer tokenizer
void errorHandleDefaultToken(DocNodeVariant *parent, Token tok, DocNodeList &children, const DString &txt)
bool defaultHandleToken(DocNodeVariant *parent, Token &tok, DocNodeList &children, bool handleWord=true)
void setStateTitleAttrValue()
void unputString(const DString &tag)
void setStateTitle()
void setStatePara()
bool is(TokenRetval rv) const
bool is_any_of(ARGS... args) const
#define AUTO_TRACE(...)
Definition docnode.cpp:48
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:50
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1335
const Mapper< CommandType > * cmdMapper
DString chars
DString text

References AUTO_TRACE, AUTO_TRACE_EXIT, AutoNodeStack::AutoNodeStack(), TokenInfo::chars, Mappers::cmdMapper, context, defaultHandleToken(), errorHandleDefaultToken(), handlePendingStyleCommands(), Token::is(), Token::is_any_of(), DString::left(), DString::length(), DocTokenizer::lex(), TokenInfo::name, parent(), DocTokenizer::setStatePara(), DocTokenizer::setStateTitle(), DocTokenizer::setStateTitleAttrValue(), TokenInfo::text, DocParserContext::token, tokenizer, and DocTokenizer::unputString().

Referenced by DocPara::handleCommand(), DocDiaFile::parse(), DocDotFile::parse(), DocImage::parse(), DocMermaidFile::parse(), DocMscFile::parse(), and DocPlantUmlFile::parse().

◆ defaultHandleToken()

bool DocParser::defaultHandleToken ( DocNodeVariant * parent,
Token & tok,
DocNodeList & children,
bool handleWord = true )

Definition at line 1472 of file docparser.cpp.

1473{
1474 AUTO_TRACE("token={} handleWord={}",tok.to_string(),handleWord);
1475 if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD,TokenRetval::TK_SYMBOL,TokenRetval::TK_URL,
1476 TokenRetval::TK_COMMAND_AT,TokenRetval::TK_COMMAND_BS,TokenRetval::TK_HTMLTAG)
1477 )
1478 {
1479 }
1480reparsetoken:
1481 DString tokenName = context.token->name;
1482 AUTO_TRACE_ADD("tokenName={}",tokenName);
1483 switch (tok.value())
1484 {
1485 case TokenRetval::TK_COMMAND_AT:
1486 // fall through
1487 case TokenRetval::TK_COMMAND_BS:
1488 switch (Mappers::cmdMapper->map(tokenName))
1489 {
1491 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_BSlash);
1492 break;
1494 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_At);
1495 break;
1497 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Less);
1498 break;
1500 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Greater);
1501 break;
1503 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Amp);
1504 break;
1506 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dollar);
1507 break;
1509 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Hash);
1510 break;
1512 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_DoubleColon);
1513 break;
1515 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Percent);
1516 break;
1518 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1519 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1520 break;
1522 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1523 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1524 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1525 break;
1527 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quot);
1528 break;
1530 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dot);
1531 break;
1533 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Exclam);
1534 break;
1536 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quest);
1537 break;
1539 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Plus);
1540 break;
1542 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1543 break;
1545 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Equal);
1546 break;
1548 {
1549 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,true);
1550 tok=handleStyleArgument(parent,children,tokenName);
1551 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,false);
1552 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1553 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1554 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1555 {
1556 AUTO_TRACE_ADD("CommandType::CMD_EMPHASIS: reparsing");
1557 goto reparsetoken;
1558 }
1559 }
1560 break;
1562 {
1563 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,true);
1564 tok=handleStyleArgument(parent,children,tokenName);
1565 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,false);
1566 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1567 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1568 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1569 {
1570 AUTO_TRACE_ADD("CommandType::CMD_BOLD: reparsing");
1571 goto reparsetoken;
1572 }
1573 }
1574 break;
1576 {
1577 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,true);
1578 tok=handleStyleArgument(parent,children,tokenName);
1579 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,false);
1580 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1581 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1582 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1583 {
1584 AUTO_TRACE_ADD("CommandType::CMD_CODE: reparsing");
1585 goto reparsetoken;
1586 }
1587 }
1588 break;
1590 {
1592 tok = tokenizer.lex();
1594 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1595 {
1596 warn_doc_error(context.fileName,tokenizer.getLineNr(),"htmlonly section ended without end marker");
1597 }
1599 }
1600 break;
1602 {
1604 tok = tokenizer.lex();
1606 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1607 {
1608 warn_doc_error(context.fileName,tokenizer.getLineNr(),"manonly section ended without end marker");
1609 }
1611 }
1612 break;
1614 {
1616 tok = tokenizer.lex();
1618 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1619 {
1620 warn_doc_error(context.fileName,tokenizer.getLineNr(),"rtfonly section ended without end marker");
1621 }
1623 }
1624 break;
1626 {
1628 tok = tokenizer.lex();
1630 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1631 {
1632 warn_doc_error(context.fileName,tokenizer.getLineNr(),"latexonly section ended without end marker");
1633 }
1635 }
1636 break;
1638 {
1640 tok = tokenizer.lex();
1642 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1643 {
1644 warn_doc_error(context.fileName,tokenizer.getLineNr(),"xmlonly section ended without end marker");
1645 }
1647 }
1648 break;
1650 {
1652 tok = tokenizer.lex();
1654 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1655 {
1656 warn_doc_error(context.fileName,tokenizer.getLineNr(),"docbookonly section ended without end marker");
1657 }
1659 }
1660 break;
1662 {
1663 children.append<DocFormula>(this,parent,context.token->id);
1664 }
1665 break;
1668 {
1669 handleAnchor(parent,children);
1670 }
1671 break;
1673 {
1674 handleCite(parent,children);
1675 }
1676 break;
1678 {
1679 handlePrefix(parent,children);
1680 }
1681 break;
1683 {
1684 handleInternalRef(parent,children);
1686 }
1687 break;
1689 {
1691 (void)tokenizer.lex();
1693 //printf("Found scope='%s'\n",qPrint(context.context));
1695 }
1696 break;
1698 handleImage(parent,children);
1699 break;
1701 handleILine(tok.command_to_char(),tokenName);
1702 break;
1704 handleIFile(tok.command_to_char(),tokenName);
1705 break;
1706 default:
1707 return false;
1708 }
1709 break;
1710 case TokenRetval::TK_HTMLTAG:
1711 {
1712 auto handleEnterLeaveStyle = [this,&parent,&children,&tokenName](DocStyleChange::Style style) {
1713 if (!context.token->endTag)
1714 {
1715 handleStyleEnter(parent,children,style,tokenName,&context.token->attribs);
1716 }
1717 else
1718 {
1719 handleStyleLeave(parent,children,style,tokenName);
1720 }
1721 };
1722 switch (Mappers::htmlTagMapper->map(tokenName))
1723 {
1725 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <div> tag in heading");
1726 break;
1728 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <pre> tag in heading");
1729 break;
1731 handleEnterLeaveStyle(DocStyleChange::Span);
1732 break;
1734 handleEnterLeaveStyle(DocStyleChange::Bold);
1735 break;
1737 handleEnterLeaveStyle(DocStyleChange::S);
1738 break;
1740 handleEnterLeaveStyle(DocStyleChange::Strike);
1741 break;
1743 handleEnterLeaveStyle(DocStyleChange::Del);
1744 break;
1746 handleEnterLeaveStyle(DocStyleChange::Underline);
1747 break;
1749 handleEnterLeaveStyle(DocStyleChange::Ins);
1750 break;
1752 case HtmlTagType::XML_C:
1753 handleEnterLeaveStyle(DocStyleChange::Code);
1754 break;
1756 handleEnterLeaveStyle(DocStyleChange::Kbd);
1757 break;
1759 handleEnterLeaveStyle(DocStyleChange::Typewriter);
1760 break;
1762 handleEnterLeaveStyle(DocStyleChange::Italic);
1763 break;
1765 handleEnterLeaveStyle(DocStyleChange::Subscript);
1766 break;
1768 handleEnterLeaveStyle(DocStyleChange::Superscript);
1769 break;
1771 handleEnterLeaveStyle(DocStyleChange::Center);
1772 break;
1774 handleEnterLeaveStyle(DocStyleChange::Small);
1775 break;
1777 handleEnterLeaveStyle(DocStyleChange::Cite);
1778 break;
1780 if (!context.token->endTag)
1781 {
1783 }
1784 break;
1785 default:
1786 return false;
1787 break;
1788 }
1789 }
1790 break;
1791 case TokenRetval::TK_SYMBOL:
1792 {
1795 {
1796 children.append<DocSymbol>(this,parent,s);
1797 }
1798 else
1799 {
1800 return false;
1801 }
1802 }
1803 break;
1804 case TokenRetval::TK_WHITESPACE:
1805 case TokenRetval::TK_NEWPARA:
1806handlepara:
1807 if (insidePRE(parent) || !children.empty())
1808 {
1809 children.append<DocWhiteSpace>(this,parent,context.token->chars);
1810 }
1811 break;
1812 case TokenRetval::TK_LNKWORD:
1813 if (handleWord)
1814 {
1815 handleLinkedWord(parent,children);
1816 }
1817 else
1818 return false;
1819 break;
1820 case TokenRetval::TK_WORD:
1821 if (handleWord)
1822 {
1823 children.append<DocWord>(this,parent,context.token->name);
1824 }
1825 else
1826 return false;
1827 break;
1828 case TokenRetval::TK_URL:
1830 {
1831 children.append<DocWord>(this,parent,context.token->name);
1832 }
1833 else
1834 {
1835 children.append<DocURL>(this,parent,context.token->name,context.token->isEMailAddr);
1836 }
1837 break;
1838 default:
1839 return false;
1840 }
1841 return true;
1842}
void handleIFile(char cmdChar, const DString &cmdName)
void handleInternalRef(DocNodeVariant *parent, DocNodeList &children)
void handleStyleEnter(DocNodeVariant *parent, DocNodeList &children, DocStyleChange::Style s, const DString &tagName, const HtmlAttribList *attribs)
Token handleStyleArgument(DocNodeVariant *parent, DocNodeList &children, const DString &cmdName)
void handleStyleLeave(DocNodeVariant *parent, DocNodeList &children, DocStyleChange::Style s, const DString &tagName)
void handleImage(DocNodeVariant *parent, DocNodeList &children)
void handleLinkedWord(DocNodeVariant *parent, DocNodeList &children, bool ignoreAutoLinkFlag=false, bool typeLinkOnly=false)
void handleCite(DocNodeVariant *parent, DocNodeList &children)
void handlePrefix(DocNodeVariant *parent, DocNodeList &children)
void handleILine(char cmdChar, const DString &cmdName)
void handleAnchor(DocNodeVariant *parent, DocNodeList &children)
void handleImg(DocNodeVariant *parent, DocNodeList &children, const HtmlAttribList &tagHtmlAttribs)
static HtmlEntityMapper::SymType decodeSymbol(const DString &symName)
Definition docnode.cpp:155
void setStateRtfOnly()
void setStateLatexOnly()
void setStateManOnly()
int getLineNr() const
void setStateDbOnly()
void setStateHtmlOnly()
void setStateXmlOnly()
void setStateSetScope()
TOKEN_SPECIFICATIONS RETVAL_SPECIFICATIONS const char * to_string() const
TokenRetval value() const
char command_to_char() const
@ CMD_INTERNALREF
Definition cmdmapper.h:65
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:49
bool insidePRE(const DocNodeVariant *n)
const Mapper< HtmlTagType > * htmlTagMapper
void append(Args &&... args)
Append a new DocNodeVariant to the list by constructing it with type T and parameters Args.
Definition docnode.h:1404
DocNodeStack nodeStack
Definition docparser_p.h:67
DString exampleName
Definition docparser_p.h:82
DString verb
HtmlAttribList attribs
bool isEMailAddr

References DocNodeList::append(), TokenInfo::attribs, AUTO_TRACE, AUTO_TRACE_ADD, DocStyleChange::Bold, DocStyleChange::Center, TokenInfo::chars, DocStyleChange::Cite, CMD_AMP, CMD_ANCHOR, CMD_AT, CMD_BOLD, CMD_BSLASH, CMD_CITE, CMD_CODE, CMD_DBONLY, CMD_DCOLON, CMD_DOLLAR, CMD_EMPHASIS, CMD_EQUAL, CMD_EXCLAMATION, CMD_FORMULA, CMD_GREATER, CMD_HASH, CMD_HTMLONLY, CMD_IANCHOR, CMD_IFILE, CMD_ILINE, CMD_IMAGE, CMD_INTERNALREF, CMD_IPREFIX, CMD_LATEXONLY, CMD_LESS, CMD_MANONLY, CMD_MDASH, CMD_MINUS, CMD_NDASH, CMD_PERCENT, CMD_PLUS, CMD_PUNT, CMD_QUESTION, CMD_QUOTE, CMD_RTFONLY, CMD_SETSCOPE, CMD_XMLONLY, Mappers::cmdMapper, DocStyleChange::Code, Token::command_to_char(), context, DocParserContext::context, DocSymbol::decodeSymbol(), DocStyleChange::Del, DocVerbatim::DocbookOnly, GrowVector< T >::empty(), TokenInfo::endTag, DocParserContext::exampleName, DocParserContext::fileName, DocTokenizer::getLineNr(), handleAnchor(), handleCite(), handleIFile(), handleILine(), handleImage(), handleImg(), handleInternalRef(), handleLinkedWord(), handlePrefix(), handleStyleArgument(), handleStyleEnter(), handleStyleLeave(), HTML_BOLD, HTML_CENTER, HTML_CITE, HTML_CODE, HTML_DEL, HTML_DIV, HTML_EMPHASIS, HTML_IMG, HTML_INS, HTML_KBD, HTML_PRE, HTML_S, HTML_SMALL, HTML_SPAN, HTML_STRIKE, HTML_SUB, HTML_SUP, HTML_TT, HTML_UNDERLINE, DocVerbatim::HtmlOnly, Mappers::htmlTagMapper, TokenInfo::id, DocStyleChange::Ins, DocParserContext::insideHtmlLink, insidePRE(), Token::is(), Token::is_any_of(), TokenInfo::isEMailAddr, DocParserContext::isExample, DocStyleChange::Italic, DocStyleChange::Kbd, DocVerbatim::LatexOnly, DocTokenizer::lex(), DocVerbatim::ManOnly, TokenInfo::name, DocParserContext::nodeStack, parent(), DocVerbatim::RtfOnly, DocStyleChange::S, DocTokenizer::setStateDbOnly(), DocTokenizer::setStateHtmlOnly(), DocTokenizer::setStateLatexOnly(), DocTokenizer::setStateManOnly(), DocTokenizer::setStatePara(), DocTokenizer::setStateRtfOnly(), DocTokenizer::setStateSetScope(), DocTokenizer::setStateXmlOnly(), DocStyleChange::Small, DocStyleChange::Span, DocStyleChange::Strike, DocStyleChange::Subscript, DocStyleChange::Superscript, HtmlEntityMapper::Sym_Amp, HtmlEntityMapper::Sym_At, HtmlEntityMapper::Sym_BSlash, HtmlEntityMapper::Sym_Dollar, HtmlEntityMapper::Sym_Dot, HtmlEntityMapper::Sym_DoubleColon, HtmlEntityMapper::Sym_Equal, HtmlEntityMapper::Sym_Exclam, HtmlEntityMapper::Sym_Greater, HtmlEntityMapper::Sym_Hash, HtmlEntityMapper::Sym_Less, HtmlEntityMapper::Sym_Minus, HtmlEntityMapper::Sym_Percent, HtmlEntityMapper::Sym_Plus, HtmlEntityMapper::Sym_Quest, HtmlEntityMapper::Sym_Quot, HtmlEntityMapper::Sym_Unknown, Token::to_string(), DocParserContext::token, tokenizer, DocStyleChange::Typewriter, DocStyleChange::Underline, Token::value(), TokenInfo::verb, warn_doc_error, XML_C, and DocVerbatim::XmlOnly.

Referenced by defaultHandleTitleAndSize(), handleStyleArgument(), and DocPara::injectToken().

◆ errorHandleDefaultToken()

void DocParser::errorHandleDefaultToken ( DocNodeVariant * parent,
Token tok,
DocNodeList & children,
const DString & txt )

Definition at line 591 of file docparser.cpp.

593{
594 switch (tok.value())
595 {
596 case TokenRetval::TK_COMMAND_AT:
597 // fall through
598 case TokenRetval::TK_COMMAND_BS:
599 {
600 char cs[2] = { tok.command_to_char(), 0 };
601 children.append<DocWord>(this,parent,cs + context.token->name);
602 warn_doc_error(context.fileName,tokenizer.getLineNr(),"Illegal command '{:c}{}' found as part of a {}",
603 tok.command_to_char(),context.token->name,txt);
604 }
605 break;
606 case TokenRetval::TK_SYMBOL:
607 warn_doc_error(context.fileName,tokenizer.getLineNr(),"Unsupported symbol '{}' found as part of a {}",
608 qPrint(context.token->name), qPrint(txt));
609 break;
610 case TokenRetval::TK_HTMLTAG:
611 warn_doc_error(context.fileName,tokenizer.getLineNr(),"Unsupported HTML tag <{}{}> found as part of a {}",
612 context.token->endTag ? "/" : "",context.token->name, txt);
613 break;
614 default:
615 children.append<DocWord>(this,parent,context.token->name);
616 warn_doc_error(context.fileName,tokenizer.getLineNr(),"Unexpected token {} found as part of a {}",
617 tok.to_string(), txt);
618 break;
619 }
620}

References DocNodeList::append(), Token::command_to_char(), context, TokenInfo::endTag, DocParserContext::fileName, DocTokenizer::getLineNr(), TokenInfo::name, parent(), qPrint(), Token::to_string(), DocParserContext::token, tokenizer, Token::value(), and warn_doc_error.

Referenced by defaultHandleTitleAndSize(), handleStyleArgument(), DocHRef::parse(), DocHtmlCaption::parse(), DocHtmlHeader::parse(), DocHtmlSummary::parse(), DocInternalRef::parse(), DocRef::parse(), DocSecRefItem::parse(), DocTitle::parse(), and DocVhdlFlow::parse().

◆ findAndCopyImage()

DString DocParser::findAndCopyImage ( const DString & fileName,
DocImage::Type type,
bool doWarn = true )

search for an image in the imageNameDict and if found copies the image to the output directory (which depends on the type parameter).

Definition at line 96 of file docparser.cpp.

97{
98 DString result;
99 bool ambig = false;
100 FileDef *fd = findFileDef(Doxygen::imageNameLinkedMap,fileName,ambig);
101 //printf("Search for %s\n",fileName);
102 if (fd)
103 {
104 if (ambig & doWarn)
105 {
107 "image file name '{}' is ambiguous.\n"
108 "Possible candidates:\n{}", fileName,showFileDefMatches(Doxygen::imageNameLinkedMap,fileName));
109 }
110
111 DString inputFile = fd->absFilePath();
112 FileInfo infi(inputFile.str());
113 if (infi.exists())
114 {
115 result = fileName;
116 if (size_t i = result.rfind('/') ; i!=DString::npos || (i=result.rfind('\\'))!=DString::npos)
117 {
118 result = result.mid(i+1);
119 }
120 //printf("fileName=%s result=%s\n",fileName,qPrint(result));
121 DString outputDir;
122 switch(type)
123 {
124 case DocImage::Html:
125 if (!Config_getBool(GENERATE_HTML)) return result;
126 outputDir = Config_getString(HTML_OUTPUT);
127 break;
128 case DocImage::Latex:
129 if (!Config_getBool(GENERATE_LATEX)) return result;
130 outputDir = Config_getString(LATEX_OUTPUT);
131 break;
133 if (!Config_getBool(GENERATE_DOCBOOK)) return result;
134 outputDir = Config_getString(DOCBOOK_OUTPUT);
135 break;
136 case DocImage::Rtf:
137 if (!Config_getBool(GENERATE_RTF)) return result;
138 outputDir = Config_getString(RTF_OUTPUT);
139 break;
140 case DocImage::Xml:
141 if (!Config_getBool(GENERATE_XML)) return result;
142 outputDir = Config_getString(XML_OUTPUT);
143 break;
144 }
145 DString outputFile = outputDir+"/"+result;
146 FileInfo outfi(outputFile.str());
147 if (outfi.isSymLink())
148 {
149 Dir().remove(outputFile.str());
151 "destination of image {} is a symlink, replacing with image",
152 outputFile);
153 }
154 if (outputFile!=inputFile) // prevent copying to ourself
155 {
156 if (copyFile(inputFile,outputFile) && type==DocImage::Html)
157 {
159 }
160 }
161 }
162 else
163 {
165 "could not open image {}",fileName);
166 }
167
168 if (type==DocImage::Latex && Config_getBool(USE_PDFLATEX) &&
169 fd->name().endsWith(".eps")
170 )
171 { // we have an .eps image in pdflatex mode => convert it to a pdf.
172 DString outputDir = Config_getString(LATEX_OUTPUT);
173 DString baseName = fd->name().left(fd->name().length()-4);
174 DString epstopdfArgs(4096, DString::ExplicitSize);
175 epstopdfArgs.sprintf("\"%s/%s.eps\" --outfile=\"%s/%s.pdf\"",
176 qPrint(outputDir), qPrint(baseName),
177 qPrint(outputDir), qPrint(baseName));
178 if (Portable::system("epstopdf",epstopdfArgs)!=0)
179 {
180 err("Problems running epstopdf. Check your TeX installation!\n");
181 }
182 else
183 {
184 Dir().remove(outputDir.str()+"/"+baseName.str()+".eps");
185 }
186 return baseName;
187 }
188 }
189 else
190 {
191 result=fileName;
192 if (!result.startsWith("http:") && !result.startsWith("https:") && doWarn)
193 {
195 "image file {} is not found in IMAGE_PATH: "
196 "assuming external image.",fileName
197 );
198 }
199 }
200 return result;
201}
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:249
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:323
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:183
@ ExplicitSize
Definition dstring.h:136
Dir()
Definition dir.cpp:189
@ DocBook
Definition docnode.h:644
static FileNameLinkedMap * imageNameLinkedMap
Definition doxygen.h:105
static IndexList * indexList
Definition doxygen.h:132
virtual DString absFilePath() const =0
void addImageFile(const DString &name)
Definition indexlist.h:123
#define Config_getString(name)
Definition config.h:32
#define err(fmt,...)
Definition message.h:127
int system(const DString &command, const DString &args, bool commandHasConsole=true)
Definition portable.cpp:105
DString showFileDefMatches(const FileNameLinkedMap *fnMap, const DString &n)
Definition util.cpp:3055
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const DString &n, bool &ambig)
Definition util.cpp:2917
bool copyFile(const DString &src, const DString &dest)
Copies the contents of file with name src to the newly created file with name dest.
Definition util.cpp:5895

References FileDef::absFilePath(), IndexList::addImageFile(), Config_getBool, Config_getString, context, copyFile(), Dir::Dir(), DocImage::DocBook, DString::endsWith(), err, FileInfo::exists(), DString::ExplicitSize, DocParserContext::fileName, findFileDef(), DocTokenizer::getLineNr(), DocImage::Html, Doxygen::imageNameLinkedMap, Doxygen::indexList, FileInfo::isSymLink(), DocImage::Latex, DString::left(), DString::length(), DString::mid(), Definition::name(), DString::npos, qPrint(), DString::rfind(), DocImage::Rtf, showFileDefMatches(), DString::sprintf(), DString::startsWith(), DString::str(), Portable::system(), tokenizer, warn_doc_error, and DocImage::Xml.

Referenced by handleImage(), and handleImg().

◆ findDocsForMemberOrCompound()

bool DocParser::findDocsForMemberOrCompound ( const DString & commandName,
DString * pDoc,
DString * pBrief,
const Definition ** pDef )

Looks for a documentation block with name commandName in the current context (g_parserContext.context). The resulting documentation string is put in pDoc, the definition in which the documentation was found is put in pDef.

Return values
trueif name was found.
falseif name was not found.

Definition at line 438 of file docparser.cpp.

442{
443 AUTO_TRACE("commandName={}",commandName);
444 *pDoc="";
445 *pBrief="";
446 *pDef=nullptr;
447 DString cmdArg=commandName;
448 if (cmdArg.empty())
449 {
450 AUTO_TRACE_EXIT("empty");
451 return false;
452 }
453
454 const FileDef *fd=nullptr;
455 const GroupDef *gd=nullptr;
456 const PageDef *pd=nullptr;
457 gd = Doxygen::groupLinkedMap->find(cmdArg);
458 if (gd) // group
459 {
460 *pDoc=gd->documentation();
461 *pBrief=gd->briefDescription();
462 *pDef=gd;
463 AUTO_TRACE_EXIT("group");
464 return true;
465 }
466 pd = Doxygen::pageLinkedMap->find(cmdArg);
467 if (pd) // page
468 {
469 *pDoc=pd->documentation();
470 *pBrief=pd->briefDescription();
471 *pDef=pd;
472 AUTO_TRACE_EXIT("page");
473 return true;
474 }
475 bool ambig = false;
476 fd = findFileDef(Doxygen::inputNameLinkedMap,cmdArg,ambig);
477 if (fd && !ambig) // file
478 {
479 *pDoc=fd->documentation();
480 *pBrief=fd->briefDescription();
481 *pDef=fd;
482 AUTO_TRACE_EXIT("file");
483 return true;
484 }
485
486 // for symbols we need to normalize the separator, so A#B, or A\B, or A.B becomes A::B
487 cmdArg = substitute(cmdArg,"#","::");
488 cmdArg = substitute(cmdArg,"\\","::");
489 bool extractAnonNs = Config_getBool(EXTRACT_ANON_NSPACES);
490 if (extractAnonNs &&
491 cmdArg.startsWith("anonymous_namespace{")
492 )
493 {
494 size_t rightBracePos = cmdArg.find("}", dstrlen("anonymous_namespace{"));
495 DString leftPart = cmdArg.left(rightBracePos + 1);
496 DString rightPart = cmdArg.mid(rightBracePos + 1);
497 rightPart = substitute(rightPart, ".", "::");
498 cmdArg = leftPart + rightPart;
499 }
500 else
501 {
502 cmdArg = substitute(cmdArg,".","::");
503 }
504
505 int l=static_cast<int>(cmdArg.length());
506
507 size_t funcStart=cmdArg.find('(');
508 if (funcStart==DString::npos)
509 {
510 funcStart=l;
511 }
512 else
513 {
514 // Check for the case of operator() and the like.
515 // beware of scenarios like operator()((foo)bar)
516 size_t secondParen = cmdArg.find('(', funcStart+1);
517 size_t leftParen = cmdArg.find(')', funcStart+1);
518 if (leftParen!=DString::npos && secondParen!=DString::npos)
519 {
520 if (leftParen<secondParen)
521 {
522 funcStart=secondParen;
523 }
524 }
525 }
526
527 DString name=removeRedundantWhiteSpace(cmdArg.left(funcStart));
528 DString args=cmdArg.right(l-funcStart);
529 // try if the link is to a member
530 GetDefInput input(
531 context.context.find('.')==DString::npos ? context.context : DString(), // find('.') is a hack to detect files
532 name,
533 args);
534 input.checkCV=true;
535 GetDefResult result = getDefs(input);
536 //printf("found=%d context=%s name=%s\n",result.found,qPrint(context.context),qPrint(name));
537 if (result.found && result.md)
538 {
539 *pDoc=result.md->documentation();
540 *pBrief=result.md->briefDescription();
541 *pDef=result.md;
542 AUTO_TRACE_EXIT("member");
543 return true;
544 }
545
546 int scopeOffset=static_cast<int>(context.context.length());
547 do // for each scope
548 {
549 DString fullName=cmdArg;
550 if (scopeOffset>0)
551 {
552 fullName.prepend(context.context.left(scopeOffset)+"::");
553 }
554 //printf("Trying fullName='%s'\n",qPrint(fullName));
555
556 // try class, namespace, group, page, file reference
557 const ClassDef *cd = Doxygen::classLinkedMap->find(fullName);
558 if (cd) // class
559 {
560 *pDoc=cd->documentation();
561 *pBrief=cd->briefDescription();
562 *pDef=cd;
563 AUTO_TRACE_EXIT("class");
564 return true;
565 }
566 const NamespaceDef *nd = Doxygen::namespaceLinkedMap->find(fullName);
567 if (nd) // namespace
568 {
569 *pDoc=nd->documentation();
570 *pBrief=nd->briefDescription();
571 *pDef=nd;
572 AUTO_TRACE_EXIT("namespace");
573 return true;
574 }
575 if (scopeOffset==0)
576 {
577 scopeOffset=-1;
578 }
579 else
580 {
581 size_t o = context.context.rfind("::",scopeOffset-1);
582 scopeOffset = o!=DString::npos ? static_cast<int>(o) : 0;
583 }
584 } while (scopeOffset>=0);
585
586 AUTO_TRACE_EXIT("not found");
587 return false;
588}
DString right(size_t len) const
Definition dstring.h:316
DString & prepend(const char *s)
Definition dstring.h:504
size_t find(char c, size_t pos=0) const
Definition dstring.h:244
bool startsWith(const char *s) const
Definition dstring.h:589
virtual DString briefDescription(bool abbreviate=false) const =0
virtual DString documentation() const =0
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:104
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:95
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:99
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
const T * find(const std::string &key) const
Definition linkedmap.h:47
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:476
uint32_t dstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
Definition dstring.h:44
const MemberDef * md
Definition util.h:174
bool found
Definition util.h:173
DString removeRedundantWhiteSpace(const DString &s)
Definition util.cpp:567
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:2304

References AUTO_TRACE, AUTO_TRACE_EXIT, Definition::briefDescription(), GetDefInput::checkCV, Doxygen::classLinkedMap, Config_getBool, context, DocParserContext::context, Definition::documentation(), dstrlen(), DString::empty(), DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), findFileDef(), GetDefResult::found, getDefs(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, DString::left(), DString::length(), GetDefResult::md, DString::mid(), Doxygen::namespaceLinkedMap, DString::npos, Doxygen::pageLinkedMap, DString::prepend(), removeRedundantWhiteSpace(), DString::rfind(), DString::right(), DString::startsWith(), and substitute().

Referenced by processCopyDoc().

◆ handleAHref()

Token DocParser::handleAHref ( DocNodeVariant * parent,
DocNodeList & children,
const HtmlAttribList & tagHtmlAttribs )

Definition at line 777 of file docparser.cpp.

779{
780 AUTO_TRACE();
781 size_t index=0;
782 Token retval = Token::make_RetVal_OK();
783 for (const auto &opt : tagHtmlAttribs)
784 {
785 if (opt.name=="name" || opt.name=="id") // <a name=label> or <a id=label> tag
786 {
787 if (!opt.value.empty())
788 {
789 children.append<DocAnchor>(this,parent,opt.value,true);
790 break; // stop looking for other tag attribs
791 }
792 else
793 {
794 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <a> tag with name option but without value!");
795 }
796 }
797 else if (opt.name=="href") // <a href=url>..</a> tag
798 {
799 // copy attributes
800 HtmlAttribList attrList = tagHtmlAttribs;
801 // and remove the href attribute
802 attrList.erase(attrList.begin()+index);
803 DString relPath;
804 if (opt.value.at(0) != '#') relPath = context.relPath;
805 children.append<DocHRef>(this, parent, attrList,
806 opt.value, relPath,
807 convertNameToFile(context.fileName, false, true));
809 retval = children.get_last<DocHRef>()->parse();
812 break;
813 }
814 else // unsupported option for tag a
815 {
816 }
817 ++index;
818 }
819 return retval;
820}
bool parse(const DString &fileName, bool update=false, CompareMode compareMode=CompareMode::Full)
T * get_last()
Returns a pointer to the last element in the list if that element exists and holds a T,...
Definition docnode.h:1415
DString convertNameToFile(const DString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3545

References DocNodeList::append(), AUTO_TRACE, context, convertNameToFile(), DocParserContext::fileName, DocNodeList::get_last(), DocTokenizer::getLineNr(), DocParserContext::insideHtmlLink, parent(), DocParserContext::relPath, DocTokenizer::setStatePara(), tokenizer, and warn_doc_error.

Referenced by DocPara::handleHtmlStartTag(), DocHtmlDescTitle::parse(), and DocHtmlHeader::parse().

◆ handleAnchor()

void DocParser::handleAnchor ( DocNodeVariant * parent,
DocNodeList & children )

Definition at line 1039 of file docparser.cpp.

1040{
1041 AUTO_TRACE();
1042 Token tok=tokenizer.lex();
1043 if (!tok.is(TokenRetval::TK_WHITESPACE))
1044 {
1045 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command",
1046 context.token->name);
1047 return;
1048 }
1049
1052 tok=tokenizer.lex();
1053 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1054 {
1055 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
1056 "argument of command {}",context.token->name);
1057 return;
1058 }
1059 else if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1060 {
1061 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of {}",
1062 tok.to_string(),context.token->name);
1063 return;
1064 }
1065 }
1066 children.append<DocAnchor>(this,parent,context.token->name,false);
1067}
void setStateAnchor()
friend class AutoSaveState

References DocNodeList::append(), AUTO_TRACE, context, DocParserContext::fileName, DocTokenizer::getLineNr(), Token::is(), Token::is_any_of(), DocTokenizer::lex(), TokenInfo::name, parent(), DocTokenizer::setStateAnchor(), Token::to_string(), DocParserContext::token, tokenizer, and warn_doc_error.

Referenced by defaultHandleToken(), and DocPara::handleCommand().

◆ handleCite()

void DocParser::handleCite ( DocNodeVariant * parent,
DocNodeList & children )

Definition at line 1069 of file docparser.cpp.

1070{
1071 AUTO_TRACE();
1072 // get the argument of the cite command.
1073 Token tok=tokenizer.lex();
1074
1075 CiteInfoOption option;
1076 if (tok.is(TokenRetval::TK_WORD) && context.token->name=="{")
1077 {
1079 tokenizer.lex();
1080 StringVector optList=split(context.token->name.str(),",");
1081 for (auto const &opt : optList)
1082 {
1083 if (opt == "number")
1084 {
1085 if (!option.isUnknown())
1086 {
1087 warn(context.fileName,tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", context.token->name, opt);
1088 }
1089 else
1090 {
1091 option = CiteInfoOption::makeNumber();
1092 }
1093 }
1094 else if (opt == "year")
1095 {
1096 if (!option.isUnknown())
1097 {
1098 warn(context.fileName,tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", context.token->name, opt);
1099 }
1100 else
1101 {
1102 option = CiteInfoOption::makeYear();
1103 }
1104 }
1105 else if (opt == "shortauthor")
1106 {
1107 if (!option.isUnknown())
1108 {
1109 warn(context.fileName,tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", context.token->name, opt);
1110 }
1111 else
1112 {
1114 }
1115 }
1116 else if (opt == "nopar")
1117 {
1118 option.setNoPar();
1119 }
1120 else if (opt == "nocite")
1121 {
1122 option.setNoCite();
1123 }
1124 else
1125 {
1126 warn(context.fileName,tokenizer.getLineNr(),"Unknown option specified with \\{}, discarding '{}'", context.token->name, opt);
1127 }
1128 }
1129
1130 if (option.isUnknown()) option.changeToNumber();
1131
1133 tok=tokenizer.lex();
1134 if (!tok.is(TokenRetval::TK_WHITESPACE))
1135 {
1136 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command",
1137 context.token->name);
1138 return;
1139 }
1140 }
1141 else if (!tok.is(TokenRetval::TK_WHITESPACE))
1142 {
1143 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after '\\{}' command",
1144 context.token->name);
1145 return;
1146 }
1147 else
1148 {
1149 option = CiteInfoOption::makeNumber();
1150 }
1151
1154 tok=tokenizer.lex();
1155 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1156 {
1157 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
1158 "argument of command '\\{}'",context.token->name);
1159 return;
1160 }
1161 else if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1162 {
1163 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of '\\{}'",
1164 tok.to_string(),context.token->name);
1165 return;
1166 }
1168 children.append<DocCite>(this,parent,context.token->name,context.context,option);
1169 }
1170
1171}
constexpr void setNoCite() noexcept
Definition cite.h:35
static constexpr CiteInfoOption makeNumber()
Definition cite.h:29
constexpr void changeToNumber() noexcept
Definition cite.h:33
constexpr void setNoPar() noexcept
Definition cite.h:34
constexpr bool isUnknown() const noexcept
Definition cite.h:37
static constexpr CiteInfoOption makeYear()
Definition cite.h:31
static constexpr CiteInfoOption makeShortAuthor()
Definition cite.h:30
void setStateCite()
void setStateOptions()
std::vector< std::string > StringVector
Definition containers.h:33
#define warn(file, line, fmt,...)
Definition message.h:97
DString sectionId
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
Definition util.cpp:6656

References DocNodeList::append(), AUTO_TRACE, CiteInfoOption::changeToNumber(), context, DocParserContext::context, DocParserContext::fileName, DocTokenizer::getLineNr(), Token::is(), Token::is_any_of(), CiteInfoOption::isUnknown(), DocTokenizer::lex(), CiteInfoOption::makeNumber(), CiteInfoOption::makeShortAuthor(), CiteInfoOption::makeYear(), TokenInfo::name, parent(), TokenInfo::sectionId, CiteInfoOption::setNoCite(), CiteInfoOption::setNoPar(), DocTokenizer::setStateCite(), DocTokenizer::setStateOptions(), DocTokenizer::setStatePara(), split(), DString::str(), Token::to_string(), DocParserContext::token, tokenizer, warn, and warn_doc_error.

Referenced by defaultHandleToken(), and DocPara::handleCommand().

◆ handleIFile()

void DocParser::handleIFile ( char cmdChar,
const DString & cmdName )

Definition at line 1425 of file docparser.cpp.

1426{
1427 AUTO_TRACE();
1428 Token tok=tokenizer.lex();
1429 if (!tok.is(TokenRetval::TK_WHITESPACE))
1430 {
1431 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after '{:c}{}' command",
1432 cmdChar,cmdName);
1433 return;
1434 }
1436 tok=tokenizer.lex();
1438 if (!tok.is(TokenRetval::TK_WORD))
1439 {
1440 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of '{:c}{}'",
1441 tok.to_string(),cmdChar,cmdName);
1442 return;
1443 }
1445}
void setStateIFile()

References AUTO_TRACE, context, DocParserContext::fileName, DocTokenizer::getLineNr(), Token::is(), DocTokenizer::lex(), TokenInfo::name, DocTokenizer::setStateIFile(), DocTokenizer::setStatePara(), Token::to_string(), DocParserContext::token, tokenizer, and warn_doc_error.

Referenced by defaultHandleToken(), and DocPara::handleCommand().

◆ handleILine()

void DocParser::handleILine ( char cmdChar,
const DString & cmdName )

Definition at line 1447 of file docparser.cpp.

1448{
1449 AUTO_TRACE();
1451 Token tok = tokenizer.lex();
1453 if (!tok.is(TokenRetval::TK_WORD))
1454 {
1455 warn_doc_error(context.fileName,tokenizer.getLineNr(),"invalid argument for command '{:c}{}'",
1456 cmdChar,cmdName);
1457 return;
1458 }
1459}
void setStateILine()

References AUTO_TRACE, context, DocParserContext::fileName, DocTokenizer::getLineNr(), Token::is(), DocTokenizer::lex(), DocTokenizer::setStateILine(), DocTokenizer::setStatePara(), tokenizer, and warn_doc_error.

Referenced by defaultHandleToken(), and DocPara::handleCommand().

◆ handleImage()

void DocParser::handleImage ( DocNodeVariant * parent,
DocNodeList & children )

Definition at line 1293 of file docparser.cpp.

1294{
1295 AUTO_TRACE();
1296 bool inlineImage = false;
1297 DString anchorStr;
1298
1299 Token tok=tokenizer.lex();
1300 if (!tok.is(TokenRetval::TK_WHITESPACE))
1301 {
1302 if (tok.is(TokenRetval::TK_WORD))
1303 {
1304 if (context.token->name == "{")
1305 {
1307 tokenizer.lex();
1309 StringVector optList=split(context.token->name.str(),",");
1310 for (const auto &opt : optList)
1311 {
1312 if (opt.empty()) continue;
1313 DString locOpt(opt);
1314 DString locOptLow;
1315 locOpt = locOpt.stripWhiteSpace();
1316 locOptLow = locOpt.lower();
1317 if (locOptLow == "inline")
1318 {
1319 inlineImage = true;
1320 }
1321 else if (locOptLow.startsWith("anchor:"))
1322 {
1323 if (!anchorStr.empty())
1324 {
1326 "multiple use of option 'anchor' for 'image' command, ignoring: '{}'",
1327 locOpt.mid(7));
1328 }
1329 else
1330 {
1331 anchorStr = locOpt.mid(7);
1332 }
1333 }
1334 else
1335 {
1337 "unknown option '{}' for 'image' command specified",
1338 locOpt);
1339 }
1340 }
1341 tok=tokenizer.lex();
1342 if (!tok.is(TokenRetval::TK_WHITESPACE))
1343 {
1344 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\image command");
1345 return;
1346 }
1347 }
1348 }
1349 else
1350 {
1351 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\image command");
1352 return;
1353 }
1354 }
1355 tok=tokenizer.lex();
1356 if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1357 {
1358 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of \\image",
1359 tok.to_string());
1360 return;
1361 }
1362 tok=tokenizer.lex();
1363 if (!tok.is(TokenRetval::TK_WHITESPACE))
1364 {
1365 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\image command");
1366 return;
1367 }
1369 DString imgType = context.token->name.lower();
1370 if (imgType=="html") t=DocImage::Html;
1371 else if (imgType=="latex") t=DocImage::Latex;
1372 else if (imgType=="docbook") t=DocImage::DocBook;
1373 else if (imgType=="rtf") t=DocImage::Rtf;
1374 else if (imgType=="xml") t=DocImage::Xml;
1375 else
1376 {
1377 warn_doc_error(context.fileName,tokenizer.getLineNr(),"output format `{}` specified as the first argument of "
1378 "\\image command is not valid", imgType);
1379 return;
1380 }
1382 tok=tokenizer.lex();
1384 if (!tok.is(TokenRetval::TK_WORD))
1385 {
1386 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of \\image", tok.to_string());
1387 return;
1388 }
1389 if (!anchorStr.empty())
1390 {
1391 children.append<DocAnchor>(this,parent,anchorStr,true);
1392 }
1393 HtmlAttribList attrList;
1394 children.append<DocImage>(this,parent,attrList,
1395 findAndCopyImage(context.token->name,t),t,"",inlineImage);
1396 children.get_last<DocImage>()->parse();
1397}
DString findAndCopyImage(const DString &fileName, DocImage::Type type, bool doWarn=true)
Definition docparser.cpp:96
void setStateFile()

References DocNodeList::append(), AUTO_TRACE, context, DocImage::DocBook, DString::empty(), DocParserContext::fileName, findAndCopyImage(), DocNodeList::get_last(), DocTokenizer::getLineNr(), DocImage::Html, Token::is(), Token::is_any_of(), DocImage::Latex, DocTokenizer::lex(), DString::lower(), DString::mid(), TokenInfo::name, parent(), DocImage::Rtf, DocTokenizer::setStateFile(), DocTokenizer::setStateOptions(), DocTokenizer::setStatePara(), split(), DString::startsWith(), DString::str(), DString::stripWhiteSpace(), Token::to_string(), DocParserContext::token, tokenizer, warn_doc_error, and DocImage::Xml.

Referenced by defaultHandleToken(), and DocPara::handleCommand().

◆ handleImg()

void DocParser::handleImg ( DocNodeVariant * parent,
DocNodeList & children,
const HtmlAttribList & tagHtmlAttribs )

Definition at line 1846 of file docparser.cpp.

1847{
1848 AUTO_TRACE();
1849 bool found=false;
1850 size_t index=0;
1851 for (const auto &opt : tagHtmlAttribs)
1852 {
1853 AUTO_TRACE_ADD("option name={} value='{}'",opt.name,opt.value);
1854 if (opt.name=="src" && !opt.value.empty())
1855 {
1856 // copy attributes
1857 HtmlAttribList attrList = tagHtmlAttribs;
1858 // and remove the src attribute
1859 attrList.erase(attrList.begin()+index);
1861 children.append<DocImage>(
1862 this,parent,attrList,
1863 findAndCopyImage(opt.value,t,false),
1864 t,opt.value);
1865 found = true;
1866 }
1867 ++index;
1868 }
1869 if (!found)
1870 {
1871 warn_doc_error(context.fileName,tokenizer.getLineNr(),"IMG tag does not have a SRC attribute!");
1872 }
1873}

References DocNodeList::append(), AUTO_TRACE, AUTO_TRACE_ADD, context, DocParserContext::fileName, findAndCopyImage(), DocTokenizer::getLineNr(), DocImage::Html, parent(), tokenizer, and warn_doc_error.

Referenced by defaultHandleToken(), and DocPara::handleHtmlStartTag().

◆ handleInitialStyleCommands()

void DocParser::handleInitialStyleCommands ( DocNodeVariant * parent,
DocNodeList & children )

Definition at line 766 of file docparser.cpp.

767{
768 AUTO_TRACE();
769 while (!context.initialStyleStack.empty())
770 {
771 const DocStyleChange &sc = std::get<DocStyleChange>(*context.initialStyleStack.top());
772 handleStyleEnter(parent,children,sc.style(),sc.tagName(),&sc.attribs());
774 }
775}
const HtmlAttribList & attribs() const
Definition docnode.h:311
Style style() const
Definition docnode.h:307
DString tagName() const
Definition docnode.h:312
DocStyleChangeStack initialStyleStack
Definition docparser_p.h:69

References DocStyleChange::attribs(), AUTO_TRACE, context, handleStyleEnter(), DocParserContext::initialStyleStack, parent(), DocStyleChange::style(), and DocStyleChange::tagName().

Referenced by DocPara::parse().

◆ handleInternalRef()

void DocParser::handleInternalRef ( DocNodeVariant * parent,
DocNodeList & children )

Definition at line 1017 of file docparser.cpp.

1018{
1019 Token tok=tokenizer.lex();
1020 DString tokenName = context.token->name;
1021 AUTO_TRACE("name={}",tokenName);
1022 if (!tok.is(TokenRetval::TK_WHITESPACE))
1023 {
1024 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command", tokenName);
1025 return;
1026 }
1028 tok=tokenizer.lex(); // get the reference id
1029 if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1030 {
1031 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of {}",
1032 tok.to_string(),tokenName);
1033 return;
1034 }
1035 children.append<DocInternalRef>(this,parent,context.token->name);
1036 children.get_last<DocInternalRef>()->parse();
1037}
void setStateInternalRef()

References DocNodeList::append(), AUTO_TRACE, context, DocParserContext::fileName, DocNodeList::get_last(), DocTokenizer::getLineNr(), Token::is(), Token::is_any_of(), DocTokenizer::lex(), TokenInfo::name, parent(), DocTokenizer::setStateInternalRef(), Token::to_string(), DocParserContext::token, tokenizer, and warn_doc_error.

Referenced by defaultHandleToken(), and DocPara::handleCommand().

◆ handleLinkedWord()

void DocParser::handleLinkedWord ( DocNodeVariant * parent,
DocNodeList & children,
bool ignoreAutoLinkFlag = false,
bool typeLinkOnly = false )

Definition at line 846 of file docparser.cpp.

847{
848 // helper to check if word w starts with any of the words in AUTOLINK_IGNORE_WORDS
849 auto ignoreWord = [](const DString &w) -> bool {
850 const auto &list = Config_getList(AUTOLINK_IGNORE_WORDS);
851 return std::find_if(list.begin(), list.end(),
852 [&w](const auto &ignore) { return w.startsWith(ignore); }
853 )!=list.end();
854 };
855 DString name = linkToText(context.lang,context.token->name,true);
856 AUTO_TRACE("word={}",name);
857 if (!context.autolinkSupport || ignoreAutoLinkFlag || ignoreWord(context.token->name)) // no autolinking -> add as normal word
858 {
859 children.append<DocWord>(this,parent,name);
860 return;
861 }
862
863 // ------- try to turn the word 'name' into a link
864
865 const Definition *compound=nullptr;
866 const MemberDef *member=nullptr;
867 size_t len = context.token->name.length();
868 ClassDef *cd=nullptr;
869 bool ambig = false;
871 auto lang = context.lang;
872 bool inSeeBlock = context.inSeeBlock || context.inCodeStyle;
873 //printf("handleLinkedWord(%s) context.context=%s\n",qPrint(context.token->name),qPrint(context.context));
874 if (!context.insideHtmlLink &&
875 (resolveRef(context.context,context.token->name,inSeeBlock,&compound,&member,lang,true,fd,true)
876 || (!context.context.empty() && // also try with global scope
877 resolveRef(DString(),context.token->name,inSeeBlock,&compound,&member,lang,false,nullptr,true))
878 )
879 )
880 {
881 //printf("ADD %s = %p (linkable?=%d typeLinkOnly=%d)\n",
882 // qPrint(context.token->name),(void*)member,member ? member->isLinkable() : false, typeLinkOnly);
883 if (member && member->isLinkable())
884 {
885 if (!typeLinkOnly || context.token->name.startsWith("#") ||
886 member->isTypedef() || member->isEnumerate() || member->isEnumValue()) // filter on type links
887 {
888 AUTO_TRACE_ADD("resolved reference as member link");
889 if (member->isObjCMethod())
890 {
891 bool localLink = context.memberDef ? member->getClassDef()==context.memberDef->getClassDef() : false;
892 name = member->objCMethodName(localLink,inSeeBlock);
893 }
894 children.append<DocLinkedWord>(
895 this,parent,name,
896 member->getReference(),
897 member->getOutputFileBase(),
898 member->anchor(),
899 member->briefDescriptionAsTooltip());
900 }
901 else // explicit type link, but not a type
902 {
903 AUTO_TRACE_ADD("no link as request is type but member is not a type or explicit link");
904 children.append<DocWord>(this,parent,context.token->name);
905 }
906 }
907 else if (compound->isLinkable()) // compound link
908 {
909 AUTO_TRACE_ADD("resolved reference as compound link");
910 DString anchor = compound->anchor();
911 if (compound->definitionType()==Definition::TypeFile)
912 {
913 name=context.token->name;
914 }
915 else if (compound->definitionType()==Definition::TypeGroup)
916 {
917 name=toGroupDef(compound)->groupTitle();
918 }
919 children.append<DocLinkedWord>(
920 this,parent,name,
921 compound->getReference(),
922 compound->getOutputFileBase(),
923 anchor,
924 compound->briefDescriptionAsTooltip());
925 }
926 else if (compound->definitionType()==Definition::TypeFile &&
927 (toFileDef(compound))->generateSourceFile()
928 ) // undocumented file that has source code we can link to
929 {
930 AUTO_TRACE_ADD("resolved reference as source link");
931 children.append<DocLinkedWord>(
932 this,parent,context.token->name,
933 compound->getReference(),
934 compound->getSourceFileBase(),
935 "",
936 compound->briefDescriptionAsTooltip());
937 }
938 else // not linkable
939 {
940 AUTO_TRACE_ADD("resolved reference as unlinkable compound={} (linkable={}) member={} (linkable={})",
941 compound ? compound->name() : "<none>", compound ? (int)compound->isLinkable() : -1,
942 member ? member->name() : "<none>", member ? (int)member->isLinkable() : -1);
943 children.append<DocWord>(this,parent,name);
944 }
945 }
946 else if (!context.insideHtmlLink && len>1 && context.token->name.at(len-1)==':')
947 {
948 // special case, where matching Foo: fails to be an Obj-C reference,
949 // but Foo itself might be linkable.
951 handleLinkedWord(parent,children,ignoreAutoLinkFlag);
952 children.append<DocWord>(this,parent,":");
953 }
954 else if (!context.insideHtmlLink && (cd=getClass(context.token->name+"-p")))
955 {
956 // special case 2, where the token name is not a class, but could
957 // be a Obj-C protocol
958 children.append<DocLinkedWord>(
959 this,parent,name,
960 cd->getReference(),
961 cd->getOutputFileBase(),
962 cd->anchor(),
964 }
965 else if (const RequirementIntf *req = RequirementManager::instance().find(name); req!=nullptr) // link to requirement
966 {
967 if (Config_getBool(GENERATE_REQUIREMENTS))
968 {
969 children.append<DocLinkedWord>(
970 this,parent,name,
971 DString(), // link to local requirements overview also for external references
972 req->getOutputFileBase(),
973 req->id(),
974 req->title()
975 );
976 }
977 else // cannot link to a page that does not exist
978 {
979 children.append<DocWord>(this,parent,name);
980 }
981 }
982 else // normal non-linkable word
983 {
984 AUTO_TRACE_ADD("non-linkable");
985 if (context.token->name.startsWith("#"))
986 {
987 warn_doc_error(context.fileName,tokenizer.getLineNr(),"explicit link request to '{}' could not be resolved",name);
988 }
989 children.append<DocWord>(this,parent,context.token->name);
990 }
991}
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:675
virtual bool isLinkable() const =0
virtual DefType definitionType() const =0
virtual DString briefDescriptionAsTooltip() const =0
virtual DString anchor() const =0
virtual DString getReference() const =0
virtual DString getSourceFileBase() const =0
virtual DString getOutputFileBase() const =0
virtual DString groupTitle() const =0
virtual bool isObjCMethod() const =0
virtual DString objCMethodName(bool localLink, bool showStatic) const =0
virtual const ClassDef * getClassDef() const =0
virtual bool isTypedef() const =0
virtual bool isEnumerate() const =0
virtual bool isEnumValue() const =0
static RequirementManager & instance()
ClassDef * getClass(const DString &n)
#define Config_getList(name)
Definition config.h:38
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1966
GroupDef * toGroupDef(Definition *d)
SrcLangExt lang
Definition docparser_p.h:85
bool resolveRef(const DString &scName, const DString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, SrcLangExt lang, bool lookForSpecialization, const FileDef *currentFile, bool checkScope)
Definition util.cpp:2449
DString linkToText(SrcLangExt lang, const DString &link, bool ignoreDots)
Definition util.cpp:2706

References Definition::anchor(), DocNodeList::append(), DString::at(), AUTO_TRACE, AUTO_TRACE_ADD, DocParserContext::autolinkSupport, Definition::briefDescriptionAsTooltip(), Config_getBool, Config_getList, context, DocParserContext::context, Definition::definitionType(), DString::DString(), DString::empty(), DocParserContext::fileName, findFileDef(), getClass(), MemberDef::getClassDef(), DocTokenizer::getLineNr(), Definition::getOutputFileBase(), Definition::getReference(), Definition::getSourceFileBase(), GroupDef::groupTitle(), handleLinkedWord(), DocParserContext::inCodeStyle, Doxygen::inputNameLinkedMap, DocParserContext::inSeeBlock, DocParserContext::insideHtmlLink, RequirementManager::instance(), MemberDef::isEnumerate(), MemberDef::isEnumValue(), Definition::isLinkable(), MemberDef::isObjCMethod(), MemberDef::isTypedef(), DocParserContext::lang, DString::left(), DString::length(), linkToText(), DocParserContext::memberDef, Definition::name(), TokenInfo::name, MemberDef::objCMethodName(), parent(), resolveRef(), DString::startsWith(), toFileDef(), toGroupDef(), DocParserContext::token, tokenizer, Definition::TypeFile, Definition::TypeGroup, and warn_doc_error.

Referenced by defaultHandleToken(), DocPara::handleHtmlStartTag(), handleLinkedWord(), handleParameterType(), DocPara::parse(), DocParamList::parse(), and DocParamList::parseXml().

◆ handleParameterType()

void DocParser::handleParameterType ( DocNodeVariant * parent,
DocNodeList & children,
const DString & paramTypes )

Definition at line 993 of file docparser.cpp.

994{
995 DString name = context.token->name; // save token name
996 AUTO_TRACE("name={}",name);
997 DString name1;
998 size_t p=0, i=0, ii=0;
999 while ((i=paramTypes.find('|',p))!=DString::npos)
1000 {
1001 name1 = paramTypes.mid(p,i-p);
1002 ii=name1.find('[');
1003 context.token->name=ii!=DString::npos ? name1.mid(0,ii) : name1; // take part without []
1004 handleLinkedWord(parent,children);
1005 if (ii!=DString::npos) children.append<DocWord>(this,parent,name1.mid(ii)); // add [] part
1006 p=i+1;
1007 children.append<DocSeparator>(this,parent,"|");
1008 }
1009 name1 = paramTypes.mid(p);
1010 ii=name1.find('[');
1011 context.token->name=ii!=DString::npos ? name1.mid(0,ii) : name1;
1012 handleLinkedWord(parent,children);
1013 if (ii!=DString::npos) children.append<DocWord>(this,parent,name1.mid(ii));
1014 context.token->name = name; // restore original token name
1015}

References DocNodeList::append(), AUTO_TRACE, context, DString::find(), handleLinkedWord(), DString::mid(), TokenInfo::name, DString::npos, parent(), and DocParserContext::token.

Referenced by DocParamList::parse().

◆ handlePendingStyleCommands()

void DocParser::handlePendingStyleCommands ( DocNodeVariant * parent,
DocNodeList & children,
size_t numberOfElementsToClose = 0 )

Called at the end of a paragraph to close all open style changes (e.g. a without a ). The closed styles are pushed onto a stack and entered again at the start of a new paragraph.

Definition at line 746 of file docparser.cpp.

747{
748 AUTO_TRACE("context.styleStack.size()={} numberOfElementsToClose={}",context.styleStack.size(),numberOfElementsToClose);
749 if (!context.styleStack.empty())
750 {
751 if (numberOfElementsToClose==0) numberOfElementsToClose = context.styleStack.size(); // 0 is special value for "close all"
752 const DocStyleChange *sc = &std::get<DocStyleChange>(*context.styleStack.top());
753 while (sc && sc->position()>=context.nodeStack.size() && numberOfElementsToClose>0)
754 { // there are unclosed style modifiers in the paragraph
755 AUTO_TRACE_ADD("unclosed style {} at position {}",sc->styleString(),sc->position());
756 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),
757 sc->style(),sc->tagName(),false);
759 context.styleStack.pop();
760 sc = !context.styleStack.empty() ? &std::get<DocStyleChange>(*context.styleStack.top()) : nullptr;
761 numberOfElementsToClose--;
762 }
763 }
764}
const char * styleString() const
Definition docnode.cpp:127
size_t position() const
Definition docnode.h:310
DocStyleChangeStack styleStack
Definition docparser_p.h:68

References DocNodeList::append(), AUTO_TRACE, AUTO_TRACE_ADD, context, DocParserContext::initialStyleStack, DocParserContext::nodeStack, parent(), DocStyleChange::position(), DocStyleChange::style(), DocParserContext::styleStack, DocStyleChange::styleString(), and DocStyleChange::tagName().

Referenced by defaultHandleTitleAndSize(), handleStyleArgument(), DocHRef::parse(), DocHtmlCaption::parse(), DocHtmlDescTitle::parse(), DocHtmlHeader::parse(), DocInternalRef::parse(), DocLink::parse(), DocPara::parse(), DocRef::parse(), DocSecRefItem::parse(), DocTitle::parse(), and DocVhdlFlow::parse().

◆ handlePrefix()

void DocParser::handlePrefix ( DocNodeVariant * parent,
DocNodeList & children )

Definition at line 1173 of file docparser.cpp.

1174{
1175 AUTO_TRACE();
1176 Token tok=tokenizer.lex();
1177 if (!tok.is(TokenRetval::TK_WHITESPACE))
1178 {
1179 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command", context.token->name);
1180 return;
1181 }
1183 tok=tokenizer.lex();
1184 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1185 {
1186 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
1187 "argument of command {}",context.token->name);
1188 return;
1189 }
1190 else if (!tok.is(TokenRetval::TK_WORD))
1191 {
1192 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of {}",
1193 tok.to_string(),context.token->name);
1194 return;
1195 }
1198}
void setStatePrefix()

References AUTO_TRACE, context, DocParserContext::fileName, DocTokenizer::getLineNr(), Token::is(), Token::is_any_of(), DocTokenizer::lex(), TokenInfo::name, parent(), DocParserContext::prefix, DocTokenizer::setStatePara(), DocTokenizer::setStatePrefix(), Token::to_string(), DocParserContext::token, tokenizer, and warn_doc_error.

Referenced by defaultHandleToken(), and DocPara::handleCommand().

◆ handleRef()

void DocParser::handleRef ( DocNodeVariant * parent,
DocNodeList & children,
char cmdChar,
const DString & cmdName )

Definition at line 1399 of file docparser.cpp.

1400{
1401 AUTO_TRACE("cmdName={}",cmdName);
1402 DString saveCmdName = cmdName;
1404 Token tok=tokenizer.lex();
1405 if (!tok.is(TokenRetval::TK_WHITESPACE))
1406 {
1407 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after '{:c}{}' command",
1408 cmdChar,qPrint(saveCmdName));
1409 return;
1410 }
1412 tok=tokenizer.lex(); // get the reference id
1413 if (!tok.is(TokenRetval::TK_WORD))
1414 {
1415 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of '{:c}{}'",
1416 tok.to_string(),cmdChar,saveCmdName);
1417 return;
1418 }
1419 children.append<DocRef>(this,parent,
1422 children.get_last<DocRef>()->parse(cmdChar,saveCmdName);
1423}

References DocNodeList::append(), AUTO_TRACE, context, DocParserContext::context, DocParserContext::fileName, DocNodeList::get_last(), DocTokenizer::getLineNr(), Token::is(), DocTokenizer::lex(), TokenInfo::name, parent(), qPrint(), DocTokenizer::setStateRef(), Token::to_string(), DocParserContext::token, tokenizer, and warn_doc_error.

Referenced by DocPara::handleCommand(), and DocHtmlSummary::parse().

◆ handleStyleArgument()

Token DocParser::handleStyleArgument ( DocNodeVariant * parent,
DocNodeList & children,
const DString & cmdName )

Definition at line 624 of file docparser.cpp.

625{
626 AUTO_TRACE("cmdName={}",cmdName);
627 DString saveCmdName = cmdName;
628 Token tok=tokenizer.lex();
629 size_t styleStackSizeAtStart = context.styleStack.size();
630 if (!tok.is(TokenRetval::TK_WHITESPACE))
631 {
632 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command",
633 saveCmdName);
634 return tok;
635 }
636 tok = tokenizer.lex();
637 while (!tok.is_any_of(TokenRetval::TK_NONE, TokenRetval::TK_EOF, TokenRetval::TK_WHITESPACE,
638 TokenRetval::TK_NEWPARA, TokenRetval::TK_LISTITEM, TokenRetval::TK_ENDLIST)
639 )
640 {
641 static const reg::Ex specialChar(R"([.,|()\‍[\‍]:;?])");
642 if (tok.is(TokenRetval::TK_WORD) && context.token->name.length()==1 &&
643 reg::match(context.token->name.str(),specialChar))
644 {
645 // special character that ends the markup command
646 AUTO_TRACE_ADD("special character ending style argument: '{}' styleStackSize {}->{}",context.token->name,styleStackSizeAtStart,context.styleStack.size());
647 if (context.styleStack.size() > styleStackSizeAtStart) // new styles opened inside command, but not closed
648 {
649 handlePendingStyleCommands(parent,children,context.styleStack.size()-styleStackSizeAtStart);
650 }
651 return tok;
652 }
653 if (!defaultHandleToken(parent,tok,children))
654 {
655 switch (tok.value())
656 {
657 case TokenRetval::TK_HTMLTAG:
659 {
660 // ignore </li> as the end of a style command
661 }
662 else
663 {
664 AUTO_TRACE_EXIT("end tok={}",tok.to_string());
665 return tok;
666 }
667 break;
668 default:
669 errorHandleDefaultToken(parent,tok,children,"\\" + saveCmdName + " command");
670 break;
671 }
672 break;
673 }
674 tok = tokenizer.lex();
675 }
676 AUTO_TRACE_EXIT("end tok={}",tok.to_string());
677 return (tok.is_any_of(TokenRetval::TK_NEWPARA,TokenRetval::TK_LISTITEM,TokenRetval::TK_ENDLIST)) ? tok : Token::make_RetVal_OK();
678}
bool insideLI(const DocNodeVariant *n)

References AUTO_TRACE, AUTO_TRACE_ADD, AUTO_TRACE_EXIT, context, defaultHandleToken(), TokenInfo::endTag, errorHandleDefaultToken(), DocParserContext::fileName, DocTokenizer::getLineNr(), handlePendingStyleCommands(), Mappers::htmlTagMapper, insideLI(), Token::is(), Token::is_any_of(), DString::length(), DocTokenizer::lex(), reg::match(), TokenInfo::name, parent(), DString::str(), DocParserContext::styleStack, Token::to_string(), DocParserContext::token, tokenizer, UNKNOWN, Token::value(), and warn_doc_error.

Referenced by defaultHandleToken(), and DocPara::handleCommand().

◆ handleStyleEnter()

void DocParser::handleStyleEnter ( DocNodeVariant * parent,
DocNodeList & children,
DocStyleChange::Style s,
const DString & tagName,
const HtmlAttribList * attribs )

Called when a style change starts. For instance a <b> command is encountered.

Definition at line 683 of file docparser.cpp.

685{
686 AUTO_TRACE("tagName={}",tagName);
687 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),s,tagName,true,
689 context.styleStack.push(&children.back());
691}
T & back()
access the last element
Definition growvector.h:135

References DocNodeList::append(), AUTO_TRACE, GrowVector< T >::back(), context, DocParserContext::fileName, DocTokenizer::getLineNr(), DocParserContext::inCodeStyle, DocParserContext::nodeStack, parent(), DocParserContext::styleStack, tokenizer, and DocStyleChange::Typewriter.

Referenced by defaultHandleToken(), DocPara::handleHtmlStartTag(), and handleInitialStyleCommands().

◆ handleStyleLeave()

void DocParser::handleStyleLeave ( DocNodeVariant * parent,
DocNodeList & children,
DocStyleChange::Style s,
const DString & tagName )

Called when a style change ends. For instance a </b> command is encountered.

Definition at line 696 of file docparser.cpp.

698{
699 AUTO_TRACE("tagName={}",tagName);
700 DString tagNameLower = DString(tagName).lower();
701
702 auto topStyleChange = [](const DocStyleChangeStack &stack) -> const DocStyleChange &
703 {
704 return std::get<DocStyleChange>(*stack.top());
705 };
706
707 if (context.styleStack.empty() || // no style change
708 topStyleChange(context.styleStack).style()!=s || // wrong style change
709 topStyleChange(context.styleStack).tagName()!=tagNameLower || // wrong style change
710 topStyleChange(context.styleStack).position()!=context.nodeStack.size() // wrong position
711 )
712 {
713 if (context.styleStack.empty())
714 {
715 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </{0}> tag without matching <{0}>",tagName);
716 }
717 else if (topStyleChange(context.styleStack).tagName()!=tagNameLower ||
718 topStyleChange(context.styleStack).style()!=s)
719 {
720 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </{}> tag while expecting </{}>",
721 tagName,topStyleChange(context.styleStack).tagName());
722 }
723 else
724 {
725 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </{}> at different nesting level ({}) than expected ({})",
726 tagName,context.nodeStack.size(),topStyleChange(context.styleStack).position());
727 }
728 }
729 else // end the section
730 {
731 children.append<DocStyleChange>(
732 this,parent,context.nodeStack.size(),s,
733 topStyleChange(context.styleStack).tagName(),false);
734 context.styleStack.pop();
735 }
737 {
738 context.inCodeStyle = false;
739 }
740}
IterableStack< const DocNodeVariant * > DocStyleChangeStack
Definition docparser_p.h:55

References DocNodeList::append(), AUTO_TRACE, context, DString::DString(), DocParserContext::fileName, DocTokenizer::getLineNr(), DocParserContext::inCodeStyle, DString::lower(), DocParserContext::nodeStack, parent(), DocParserContext::styleStack, tokenizer, DocStyleChange::Typewriter, and warn_doc_error.

Referenced by defaultHandleToken(), DocPara::handleHtmlEndTag(), and DocPara::handleHtmlStartTag().

◆ handleUnclosedStyleCommands()

void DocParser::handleUnclosedStyleCommands ( )

Definition at line 822 of file docparser.cpp.

823{
824 AUTO_TRACE("content.initialStyleStack.size()={}",context.initialStyleStack.size());
825 if (!context.initialStyleStack.empty())
826 {
827 DString tagName = std::get<DocStyleChange>(*context.initialStyleStack.top()).tagName();
828 DString fileName = std::get<DocStyleChange>(*context.initialStyleStack.top()).fileName();
829 int lineNr = std::get<DocStyleChange>(*context.initialStyleStack.top()).lineNr();
832 if (lineNr != -1)
833 {
835 "end of comment block while expecting "
836 "command </{}> (Probable start '{}' at line {})",tagName, fileName, lineNr);
837 }
838 else
839 {
841 "end of comment block while expecting command </{}>",tagName);
842 }
843 }
844}
void handleUnclosedStyleCommands()

References AUTO_TRACE, context, DocParserContext::fileName, DocTokenizer::getLineNr(), handleUnclosedStyleCommands(), DocParserContext::initialStyleStack, tokenizer, and warn_doc_error.

Referenced by handleUnclosedStyleCommands(), DocRoot::parse(), and DocText::parse().

◆ internalValidatingParseDoc()

Token DocParser::internalValidatingParseDoc ( DocNodeVariant * parent,
DocNodeList & children,
const DString & doc )

Definition at line 1877 of file docparser.cpp.

1879{
1880 AUTO_TRACE();
1881 Token retval = Token::make_RetVal_OK();
1882
1883 if (doc.empty()) return retval;
1884
1886
1887 // first parse any number of paragraphs
1888 bool isFirst=true;
1889 DocPara *lastPar=!children.empty() ? std::get_if<DocPara>(&children.back()): nullptr;
1890 if (lastPar)
1891 { // last child item was a paragraph
1892 isFirst=false;
1893 }
1894 do
1895 {
1896 children.append<DocPara>(this,parent);
1897 DocPara *par = children.get_last<DocPara>();
1898 if (isFirst) { par->markFirst(); isFirst=false; }
1899 retval=par->parse();
1900 if (!par->empty())
1901 {
1902 if (lastPar) lastPar->markLast(false);
1903 lastPar=par;
1904 }
1905 else
1906 {
1907 children.pop_back();
1908 }
1909 } while (retval.is(TokenRetval::TK_NEWPARA));
1910 if (lastPar) lastPar->markLast();
1911
1912 AUTO_TRACE_EXIT("isFirst={} isLast={}",lastPar?lastPar->isFirst():-1,lastPar?lastPar->isLast():-1);
1913 return retval;
1914}
bool isLast() const
Definition docnode.h:1097
bool isFirst() const
Definition docnode.h:1096
void markLast(bool v=true)
Definition docnode.h:1095
void init(const char *input, const DString &fileName, bool markdownSupport, bool insideHtmlLink)
void pop_back()
removes the last element
Definition growvector.h:115
bool empty() const
checks whether the container is empty
Definition growvector.h:140

References DocNodeList::append(), AUTO_TRACE, AUTO_TRACE_EXIT, GrowVector< T >::back(), context, DString::data(), DString::empty(), GrowVector< T >::empty(), DocParserContext::fileName, DocNodeList::get_last(), DocTokenizer::init(), DocParserContext::insideHtmlLink, Token::is(), DocPara::isFirst(), DocPara::isLast(), DocParserContext::markdownSupport, DocPara::markLast(), parent(), GrowVector< T >::pop_back(), and tokenizer.

Referenced by DocPara::handleInheritDoc(), DocRef::parse(), DocXRefItem::parse(), DocTitle::parseFromString(), and DocSimpleSect::parseRcs().

◆ popContext()

void DocParser::popContext ( )
private

Definition at line 75 of file docparser.cpp.

76{
77 auto &ctx = contextStack.top();
78 context = ctx;
79 tokenizer.setFileName(ctx.fileName);
80 tokenizer.setLineNr(ctx.lineNo);
81 contextStack.pop();
84
85 //DString indent;
86 //indent.fill(' ',contextStack.size()*2+2);
87 //printf("%sdocParserPopContext() count=%zu\n",qPrint(indent),context.nodeStack.size());
88}
std::stack< DocParserContext > contextStack
TokenInfo * token()
void setLineNr(int lineno)
void setFileName(const DString &fileName)

References context, contextStack, DocTokenizer::popContext(), DocTokenizer::setFileName(), DocTokenizer::setLineNr(), DocParserContext::token, DocTokenizer::token(), and tokenizer.

Referenced by DocParser::AutoSaveContext::~AutoSaveContext().

◆ processCopyDoc()

DString DocParser::processCopyDoc ( const char * data,
size_t & len )

Definition at line 2074 of file docparser.cpp.

2075{
2076 AUTO_TRACE("data={} len={}",Trace::trunc(data),len);
2077 DString result;
2078 result.reserve(len+32);
2079 size_t i=0;
2080 int lineNr = tokenizer.getLineNr();
2081 while (i<len)
2082 {
2083 char c = data[i];
2084 if (c=='@' || c=='\\') // look for a command
2085 {
2086 bool isBrief=true;
2087 size_t j=isCopyBriefOrDetailsCmd(data,i,len,isBrief);
2088 if (j>0)
2089 {
2090 // skip whitespace
2091 while (j<len && (data[j]==' ' || data[j]=='\t')) j++;
2092 // extract the argument
2093 DString id = extractCopyDocId(data,j,len);
2094 const Definition *def = nullptr;
2095 DString doc,brief;
2096 //printf("resolving docs='%s'\n",qPrint(id));
2097 bool found = findDocsForMemberOrCompound(id,&doc,&brief,&def);
2098 if (found && def->isReference())
2099 {
2101 "@copy{} or @copydoc target '{}' found but is from a tag file, skipped",
2102 isBrief?"brief":"details", id);
2103 }
2104 else if (found)
2105 {
2106 //printf("found it def=%p brief='%s' doc='%s' isBrief=%d\n",def,qPrint(brief),qPrint(doc),isBrief);
2107 auto it = std::find(context.copyStack.begin(),context.copyStack.end(),def);
2108 if (it==context.copyStack.end()) // definition not parsed earlier
2109 {
2110 DString orgFileName = context.fileName;
2111 context.copyStack.push_back(def);
2112 auto addDocs = [&](const DString &file_,int line_,const DString &doc_)
2113 {
2114 result+=" \\ifile \""+file_+"\" ";
2115 result+="\\iline "+DString().setNum(line_)+" \\ilinebr ";
2116 size_t len_ = doc_.length();
2117 result+=processCopyDoc(doc_.data(),len_);
2118 };
2119 if (isBrief)
2120 {
2121 addDocs(def->briefFile(),def->briefLine(),brief);
2122 }
2123 else
2124 {
2125 addDocs(def->docFile(),def->docLine(),doc);
2127 {
2128 const MemberDef *md = toMemberDef(def);
2129 const ArgumentList &docArgList = md->templateMaster() ?
2130 md->templateMaster()->argumentList() :
2131 md->argumentList();
2132 result+=inlineArgListToDoc(docArgList);
2133 }
2134 }
2135 context.copyStack.pop_back();
2136 result+=" \\ilinebr \\ifile \""+context.fileName+"\" ";
2137 result+="\\iline "+DString().setNum(lineNr)+" ";
2138 }
2139 else
2140 {
2142 "Found recursive @copy{} or @copydoc relation for argument '{}'.",
2143 isBrief?"brief":"details",id);
2144 }
2145 }
2146 else
2147 {
2149 "@copy{} or @copydoc target '{}' not found", isBrief?"brief":"details",id);
2150 }
2151 // skip over command
2152 i=j;
2153 }
2154 else
2155 {
2156 DString endMarker;
2157 size_t k = isVerbatimSection(data,i,len,endMarker);
2158 if (k>0)
2159 {
2160 size_t orgPos = i;
2161 i=skipToEndMarker(data,k,len,endMarker);
2162 result+=DString(data+orgPos,i-orgPos);
2163 // TODO: adjust lineNr
2164 }
2165 else
2166 {
2167 result+=c;
2168 i++;
2169 }
2170 }
2171 }
2172 else // not a command, just copy
2173 {
2174 result+=c;
2175 i++;
2176 lineNr += (c=='\n') ? 1 : 0;
2177 }
2178 }
2179 len = result.length();
2180 AUTO_TRACE_EXIT("result={}",Trace::trunc(result));
2181 return result;
2182}
DString & setNum(short n)
Definition dstring.h:541
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition dstring.h:222
virtual DString briefFile() const =0
virtual int briefLine() const =0
virtual bool isReference() const =0
bool findDocsForMemberOrCompound(const DString &commandName, DString *pDoc, DString *pBrief, const Definition **pDef)
DString processCopyDoc(const char *data, size_t &len)
virtual const MemberDef * templateMaster() const =0
static DString extractCopyDocId(const char *data, size_t &j, size_t len)
static size_t isVerbatimSection(const char *data, size_t i, size_t len, DString &endMarker)
static size_t skipToEndMarker(const char *data, size_t i, size_t len, const DString &endMarker)
static size_t isCopyBriefOrDetailsCmd(const char *data, size_t i, size_t len, bool &brief)
MemberDef * toMemberDef(Definition *d)
DString trunc(const DString &s, size_t numChars=15)
Definition trace.h:56
DefinitionStack copyStack
Definition docparser_p.h:70
DString inlineArgListToDoc(const ArgumentList &al)
Definition util.cpp:1203

References MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_EXIT, Definition::briefFile(), Definition::briefLine(), context, DocParserContext::copyStack, Definition::definitionType(), Definition::docFile(), Definition::docLine(), DString::DString(), extractCopyDocId(), DocParserContext::fileName, findDocsForMemberOrCompound(), DocTokenizer::getLineNr(), inlineArgListToDoc(), isCopyBriefOrDetailsCmd(), Definition::isReference(), isVerbatimSection(), DString::length(), processCopyDoc(), DString::reserve(), DString::setNum(), skipToEndMarker(), MemberDef::templateMaster(), tokenizer, toMemberDef(), Trace::trunc(), Definition::TypeMember, and warn_doc_error.

Referenced by processCopyDoc(), and validatingParseDoc().

◆ pushContext()

void DocParser::pushContext ( )
private

Definition at line 60 of file docparser.cpp.

61{
62 //DString indent;
63 //indent.fill(' ',contextStack.size()*2+2);
64 //printf("%sdocParserPushContext() count=%zu\n",qPrint(indent),context.nodeStack.size());
65
67 contextStack.emplace();
68 auto &ctx = contextStack.top();
69 ctx = context;
71 ctx.lineNo = tokenizer.getLineNr();
73}
DString getFileName() const

References context, contextStack, DocParserContext::fileName, DocTokenizer::getFileName(), DocTokenizer::getLineNr(), DocTokenizer::pushContext(), DocParserContext::token, DocTokenizer::token(), and tokenizer.

Referenced by DocParser::AutoSaveContext::AutoSaveContext().

◆ readTextFileByName()

void DocParser::readTextFileByName ( const DString & file,
DString & text )

Definition at line 1918 of file docparser.cpp.

1919{
1920 AUTO_TRACE("file={} text={}",file,text);
1921 bool ambig = false;
1922 DString filePath = findFilePath(file,ambig);
1923 if (!filePath.empty())
1924 {
1925 size_t indent = 0;
1926 text = detab(fileToString(filePath,Config_getBool(FILTER_SOURCE_FILES)),indent);
1927 if (ambig)
1928 {
1929 warn_doc_error(context.fileName,tokenizer.getLineNr(),"included file name '{}' is ambiguous"
1930 "Possible candidates:\n{}",file, showFileDefMatches(Doxygen::exampleNameLinkedMap,file));
1931 }
1932 }
1933 else
1934 {
1935 warn_doc_error(context.fileName,tokenizer.getLineNr(),"included file '{}' is not found. "
1936 "Check your EXAMPLE_PATH",file);
1937 }
1938}
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:102
DString findFilePath(const DString &file, bool &ambig)
Definition util.cpp:3012
DString detab(const DString &s, size_t &refIndent)
Definition util.cpp:6758
DString fileToString(const DString &name, bool filter, bool isSourceCode)
Definition util.cpp:1491

References AUTO_TRACE, Config_getBool, context, detab(), DString::empty(), Doxygen::exampleNameLinkedMap, DocParserContext::fileName, fileToString(), findFilePath(), DocTokenizer::getLineNr(), showFileDefMatches(), tokenizer, and warn_doc_error.

Referenced by DocInclude::parse().

Member Data Documentation

◆ context

DocParserContext DocParser::context

Definition at line 153 of file docparser_p.h.

Referenced by DocSimpleSect::appendLinkWord(), AutoNodeStack::AutoNodeStack(), checkArgumentName(), checkIfHtmlEndTagEndsAutoList(), checkRetvalName(), checkUnOrMultipleDocumentedParams(), createRef(), defaultHandleTitleAndSize(), defaultHandleToken(), DocAnchor::DocAnchor(), DocCite::DocCite(), DocDiaFile::DocDiaFile(), DocDotFile::DocDotFile(), DocEmoji::DocEmoji(), DocFormula::DocFormula(), DocHtmlCaption::DocHtmlCaption(), DocLink::DocLink(), DocLinkedWord::DocLinkedWord(), DocMermaidFile::DocMermaidFile(), DocMscFile::DocMscFile(), DocPlantUmlFile::DocPlantUmlFile(), DocRef::DocRef(), DocWord::DocWord(), errorHandleDefaultToken(), findAndCopyImage(), findDocsForMemberOrCompound(), handleAHref(), handleAnchor(), handleCite(), DocPara::handleCommand(), DocPara::handleDoxyConfig(), DocPara::handleEmoji(), DocPara::handleFile(), DocPara::handleHtmlStartTag(), handleIFile(), handleILine(), handleImage(), handleImg(), DocPara::handleInclude(), DocPara::handleIncludeOperator(), DocPara::handleInheritDoc(), handleInitialStyleCommands(), handleInternalRef(), DocPara::handleLink(), handleLinkedWord(), handleParameterType(), handlePendingStyleCommands(), handlePrefix(), handleRef(), DocPara::handleSection(), DocPara::handleShowDate(), DocPara::handleStartCode(), handleStyleArgument(), handleStyleEnter(), handleStyleLeave(), handleUnclosedStyleCommands(), DocPara::handleXRefItem(), DocPara::injectToken(), internalValidatingParseDoc(), DocAutoList::parse(), DocHRef::parse(), DocHtmlDescData::parse(), DocHtmlDescList::parse(), DocHtmlDescTitle::parse(), DocHtmlHeader::parse(), DocHtmlList::parse(), DocHtmlRow::parse(), DocHtmlTable::parse(), DocInclude::parse(), DocIncOperator::parse(), DocIndexEntry::parse(), DocInternal::parse(), DocLink::parse(), DocPara::parse(), DocParamList::parse(), DocRef::parse(), DocRoot::parse(), DocSecRefList::parse(), DocSection::parse(), DocText::parse(), DocTitle::parseFromString(), DocSimpleSect::parseRcs(), DocHtmlList::parseXml(), DocHtmlRow::parseXml(), DocHtmlTable::parseXml(), DocParamList::parseXml(), popContext(), processCopyDoc(), pushContext(), readTextFileByName(), skipSpacesForTable(), validatingParseDoc(), validatingParseText(), validatingParseTitle(), and AutoNodeStack::~AutoNodeStack().

◆ contextStack

std::stack< DocParserContext > DocParser::contextStack

Definition at line 152 of file docparser_p.h.

Referenced by popContext(), and pushContext().

◆ tokenizer

DocTokenizer DocParser::tokenizer

Definition at line 154 of file docparser_p.h.

Referenced by checkIfHtmlEndTagEndsAutoList(), createRef(), defaultHandleTitleAndSize(), defaultHandleToken(), DocAnchor::DocAnchor(), DocCite::DocCite(), DocEmoji::DocEmoji(), docFindSections(), DocFormula::DocFormula(), DocHtmlCaption::DocHtmlCaption(), DocRef::DocRef(), errorHandleDefaultToken(), findAndCopyImage(), handleAHref(), handleAnchor(), handleCite(), DocPara::handleCommand(), DocPara::handleDoxyConfig(), DocPara::handleEmoji(), DocPara::handleFile(), DocPara::handleHtmlEndTag(), DocPara::handleHtmlStartTag(), handleIFile(), handleILine(), handleImage(), handleImg(), DocPara::handleInclude(), DocPara::handleIncludeOperator(), handleInternalRef(), DocPara::handleLink(), handleLinkedWord(), handlePrefix(), handleRef(), DocPara::handleSection(), DocPara::handleShowDate(), DocPara::handleStartCode(), handleStyleArgument(), handleStyleEnter(), handleStyleLeave(), handleUnclosedStyleCommands(), DocPara::handleXRefItem(), internalValidatingParseDoc(), DocAutoList::parse(), DocHRef::parse(), DocHtmlCaption::parse(), DocHtmlDescList::parse(), DocHtmlDescTitle::parse(), DocHtmlHeader::parse(), DocHtmlList::parse(), DocHtmlRow::parse(), DocHtmlSummary::parse(), DocHtmlTable::parse(), DocIndexEntry::parse(), DocInternalRef::parse(), DocLink::parse(), DocPara::parse(), DocParamList::parse(), DocRef::parse(), DocRoot::parse(), DocSecRefItem::parse(), DocSecRefList::parse(), DocText::parse(), DocTitle::parse(), DocVhdlFlow::parse(), DocTitle::parseFromString(), DocHtmlList::parseXml(), DocHtmlRow::parseXml(), DocHtmlTable::parseXml(), popContext(), processCopyDoc(), pushContext(), readTextFileByName(), skipSpacesForTable(), validatingParseDoc(), validatingParseText(), and validatingParseTitle().


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