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 100 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 213 of file docparser.cpp.

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

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 314 of file docparser.cpp.

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

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 335 of file docparser.cpp.

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

References argListToString(), MemberDef::argumentList(), Config_getBool, context, MemberDef::declArgumentList(), Definition::docFile(), Definition::docLine(), 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 1213 of file docparser.cpp.

1214{
1215 AUTO_TRACE();
1216 auto ns = AutoNodeStack(this,parent);
1217
1218 // parse title
1220 Token tok = tokenizer.lex();
1221 while (!tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1222 {
1223 if (tok.is(TokenRetval::TK_WORD) && (context.token->name=="width=" || context.token->name=="height="))
1224 {
1225 // special case: no title, but we do have a size indicator
1226 break;
1227 }
1228 else if (tok.is(TokenRetval::TK_HTMLTAG))
1229 {
1231 break;
1232 }
1233 if (!defaultHandleToken(parent,tok,children))
1234 {
1235 errorHandleDefaultToken(parent,tok,children,Mappers::cmdMapper->find(cmd));
1236 }
1237 tok = tokenizer.lex();
1238 }
1239 // parse size attributes
1240 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1241 {
1242 tok=tokenizer.lex();
1243 }
1244 while (tok.is_any_of(TokenRetval::TK_WHITESPACE,TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG)) // there are values following the title
1245 {
1246 if (tok.is(TokenRetval::TK_WORD))
1247 {
1248 if (context.token->name=="width=" || context.token->name=="height=")
1249 {
1252 }
1253
1254 if (context.token->name=="width")
1255 {
1256 width = context.token->chars;
1257 }
1258 else if (context.token->name=="height")
1259 {
1260 height = context.token->chars;
1261 }
1262 else // other text after the title -> treat as normal text
1263 {
1265 //warn_doc_error(context.fileName,tokenizer.getLineNr(),"Unknown option '{}' after \\{} command, expected 'width' or 'height'",
1266 // context.token->name, Mappers::cmdMapper->find(cmd));
1267 break;
1268 }
1269 }
1270
1271 tok=tokenizer.lex();
1272 // if we found something we did not expect, push it back to the stream
1273 // so it can still be processed
1274 if (tok.is_any_of(TokenRetval::TK_COMMAND_AT,TokenRetval::TK_COMMAND_BS))
1275 {
1277 tokenizer.unputString(tok.is(TokenRetval::TK_COMMAND_AT) ? "@" : "\\");
1278 break;
1279 }
1280 else if (tok.is(TokenRetval::TK_SYMBOL))
1281 {
1283 break;
1284 }
1285 else if (tok.is(TokenRetval::TK_HTMLTAG))
1286 {
1288 break;
1289 }
1290 }
1292
1294 AUTO_TRACE_EXIT("width={} height={}",width,height);
1295}
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
DString chars
DString text
#define AUTO_TRACE(...)
Definition docnode.cpp:51
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:53
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

References AUTO_TRACE, AUTO_TRACE_EXIT, 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 1476 of file docparser.cpp.

1477{
1478 AUTO_TRACE("token={} handleWord={}",tok.to_string(),handleWord);
1479 if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD,TokenRetval::TK_SYMBOL,TokenRetval::TK_URL,
1480 TokenRetval::TK_COMMAND_AT,TokenRetval::TK_COMMAND_BS,TokenRetval::TK_HTMLTAG)
1481 )
1482 {
1483 }
1484reparsetoken:
1485 DString tokenName = context.token->name;
1486 AUTO_TRACE_ADD("tokenName={}",tokenName);
1487 switch (tok.value())
1488 {
1489 case TokenRetval::TK_COMMAND_AT:
1490 // fall through
1491 case TokenRetval::TK_COMMAND_BS:
1492 switch (Mappers::cmdMapper->map(tokenName))
1493 {
1495 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_BSlash);
1496 break;
1498 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_At);
1499 break;
1501 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Less);
1502 break;
1504 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Greater);
1505 break;
1507 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Amp);
1508 break;
1510 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dollar);
1511 break;
1513 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Hash);
1514 break;
1516 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_DoubleColon);
1517 break;
1519 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Percent);
1520 break;
1522 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1523 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1524 break;
1526 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1527 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1528 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1529 break;
1531 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quot);
1532 break;
1534 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dot);
1535 break;
1537 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Exclam);
1538 break;
1540 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quest);
1541 break;
1543 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Plus);
1544 break;
1546 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1547 break;
1549 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Equal);
1550 break;
1552 {
1553 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,true);
1554 tok=handleStyleArgument(parent,children,tokenName);
1555 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,false);
1556 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1557 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1558 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1559 {
1560 AUTO_TRACE_ADD("CommandType::CMD_EMPHASIS: reparsing");
1561 goto reparsetoken;
1562 }
1563 }
1564 break;
1566 {
1567 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,true);
1568 tok=handleStyleArgument(parent,children,tokenName);
1569 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,false);
1570 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1571 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1572 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1573 {
1574 AUTO_TRACE_ADD("CommandType::CMD_BOLD: reparsing");
1575 goto reparsetoken;
1576 }
1577 }
1578 break;
1580 {
1581 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,true);
1582 tok=handleStyleArgument(parent,children,tokenName);
1583 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,false);
1584 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1585 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1586 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1587 {
1588 AUTO_TRACE_ADD("CommandType::CMD_CODE: reparsing");
1589 goto reparsetoken;
1590 }
1591 }
1592 break;
1594 {
1596 tok = tokenizer.lex();
1598 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1599 {
1600 warn_doc_error(context.fileName,tokenizer.getLineNr(),"htmlonly section ended without end marker");
1601 }
1603 }
1604 break;
1606 {
1608 tok = tokenizer.lex();
1610 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1611 {
1612 warn_doc_error(context.fileName,tokenizer.getLineNr(),"manonly section ended without end marker");
1613 }
1615 }
1616 break;
1618 {
1620 tok = tokenizer.lex();
1622 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1623 {
1624 warn_doc_error(context.fileName,tokenizer.getLineNr(),"rtfonly section ended without end marker");
1625 }
1627 }
1628 break;
1630 {
1632 tok = tokenizer.lex();
1634 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1635 {
1636 warn_doc_error(context.fileName,tokenizer.getLineNr(),"latexonly section ended without end marker");
1637 }
1639 }
1640 break;
1642 {
1644 tok = tokenizer.lex();
1646 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1647 {
1648 warn_doc_error(context.fileName,tokenizer.getLineNr(),"xmlonly section ended without end marker");
1649 }
1651 }
1652 break;
1654 {
1656 tok = tokenizer.lex();
1658 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1659 {
1660 warn_doc_error(context.fileName,tokenizer.getLineNr(),"docbookonly section ended without end marker");
1661 }
1663 }
1664 break;
1666 {
1667 children.append<DocFormula>(this,parent,context.token->id);
1668 }
1669 break;
1672 {
1673 handleAnchor(parent,children);
1674 }
1675 break;
1677 {
1678 handleCite(parent,children);
1679 }
1680 break;
1682 {
1683 handlePrefix(parent,children);
1684 }
1685 break;
1687 {
1688 handleInternalRef(parent,children);
1690 }
1691 break;
1693 {
1695 (void)tokenizer.lex();
1697 //printf("Found scope='%s'\n",qPrint(context.context));
1699 }
1700 break;
1702 handleImage(parent,children);
1703 break;
1705 handleILine(tok.command_to_char(),tokenName);
1706 break;
1708 handleIFile(tok.command_to_char(),tokenName);
1709 break;
1710 default:
1711 return false;
1712 }
1713 break;
1714 case TokenRetval::TK_HTMLTAG:
1715 {
1716 auto handleEnterLeaveStyle = [this,&parent,&children,&tokenName](DocStyleChange::Style style) {
1717 if (!context.token->endTag)
1718 {
1719 handleStyleEnter(parent,children,style,tokenName,&context.token->attribs);
1720 }
1721 else
1722 {
1723 handleStyleLeave(parent,children,style,tokenName);
1724 }
1725 };
1726 switch (Mappers::htmlTagMapper->map(tokenName))
1727 {
1729 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <div> tag in heading");
1730 break;
1732 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <pre> tag in heading");
1733 break;
1735 handleEnterLeaveStyle(DocStyleChange::Span);
1736 break;
1738 handleEnterLeaveStyle(DocStyleChange::Bold);
1739 break;
1741 handleEnterLeaveStyle(DocStyleChange::S);
1742 break;
1744 handleEnterLeaveStyle(DocStyleChange::Strike);
1745 break;
1747 handleEnterLeaveStyle(DocStyleChange::Del);
1748 break;
1750 handleEnterLeaveStyle(DocStyleChange::Underline);
1751 break;
1753 handleEnterLeaveStyle(DocStyleChange::Ins);
1754 break;
1756 case HtmlTagType::XML_C:
1757 handleEnterLeaveStyle(DocStyleChange::Code);
1758 break;
1760 handleEnterLeaveStyle(DocStyleChange::Kbd);
1761 break;
1763 handleEnterLeaveStyle(DocStyleChange::Typewriter);
1764 break;
1766 handleEnterLeaveStyle(DocStyleChange::Italic);
1767 break;
1769 handleEnterLeaveStyle(DocStyleChange::Subscript);
1770 break;
1772 handleEnterLeaveStyle(DocStyleChange::Superscript);
1773 break;
1775 handleEnterLeaveStyle(DocStyleChange::Center);
1776 break;
1778 handleEnterLeaveStyle(DocStyleChange::Small);
1779 break;
1781 handleEnterLeaveStyle(DocStyleChange::Cite);
1782 break;
1784 if (!context.token->endTag)
1785 {
1787 }
1788 break;
1789 default:
1790 return false;
1791 break;
1792 }
1793 }
1794 break;
1795 case TokenRetval::TK_SYMBOL:
1796 {
1799 {
1800 children.append<DocSymbol>(this,parent,s);
1801 }
1802 else
1803 {
1804 return false;
1805 }
1806 }
1807 break;
1808 case TokenRetval::TK_WHITESPACE:
1809 case TokenRetval::TK_NEWPARA:
1810handlepara:
1811 if (insidePRE(parent) || !children.empty())
1812 {
1813 children.append<DocWhiteSpace>(this,parent,context.token->chars);
1814 }
1815 break;
1816 case TokenRetval::TK_LNKWORD:
1817 if (handleWord)
1818 {
1819 handleLinkedWord(parent,children);
1820 }
1821 else
1822 return false;
1823 break;
1824 case TokenRetval::TK_WORD:
1825 if (handleWord)
1826 {
1827 children.append<DocWord>(this,parent,context.token->name);
1828 }
1829 else
1830 return false;
1831 break;
1832 case TokenRetval::TK_URL:
1834 {
1835 children.append<DocWord>(this,parent,context.token->name);
1836 }
1837 else
1838 {
1839 children.append<DocURL>(this,parent,context.token->name,context.token->isEMailAddr);
1840 }
1841 break;
1842 default:
1843 return false;
1844 }
1845 return true;
1846}
void append(Args &&... args)
Append a new DocNodeVariant to the list by constructing it with type T and parameters Args.
Definition docnode.h:1404
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:158
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
DString verb
HtmlAttribList attribs
bool isEMailAddr
@ CMD_INTERNALREF
Definition cmdmapper.h:66
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:52
bool insidePRE(const DocNodeVariant *n)
const Mapper< HtmlTagType > * htmlTagMapper
DocNodeStack nodeStack
Definition docparser_p.h:66
DString exampleName
Definition docparser_p.h:81

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 595 of file docparser.cpp.

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

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 100 of file docparser.cpp.

101{
102 DString result;
103 bool ambig = false;
104 FileDef *fd = Doxygen::imageNameLinkedMap->findFileDef(fileName,ambig);
105 //printf("Search for %s\n",fileName);
106 if (fd)
107 {
108 if (ambig & doWarn)
109 {
111 "image file name '{}' is ambiguous.\n"
112 "Possible candidates:\n{}", fileName,Doxygen::imageNameLinkedMap->showFileDefMatches(fileName));
113 }
114
115 DString inputFile = fd->absFilePath();
116 FileInfo infi(inputFile.str());
117 if (infi.exists())
118 {
119 result = fileName;
120 if (size_t i = result.rfind('/') ; i!=DString::npos || (i=result.rfind('\\'))!=DString::npos)
121 {
122 result = result.mid(i+1);
123 }
124 //printf("fileName=%s result=%s\n",fileName,qPrint(result));
125 DString outputDir;
126 switch(type)
127 {
128 case DocImage::Html:
129 if (!Config_getBool(GENERATE_HTML)) return result;
130 outputDir = Config_getString(HTML_OUTPUT);
131 break;
132 case DocImage::Latex:
133 if (!Config_getBool(GENERATE_LATEX)) return result;
134 outputDir = Config_getString(LATEX_OUTPUT);
135 break;
137 if (!Config_getBool(GENERATE_DOCBOOK)) return result;
138 outputDir = Config_getString(DOCBOOK_OUTPUT);
139 break;
140 case DocImage::Rtf:
141 if (!Config_getBool(GENERATE_RTF)) return result;
142 outputDir = Config_getString(RTF_OUTPUT);
143 break;
144 case DocImage::Xml:
145 if (!Config_getBool(GENERATE_XML)) return result;
146 outputDir = Config_getString(XML_OUTPUT);
147 break;
148 }
149 DString outputFile = outputDir+"/"+result;
150 FileInfo outfi(outputFile.str());
151 if (outfi.isSymLink())
152 {
153 Dir().remove(outputFile.str());
155 "destination of image {} is a symlink, replacing with image",
156 outputFile);
157 }
158 if (outputFile!=inputFile) // prevent copying to ourself
159 {
160 if (copyFile(inputFile,outputFile) && type==DocImage::Html)
161 {
163 }
164 }
165 }
166 else
167 {
169 "could not open image {}",fileName);
170 }
171
172 if (type==DocImage::Latex && Config_getBool(USE_PDFLATEX) &&
173 fd->name().endsWith(".eps")
174 )
175 { // we have an .eps image in pdflatex mode => convert it to a pdf.
176 DString outputDir = Config_getString(LATEX_OUTPUT);
177 DString baseName = fd->name().left(fd->name().length()-4);
178 DString epstopdfArgs(4096, DString::ExplicitSize);
179 epstopdfArgs.sprintf("\"%s/%s.eps\" --outfile=\"%s/%s.pdf\"",
180 qPrint(outputDir), qPrint(baseName),
181 qPrint(outputDir), qPrint(baseName));
182 if (Portable::system("epstopdf",epstopdfArgs)!=0)
183 {
184 err("Problems running epstopdf. Check your TeX installation!\n");
185 }
186 else
187 {
188 Dir().remove(outputDir.str()+"/"+baseName.str()+".eps");
189 }
190 return baseName;
191 }
192 }
193 else
194 {
195 result=fileName;
196 if (!result.startsWith("http:") && !result.startsWith("https:") && doWarn)
197 {
199 "image file {} is not found in IMAGE_PATH: "
200 "assuming external image.",fileName
201 );
202 }
203 }
204 return result;
205}
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:248
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:322
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:182
@ ExplicitSize
Definition dstring.h:135
@ DocBook
Definition docnode.h:644
static FileNameLinkedMap * imageNameLinkedMap
Definition doxygen.h:98
static IndexList * indexList
Definition doxygen.h:125
virtual DString absFilePath() const =0
DString showFileDefMatches(const DString &n) const
Returns a list of file definitions in fnMap that match the file name n.
Definition filename.cpp:129
FileDef * findFileDef(const DString &n, bool &ambig) const
Returns the file definition in fnMap that matches the file name n.
Definition filename.cpp:36
void addImageFile(const DString &name)
Definition indexlist.h:124
#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
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:4621

