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

#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 QCString &doc)
QCString processCopyDoc (const char *data, size_t &len)
QCString findAndCopyImage (const QCString &fileName, DocImage::Type type, bool doWarn=true)
void checkArgumentName ()
void checkRetvalName ()
void checkUnOrMultipleDocumentedParams ()
bool findDocsForMemberOrCompound (const QCString &commandName, QCString *pDoc, QCString *pBrief, const Definition **pDef)
bool defaultHandleToken (DocNodeVariant *parent, Token &tok, DocNodeList &children, bool handleWord=TRUE)
void errorHandleDefaultToken (DocNodeVariant *parent, Token tok, DocNodeList &children, const QCString &txt)
void defaultHandleTitleAndSize (const CommandType cmd, DocNodeVariant *parent, DocNodeList &children, QCString &width, QCString &height)
Token handleStyleArgument (DocNodeVariant *parent, DocNodeList &children, const QCString &cmdName)
void handleStyleEnter (DocNodeVariant *parent, DocNodeList &children, DocStyleChange::Style s, const QCString &tagName, const HtmlAttribList *attribs)
void handleStyleLeave (DocNodeVariant *parent, DocNodeList &children, DocStyleChange::Style s, const QCString &tagName)
void handlePendingStyleCommands (DocNodeVariant *parent, DocNodeList &children)
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)
void handleParameterType (DocNodeVariant *parent, DocNodeList &children, const QCString &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 QCString &cmdName)
void handleIFile (char cmdChar, const QCString &cmdName)
void handleILine (char cmdChar, const QCString &cmdName)
void readTextFileByName (const QCString &file, QCString &text)

Public Attributes

std::stack< DocParserContextcontextStack
DocParserContext context
DocTokenizer tokenizer

Private Member Functions

void pushContext ()
void popContext ()

Detailed Description

Definition at line 101 of file docparser_p.h.

Member Function Documentation

◆ checkArgumentName()

void DocParser::checkArgumentName ( )

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

Definition at line 210 of file docparser.cpp.

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

References argListToString(), Config_getBool, context, QCString::data(), Definition::docFile(), Definition::docLine(), ArgumentList::empty(), end(), QCString::endsWith(), FALSE, QCString::isEmpty(), QCString::left(), QCString::length(), QCString::lower(), reg::match(), Definition::name(), qPrint(), ArgumentList::size(), QCString::size(), QCString::sprintf(), QCString::str(), QCString::stripWhiteSpace(), QCString::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 311 of file docparser.cpp.

312{
313 QCString name = context.token->name;
314 if (!Config_getBool(WARN_IF_DOC_ERROR)) return;
315 if (context.memberDef==nullptr || name.isEmpty()) return; // not a member or no valid name
316 if (context.retvalsFound.count(name.str())==1) // only report the first double entry
317 {
318 warn_doc_error(context.memberDef->getDefFileName(),
319 context.memberDef->getDefLine(),
320 "return value '{}' of {} has multiple documentation sections",
321 name, context.memberDef->qualifiedName());
322 }
323 context.retvalsFound.insert(name.str());
324}

References Config_getBool, context, QCString::isEmpty(), QCString::str(), 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 332 of file docparser.cpp.

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

References argListToString(), Config_getBool, context, ArgumentList::empty(), QCString::endsWith(), FALSE, QCString::isEmpty(), QCString::left(), QCString::length(), QCString::lower(), ArgumentList::push_back(), ArgumentList::size(), QCString::str(), QCString::stripWhiteSpace(), TRUE, warn_doc_error, and warn_incomplete_doc.

Referenced by validatingParseDoc().

◆ defaultHandleTitleAndSize()

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

Definition at line 1193 of file docparser.cpp.

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

References AUTO_TRACE, AUTO_TRACE_EXIT, Mappers::cmdMapper, context, defaultHandleToken(), errorHandleDefaultToken(), handlePendingStyleCommands(), Token::is(), Token::is_any_of(), parent(), and tokenizer.

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

1458{
1459 AUTO_TRACE("token={} handleWord={}",tok.to_string(),handleWord);
1460 if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD,TokenRetval::TK_SYMBOL,TokenRetval::TK_URL,
1461 TokenRetval::TK_COMMAND_AT,TokenRetval::TK_COMMAND_BS,TokenRetval::TK_HTMLTAG)
1462 )
1463 {
1464 }
1465reparsetoken:
1466 QCString tokenName = context.token->name;
1467 AUTO_TRACE_ADD("tokenName={}",tokenName);
1468 switch (tok.value())
1469 {
1470 case TokenRetval::TK_COMMAND_AT:
1471 // fall through
1472 case TokenRetval::TK_COMMAND_BS:
1473 switch (Mappers::cmdMapper->map(tokenName))
1474 {
1476 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_BSlash);
1477 break;
1479 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_At);
1480 break;
1482 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Less);
1483 break;
1485 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Greater);
1486 break;
1488 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Amp);
1489 break;
1491 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dollar);
1492 break;
1494 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Hash);
1495 break;
1497 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_DoubleColon);
1498 break;
1500 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Percent);
1501 break;
1503 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1504 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1505 break;
1507 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1508 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1509 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1510 break;
1512 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quot);
1513 break;
1515 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dot);
1516 break;
1518 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Exclam);
1519 break;
1521 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quest);
1522 break;
1524 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Plus);
1525 break;
1527 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1528 break;
1530 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Equal);
1531 break;
1533 {
1534 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,TRUE);
1535 tok=handleStyleArgument(parent,children,tokenName);
1536 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,FALSE);
1537 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1538 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1539 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1540 {
1541 AUTO_TRACE_ADD("CommandType::CMD_EMPHASIS: reparsing");
1542 goto reparsetoken;
1543 }
1544 }
1545 break;
1547 {
1548 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,TRUE);
1549 tok=handleStyleArgument(parent,children,tokenName);
1550 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,FALSE);
1551 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1552 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1553 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1554 {
1555 AUTO_TRACE_ADD("CommandType::CMD_BOLD: reparsing");
1556 goto reparsetoken;
1557 }
1558 }
1559 break;
1561 {
1562 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,TRUE);
1563 tok=handleStyleArgument(parent,children,tokenName);
1564 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,FALSE);
1565 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1566 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1567 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1568 {
1569 AUTO_TRACE_ADD("CommandType::CMD_CODE: reparsing");
1570 goto reparsetoken;
1571 }
1572 }
1573 break;
1575 {
1576 tokenizer.setStateHtmlOnly();
1577 tok = tokenizer.lex();
1578 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::HtmlOnly,context.isExample,context.exampleName,context.token->name=="block");
1579 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1580 {
1581 warn_doc_error(context.fileName,tokenizer.getLineNr(),"htmlonly section ended without end marker");
1582 }
1583 tokenizer.setStatePara();
1584 }
1585 break;
1587 {
1588 tokenizer.setStateManOnly();
1589 tok = tokenizer.lex();
1590 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::ManOnly,context.isExample,context.exampleName);
1591 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1592 {
1593 warn_doc_error(context.fileName,tokenizer.getLineNr(),"manonly section ended without end marker");
1594 }
1595 tokenizer.setStatePara();
1596 }
1597 break;
1599 {
1600 tokenizer.setStateRtfOnly();
1601 tok = tokenizer.lex();
1602 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::RtfOnly,context.isExample,context.exampleName);
1603 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1604 {
1605 warn_doc_error(context.fileName,tokenizer.getLineNr(),"rtfonly section ended without end marker");
1606 }
1607 tokenizer.setStatePara();
1608 }
1609 break;
1611 {
1612 tokenizer.setStateLatexOnly();
1613 tok = tokenizer.lex();
1614 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::LatexOnly,context.isExample,context.exampleName);
1615 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1616 {
1617 warn_doc_error(context.fileName,tokenizer.getLineNr(),"latexonly section ended without end marker");
1618 }
1619 tokenizer.setStatePara();
1620 }
1621 break;
1623 {
1624 tokenizer.setStateXmlOnly();
1625 tok = tokenizer.lex();
1626 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::XmlOnly,context.isExample,context.exampleName);
1627 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1628 {
1629 warn_doc_error(context.fileName,tokenizer.getLineNr(),"xmlonly section ended without end marker");
1630 }
1631 tokenizer.setStatePara();
1632 }
1633 break;
1635 {
1636 tokenizer.setStateDbOnly();
1637 tok = tokenizer.lex();
1638 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::DocbookOnly,context.isExample,context.exampleName);
1639 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1640 {
1641 warn_doc_error(context.fileName,tokenizer.getLineNr(),"docbookonly section ended without end marker");
1642 }
1643 tokenizer.setStatePara();
1644 }
1645 break;
1647 {
1648 children.append<DocFormula>(this,parent,context.token->id);
1649 }
1650 break;
1653 {
1654 handleAnchor(parent,children);
1655 }
1656 break;
1658 {
1659 handleCite(parent,children);
1660 }
1661 break;
1663 {
1664 handlePrefix(parent,children);
1665 }
1666 break;
1668 {
1669 handleInternalRef(parent,children);
1670 tokenizer.setStatePara();
1671 }
1672 break;
1674 {
1675 tokenizer.setStateSetScope();
1676 (void)tokenizer.lex();
1677 context.context = context.token->name;
1678 //printf("Found scope='%s'\n",qPrint(context.context));
1679 tokenizer.setStatePara();
1680 }
1681 break;
1683 handleImage(parent,children);
1684 break;
1686 handleILine(tok.command_to_char(),tokenName);
1687 break;
1689 handleIFile(tok.command_to_char(),tokenName);
1690 break;
1691 default:
1692 return FALSE;
1693 }
1694 break;
1695 case TokenRetval::TK_HTMLTAG:
1696 {
1697 auto handleEnterLeaveStyle = [this,&parent,&children,&tokenName](DocStyleChange::Style style) {
1698 if (!context.token->endTag)
1699 {
1700 handleStyleEnter(parent,children,style,tokenName,&context.token->attribs);
1701 }
1702 else
1703 {
1704 handleStyleLeave(parent,children,style,tokenName);
1705 }
1706 };
1707 switch (Mappers::htmlTagMapper->map(tokenName))
1708 {
1710 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <div> tag in heading");
1711 break;
1713 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <pre> tag in heading");
1714 break;
1716 handleEnterLeaveStyle(DocStyleChange::Span);
1717 break;
1719 handleEnterLeaveStyle(DocStyleChange::Bold);
1720 break;
1722 handleEnterLeaveStyle(DocStyleChange::S);
1723 break;
1725 handleEnterLeaveStyle(DocStyleChange::Strike);
1726 break;
1728 handleEnterLeaveStyle(DocStyleChange::Del);
1729 break;
1731 handleEnterLeaveStyle(DocStyleChange::Underline);
1732 break;
1734 handleEnterLeaveStyle(DocStyleChange::Ins);
1735 break;
1737 case HtmlTagType::XML_C:
1738 handleEnterLeaveStyle(DocStyleChange::Code);
1739 break;
1741 handleEnterLeaveStyle(DocStyleChange::Kbd);
1742 break;
1744 handleEnterLeaveStyle(DocStyleChange::Typewriter);
1745 break;
1747 handleEnterLeaveStyle(DocStyleChange::Italic);
1748 break;
1750 handleEnterLeaveStyle(DocStyleChange::Subscript);
1751 break;
1753 handleEnterLeaveStyle(DocStyleChange::Superscript);
1754 break;
1756 handleEnterLeaveStyle(DocStyleChange::Center);
1757 break;
1759 handleEnterLeaveStyle(DocStyleChange::Small);
1760 break;
1762 handleEnterLeaveStyle(DocStyleChange::Cite);
1763 break;
1765 if (!context.token->endTag)
1766 {
1767 handleImg(parent,children,context.token->attribs);
1768 }
1769 break;
1770 default:
1771 return FALSE;
1772 break;
1773 }
1774 }
1775 break;
1776 case TokenRetval::TK_SYMBOL:
1777 {
1780 {
1781 children.append<DocSymbol>(this,parent,s);
1782 }
1783 else
1784 {
1785 return FALSE;
1786 }
1787 }
1788 break;
1789 case TokenRetval::TK_WHITESPACE:
1790 case TokenRetval::TK_NEWPARA:
1791handlepara:
1792 if (insidePRE(parent) || !children.empty())
1793 {
1794 children.append<DocWhiteSpace>(this,parent,context.token->chars);
1795 }
1796 break;
1797 case TokenRetval::TK_LNKWORD:
1798 if (handleWord)
1799 {
1800 handleLinkedWord(parent,children);
1801 }
1802 else
1803 return FALSE;
1804 break;
1805 case TokenRetval::TK_WORD:
1806 if (handleWord)
1807 {
1808 children.append<DocWord>(this,parent,context.token->name);
1809 }
1810 else
1811 return FALSE;
1812 break;
1813 case TokenRetval::TK_URL:
1814 if (context.insideHtmlLink)
1815 {
1816 children.append<DocWord>(this,parent,context.token->name);
1817 }
1818 else
1819 {
1820 children.append<DocURL>(this,parent,context.token->name,context.token->isEMailAddr);
1821 }
1822 break;
1823 default:
1824 return FALSE;
1825 }
1826 return TRUE;
1827}
void handleLinkedWord(DocNodeVariant *parent, DocNodeList &children, bool ignoreAutoLinkFlag=FALSE)
void handleInternalRef(DocNodeVariant *parent, DocNodeList &children)
void handleStyleLeave(DocNodeVariant *parent, DocNodeList &children, DocStyleChange::Style s, const QCString &tagName)
void handleImage(DocNodeVariant *parent, DocNodeList &children)
void handleStyleEnter(DocNodeVariant *parent, DocNodeList &children, DocStyleChange::Style s, const QCString &tagName, const HtmlAttribList *attribs)
void handleCite(DocNodeVariant *parent, DocNodeList &children)
void handlePrefix(DocNodeVariant *parent, DocNodeList &children)
Token handleStyleArgument(DocNodeVariant *parent, DocNodeList &children, const QCString &cmdName)
void handleIFile(char cmdChar, const QCString &cmdName)
void handleILine(char cmdChar, const QCString &cmdName)
void handleAnchor(DocNodeVariant *parent, DocNodeList &children)
void handleImg(DocNodeVariant *parent, DocNodeList &children, const HtmlAttribList &tagHtmlAttribs)
static HtmlEntityMapper::SymType decodeSymbol(const QCString &symName)
Definition docnode.cpp:155
TOKEN_SPECIFICATIONS RETVAL_SPECIFICATIONS const char * to_string() const
TokenRetval value() const
char command_to_char() const
@ CMD_INTERNALREF
Definition cmdmapper.h:65
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:49
bool insidePRE(const DocNodeVariant *n)
const Mapper< HtmlTagType > * htmlTagMapper
void append(Args &&... args)
Append a new DocNodeVariant to the list by constructing it with type T and parameters Args.
Definition docnode.h:1404

References DocNodeList::append(), AUTO_TRACE, AUTO_TRACE_ADD, DocStyleChange::Bold, DocStyleChange::Center, 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, DocSymbol::decodeSymbol(), DocStyleChange::Del, DocVerbatim::DocbookOnly, GrowVector< T >::empty(), FALSE, 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, DocStyleChange::Ins, insidePRE(), Token::is(), Token::is_any_of(), DocStyleChange::Italic, DocStyleChange::Kbd, DocVerbatim::LatexOnly, DocVerbatim::ManOnly, parent(), DocVerbatim::RtfOnly, DocStyleChange::S, 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(), tokenizer, TRUE, DocStyleChange::Typewriter, DocStyleChange::Underline, Token::value(), 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 QCString & txt )

Definition at line 592 of file docparser.cpp.

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

References DocNodeList::append(), Token::command_to_char(), context, parent(), qPrint(), Token::to_string(), 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()

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

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

Definition at line 96 of file docparser.cpp.

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

References FileDef::absFilePath(), Config_getBool, Config_getString, context, copyFile(), DocImage::DocBook, QCString::endsWith(), err, FileInfo::exists(), QCString::ExplicitSize, findFileDef(), QCString::findRev(), DocImage::Html, Doxygen::imageNameLinkedMap, Doxygen::indexList, FileInfo::isSymLink(), DocImage::Latex, QCString::left(), QCString::length(), Definition::name(), qPrint(), Dir::remove(), QCString::right(), DocImage::Rtf, showFileDefMatches(), QCString::sprintf(), QCString::startsWith(), QCString::str(), Portable::system(), tokenizer, warn_doc_error, and DocImage::Xml.

Referenced by handleImage(), and handleImg().

◆ findDocsForMemberOrCompound()

bool DocParser::findDocsForMemberOrCompound ( const QCString & commandName,
QCString * pDoc,
QCString * 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 439 of file docparser.cpp.

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

References AUTO_TRACE, AUTO_TRACE_EXIT, Definition::briefDescription(), GetDefInput::checkCV, Doxygen::classLinkedMap, Config_getBool, context, Definition::documentation(), FALSE, QCString::find(), findFileDef(), GetDefResult::found, getDefs(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, QCString::isEmpty(), QCString::left(), QCString::length(), GetDefResult::md, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, QCString::prepend(), qstrlen(), removeRedundantWhiteSpace(), QCString::right(), QCString::size(), QCString::startsWith(), and substitute().

Referenced by processCopyDoc().

◆ handleAHref()

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

Definition at line 771 of file docparser.cpp.

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

References DocNodeList::append(), AUTO_TRACE, context, convertNameToFile(), FALSE, DocNodeList::get_last(), parent(), tokenizer, TRUE, and warn_doc_error.

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

◆ handleAnchor()

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

Definition at line 1023 of file docparser.cpp.

1024{
1025 AUTO_TRACE();
1026 Token tok=tokenizer.lex();
1027 if (!tok.is(TokenRetval::TK_WHITESPACE))
1028 {
1029 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command",
1030 context.token->name);
1031 return;
1032 }
1033
1035 tokenizer.setStateAnchor();
1036 tok=tokenizer.lex();
1037 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1038 {
1039 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
1040 "argument of command {}",context.token->name);
1041 return;
1042 }
1043 else if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1044 {
1045 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of {}",
1046 tok.to_string(),context.token->name);
1047 return;
1048 }
1049 }
1050 children.append<DocAnchor>(this,parent,context.token->name,FALSE);
1051}
friend class AutoSaveState

References DocNodeList::append(), AUTO_TRACE, context, FALSE, Token::is(), Token::is_any_of(), parent(), Token::to_string(), tokenizer, and warn_doc_error.

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

◆ handleCite()

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

Definition at line 1053 of file docparser.cpp.

1054{
1055 AUTO_TRACE();
1056 // get the argument of the cite command.
1057 Token tok=tokenizer.lex();
1058
1059 CiteInfoOption option;
1060 if (tok.is(TokenRetval::TK_WORD) && context.token->name=="{")
1061 {
1062 tokenizer.setStateOptions();
1063 tokenizer.lex();
1064 StringVector optList=split(context.token->name.str(),",");
1065 for (auto const &opt : optList)
1066 {
1067 if (opt == "number")
1068 {
1069 if (!option.isUnknown())
1070 {
1071 warn(context.fileName,tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", context.token->name, opt);
1072 }
1073 else
1074 {
1075 option = CiteInfoOption::makeNumber();
1076 }
1077 }
1078 else if (opt == "year")
1079 {
1080 if (!option.isUnknown())
1081 {
1082 warn(context.fileName,tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", context.token->name, opt);
1083 }
1084 else
1085 {
1086 option = CiteInfoOption::makeYear();
1087 }
1088 }
1089 else if (opt == "shortauthor")
1090 {
1091 if (!option.isUnknown())
1092 {
1093 warn(context.fileName,tokenizer.getLineNr(),"Multiple options specified with \\{}, discarding '{}'", context.token->name, opt);
1094 }
1095 else
1096 {
1098 }
1099 }
1100 else if (opt == "nopar")
1101 {
1102 option.setNoPar();
1103 }
1104 else if (opt == "nocite")
1105 {
1106 option.setNoCite();
1107 }
1108 else
1109 {
1110 warn(context.fileName,tokenizer.getLineNr(),"Unknown option specified with \\{}, discarding '{}'", context.token->name, opt);
1111 }
1112 }
1113
1114 if (option.isUnknown()) option.changeToNumber();
1115
1116 tokenizer.setStatePara();
1117 tok=tokenizer.lex();
1118 if (!tok.is(TokenRetval::TK_WHITESPACE))
1119 {
1120 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command",
1121 context.token->name);
1122 return;
1123 }
1124 }
1125 else if (!tok.is(TokenRetval::TK_WHITESPACE))
1126 {
1127 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after '\\{}' command",
1128 context.token->name);
1129 return;
1130 }
1131 else
1132 {
1133 option = CiteInfoOption::makeNumber();
1134 }
1135
1137 tokenizer.setStateCite();
1138 tok=tokenizer.lex();
1139 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1140 {
1141 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
1142 "argument of command '\\{}'",context.token->name);
1143 return;
1144 }
1145 else if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1146 {
1147 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of '\\{}'",
1148 tok.to_string(),context.token->name);
1149 return;
1150 }
1151 context.token->sectionId = context.token->name;
1152 children.append<DocCite>(this,parent,context.token->name,context.context,option);
1153 }
1154
1155}
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
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 util.cpp:6636

References DocNodeList::append(), AUTO_TRACE, CiteInfoOption::changeToNumber(), context, Token::is(), Token::is_any_of(), CiteInfoOption::isUnknown(), CiteInfoOption::makeNumber(), CiteInfoOption::makeShortAuthor(), CiteInfoOption::makeYear(), parent(), CiteInfoOption::setNoCite(), CiteInfoOption::setNoPar(), split(), Token::to_string(), tokenizer, warn, and warn_doc_error.

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

◆ handleIFile()

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

Definition at line 1409 of file docparser.cpp.

1410{
1411 AUTO_TRACE();
1412 Token tok=tokenizer.lex();
1413 if (!tok.is(TokenRetval::TK_WHITESPACE))
1414 {
1415 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after '{:c}{}' command",
1416 cmdChar,cmdName);
1417 return;
1418 }
1419 tokenizer.setStateFile();
1420 tok=tokenizer.lex();
1421 tokenizer.setStatePara();
1422 if (!tok.is(TokenRetval::TK_WORD))
1423 {
1424 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of '{:c}{}'",
1425 tok.to_string(),cmdChar,cmdName);
1426 return;
1427 }
1428 context.fileName = context.token->name;
1429 tokenizer.setStatePara();
1430}

References AUTO_TRACE, context, Token::is(), Token::to_string(), tokenizer, and warn_doc_error.

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

◆ handleILine()

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

Definition at line 1432 of file docparser.cpp.

1433{
1434 AUTO_TRACE();
1435 tokenizer.setStateILine();
1436 Token tok = tokenizer.lex();
1437 if (!tok.is(TokenRetval::TK_WORD))
1438 {
1439 warn_doc_error(context.fileName,tokenizer.getLineNr(),"invalid argument for command '{:c}{}'",
1440 cmdChar,cmdName);
1441 return;
1442 }
1443 tokenizer.setStatePara();
1444}

References AUTO_TRACE, context, Token::is(), tokenizer, and warn_doc_error.

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

◆ handleImage()

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

Definition at line 1277 of file docparser.cpp.

1278{
1279 AUTO_TRACE();
1280 bool inlineImage = false;
1281 QCString anchorStr;
1282
1283 Token tok=tokenizer.lex();
1284 if (!tok.is(TokenRetval::TK_WHITESPACE))
1285 {
1286 if (tok.is(TokenRetval::TK_WORD))
1287 {
1288 if (context.token->name == "{")
1289 {
1290 tokenizer.setStateOptions();
1291 tokenizer.lex();
1292 tokenizer.setStatePara();
1293 StringVector optList=split(context.token->name.str(),",");
1294 for (const auto &opt : optList)
1295 {
1296 if (opt.empty()) continue;
1297 QCString locOpt(opt);
1298 QCString locOptLow;
1299 locOpt = locOpt.stripWhiteSpace();
1300 locOptLow = locOpt.lower();
1301 if (locOptLow == "inline")
1302 {
1303 inlineImage = true;
1304 }
1305 else if (locOptLow.startsWith("anchor:"))
1306 {
1307 if (!anchorStr.isEmpty())
1308 {
1309 warn_doc_error(context.fileName,tokenizer.getLineNr(),
1310 "multiple use of option 'anchor' for 'image' command, ignoring: '{}'",
1311 locOpt.mid(7));
1312 }
1313 else
1314 {
1315 anchorStr = locOpt.mid(7);
1316 }
1317 }
1318 else
1319 {
1320 warn_doc_error(context.fileName,tokenizer.getLineNr(),
1321 "unknown option '{}' for 'image' command specified",
1322 locOpt);
1323 }
1324 }
1325 tok=tokenizer.lex();
1326 if (!tok.is(TokenRetval::TK_WHITESPACE))
1327 {
1328 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\image command");
1329 return;
1330 }
1331 }
1332 }
1333 else
1334 {
1335 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\image command");
1336 return;
1337 }
1338 }
1339 tok=tokenizer.lex();
1340 if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1341 {
1342 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of \\image",
1343 tok.to_string());
1344 return;
1345 }
1346 tok=tokenizer.lex();
1347 if (!tok.is(TokenRetval::TK_WHITESPACE))
1348 {
1349 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\image command");
1350 return;
1351 }
1353 QCString imgType = context.token->name.lower();
1354 if (imgType=="html") t=DocImage::Html;
1355 else if (imgType=="latex") t=DocImage::Latex;
1356 else if (imgType=="docbook") t=DocImage::DocBook;
1357 else if (imgType=="rtf") t=DocImage::Rtf;
1358 else if (imgType=="xml") t=DocImage::Xml;
1359 else
1360 {
1361 warn_doc_error(context.fileName,tokenizer.getLineNr(),"output format `{}` specified as the first argument of "
1362 "\\image command is not valid", imgType);
1363 return;
1364 }
1365 tokenizer.setStateFile();
1366 tok=tokenizer.lex();
1367 tokenizer.setStatePara();
1368 if (!tok.is(TokenRetval::TK_WORD))
1369 {
1370 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of \\image", tok.to_string());
1371 return;
1372 }
1373 if (!anchorStr.isEmpty())
1374 {
1375 children.append<DocAnchor>(this,parent,anchorStr,true);
1376 }
1377 HtmlAttribList attrList;
1378 children.append<DocImage>(this,parent,attrList,
1379 findAndCopyImage(context.token->name,t),t,"",inlineImage);
1380 children.get_last<DocImage>()->parse();
1381}
QCString findAndCopyImage(const QCString &fileName, DocImage::Type type, bool doWarn=true)
Definition docparser.cpp:96
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:241

References DocNodeList::append(), AUTO_TRACE, context, DocImage::DocBook, findAndCopyImage(), DocNodeList::get_last(), DocImage::Html, Token::is(), Token::is_any_of(), QCString::isEmpty(), DocImage::Latex, QCString::lower(), QCString::mid(), parent(), DocImage::Rtf, split(), QCString::startsWith(), QCString::stripWhiteSpace(), Token::to_string(), 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 1831 of file docparser.cpp.

1832{
1833 AUTO_TRACE();
1834 bool found=FALSE;
1835 size_t index=0;
1836 for (const auto &opt : tagHtmlAttribs)
1837 {
1838 AUTO_TRACE_ADD("option name={} value='{}'",opt.name,opt.value);
1839 if (opt.name=="src" && !opt.value.isEmpty())
1840 {
1841 // copy attributes
1842 HtmlAttribList attrList = tagHtmlAttribs;
1843 // and remove the src attribute
1844 attrList.erase(attrList.begin()+index);
1846 children.append<DocImage>(
1847 this,parent,attrList,
1848 findAndCopyImage(opt.value,t,false),
1849 t,opt.value);
1850 found = TRUE;
1851 }
1852 ++index;
1853 }
1854 if (!found)
1855 {
1856 warn_doc_error(context.fileName,tokenizer.getLineNr(),"IMG tag does not have a SRC attribute!");
1857 }
1858}

References DocNodeList::append(), AUTO_TRACE, AUTO_TRACE_ADD, context, FALSE, findAndCopyImage(), DocImage::Html, parent(), tokenizer, TRUE, and warn_doc_error.

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

◆ handleInitialStyleCommands()

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

Definition at line 760 of file docparser.cpp.

761{
762 AUTO_TRACE();
763 while (!context.initialStyleStack.empty())
764 {
765 const DocStyleChange &sc = std::get<DocStyleChange>(*context.initialStyleStack.top());
766 handleStyleEnter(parent,children,sc.style(),sc.tagName(),&sc.attribs());
767 context.initialStyleStack.pop();
768 }
769}
const HtmlAttribList & attribs() const
Definition docnode.h:311
QCString tagName() const
Definition docnode.h:312
Style style() const
Definition docnode.h:307

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

Referenced by DocPara::parse().

◆ handleInternalRef()

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

Definition at line 1001 of file docparser.cpp.

1002{
1003 Token tok=tokenizer.lex();
1004 QCString tokenName = context.token->name;
1005 AUTO_TRACE("name={}",tokenName);
1006 if (!tok.is(TokenRetval::TK_WHITESPACE))
1007 {
1008 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command", tokenName);
1009 return;
1010 }
1011 tokenizer.setStateInternalRef();
1012 tok=tokenizer.lex(); // get the reference id
1013 if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
1014 {
1015 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of {}",
1016 tok.to_string(),tokenName);
1017 return;
1018 }
1019 children.append<DocInternalRef>(this,parent,context.token->name);
1020 children.get_last<DocInternalRef>()->parse();
1021}

References DocNodeList::append(), AUTO_TRACE, context, DocNodeList::get_last(), Token::is(), Token::is_any_of(), parent(), Token::to_string(), tokenizer, and warn_doc_error.

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

◆ handleLinkedWord()

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

Definition at line 840 of file docparser.cpp.

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

References Definition::anchor(), DocNodeList::append(), AUTO_TRACE, AUTO_TRACE_ADD, Definition::briefDescriptionAsTooltip(), Config_getBool, Config_getList, context, Definition::definitionType(), FALSE, findFileDef(), getClass(), MemberDef::getClassDef(), Definition::getOutputFileBase(), Definition::getReference(), Definition::getSourceFileBase(), GroupDef::groupTitle(), handleLinkedWord(), Doxygen::inputNameLinkedMap, RequirementManager::instance(), Definition::isLinkable(), MemberDef::isObjCMethod(), linkToText(), Definition::name(), MemberDef::objCMethodName(), parent(), resolveRef(), toFileDef(), toGroupDef(), tokenizer, TRUE, 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 QCString & paramTypes )

Definition at line 977 of file docparser.cpp.

978{
979 QCString name = context.token->name; // save token name
980 AUTO_TRACE("name={}",name);
981 QCString name1;
982 int p=0, i=0, ii=0;
983 while ((i=paramTypes.find('|',p))!=-1)
984 {
985 name1 = paramTypes.mid(p,i-p);
986 ii=name1.find('[');
987 context.token->name=ii!=-1 ? name1.mid(0,ii) : name1; // take part without []
988 handleLinkedWord(parent,children);
989 if (ii!=-1) children.append<DocWord>(this,parent,name1.mid(ii)); // add [] part
990 p=i+1;
991 children.append<DocSeparator>(this,parent,"|");
992 }
993 name1 = paramTypes.mid(p);
994 ii=name1.find('[');
995 context.token->name=ii!=-1 ? name1.mid(0,ii) : name1;
996 handleLinkedWord(parent,children);
997 if (ii!=-1) children.append<DocWord>(this,parent,name1.mid(ii));
998 context.token->name = name; // restore original token name
999}

References DocNodeList::append(), AUTO_TRACE, context, QCString::find(), handleLinkedWord(), QCString::mid(), and parent().

Referenced by DocParamList::parse().

◆ handlePendingStyleCommands()

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

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

743{
744 AUTO_TRACE("context.styleStack.size()={}",context.styleStack.size());
745 if (!context.styleStack.empty())
746 {
747 const DocStyleChange *sc = &std::get<DocStyleChange>(*context.styleStack.top());
748 while (sc && sc->position()>=context.nodeStack.size())
749 { // there are unclosed style modifiers in the paragraph
750 AUTO_TRACE_ADD("unclosed style at position {}",sc->position());
751 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),
752 sc->style(),sc->tagName(),FALSE);
753 context.initialStyleStack.push(context.styleStack.top());
754 context.styleStack.pop();
755 sc = !context.styleStack.empty() ? &std::get<DocStyleChange>(*context.styleStack.top()) : nullptr;
756 }
757 }
758}
size_t position() const
Definition docnode.h:310

References DocNodeList::append(), AUTO_TRACE, AUTO_TRACE_ADD, context, FALSE, parent(), DocStyleChange::position(), DocStyleChange::style(), and DocStyleChange::tagName().

Referenced by defaultHandleTitleAndSize(), 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 1157 of file docparser.cpp.

1158{
1159 AUTO_TRACE();
1160 Token tok=tokenizer.lex();
1161 if (!tok.is(TokenRetval::TK_WHITESPACE))
1162 {
1163 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after \\{} command", context.token->name);
1164 return;
1165 }
1166 tokenizer.setStatePrefix();
1167 tok=tokenizer.lex();
1168 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1169 {
1170 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
1171 "argument of command {}",context.token->name);
1172 return;
1173 }
1174 else if (!tok.is(TokenRetval::TK_WORD))
1175 {
1176 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of {}",
1177 tok.to_string(),context.token->name);
1178 return;
1179 }
1180 context.prefix = context.token->name;
1181 tokenizer.setStatePara();
1182}

References AUTO_TRACE, context, Token::is(), Token::is_any_of(), parent(), Token::to_string(), tokenizer, and warn_doc_error.

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

◆ handleRef()

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

Definition at line 1383 of file docparser.cpp.

1384{
1385 AUTO_TRACE("cmdName={}",cmdName);
1386 QCString saveCmdName = cmdName;
1388 Token tok=tokenizer.lex();
1389 if (!tok.is(TokenRetval::TK_WHITESPACE))
1390 {
1391 warn_doc_error(context.fileName,tokenizer.getLineNr(),"expected whitespace after '{:c}{}' command",
1392 cmdChar,qPrint(saveCmdName));
1393 return;
1394 }
1395 tokenizer.setStateRef();
1396 tok=tokenizer.lex(); // get the reference id
1397 if (!tok.is(TokenRetval::TK_WORD))
1398 {
1399 warn_doc_error(context.fileName,tokenizer.getLineNr(),"unexpected token {} as the argument of '{:c}{}'",
1400 tok.to_string(),cmdChar,saveCmdName);
1401 return;
1402 }
1403 children.append<DocRef>(this,parent,
1404 context.token->name,
1405 context.context);
1406 children.get_last<DocRef>()->parse(cmdChar,saveCmdName);
1407}

References DocNodeList::append(), AUTO_TRACE, context, DocNodeList::get_last(), Token::is(), parent(), qPrint(), Token::to_string(), tokenizer, and warn_doc_error.

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

◆ handleStyleArgument()

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

Definition at line 625 of file docparser.cpp.

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

References AUTO_TRACE, AUTO_TRACE_ADD, AUTO_TRACE_EXIT, context, defaultHandleToken(), errorHandleDefaultToken(), Mappers::htmlTagMapper, insideLI(), Token::is(), Token::is_any_of(), reg::match(), parent(), Token::to_string(), 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 QCString & tagName,
const HtmlAttribList * attribs )

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

Definition at line 679 of file docparser.cpp.

681{
682 AUTO_TRACE("tagName={}",tagName);
683 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),s,tagName,TRUE,
684 context.fileName,tokenizer.getLineNr(),attribs);
685 context.styleStack.push(&children.back());
687}
T & back()
access the last element
Definition growvector.h:135

References DocNodeList::append(), AUTO_TRACE, GrowVector< T >::back(), context, parent(), tokenizer, TRUE, and DocStyleChange::Typewriter.

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

◆ handleStyleLeave()

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

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

Definition at line 692 of file docparser.cpp.

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

References DocNodeList::append(), AUTO_TRACE, context, FALSE, QCString::lower(), parent(), tokenizer, DocStyleChange::Typewriter, and warn_doc_error.

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

◆ handleUnclosedStyleCommands()

void DocParser::handleUnclosedStyleCommands ( )

Definition at line 816 of file docparser.cpp.

817{
818 AUTO_TRACE("content.initialStyleStack.size()={}",context.initialStyleStack.size());
819 if (!context.initialStyleStack.empty())
820 {
821 QCString tagName = std::get<DocStyleChange>(*context.initialStyleStack.top()).tagName();
822 QCString fileName = std::get<DocStyleChange>(*context.initialStyleStack.top()).fileName();
823 int lineNr = std::get<DocStyleChange>(*context.initialStyleStack.top()).lineNr();
824 context.initialStyleStack.pop();
826 if (lineNr != -1)
827 {
828 warn_doc_error(context.fileName,tokenizer.getLineNr(),
829 "end of comment block while expecting "
830 "command </{}> (Probable start '{}' at line {})",tagName, fileName, lineNr);
831 }
832 else
833 {
834 warn_doc_error(context.fileName,tokenizer.getLineNr(),
835 "end of comment block while expecting command </{}>",tagName);
836 }
837 }
838}
void handleUnclosedStyleCommands()

References AUTO_TRACE, context, handleUnclosedStyleCommands(), tokenizer, and warn_doc_error.

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

◆ internalValidatingParseDoc()

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

Definition at line 1862 of file docparser.cpp.

1864{
1865 AUTO_TRACE();
1866 Token retval = Token::make_RetVal_OK();
1867
1868 if (doc.isEmpty()) return retval;
1869
1870 tokenizer.init(doc.data(),context.fileName,context.markdownSupport,context.insideHtmlLink);
1871
1872 // first parse any number of paragraphs
1873 bool isFirst=TRUE;
1874 DocPara *lastPar=!children.empty() ? std::get_if<DocPara>(&children.back()): nullptr;
1875 if (lastPar)
1876 { // last child item was a paragraph
1877 isFirst=FALSE;
1878 }
1879 do
1880 {
1881 children.append<DocPara>(this,parent);
1882 DocPara *par = children.get_last<DocPara>();
1883 if (isFirst) { par->markFirst(); isFirst=FALSE; }
1884 retval=par->parse();
1885 if (!par->isEmpty())
1886 {
1887 if (lastPar) lastPar->markLast(FALSE);
1888 lastPar=par;
1889 }
1890 else
1891 {
1892 children.pop_back();
1893 }
1894 } while (retval.is(TokenRetval::TK_NEWPARA));
1895 if (lastPar) lastPar->markLast();
1896
1897 AUTO_TRACE_EXIT("isFirst={} isLast={}",lastPar?lastPar->isFirst():-1,lastPar?lastPar->isLast():-1);
1898 return retval;
1899}
bool isLast() const
Definition docnode.h:1097
void markLast(bool v=TRUE)
Definition docnode.h:1095
bool isFirst() const
Definition docnode.h:1096
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, QCString::data(), GrowVector< T >::empty(), FALSE, DocNodeList::get_last(), Token::is(), QCString::isEmpty(), DocPara::isFirst(), DocPara::isLast(), DocPara::markLast(), parent(), GrowVector< T >::pop_back(), tokenizer, and TRUE.

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

◆ popContext()

void DocParser::popContext ( )
private

Definition at line 75 of file docparser.cpp.

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

References context, contextStack, and tokenizer.

◆ processCopyDoc()

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

Definition at line 2058 of file docparser.cpp.

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

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

Referenced by processCopyDoc(), and validatingParseDoc().

◆ pushContext()

void DocParser::pushContext ( )
private

Definition at line 60 of file docparser.cpp.

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

References context, contextStack, and tokenizer.

◆ readTextFileByName()

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

Definition at line 1903 of file docparser.cpp.

1904{
1905 AUTO_TRACE("file={} text={}",file,text);
1906 bool ambig = false;
1907 QCString filePath = findFilePath(file,ambig);
1908 if (!filePath.isEmpty())
1909 {
1910 size_t indent = 0;
1911 text = detab(fileToString(filePath,Config_getBool(FILTER_SOURCE_FILES)),indent);
1912 if (ambig)
1913 {
1914 warn_doc_error(context.fileName,tokenizer.getLineNr(),"included file name '{}' is ambiguous"
1915 "Possible candidates:\n{}",file, showFileDefMatches(Doxygen::exampleNameLinkedMap,file));
1916 }
1917 }
1918 else
1919 {
1920 warn_doc_error(context.fileName,tokenizer.getLineNr(),"included file '{}' is not found. "
1921 "Check your EXAMPLE_PATH",file);
1922 }
1923}
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:102
QCString findFilePath(const QCString &file, bool &ambig)
Definition util.cpp:2996
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
Definition util.cpp:1494
QCString detab(const QCString &s, size_t &refIndent)
Definition util.cpp:6738

References AUTO_TRACE, Config_getBool, context, detab(), Doxygen::exampleNameLinkedMap, fileToString(), findFilePath(), QCString::isEmpty(), showFileDefMatches(), tokenizer, and warn_doc_error.

Referenced by DocInclude::parse().

Member Data Documentation

◆ context

DocParserContext DocParser::context

Definition at line 153 of file docparser_p.h.

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

◆ contextStack

std::stack< DocParserContext > DocParser::contextStack

Definition at line 152 of file docparser_p.h.

Referenced by popContext(), and pushContext().

◆ tokenizer

DocTokenizer DocParser::tokenizer

Definition at line 154 of file docparser_p.h.

Referenced by checkIfHtmlEndTagEndsAutoList(), createRef(), defaultHandleTitleAndSize(), defaultHandleToken(), docFindSections(), 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: