summaryrefslogtreecommitdiffstats
path: root/qmake/library
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-04-03 17:11:36 +0200
committerLars Knoll <lars.knoll@qt.io>2020-05-05 18:41:27 +0200
commita1947aeffe158a0ea7de3ced1bf8d6a4719a27ef (patch)
treec1b249b7d8bd9b3079df3ad5fe468f7ff4df861b /qmake/library
parent412dd857b81471277e1014b6329f46a389a42cb3 (diff)
Port qmake over to user QRegularExpression
Use the DotMatchesEverythingOption for all places where we interpret .pro files, to increase compatibility with QRegExp. Change-Id: I347d6b17858069f3c9cedcedd04df58358d83f27 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'qmake/library')
-rw-r--r--qmake/library/ioutils.cpp6
-rw-r--r--qmake/library/qmakebuiltins.cpp72
-rw-r--r--qmake/library/qmakeevaluator.cpp15
3 files changed, 58 insertions, 35 deletions
diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp
index d2171274d8..fac0541779 100644
--- a/qmake/library/ioutils.cpp
+++ b/qmake/library/ioutils.cpp
@@ -30,7 +30,7 @@
#include <qdir.h>
#include <qfile.h>
-#include <qregexp.h>
+#include <qregularexpression.h>
#ifdef Q_OS_WIN
# include <windows.h>
@@ -178,9 +178,9 @@ QString IoUtils::shellQuoteWin(const QString &arg)
// The process-level standard quoting allows escaping quotes with backslashes (note
// that backslashes don't escape themselves, unless they are followed by a quote).
// Consequently, quotes are escaped and their preceding backslashes are doubled.
- ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
+ ret.replace(QRegularExpression(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
// Trailing backslashes must be doubled as well, as they are followed by a quote.
- ret.replace(QRegExp(QLatin1String("(\\\\+)$")), QLatin1String("\\1\\1"));
+ ret.replace(QRegularExpression(QLatin1String("(\\\\+)$")), QLatin1String("\\1\\1"));
// However, the shell also interprets the command, and no backslash-escaping exists
// there - a quote always toggles the quoting state, but is nonetheless passed down
// to the called process verbatim. In the unquoted state, the circumflex escapes
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 460720168f..96583e5e76 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -39,7 +39,7 @@
#include <qfile.h>
#include <qfileinfo.h>
#include <qlist.h>
-#include <qregexp.h>
+#include <qregularexpression.h>
#include <qset.h>
#include <qstringlist.h>
#include <qtextstream.h>
@@ -639,7 +639,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
if (!var.isEmpty()) {
const auto strings = values(map(var));
if (regexp) {
- QRegExp sepRx(sep);
+ QRegularExpression sepRx(sep, QRegularExpression::DotMatchesEverythingOption);
+ if (!sepRx.isValid()) {
+ evalError(fL1S("section(): Encountered invalid regular expression '%1'.").arg(sep));
+ goto allfail;
+ }
for (const ProString &str : strings) {
ProStringRwUser u1(str, m_tmp[m_toggle ^= 1]);
ret << u1.extract(u1.str().section(sepRx, beg, end));
@@ -890,11 +894,15 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
m_valuemapStack.top()[ret.at(0).toKey()] = lst;
break; }
case E_FIND: {
- QRegExp regx(args.at(1).toQString());
+ QRegularExpression regx(args.at(1).toQString(), QRegularExpression::DotMatchesEverythingOption);
+ if (!regx.isValid()) {
+ evalError(fL1S("find(): Encountered invalid regular expression '%1'.").arg(regx.pattern()));
+ goto allfail;
+ }
const auto vals = values(map(args.at(0)));
for (const ProString &val : vals) {
ProStringRoUser u1(val, m_tmp[m_toggle ^= 1]);
- if (regx.indexIn(u1.str()) != -1)
+ if (u1.str().contains(regx))
ret += val;
}
break;
@@ -990,7 +998,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
case E_RE_ESCAPE:
for (int i = 0; i < args.size(); ++i) {
ProStringRwUser u1(args.at(i), m_tmp1);
- ret << u1.extract(QRegExp::escape(u1.str()));
+ ret << u1.extract(QRegularExpression::escape(u1.str()));
}
break;
case E_VAL_ESCAPE: {
@@ -1038,8 +1046,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
dirs.append(QString());
}
- r.detach(); // Keep m_tmp out of QRegExp's cache
- QRegExp regex(r, Qt::CaseSensitive, QRegExp::Wildcard);
+ QString pattern = QRegularExpression::wildcardToRegularExpression(r);
+ QRegularExpression regex(pattern, QRegularExpression::DotMatchesEverythingOption);
+ if (!regex.isValid()) {
+ evalError(fL1S("section(): Encountered invalid wildcard expression '%1'.").arg(pattern));
+ goto allfail;
+ }
for (int d = 0; d < dirs.count(); d++) {
QString dir = dirs[d];
QDir qdir(pfx + dir);
@@ -1051,7 +1063,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
if (recursive)
dirs.append(fname + QLatin1Char('/'));
}
- if (regex.exactMatch(qdir[i]))
+ if (regex.match(qdir[i]).hasMatch())
ret += ProString(fname).setSource(currentFileId());
}
}
@@ -1086,7 +1098,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
}
#endif
case E_REPLACE: {
- const QRegExp before(args.at(1).toQString());
+ const QRegularExpression before(args.at(1).toQString(), QRegularExpression::DotMatchesEverythingOption);
+ if (!before.isValid()) {
+ evalError(fL1S("replace(): Encountered invalid regular expression '%1'.").arg(before.pattern()));
+ goto allfail;
+ }
ProStringRwUser u2(args.at(2), m_tmp2);
const QString &after = u2.str();
const auto vals = values(map(args.at(0)));
@@ -1528,21 +1544,24 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ok;
if (args.count() == 2)
return returnBool(vars.contains(map(args.at(1))));
- QRegExp regx;
+ QRegularExpression regx;
+ regx.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
ProStringRoUser u1(args.at(2), m_tmp1);
const QString &qry = u1.str();
- if (qry != QRegExp::escape(qry)) {
- QString copy = qry;
- copy.detach();
- regx.setPattern(copy);
+ if (qry != QRegularExpression::escape(qry)) {
+ regx.setPattern(QRegularExpression::anchoredPattern(qry));
+ if (!regx.isValid()) {
+ evalError(fL1S("infile(): Encountered invalid regular expression '%1'.").arg(qry));
+ return ReturnFalse;
+ }
}
const auto strings = vars.value(map(args.at(1)));
for (const ProString &s : strings) {
if (s == qry)
return ReturnTrue;
- if (!regx.isEmpty()) {
+ if (!regx.pattern().isEmpty()) {
ProStringRoUser u2(s, m_tmp[m_toggle ^= 1]);
- if (regx.exactMatch(u2.str()))
+ if (regx.match(u2.str()).hasMatch())
return ReturnTrue;
}
}
@@ -1590,11 +1609,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
case T_CONTAINS: {
ProStringRoUser u1(args.at(1), m_tmp1);
const QString &qry = u1.str();
- QRegExp regx;
- if (qry != QRegExp::escape(qry)) {
- QString copy = qry;
- copy.detach();
- regx.setPattern(copy);
+ QRegularExpression regx;
+ regx.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
+ if (qry != QRegularExpression::escape(qry)) {
+ regx.setPattern(QRegularExpression::anchoredPattern(qry));
+ if (!regx.isValid()) {
+ evalError(fL1S("contains(): Encountered invalid regular expression '%1'.").arg(qry));
+ return ReturnFalse;
+ }
}
const ProStringList &l = values(map(args.at(0)));
if (args.count() == 2) {
@@ -1602,9 +1624,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
const ProString &val = l[i];
if (val == qry)
return ReturnTrue;
- if (!regx.isEmpty()) {
+ if (!regx.pattern().isEmpty()) {
ProStringRoUser u2(val, m_tmp[m_toggle ^= 1]);
- if (regx.exactMatch(u2.str()))
+ if (regx.match(u2.str()).hasMatch())
return ReturnTrue;
}
}
@@ -1617,9 +1639,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (val.toQStringRef() == mutuals[mut].trimmed()) {
if (val == qry)
return ReturnTrue;
- if (!regx.isEmpty()) {
+ if (!regx.pattern().isEmpty()) {
ProStringRoUser u2(val, m_tmp[m_toggle ^= 1]);
- if (regx.exactMatch(u2.str()))
+ if (regx.match(u2.str()).hasMatch())
return ReturnTrue;
}
return ReturnFalse;
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 7041a2402e..f78537c340 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -41,7 +41,7 @@
#include <qfile.h>
#include <qfileinfo.h>
#include <qlist.h>
-#include <qregexp.h>
+#include <qregularexpression.h>
#include <qset.h>
#include <qstack.h>
#include <qstring.h>
@@ -334,7 +334,7 @@ ProStringList QMakeEvaluator::split_value_list(const QStringRef &vals, int sourc
}
static void replaceInList(ProStringList *varlist,
- const QRegExp &regexp, const QString &replace, bool global, QString &tmp)
+ const QRegularExpression &regexp, const QString &replace, bool global, QString &tmp)
{
for (ProStringList::Iterator varit = varlist->begin(); varit != varlist->end(); ) {
ProStringRoUser u1(*varit, tmp);
@@ -898,9 +898,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable(
QString pattern = func[1].toString();
QString replace = func[2].toString();
if (quote)
- pattern = QRegExp::escape(pattern);
+ pattern = QRegularExpression::escape(pattern);
- QRegExp regexp(pattern, case_sense ? Qt::CaseSensitive : Qt::CaseInsensitive);
+ QRegularExpression regexp(pattern, case_sense ? QRegularExpression::NoPatternOption :
+ QRegularExpression::CaseInsensitiveOption);
// We could make a union of modified and unmodified values,
// but this will break just as much as it fixes, so leave it as is.
@@ -1635,17 +1636,17 @@ bool QMakeEvaluator::isActiveConfig(const QStringRef &config, bool regex)
return m_hostBuild;
if (regex && (config.contains(QLatin1Char('*')) || config.contains(QLatin1Char('?')))) {
- QRegExp re(config.toString(), Qt::CaseSensitive, QRegExp::Wildcard);
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(config.toString()));
// mkspecs
- if (re.exactMatch(m_qmakespecName))
+ if (re.match(m_qmakespecName).hasMatch())
return true;
// CONFIG variable
const auto configValues = values(statics.strCONFIG);
for (const ProString &configValue : configValues) {
ProStringRoUser u1(configValue, m_tmp[m_toggle ^= 1]);
- if (re.exactMatch(u1.str()))
+ if (re.match(u1.str()).hasMatch())
return true;
}
} else {