References FileDef::absFilePath(), IndexList::addImageFile(), Config_getBool, Config_getString, context, copyFile(), DocImage::DocBook, DString::endsWith(), err, FileInfo::exists(), DString::ExplicitSize, DocParserContext::fileName, FileNameLinkedMap::findFileDef(), DocTokenizer::getLineNr(), DocImage::Html, Doxygen::imageNameLinkedMap, Doxygen::indexList, FileInfo::isSymLink(), DocImage::Latex, DString::left(), DString::length(), DString::mid(), Definition::name(), DString::npos, qPrint(), Dir::remove(), DString::rfind(), DocImage::Rtf, FileNameLinkedMap::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 442 of file docparser.cpp.

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

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(), FileNameLinkedMap::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 781 of file docparser.cpp.

783{
784 AUTO_TRACE();
785 size_t index=0;
786 Token retval = Token::make_RetVal_OK();
787 for (const auto &opt : tagHtmlAttribs)
788 {
789 if (opt.name=="name" || opt.name=="id") // <a name=label> or <a id=label> tag
790 {
791 if (!opt.value.empty())
792 {
793 children.append<DocAnchor>(this,parent,opt.value,true);
794 break; // stop looking for other tag attribs
795 }
796 else
797 {
798 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <a> tag with name option but without value!");
799 }
800 }
801 else if (opt.name=="href") // <a href=url>..</a> tag
802 {
803 // copy attributes
804 HtmlAttribList attrList = tagHtmlAttribs;
805 // and remove the href attribute
806 attrList.erase(attrList.begin()+index);
807 DString relPath;
808 if (opt.value.at(0) != '#') relPath = context.relPath;
809 children.append<DocHRef>(this, parent, attrList,
810 opt.value, relPath,
811 convertNameToFile(context.fileName, false, true));
813 retval = children.get_last<DocHRef>()->parse();
816 break;
817 }
818 else // unsupported option for tag a
819 {
820 }
821 ++index;
822 }
823 return retval;
824}
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
bool parse(const DString &fileName, bool update=false, CompareMode compareMode=CompareMode::Full)
DString convertNameToFile(const DString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:2865

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 1043 of file docparser.cpp.

1044{
1045 AUTO_TRACE();
1046 Token tok=tokenizer.lex();
1047 if (!tok.is(TokenRetval::TK_WHITESPACE))
1048 {
1049 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command",
1050 context.token->name);
1051 return;
1052 }
1053
1056 tok=tokenizer.lex();
1057 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1058 {
1059 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
1060 "argument of command {}",context.token->name);
1061 return;
1062 }
1063 else if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1064 {
1065 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of {}",
1066 tok.to_string(),context.token->name);
1067 return;
1068 }
1069 }
1070 children.append<DocAnchor>(this,parent,context.token->name,false);
1071}
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 1073 of file docparser.cpp.

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

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 1429 of file docparser.cpp.

1430{
1431 AUTO_TRACE();
1432 Token tok=tokenizer.lex();
1433 if (!tok.is(TokenRetval::TK_WHITESPACE))
1434 {
1435 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after '{:c}{}' command",
1436 cmdChar,cmdName);
1437 return;
1438 }
1440 tok=tokenizer.lex();
1442 if (!tok.is(TokenRetval::TK_WORD))
1443 {
1444 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of '{:c}{}'",
1445 tok.to_string(),cmdChar,cmdName);
1446 return;
1447 }
1449}
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 1451 of file docparser.cpp.

1452{
1453 AUTO_TRACE();
1455 Token tok = tokenizer.lex();
1457 if (!tok.is(TokenRetval::TK_WORD))
1458 {
1459 warn_doc_error(context.fileName,tokenizer.getLineNr(),"invalid argument for command '{:c}{}'",
1460 cmdChar,cmdName);
1461 return;
1462 }
1463}
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 1297 of file docparser.cpp.

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

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

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 770 of file docparser.cpp.

771{
772 AUTO_TRACE();
773 while (!context.initialStyleStack.empty())
774 {
775 const DocStyleChange &sc = std::get<DocStyleChange>(*context.initialStyleStack.top());
776 handleStyleEnter(parent,children,sc.style(),sc.tagName(),&sc.attribs());
778 }
779}
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:68

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 1021 of file docparser.cpp.

