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:326
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
std::string_view view() const
Definition dstring.h:162
DString & sprintf(const char *format,...)
Definition dstring.cpp:34
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:337
DString left(size_t len) const
Definition dstring.h:306
const std::string & str() const
Definition dstring.h:645
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:157
bool endsWith(const char *s) const
Definition dstring.h:617
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151
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:181
const char * qPrint(const char *s)
Definition dstring.h:783
#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:861
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:859

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

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

1484{
1485 AUTO_TRACE("token={} handleWord={}",tok.to_string(),handleWord);
1486 if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD,TokenRetval::TK_SYMBOL,TokenRetval::TK_URL,
1487 TokenRetval::TK_COMMAND_AT,TokenRetval::TK_COMMAND_BS,TokenRetval::TK_HTMLTAG)
1488 )
1489 {
1490 }
1491reparsetoken:
1492 DString tokenName = context.token->name;
1493 AUTO_TRACE_ADD("tokenName={}",tokenName);
1494 switch (tok.value())
1495 {
1496 case TokenRetval::TK_COMMAND_AT:
1497 // fall through
1498 case TokenRetval::TK_COMMAND_BS:
1499 switch (Mappers::cmdMapper->map(tokenName))
1500 {
1502 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_BSlash);
1503 break;
1505 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_At);
1506 break;
1508 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Less);
1509 break;
1511 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Greater);
1512 break;
1514 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Amp);
1515 break;
1517 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dollar);
1518 break;
1520 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Hash);
1521 break;
1523 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_DoubleColon);
1524 break;
1526 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Percent);
1527 break;
1529 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1530 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1531 break;
1533 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1534 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1535 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1536 break;
1538 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quot);
1539 break;
1541 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dot);
1542 break;
1544 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Exclam);
1545 break;
1547 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quest);
1548 break;
1550 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Plus);
1551 break;
1553 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1554 break;
1556 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Equal);
1557 break;
1559 {
1560 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,true);
1561 tok=handleStyleArgument(parent,children,tokenName);
1562 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,false);
1563 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1564 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1565 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1566 {
1567 AUTO_TRACE_ADD("CommandType::CMD_EMPHASIS: reparsing");
1568 goto reparsetoken;
1569 }
1570 }
1571 break;
1573 {
1574 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,true);
1575 tok=handleStyleArgument(parent,children,tokenName);
1576 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,false);
1577 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1578 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1579 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1580 {
1581 AUTO_TRACE_ADD("CommandType::CMD_BOLD: reparsing");
1582 goto reparsetoken;
1583 }
1584 }
1585 break;
1587 {
1588 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,true);
1589 tok=handleStyleArgument(parent,children,tokenName);
1590 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,false);
1591 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1592 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1593 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1594 {
1595 AUTO_TRACE_ADD("CommandType::CMD_CODE: reparsing");
1596 goto reparsetoken;
1597 }
1598 }
1599 break;
1601 {
1603 tok = tokenizer.lex();
1605 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1606 {
1607 warn_doc_error(context.fileName,tokenizer.getLineNr(),"htmlonly section ended without end marker");
1608 }
1610 }
1611 break;
1613 {
1615 tok = tokenizer.lex();
1617 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1618 {
1619 warn_doc_error(context.fileName,tokenizer.getLineNr(),"manonly section ended without end marker");
1620 }
1622 }
1623 break;
1625 {
1627 tok = tokenizer.lex();
1629 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1630 {
1631 warn_doc_error(context.fileName,tokenizer.getLineNr(),"rtfonly section ended without end marker");
1632 }
1634 }
1635 break;
1637 {
1639 tok = tokenizer.lex();
1641 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1642 {
1643 warn_doc_error(context.fileName,tokenizer.getLineNr(),"latexonly section ended without end marker");
1644 }
1646 }
1647 break;
1649 {
1651 tok = tokenizer.lex();
1653 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1654 {
1655 warn_doc_error(context.fileName,tokenizer.getLineNr(),"xmlonly section ended without end marker");
1656 }
1658 }
1659 break;
1661 {
1663 tok = tokenizer.lex();
1665 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1666 {
1667 warn_doc_error(context.fileName,tokenizer.getLineNr(),"docbookonly section ended without end marker");
1668 }
1670 }
1671 break;
1673 {
1674 children.append<DocFormula>(this,parent,context.token->id);
1675 }
1676 break;
1679 {
1680 handleAnchor(parent,children);
1681 }
1682 break;
1684 {
1685 handleCite(parent,children);
1686 }
1687 break;
1689 {
1690 handlePrefix(parent,children);
1691 }
1692 break;
1694 {
1695 handleInternalRef(parent,children);
1697 }
1698 break;
1700 {
1702 (void)tokenizer.lex();
1704 //printf("Found scope='%s'\n",qPrint(context.context));
1706 }
1707 break;
1709 handleImage(parent,children);
1710 break;
1712 handleILine(tok.command_to_char(),tokenName);
1713 break;
1715 handleIFile(tok.command_to_char(),tokenName);
1716 break;
1717 default:
1718 return false;
1719 }
1720 break;
1721 case TokenRetval::TK_HTMLTAG:
1722 {
1723 auto handleEnterLeaveStyle = [this,&parent,&children,&tokenName](DocStyleChange::Style style) {
1724 if (!context.token->endTag)
1725 {
1726 handleStyleEnter(parent,children,style,tokenName,&context.token->attribs);
1727 }
1728 else
1729 {
1730 handleStyleLeave(parent,children,style,tokenName);
1731 }
1732 };
1733 switch (Mappers::htmlTagMapper->map(tokenName))
1734 {
1736 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <div> tag in heading");
1737 break;
1739 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <pre> tag in heading");
1740 break;
1742 handleEnterLeaveStyle(DocStyleChange::Span);
1743 break;
1745 handleEnterLeaveStyle(DocStyleChange::Bold);
1746 break;
1748 handleEnterLeaveStyle(DocStyleChange::S);
1749 break;
1751 handleEnterLeaveStyle(DocStyleChange::Strike);
1752 break;
1754 handleEnterLeaveStyle(DocStyleChange::Del);
1755 break;
1757 handleEnterLeaveStyle(DocStyleChange::Underline);
1758 break;
1760 handleEnterLeaveStyle(DocStyleChange::Ins);
1761 break;
1763 case HtmlTagType::XML_C:
1764 handleEnterLeaveStyle(DocStyleChange::Code);
1765 break;
1767 handleEnterLeaveStyle(DocStyleChange::Kbd);
1768 break;
1770 handleEnterLeaveStyle(DocStyleChange::Typewriter);
1771 break;
1773 handleEnterLeaveStyle(DocStyleChange::Italic);
1774 break;
1776 handleEnterLeaveStyle(DocStyleChange::Subscript);
1777 break;
1779 handleEnterLeaveStyle(DocStyleChange::Superscript);
1780 break;
1782 handleEnterLeaveStyle(DocStyleChange::Center);
1783 break;
1785 handleEnterLeaveStyle(DocStyleChange::Small);
1786 break;
1788 handleEnterLeaveStyle(DocStyleChange::Cite);
1789 break;
1791 if (!context.token->endTag)
1792 {
1794 }
1795 break;
1796 default:
1797 return false;
1798 break;
1799 }
1800 }
1801 break;
1802 case TokenRetval::TK_SYMBOL:
1803 {
1806 {
1807 children.append<DocSymbol>(this,parent,s);
1808 }
1809 else
1810 {
1811 return false;
1812 }
1813 }
1814 break;
1815 case TokenRetval::TK_WHITESPACE:
1816 case TokenRetval::TK_NEWPARA:
1817handlepara:
1818 if (insidePRE(parent) || !children.empty())
1819 {
1820 children.append<DocWhiteSpace>(this,parent,context.token->chars);
1821 }
1822 break;
1823 case TokenRetval::TK_LNKWORD:
1824 if (handleWord)
1825 {
1826 handleLinkedWord(parent,children);
1827 }
1828 else
1829 return false;
1830 break;
1831 case TokenRetval::TK_WORD:
1832 if (handleWord)
1833 {
1834 children.append<DocWord>(this,parent,context.token->name);
1835 }
1836 else
1837 return false;
1838 break;
1839 case TokenRetval::TK_URL:
1841 {
1842 children.append<DocWord>(this,parent,context.token->name);
1843 }
1844 else
1845 {
1846 children.append<DocURL>(this,parent,context.token->name,context.token->isEMailAddr);
1847 }
1848 break;
1849 default:
1850 return false;
1851 }
1852 return true;
1853}
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:160
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:54
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 602 of file docparser.cpp.

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

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:244
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:318
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:178
@ ExplicitSize
Definition dstring.h:131
@ 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:131
FileDef * findFileDef(const DString &n, bool &ambig) const
Returns the file definition in fnMap that matches the file name n.
Definition filename.cpp:38
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:121
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:4619

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 if (rightBracePos != DString::npos)
500 {
501 DString leftPart = cmdArg.left(rightBracePos + 1);
502 DString rightPart = cmdArg.mid(rightBracePos + 1);
503 rightPart = substitute(rightPart, ".", "::");
504 cmdArg = leftPart + rightPart;
505 }
506 else
507 {
508 cmdArg = substitute(cmdArg,".","::");
509 }
510 }
511 else
512 {
513 cmdArg = substitute(cmdArg,".","::");
514 }
515
516 int l=static_cast<int>(cmdArg.length());
517
518 size_t funcStart=cmdArg.find('(');
519 if (funcStart==DString::npos)
520 {
521 funcStart=l;
522 }
523 else
524 {
525 // Check for the case of operator() and the like.
526 // beware of scenarios like operator()((foo)bar)
527 size_t secondParen = cmdArg.find('(', funcStart+1);
528 size_t leftParen = cmdArg.find(')', funcStart+1);
529 if (leftParen!=DString::npos && secondParen!=DString::npos)
530 {
531 if (leftParen<secondParen)
532 {
533 funcStart=secondParen;
534 }
535 }
536 }
537
538 DString name=removeRedundantWhiteSpace(cmdArg.left(funcStart));
539 DString args=cmdArg.right(l-funcStart);
540 // try if the link is to a member
541 GetDefInput input(
542 context.context.find('.')==DString::npos ? context.context : DString(), // find('.') is a hack to detect files
543 name,
544 args);
545 input.checkCV=true;
546 GetDefResult result = getDefs(input);
547 //printf("found=%d context=%s name=%s\n",result.found,qPrint(context.context),qPrint(name));
548 if (result.found && result.md)
549 {
550 *pDoc=result.md->documentation();
551 *pBrief=result.md->briefDescription();
552 *pDef=result.md;
553 AUTO_TRACE_EXIT("member");
554 return true;
555 }
556
557 int scopeOffset=static_cast<int>(context.context.length());
558 do // for each scope
559 {
560 DString fullName=cmdArg;
561 if (scopeOffset>0)
562 {
563 fullName.prepend(context.context.left(scopeOffset)+"::");
564 }
565 //printf("Trying fullName='%s'\n",qPrint(fullName));
566
567 // try class, namespace, group, page, file reference
568 const ClassDef *cd = Doxygen::classLinkedMap->find(fullName);
569 if (cd) // class
570 {
571 *pDoc=cd->documentation();
572 *pBrief=cd->briefDescription();
573 *pDef=cd;
574 AUTO_TRACE_EXIT("class");
575 return true;
576 }
577 const NamespaceDef *nd = Doxygen::namespaceLinkedMap->find(fullName);
578 if (nd) // namespace
579 {
580 *pDoc=nd->documentation();
581 *pBrief=nd->briefDescription();
582 *pDef=nd;
583 AUTO_TRACE_EXIT("namespace");
584 return true;
585 }
586 if (scopeOffset==0)
587 {
588 scopeOffset=-1;
589 }
590 else
591 {
592 size_t o = context.context.rfind("::",scopeOffset-1);
593 scopeOffset = o!=DString::npos ? static_cast<int>(o) : 0;
594 }
595 } while (scopeOffset>=0);
596
597 AUTO_TRACE_EXIT("not found");
598 return false;
599}
DString right(size_t len) const
Definition dstring.h:311
DString & prepend(const char *s)
Definition dstring.h:515
size_t find(char c, size_t pos=0) const
Definition dstring.h:239
bool startsWith(const char *s) const
Definition dstring.h:600
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:485
uint32_t dstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
Definition dstring.h:39
const MemberDef * md
Definition util.h:95
bool found
Definition util.h:94
DString removeRedundantWhiteSpace(const DString &s)
Definition util.cpp:426
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:1866

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

790{
791 AUTO_TRACE();
792 size_t index=0;
793 Token retval = Token::make_RetVal_OK();
794 for (const auto &opt : tagHtmlAttribs)
795 {
796 if (opt.name=="name" || opt.name=="id") // <a name=label> or <a id=label> tag
797 {
798 if (!opt.value.empty())
799 {
800 children.append<DocAnchor>(this,parent,opt.value,true);
801 break; // stop looking for other tag attribs
802 }
803 else
804 {
805 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <a> tag with name option but without value!");
806 }
807 }
808 else if (opt.name=="href") // <a href=url>..</a> tag
809 {
810 // copy attributes
811 HtmlAttribList attrList = tagHtmlAttribs;
812 // and remove the href attribute
813 attrList.erase(attrList.begin()+index);
814 DString relPath;
815 if (opt.value.at(0) != '#') relPath = context.relPath;
816 children.append<DocHRef>(this, parent, attrList,
817 opt.value, relPath,
818 convertNameToFile(context.fileName, false, true));
820 retval = children.get_last<DocHRef>()->parse();
823 break;
824 }
825 else // unsupported option for tag a
826 {
827 }
828 ++index;
829 }
830 return retval;
831}
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:2863

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

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

1081{
1082 AUTO_TRACE();
1083 // get the argument of the cite command.
1084 Token tok=tokenizer.lex();
1085
1086 CiteInfoOption option;
1087 if (tok.is(TokenRetval::TK_WORD) && context.token->name=="{")
1088 {
1090 tokenizer.lex();
1091 StringVector optList=split(context.token->name.str(),",");
1092 for (auto const &opt : optList)
1093 {
1094 if (opt == "number")
1095 {
1096 if (!option.isUnknown())
1097 {
1098 warn(context.fileName,tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", context.token->name, opt);
1099 }
1100 else
1101 {
1102 option = CiteInfoOption::makeNumber();
1103 }
1104 }
1105 else if (opt == "year")
1106 {
1107 if (!option.isUnknown())
1108 {
1109 warn(context.fileName,tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", context.token->name, opt);
1110 }
1111 else
1112 {
1113 option = CiteInfoOption::makeYear();
1114 }
1115 }
1116 else if (opt == "shortauthor")
1117 {
1118 if (!option.isUnknown())
1119 {
1120 warn(context.fileName,tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", context.token->name, opt);
1121 }
1122 else
1123 {
1125 }
1126 }
1127 else if (opt == "nopar")
1128 {
1129 option.setNoPar();
1130 }
1131 else if (opt == "nocite")
1132 {
1133 option.setNoCite();
1134 }
1135 else
1136 {
1137 warn(context.fileName,tokenizer.getLineNr(),"Unknown option specified with \\{}, discarding '{}'", context.token->name, opt);
1138 }
1139 }
1140
1141 if (option.isUnknown()) option.changeToNumber();
1142
1144 tok=tokenizer.lex();
1145 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 }
1152 else if (!tok.is(TokenRetval::TK_WHITESPACE))
1153 {
1154 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after '\\{}' command",
1155 context.token->name);
1156 return;
1157 }
1158 else
1159 {
1160 option = CiteInfoOption::makeNumber();
1161 }
1162
1165 tok=tokenizer.lex();
1166 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1167 {
1168 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
1169 "argument of command '\\{}'",context.token->name);
1170 return;
1171 }
1172 else if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1173 {
1174 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of '\\{}'",
1175 tok.to_string(),context.token->name);
1176 return;
1177 }
1179 children.append<DocCite>(this,parent,context.token->name,context.context,option);
1180 }
1181
1182}
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 1436 of file docparser.cpp.

1437{
1438 AUTO_TRACE();
1439 Token tok=tokenizer.lex();
1440 if (!tok.is(TokenRetval::TK_WHITESPACE))
1441 {
1442 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after '{:c}{}' command",
1443 cmdChar,cmdName);
1444 return;
1445 }
1447 tok=tokenizer.lex();
1449 if (!tok.is(TokenRetval::TK_WORD))
1450 {
1451 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of '{:c}{}'",
1452 tok.to_string(),cmdChar,cmdName);
1453 return;
1454 }
1456}
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 1458 of file docparser.cpp.

1459{
1460 AUTO_TRACE();
1462 Token tok = tokenizer.lex();
1464 if (!tok.is(TokenRetval::TK_WORD))
1465 {
1466 warn_doc_error(context.fileName,tokenizer.getLineNr(),"invalid argument for command '{:c}{}'",
1467 cmdChar,cmdName);
1468 return;
1469 }
1470}
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 1304 of file docparser.cpp.

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

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

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

778{
779 AUTO_TRACE();
780 while (!context.initialStyleStack.empty())
781 {
782 const DocStyleChange &sc = std::get<DocStyleChange>(*context.initialStyleStack.top());
783 handleStyleEnter(parent,children,sc.style(),sc.tagName(),&sc.attribs());
785 }
786}
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 1028 of file docparser.cpp.

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

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

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

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

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

758{
759 AUTO_TRACE("context.styleStack.size()={} numberOfElementsToClose={}",context.styleStack.size(),numberOfElementsToClose);
760 if (!context.styleStack.empty())
761 {
762 if (numberOfElementsToClose==0) numberOfElementsToClose = context.styleStack.size(); // 0 is special value for "close all"
763 const DocStyleChange *sc = &std::get<DocStyleChange>(*context.styleStack.top());
764 while (sc && sc->position()>=context.nodeStack.size() && numberOfElementsToClose>0)
765 { // there are unclosed style modifiers in the paragraph
766 AUTO_TRACE_ADD("unclosed style {} at position {}",sc->styleString(),sc->position());
767 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),
768 sc->style(),sc->tagName(),false);
770 context.styleStack.pop();
771 sc = !context.styleStack.empty() ? &std::get<DocStyleChange>(*context.styleStack.top()) : nullptr;
772 numberOfElementsToClose--;
773 }
774 }
775}
const char * styleString() const
Definition docnode.cpp:132
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 1184 of file docparser.cpp.

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

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

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

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

696{
697 AUTO_TRACE("tagName={}",tagName);
698 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),s,tagName,true,
700 context.styleStack.push(&children.back());
702}
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 707 of file docparser.cpp.

709{
710 AUTO_TRACE("tagName={}",tagName);
711 DString tagNameLower = DString(tagName).lower();
712
713 auto topStyleChange = [](const DocStyleChangeStack &stack) -> const DocStyleChange &
714 {
715 return std::get<DocStyleChange>(*stack.top());
716 };
717
718 if (context.styleStack.empty() || // no style change
719 topStyleChange(context.styleStack).style()!=s || // wrong style change
720 topStyleChange(context.styleStack).tagName()!=tagNameLower || // wrong style change
721 topStyleChange(context.styleStack).position()!=context.nodeStack.size() // wrong position
722 )
723 {
724 if (context.styleStack.empty())
725 {
726 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </{0}> tag without matching <{0}>",tagName);
727 }
728 else if (topStyleChange(context.styleStack).tagName()!=tagNameLower ||
729 topStyleChange(context.styleStack).style()!=s)
730 {
731 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </{}> tag while expecting </{}>",
732 tagName,topStyleChange(context.styleStack).tagName());
733 }
734 else
735 {
736 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found </{}> at different nesting level ({}) than expected ({})",
737 tagName,context.nodeStack.size(),topStyleChange(context.styleStack).position());
738 }
739 }
740 else // end the section
741 {
742 children.append<DocStyleChange>(
743 this,parent,context.nodeStack.size(),s,
744 topStyleChange(context.styleStack).tagName(),false);
745 context.styleStack.pop();
746 }
748 {
749 context.inCodeStyle = false;
750 }
751}
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 833 of file docparser.cpp.

834{
835 AUTO_TRACE("content.initialStyleStack.size()={}",context.initialStyleStack.size());
836 if (!context.initialStyleStack.empty())
837 {
838 DString tagName = std::get<DocStyleChange>(*context.initialStyleStack.top()).tagName();
839 DString fileName = std::get<DocStyleChange>(*context.initialStyleStack.top()).fileName();
840 int lineNr = std::get<DocStyleChange>(*context.initialStyleStack.top()).lineNr();
843 if (lineNr != -1)
844 {
846 "end of comment block while expecting "
847 "command </{}> (Probable start '{}' at line {})",tagName, fileName, lineNr);
848 }
849 else
850 {
852 "end of comment block while expecting command </{}>",tagName);
853 }
854 }
855}
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 1888 of file docparser.cpp.

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

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

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

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

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(), DocHtmlCaption::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: