summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTopi Reinio <topi.reinio@qt.io>2018-07-26 15:07:54 +0200
committerTopi Reiniƶ <topi.reinio@qt.io>2018-07-31 09:33:13 +0000
commit85bc558660648671020b4fb0a9032ec68ba969ec (patch)
tree4f1c4df571bfd0c9b0b6656981586f1bb1f68327 /src
parentd8084e902a91eebebc8332a8cb789d917d5e0a9b (diff)
qdoc: Allow macro expansion in qdoc command arguments
Until now, QDoc did not expand macros if they were used in arguments for other commands. Macros can be useful in command arguments, for example: \qmlmodule QtQuick 2.\qtminorversion where \qtminorversion expands to the current minor version, or \title \productname Manual where \productname expands to the current product name. Task-number: QTBUG-67818 Change-Id: Ib3e2da9f6bd20343a454f467742cfa00ee09b39a Reviewed-by: Martin Smith <martin.smith@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qdoc/doc.cpp93
1 files changed, 56 insertions, 37 deletions
diff --git a/src/qdoc/doc.cpp b/src/qdoc/doc.cpp
index 723e88092..29f1eed77 100644
--- a/src/qdoc/doc.cpp
+++ b/src/qdoc/doc.cpp
@@ -469,6 +469,7 @@ private:
void leaveValueList();
void leaveTableRow();
CodeMarker *quoteFromFile();
+ bool expandMacro();
void expandMacro(const QString& name, const QString& def, int numParams);
QString expandMacroToString(const QString &name, const QString &def, int numParams);
Doc::Sections getSectioningUnit();
@@ -2107,6 +2108,55 @@ CodeMarker *DocParser::quoteFromFile()
return Doc::quoteFromFile(location(), quoter, getArgument());
}
+/*!
+ Expands a macro in-place in input.
+
+ Expects the current \e pos in the input to point to a backslash, and the macro to have a
+ default definition. Format-specific macros are currently not expanded.
+
+ \note In addition to macros, a valid use for a backslash in an argument include
+ escaping non-alnum characters, and splitting a single argument across multiple
+ lines by escaping newlines. Escaping is also handled here.
+
+ Returns \c true on successful macro expansion.
+ */
+bool DocParser::expandMacro()
+{
+ Q_ASSERT(input_[pos].unicode() == '\\');
+
+ QString cmdStr;
+ int backslashPos = pos++;
+ while (pos < (int) input_.length() && input_[pos].isLetterOrNumber())
+ cmdStr += input_[pos++];
+
+ if (!cmdStr.isEmpty()) {
+ if (macroHash()->contains(cmdStr)) {
+ const Macro &macro = macroHash()->value(cmdStr);
+ if (!macro.defaultDef.isEmpty()) {
+ QString expanded = expandMacroToString(cmdStr,
+ macro.defaultDef,
+ macro.numParams);
+ input_.replace(backslashPos, endPos - backslashPos, expanded);
+ len = input_.length();
+ pos = backslashPos;
+ return true;
+ } else {
+ location().warning(tr("Macro '%1' does not have a default definition").arg(cmdStr));
+ }
+ } else {
+ location().warning(tr("Unknown macro '%1'").arg(cmdStr));
+ pos = ++backslashPos;
+ }
+ } else if (input_[pos].isSpace()) {
+ skipAllSpaces();
+ } else if (input_[pos].unicode() == '\\') {
+ // allow escaping a backslash
+ input_.remove(pos--, 1);
+ --len;
+ }
+ return false;
+}
+
void DocParser::expandMacro(const QString &name,
const QString &def,
int numParams)
@@ -2244,24 +2294,8 @@ QString DocParser::getBracedArgument(bool verbatim)
pos++;
break;
case '\\':
- if (verbatim) {
- arg += input_[pos];
- pos++;
- }
- else {
- pos++;
- if (pos < (int) input_.length()) {
- if (input_[pos].isLetterOrNumber())
- break;
- arg += input_[pos];
- if (input_[pos].isSpace()) {
- skipAllSpaces();
- }
- else {
- pos++;
- }
- }
- }
+ if (verbatim || !expandMacro())
+ arg += input_[pos++];
break;
default:
if (input_[pos].isSpace() && !verbatim)
@@ -2320,24 +2354,8 @@ QString DocParser::getArgument(bool verbatim)
}
break;
case '\\':
- if (verbatim) {
- arg += input_[pos];
- pos++;
- }
- else {
- pos++;
- if (pos < (int) input_.length()) {
- if (input_[pos].isLetterOrNumber())
- break;
- arg += input_[pos];
- if (input_[pos].isSpace()) {
- skipAllSpaces();
- }
- else {
- pos++;
- }
- }
- }
+ if (verbatim || !expandMacro())
+ arg += input_[pos++];
break;
default:
arg += input_[pos];
@@ -2470,7 +2488,8 @@ QString DocParser::getMetaCommandArgument(const QString &cmdStr)
++parenDepth;
else if (input_.at(pos) == ')')
--parenDepth;
-
+ else if (input_.at(pos) == '\\' && expandMacro())
+ continue;
++pos;
}
if (pos == input_.size() && parenDepth > 0) {