1022{
1023 Token tok=tokenizer.lex();
1024 DString tokenName = context.token->name;
1025 AUTO_TRACE("name={}",tokenName);
1026 if (!tok.is(TokenRetval::TK_WHITESPACE))
1027 {
1028 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command", tokenName);
1029 return;
1030 }
1032 tok=tokenizer.lex(); // get the reference id
1033 if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1034 {
1035 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of {}",
1036 tok.to_string(),tokenName);
1037 return;
1038 }
1039 children.append<DocInternalRef>(this,parent,context.token->name);
1040 children.get_last<DocInternalRef>()->parse();
1041}
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 850 of file docparser.cpp.

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

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::empty(), DocParserContext::fileName, FileNameLinkedMap::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 997 of file docparser.cpp.

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

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 750 of file docparser.cpp.

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

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 1177 of file docparser.cpp.

1178{
1179 AUTO_TRACE();
1180 Token tok=tokenizer.lex();
1181 if (!tok.is(TokenRetval::TK_WHITESPACE))
1182 {
1183 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command", context.token->name);
1184 return;
1185 }
1187 tok=tokenizer.lex();
1188 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1189 {
1190 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
1191 "argument of command {}",context.token->name);
1192 return;
1193 }
1194 else if (!tok.is(TokenRetval::TK_WORD))
1195 {
1196 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of {}",
1197 tok.to_string(),context.token->name);
1198 return;
1199 }
1202}
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 1403 of file docparser.cpp.

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

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 628 of file docparser.cpp.

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

689{
690 AUTO_TRACE("tagName={}",tagName);
691 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),s,tagName,true,
693 context.styleStack.push(&children.back());
695}
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 700 of file docparser.cpp.

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

References DocNodeList::append(), AUTO_TRACE, context, 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 826 of file docparser.cpp.

827{
828 AUTO_TRACE("content.initialStyleStack.size()={}",context.initialStyleStack.size());
829 if (!context.initialStyleStack.empty())
830 {
831 DString tagName = std::get<DocStyleChange>(*context.initialStyleStack.top()).tagName();
832 DString fileName = std::get<DocStyleChange>(*context.initialStyleStack.top()).fileName();
833 int lineNr = std::get<DocStyleChange>(*context.initialStyleStack.top()).lineNr();
836 if (lineNr != -1)
837 {
839 "end of comment block while expecting "
840 "command </{}> (Probable start '{}' at line {})",tagName, fileName, lineNr);
841 }
842 else
843 {
845 "end of comment block while expecting command </{}>",tagName);
846 }
847 }
848}
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 1881 of file docparser.cpp.

1883{
1884 AUTO_TRACE();
1885 Token retval = Token::make_RetVal_OK();
1886
1887 if (doc.empty()) return retval;
1888
1890
1891 // first parse any number of paragraphs
1892 bool isFirst=true;
1893 DocPara *lastPar=!children.empty() ? std::get_if<DocPara>(&children.back()): nullptr;
1894 if (lastPar)
1895 { // last child item was a paragraph
1896 isFirst=false;
1897 }
1898 do
1899 {
1900 children.append<DocPara>(this,parent);
1901 DocPara *par = children.get_last<DocPara>();
1902 if (isFirst) { par->markFirst(); isFirst=false; }
1903 retval=par->parse();
1904 if (!par->empty())
1905 {
1906 if (lastPar) lastPar->markLast(false);
1907 lastPar=par;
1908 }
1909 else
1910 {
1911 children.pop_back();
1912 }
1913 } while (retval.is(TokenRetval::TK_NEWPARA));
1914 if (lastPar) lastPar->markLast();
1915
1916 AUTO_TRACE_EXIT("isFirst={} isLast={}",lastPar?lastPar->isFirst():-1,lastPar?lastPar->isLast():-1);
1917 return retval;
1918}
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 79 of file docparser.cpp.

80{
81 auto &ctx = contextStack.top();
82 context = ctx;
83 tokenizer.setFileName(ctx.fileName);
84 tokenizer.setLineNr(ctx.lineNo);
85 contextStack.pop();
88
89 //DString indent;
90 //indent.fill(' ',contextStack.size()*2+2);
91 //printf("%sdocParserPopContext() count=%zu\n",qPrint(indent),context.nodeStack.size());
92}
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 2078 of file docparser.cpp.

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

References MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_EXIT, Definition::briefFile(), Definition::briefLine(), context, DocParserContext::copyStack, Definition::definitionType(), Definition::docFile(), Definition::docLine(), 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 64 of file docparser.cpp.

65{
66 //DString indent;
67 //indent.fill(' ',contextStack.size()*2+2);
68 //printf("%sdocParserPushContext() count=%zu\n",qPrint(indent),context.nodeStack.size());
69
71 contextStack.emplace();
72 auto &ctx = contextStack.top();
73 ctx = context;
75 ctx.lineNo = tokenizer.getLineNr();
77}
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 1922 of file docparser.cpp.

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

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

Referenced by DocInclude::parse().

Member Data Documentation

◆ context

DocParserContext DocParser::context

Definition at line 152 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 151 of file docparser_p.h.

Referenced by popContext(), and pushContext().

◆ tokenizer

DocTokenizer DocParser::tokenizer

Definition at line 153 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: