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

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

1456{
1457 AUTO_TRACE("token={} handleWord={}",tok.to_string(),handleWord);
1458 if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD,TokenRetval::TK_SYMBOL,TokenRetval::TK_URL,
1459 TokenRetval::TK_COMMAND_AT,TokenRetval::TK_COMMAND_BS,TokenRetval::TK_HTMLTAG)
1460 )
1461 {
1462 }
1463reparsetoken:
1464 QCString tokenName = context.token->name;
1465 AUTO_TRACE_ADD("tokenName={}",tokenName);
1466 switch (tok.value())
1467 {
1468 case TokenRetval::TK_COMMAND_AT:
1469 // fall through
1470 case TokenRetval::TK_COMMAND_BS:
1471 switch (Mappers::cmdMapper->map(tokenName))
1472 {
1474 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_BSlash);
1475 break;
1477 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_At);
1478 break;
1480 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Less);
1481 break;
1483 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Greater);
1484 break;
1486 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Amp);
1487 break;
1489 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dollar);
1490 break;
1492 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Hash);
1493 break;
1495 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_DoubleColon);
1496 break;
1498 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Percent);
1499 break;
1501 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1502 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1503 break;
1505 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1506 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1507 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1508 break;
1510 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quot);
1511 break;
1513 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Dot);
1514 break;
1516 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Exclam);
1517 break;
1519 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Quest);
1520 break;
1522 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Plus);
1523 break;
1525 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Minus);
1526 break;
1528 children.append<DocSymbol>(this,parent,HtmlEntityMapper::Sym_Equal);
1529 break;
1531 {
1532 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,TRUE);
1533 tok=handleStyleArgument(parent,children,tokenName);
1534 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Italic,tokenName,FALSE);
1535 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1536 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1537 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1538 {
1539 AUTO_TRACE_ADD("CommandType::CMD_EMPHASIS: reparsing");
1540 goto reparsetoken;
1541 }
1542 }
1543 break;
1545 {
1546 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,TRUE);
1547 tok=handleStyleArgument(parent,children,tokenName);
1548 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Bold,tokenName,FALSE);
1549 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1550 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1551 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1552 {
1553 AUTO_TRACE_ADD("CommandType::CMD_BOLD: reparsing");
1554 goto reparsetoken;
1555 }
1556 }
1557 break;
1559 {
1560 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,TRUE);
1561 tok=handleStyleArgument(parent,children,tokenName);
1562 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),DocStyleChange::Code,tokenName,FALSE);
1563 if (!tok.is(TokenRetval::TK_WORD)) children.append<DocWhiteSpace>(this,parent," ");
1564 if (tok.is(TokenRetval::TK_NEWPARA)) goto handlepara;
1565 else if (tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_HTMLTAG))
1566 {
1567 AUTO_TRACE_ADD("CommandType::CMD_CODE: reparsing");
1568 goto reparsetoken;
1569 }
1570 }
1571 break;
1573 {
1574 tokenizer.setStateHtmlOnly();
1575 tok = tokenizer.lex();
1576 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::HtmlOnly,context.isExample,context.exampleName,context.token->name=="block");
1577 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1578 {
1579 warn_doc_error(context.fileName,tokenizer.getLineNr(),"htmlonly section ended without end marker");
1580 }
1581 tokenizer.setStatePara();
1582 }
1583 break;
1585 {
1586 tokenizer.setStateManOnly();
1587 tok = tokenizer.lex();
1588 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::ManOnly,context.isExample,context.exampleName);
1589 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1590 {
1591 warn_doc_error(context.fileName,tokenizer.getLineNr(),"manonly section ended without end marker");
1592 }
1593 tokenizer.setStatePara();
1594 }
1595 break;
1597 {
1598 tokenizer.setStateRtfOnly();
1599 tok = tokenizer.lex();
1600 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::RtfOnly,context.isExample,context.exampleName);
1601 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1602 {
1603 warn_doc_error(context.fileName,tokenizer.getLineNr(),"rtfonly section ended without end marker");
1604 }
1605 tokenizer.setStatePara();
1606 }
1607 break;
1609 {
1610 tokenizer.setStateLatexOnly();
1611 tok = tokenizer.lex();
1612 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::LatexOnly,context.isExample,context.exampleName);
1613 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1614 {
1615 warn_doc_error(context.fileName,tokenizer.getLineNr(),"latexonly section ended without end marker");
1616 }
1617 tokenizer.setStatePara();
1618 }
1619 break;
1621 {
1622 tokenizer.setStateXmlOnly();
1623 tok = tokenizer.lex();
1624 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::XmlOnly,context.isExample,context.exampleName);
1625 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1626 {
1627 warn_doc_error(context.fileName,tokenizer.getLineNr(),"xmlonly section ended without end marker");
1628 }
1629 tokenizer.setStatePara();
1630 }
1631 break;
1633 {
1634 tokenizer.setStateDbOnly();
1635 tok = tokenizer.lex();
1636 children.append<DocVerbatim>(this,parent,context.context,context.token->verb,DocVerbatim::DocbookOnly,context.isExample,context.exampleName);
1637 if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
1638 {
1639 warn_doc_error(context.fileName,tokenizer.getLineNr(),"docbookonly section ended without end marker");
1640 }
1641 tokenizer.setStatePara();
1642 }
1643 break;
1645 {
1646 children.append<DocFormula>(this,parent,context.token->id);
1647 }
1648 break;
1651 {
1652 handleAnchor(parent,children);
1653 }
1654 break;
1656 {
1657 handleCite(parent,children);
1658 }
1659 break;
1661 {
1662 handlePrefix(parent,children);
1663 }
1664 break;
1666 {
1667 handleInternalRef(parent,children);
1668 tokenizer.setStatePara();
1669 }
1670 break;
1672 {
1673 tokenizer.setStateSetScope();
1674 (void)tokenizer.lex();
1675 context.context = context.token->name;
1676 //printf("Found scope='%s'\n",qPrint(context.context));
1677 tokenizer.setStatePara();
1678 }
1679 break;
1681 handleImage(parent,children);
1682 break;
1684 handleILine(tok.command_to_char(),tokenName);
1685 break;
1687 handleIFile(tok.command_to_char(),tokenName);
1688 break;
1689 default:
1690 return FALSE;
1691 }
1692 break;
1693 case TokenRetval::TK_HTMLTAG:
1694 {
1695 auto handleEnterLeaveStyle = [this,&parent,&children,&tokenName](DocStyleChange::Style style) {
1696 if (!context.token->endTag)
1697 {
1698 handleStyleEnter(parent,children,style,tokenName,&context.token->attribs);
1699 }
1700 else
1701 {
1702 handleStyleLeave(parent,children,style,tokenName);
1703 }
1704 };
1705 switch (Mappers::htmlTagMapper->map(tokenName))
1706 {
1708 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <div> tag in heading");
1709 break;
1711 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <pre> tag in heading");
1712 break;
1714 handleEnterLeaveStyle(DocStyleChange::Span);
1715 break;
1717 handleEnterLeaveStyle(DocStyleChange::Bold);
1718 break;
1720 handleEnterLeaveStyle(DocStyleChange::S);
1721 break;
1723 handleEnterLeaveStyle(DocStyleChange::Strike);
1724 break;
1726 handleEnterLeaveStyle(DocStyleChange::Del);
1727 break;
1729 handleEnterLeaveStyle(DocStyleChange::Underline);
1730 break;
1732 handleEnterLeaveStyle(DocStyleChange::Ins);
1733 break;
1735 case HtmlTagType::XML_C:
1736 handleEnterLeaveStyle(DocStyleChange::Code);
1737 break;
1739 handleEnterLeaveStyle(DocStyleChange::Kbd);
1740 break;
1742 handleEnterLeaveStyle(DocStyleChange::Typewriter);
1743 break;
1745 handleEnterLeaveStyle(DocStyleChange::Italic);
1746 break;
1748 handleEnterLeaveStyle(DocStyleChange::Subscript);
1749 break;
1751 handleEnterLeaveStyle(DocStyleChange::Superscript);
1752 break;
1754 handleEnterLeaveStyle(DocStyleChange::Center);
1755 break;
1757 handleEnterLeaveStyle(DocStyleChange::Small);
1758 break;
1760 handleEnterLeaveStyle(DocStyleChange::Cite);
1761 break;
1763 if (!context.token->endTag)
1764 {
1765 handleImg(parent,children,context.token->attribs);
1766 }
1767 break;
1768 default:
1769 return FALSE;
1770 break;
1771 }
1772 }
1773 break;
1774 case TokenRetval::TK_SYMBOL:
1775 {
1778 {
1779 children.append<DocSymbol>(this,parent,s);
1780 }
1781 else
1782 {
1783 return FALSE;
1784 }
1785 }
1786 break;
1787 case TokenRetval::TK_WHITESPACE:
1788 case TokenRetval::TK_NEWPARA:
1789handlepara:
1790 if (insidePRE(parent) || !children.empty())
1791 {
1792 children.append<DocWhiteSpace>(this,parent,context.token->chars);
1793 }
1794 break;
1795 case TokenRetval::TK_LNKWORD:
1796 if (handleWord)
1797 {
1798 handleLinkedWord(parent,children);
1799 }
1800 else
1801 return FALSE;
1802 break;
1803 case TokenRetval::TK_WORD:
1804 if (handleWord)
1805 {
1806 children.append<DocWord>(this,parent,context.token->name);
1807 }
1808 else
1809 return FALSE;
1810 break;
1811 case TokenRetval::TK_URL:
1812 if (context.insideHtmlLink)
1813 {
1814 children.append<DocWord>(this,parent,context.token->name);
1815 }
1816 else
1817 {
1818 children.append<DocURL>(this,parent,context.token->name,context.token->isEMailAddr);
1819 }
1820 break;
1821 default:
1822 return FALSE;
1823 }
1824 return TRUE;
1825}
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 769 of file docparser.cpp.

771{
772 AUTO_TRACE();
773 size_t index=0;
774 Token retval = Token::make_RetVal_OK();
775 for (const auto &opt : tagHtmlAttribs)
776 {
777 if (opt.name=="name" || opt.name=="id") // <a name=label> or <a id=label> tag
778 {
779 if (!opt.value.isEmpty())
780 {
781 children.append<DocAnchor>(this,parent,opt.value,TRUE);
782 break; // stop looking for other tag attribs
783 }
784 else
785 {
786 warn_doc_error(context.fileName,tokenizer.getLineNr(),"found <a> tag with name option but without value!");
787 }
788 }
789 else if (opt.name=="href") // <a href=url>..</a> tag
790 {
791 // copy attributes
792 HtmlAttribList attrList = tagHtmlAttribs;
793 // and remove the href attribute
794 attrList.erase(attrList.begin()+index);
795 QCString relPath;
796 if (opt.value.at(0) != '#') relPath = context.relPath;
797 children.append<DocHRef>(this, parent, attrList,
798 opt.value, relPath,
799 convertNameToFile(context.fileName, FALSE, TRUE));
800 context.insideHtmlLink=TRUE;
801 retval = children.get_last<DocHRef>()->parse();
802 context.insideHtmlLink=FALSE;
803 tokenizer.setStatePara();
804 break;
805 }
806 else // unsupported option for tag a
807 {
808 }
809 ++index;
810 }
811 return retval;
812}
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 1021 of file docparser.cpp.

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

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

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

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

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

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

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

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

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

759{
760 AUTO_TRACE();
761 while (!context.initialStyleStack.empty())
762 {
763 const DocStyleChange &sc = std::get<DocStyleChange>(*context.initialStyleStack.top());
764 handleStyleEnter(parent,children,sc.style(),sc.tagName(),&sc.attribs());
765 context.initialStyleStack.pop();
766 }
767}
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 999 of file docparser.cpp.

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

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

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

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

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

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

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

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

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

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

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 return tok;
647 }
648 if (!defaultHandleToken(parent,tok,children))
649 {
650 switch (tok.value())
651 {
652 case TokenRetval::TK_HTMLTAG:
653 if (insideLI(parent) && Mappers::htmlTagMapper->map(context.token->name)!=HtmlTagType::UNKNOWN && context.token->endTag)
654 {
655 // ignore </li> as the end of a style command
656 }
657 else
658 {
659 AUTO_TRACE_EXIT("end tok={}",tok.to_string());
660 return tok;
661 }
662 break;
663 default:
664 errorHandleDefaultToken(parent,tok,children,"\\" + saveCmdName + " command");
665 break;
666 }
667 break;
668 }
669 tok = tokenizer.lex();
670 }
671 AUTO_TRACE_EXIT("end tok={}",tok.to_string());
672 return (tok.is_any_of(TokenRetval::TK_NEWPARA,TokenRetval::TK_LISTITEM,TokenRetval::TK_ENDLIST)) ? tok : Token::make_RetVal_OK();
673}
bool insideLI(const DocNodeVariant *n)

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

680{
681 AUTO_TRACE("tagName={}",tagName);
682 children.append<DocStyleChange>(this,parent,context.nodeStack.size(),s,tagName,TRUE,
683 context.fileName,tokenizer.getLineNr(),attribs);
684 context.styleStack.push(&children.back());
686}
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 691 of file docparser.cpp.

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

815{
816 AUTO_TRACE();
817 if (!context.initialStyleStack.empty())
818 {
819 QCString tagName = std::get<DocStyleChange>(*context.initialStyleStack.top()).tagName();
820 QCString fileName = std::get<DocStyleChange>(*context.initialStyleStack.top()).fileName();
821 int lineNr = std::get<DocStyleChange>(*context.initialStyleStack.top()).lineNr();
822 context.initialStyleStack.pop();
824 if (lineNr != -1)
825 {
826 warn_doc_error(context.fileName,tokenizer.getLineNr(),
827 "end of comment block while expecting "
828 "command </{}> (Probable start '{}' at line {})",tagName, fileName, lineNr);
829 }
830 else
831 {
832 warn_doc_error(context.fileName,tokenizer.getLineNr(),
833 "end of comment block while expecting command </{}>",tagName);
834 }
835 }
836}
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 1860 of file docparser.cpp.

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

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

1902{
1903 AUTO_TRACE("file={} text={}",file,text);
1904 bool ambig = false;
1905 QCString filePath = findFilePath(file,ambig);
1906 if (!filePath.isEmpty())
1907 {
1908 size_t indent = 0;
1909 text = detab(fileToString(filePath,Config_getBool(FILTER_SOURCE_FILES)),indent);
1910 if (ambig)
1911 {
1912 warn_doc_error(context.fileName,tokenizer.getLineNr(),"included file name '{}' is ambiguous"
1913 "Possible candidates:\n{}",file, showFileDefMatches(Doxygen::exampleNameLinkedMap,file));
1914 }
1915 }
1916 else
1917 {
1918 warn_doc_error(context.fileName,tokenizer.getLineNr(),"included file '{}' is not found. "
1919 "Check your EXAMPLE_PATH",file);
1920 }
1921}
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: