Commit 62da66a0 authored by Oswald Buddenhagen's avatar Oswald Buddenhagen Committed by Tobias Hunger

AbstractMacroExpander: expand macros recursively

Started-by: default avatarTobias Hunger <tobias.hunger@digia.com>
Change-Id: Id2e88efbb475221cd7c0347f7d5e7009e4372eec
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
parent 1b11f9b3
......@@ -115,6 +115,40 @@ QTCREATOR_UTILS_EXPORT QString withTildeHomePath(const QString &path)
return outPath;
}
bool AbstractMacroExpander::expandNestedMacros(const QString &str, int *pos, QString *ret)
{
QString varName;
QChar prev;
QChar c;
int i = *pos;
int strLen = str.length();
varName.reserve(strLen - i);
for (; i < strLen; prev = c) {
c = str.at(i++);
if (c == QLatin1Char('}')) {
if (varName.isEmpty()) { // replace "%{}" with "%"
*ret = QString(QLatin1Char('%'));
*pos = i;
return true;
}
if (resolveMacro(varName, ret)) {
*pos = i;
return true;
}
return false;
} else if (c == QLatin1Char('{') && prev == QLatin1Char('%')) {
if (!expandNestedMacros(str, &i, ret))
return false;
varName.chop(1);
varName += ret;
} else {
varName += c;
}
}
return false;
}
int AbstractMacroExpander::findMacro(const QString &str, int *pos, QString *ret)
{
forever {
......@@ -122,22 +156,13 @@ int AbstractMacroExpander::findMacro(const QString &str, int *pos, QString *ret)
if (openPos < 0)
return 0;
int varPos = openPos + 2;
int closePos = str.indexOf(QLatin1Char('}'), varPos);
if (closePos < 0)
return 0;
int varLen = closePos - varPos;
if (varLen == 0) { // replace "%{}" with "%"
*pos = openPos;
*ret = QString(QLatin1Char('%'));
return 3;
}
if (resolveMacro(str.mid(varPos, varLen), ret)) {
if (expandNestedMacros(str, &varPos, ret)) {
*pos = openPos;
return varLen + 3;
return varPos - openPos;
}
// An actual expansion may be nested into a "false" one,
// so we continue right after the last %{.
*pos = varPos;
*pos = openPos + 2;
}
}
......
......@@ -71,6 +71,8 @@ public:
//! \param ret Replacement string on output
//! \return True if the expando was found
virtual bool resolveMacro(const QString &name, QString *ret) = 0;
private:
bool expandNestedMacros(const QString &str, int *pos, QString *ret);
};
QTCREATOR_UTILS_EXPORT void expandMacros(QString *str, AbstractMacroExpander *mx);
......
......@@ -38,12 +38,20 @@ class TestMacroExpander : public Utils::AbstractMacroExpander
public:
virtual bool resolveMacro(const QString &name, QString *ret)
{
if (name == QLatin1String("foo")) {
*ret = QLatin1String("a");
return true;
}
if (name == QLatin1String("a")) {
*ret = QLatin1String("hi");
return true;
}
if (name == QLatin1String("foo")) {
*ret = QLatin1String("a");
if (name == QLatin1String("hi")) {
*ret = QLatin1String("ho");
return true;
}
if (name == QLatin1String("hihi")) {
*ret = QLatin1String("bar");
return true;
}
return false;
......@@ -116,7 +124,15 @@ void tst_StringUtils::testMacroExpander_data()
{ "%{a}text%{a}", "hitexthi" },
{ "%{foo}%{a}text%{a}", "ahitexthi" },
{ "%{}{a}", "%{a}" },
{ "%{abc", "%{abc" }
{ "%{}", "%" },
{ "test%{}", "test%" },
{ "%{}test", "%test" },
{ "%{abc", "%{abc" },
{ "%{%{a}", "%{hi" },
{ "%{%{a}}", "ho" },
{ "%{%{a}}}post", "ho}post" },
{ "%{hi%{a}}", "bar" },
{ "%{hi%{%{foo}}}", "bar" },
};
for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment