diff options
author | Liang Qi <liang.qi@qt.io> | 2017-08-31 13:10:18 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-08-31 14:31:31 +0200 |
commit | 112a4af10741409b3d8503cb77852a777b607ce0 (patch) | |
tree | fa99f0f37fc1505522fe9368e95484c7732ccda8 /qmake | |
parent | 29ef0d2bccd1874e20de94485ee05777c3a95c5d (diff) | |
parent | e938150412d22e61926fe16791158805b71268bb (diff) | |
download | qtbase-112a4af10741409b3d8503cb77852a777b607ce0.tar.gz |
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts:
examples/examples.pro
qmake/library/qmakebuiltins.cpp
src/corelib/global/qglobal.cpp
Re-apply b525ec2 to qrandom.cpp(code movement in 030782e)
src/corelib/global/qnamespace.qdoc
src/corelib/global/qrandom.cpp
src/gui/kernel/qwindow.cpp
Re-apply a3d59c7 to QWindowPrivate::setVisible() (code movement in d7a9e08)
src/network/ssl/qsslkey_openssl.cpp
src/plugins/platforms/android/androidjniinput.cpp
src/plugins/platforms/xcb/qxcbconnection.cpp
src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
src/widgets/widgets/qmenu.cpp
tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
Change-Id: If7ab427804408877a93cbe02079fca58e568bfd3
Diffstat (limited to 'qmake')
-rw-r--r-- | qmake/generators/mac/pbuilder_pbx.cpp | 2 | ||||
-rw-r--r-- | qmake/generators/makefiledeps.cpp | 42 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_nmake.cpp | 1 | ||||
-rw-r--r-- | qmake/library/proitems.cpp | 7 | ||||
-rw-r--r-- | qmake/library/proitems.h | 10 | ||||
-rw-r--r-- | qmake/library/qmakebuiltins.cpp | 66 | ||||
-rw-r--r-- | qmake/library/qmakeevaluator.cpp | 31 | ||||
-rw-r--r-- | qmake/library/qmakeevaluator.h | 2 | ||||
-rw-r--r-- | qmake/library/qmakeevaluator_p.h | 2 |
9 files changed, 97 insertions, 66 deletions
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index ab699157ca..63926e7ef0 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1902,7 +1902,7 @@ int ProjectBuilderMakefileGenerator::pbuilderVersion() const { if (!project->isEmpty("QMAKE_PBUILDER_VERSION")) - return project->first("QMAKE_PBUILDER_VERSION").toQString().toInt(); + return project->first("QMAKE_PBUILDER_VERSION").toInt(); return 46; // Xcode 3.2-compatible; default format since that version } diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp index 3140b045a1..c68eeb13d6 100644 --- a/qmake/generators/makefiledeps.cpp +++ b/qmake/generators/makefiledeps.cpp @@ -422,25 +422,53 @@ static bool matchWhileUnsplitting(const char *buffer, int buffer_len, int start, /* Advance from an opening quote at buffer[offset] to the matching close quote. */ static int scanPastString(char *buffer, int buffer_len, int offset, int *lines) { + // http://en.cppreference.com/w/cpp/language/string_literal // It might be a C++11 raw string. bool israw = false; if (buffer[offset] == '"' && offset > 0) { int explore = offset - 1; - while (explore > 0 && buffer[explore] != 'R') { - if (buffer[explore] == '8' || buffer[explore] == 'u' || buffer[explore] == 'U') { - explore--; - } else if (explore > 1 && qmake_endOfLine(buffer[explore]) - && buffer[explore - 1] == '\\') { + bool prefix = false; // One of L, U, u or u8 may appear before R + bool saw8 = false; // Partial scan of u8 + while (explore >= 0) { + // Cope with backslash-newline interruptions of the prefix: + if (explore > 0 + && qmake_endOfLine(buffer[explore]) + && buffer[explore - 1] == '\\') { explore -= 2; - } else if (explore > 2 && buffer[explore] == '\n' + } else if (explore > 1 + && buffer[explore] == '\n' && buffer[explore - 1] == '\r' && buffer[explore - 2] == '\\') { explore -= 3; + // Remaining cases can only decrement explore by one at a time: + } else if (saw8 && buffer[explore] == 'u') { + explore--; + saw8 = false; + prefix = true; + } else if (saw8 || prefix) { + break; + } else if (explore > 1 && buffer[explore] == '8') { + explore--; + saw8 = true; + } else if (buffer[explore] == 'L' + || buffer[explore] == 'U' + || buffer[explore] == 'u') { + explore--; + prefix = true; + } else if (buffer[explore] == 'R') { + if (israw) + break; + explore--; + israw = true; } else { break; } } - israw = (buffer[explore] == 'R'); + // Check the R (with possible prefix) isn't just part of an identifier: + if (israw && explore >= 0 + && (isalnum(buffer[explore]) || buffer[explore] == '_')) { + israw = false; + } } if (israw) { diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index a22e4bf48f..b4c2579c5c 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -634,6 +634,7 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) if (generateManifest) { manifest = escapeFilePath(manifest); QString manifest_bak = escapeFilePath(target + "_manifest.bak"); + project->values("QMAKE_CLEAN") << manifest_bak; t << "\n\tif not exist $(DESTDIR_TARGET) if exist " << manifest << " del " << manifest; t << "\n\tif exist " << manifest << " copy /Y " << manifest << ' ' << manifest_bak; diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp index 1744304c67..8bbde9f8c0 100644 --- a/qmake/library/proitems.cpp +++ b/qmake/library/proitems.cpp @@ -74,6 +74,11 @@ ProString::ProString(const QString &str) : { } +ProString::ProString(const QStringRef &str) : + m_string(*str.string()), m_offset(str.position()), m_length(str.size()), m_file(0), m_hash(0x80000000) +{ +} + ProString::ProString(const char *str, DoPreHashing) : m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0) { @@ -336,7 +341,7 @@ ProString ProString::trimmed() const QTextStream &operator<<(QTextStream &t, const ProString &str) { - t << str.toQString(); // XXX optimize ... somehow + t << str.toQStringRef(); return t; } diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index c58b017857..1d7ebed3aa 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -68,6 +68,7 @@ public: ProString(); ProString(const ProString &other); PROITEM_EXPLICIT ProString(const QString &str); + PROITEM_EXPLICIT ProString(const QStringRef &str); PROITEM_EXPLICIT ProString(const char *str); ProString(const QString &str, int offset, int length); void setValue(const QString &str); @@ -94,6 +95,7 @@ public: bool operator==(const ProString &other) const { return toQStringRef() == other.toQStringRef(); } bool operator==(const QString &other) const { return toQStringRef() == other; } + bool operator==(const QStringRef &other) const { return toQStringRef() == other; } bool operator==(QLatin1String other) const { return toQStringRef() == other; } bool operator==(const char *other) const { return toQStringRef() == QLatin1String(other); } bool operator!=(const ProString &other) const { return !(*this == other); } @@ -204,14 +206,14 @@ Q_DECLARE_TYPEINFO(ProKey, Q_MOVABLE_TYPE); uint qHash(const ProString &str); QString operator+(const ProString &one, const ProString &two); inline QString operator+(const ProString &one, const QString &two) - { return one + ProString(two); } + { return one.toQStringRef() + two; } inline QString operator+(const QString &one, const ProString &two) - { return ProString(one) + two; } + { return one + two.toQStringRef(); } inline QString operator+(const ProString &one, const char *two) - { QString ret = one.toQStringRef() + QLatin1String(two); ret.detach(); return ret; } + { return one.toQStringRef() + QLatin1String(two); } inline QString operator+(const char *one, const ProString &two) - { QString ret = QLatin1String(one) + two.toQStringRef(); ret.detach(); return ret; } + { return QLatin1String(one) + two.toQStringRef(); } inline QString operator+(const ProString &one, QChar two) { return one.toQStringRef() + two; } inline QString operator+(QChar one, const ProString &two) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 120e96ccc3..759bff314e 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -589,8 +589,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( if (regexp) { QRegExp sepRx(sep); for (const ProString &str : strings) { - const QString &rstr = str.toQString(m_tmp1).section(sepRx, beg, end); - ret << (rstr.isSharedWith(m_tmp1) ? str : ProString(rstr).setSource(str)); + const QString &rstr = str.toQString(m_tmp[m_toggle ^= 1]).section(sepRx, beg, end); + ret << (rstr.isSharedWith(m_tmp[m_toggle]) ? str : ProString(rstr).setSource(str)); } } else { for (const ProString &str : strings) { @@ -735,9 +735,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( const QString &sep = (args.count() == 2) ? args.at(1).toQString(m_tmp1) : statics.field_sep; const auto vars = values(map(args.at(0))); for (const ProString &var : vars) { - const auto splits = var.toQString(m_tmp2).split(sep); - for (const QString &splt : splits) - ret << (splt.isSharedWith(m_tmp2) ? var : ProString(splt).setSource(var)); + const auto splits = var.toQStringRef().split(sep); + for (const auto &splt : splits) + ret << ProString(splt).setSource(var); } } break; @@ -823,7 +823,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( if (args.count() < 1 || args.count() > 2) { evalError(fL1S("cat(file, singleline=true) requires one or two arguments.")); } else { - const QString &file = args.at(0).toQString(m_tmp1); + QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1))); + fn.detach(); bool blob = false; bool lines = false; @@ -837,7 +838,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( lines = true; } - QFile qfile(resolvePath(m_option->expandEnvVars(file))); + QFile qfile(fn); if (qfile.open(QIODevice::ReadOnly)) { QTextStream stream(&qfile); if (blob) { @@ -888,12 +889,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( evalError(fL1S("find(var, str) requires two arguments.")); } else { QRegExp regx(args.at(1).toQString()); - int t = 0; const auto vals = values(map(args.at(0))); for (const ProString &val : vals) { - if (regx.indexIn(val.toQString(m_tmp[t])) != -1) + if (regx.indexIn(val.toQString(m_tmp[m_toggle ^= 1])) != -1) ret += val; - t ^= 1; } } break; @@ -914,7 +913,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( lines = true; } int exitCode; - QByteArray bytes = getCommandOutput(args.at(0).toQString(m_tmp2), &exitCode); + QByteArray bytes = getCommandOutput(args.at(0).toQString(), &exitCode); if (args.count() > 2 && !args.at(2).isEmpty()) { m_valuemapStack.top()[args.at(2).toKey()] = ProStringList(ProString(QString::number(exitCode))); @@ -1116,7 +1115,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( QString rstr = val.toQString(m_tmp1); QString copy = rstr; // Force a detach on modify rstr.replace(before, after); - ret << (rstr.isSharedWith(m_tmp1) ? val : ProString(rstr).setSource(val)); + ret << (rstr.isSharedWith(m_tmp1) + ? val + : rstr.isSharedWith(m_tmp2) + ? args.at(2) + : ProString(rstr).setSource(val)); } } break; @@ -1391,12 +1394,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( copy.detach(); regx.setPattern(copy); } - int t = 0; const auto strings = vars.value(map(args.at(1))); for (const ProString &s : strings) { - if ((!regx.isEmpty() && regx.exactMatch(s.toQString(m_tmp[t]))) || s == qry) + if ((!regx.isEmpty() && regx.exactMatch(s.toQString(m_tmp[m_toggle ^= 1]))) || s == qry) return ReturnTrue; - t ^= 1; } } return ReturnFalse; @@ -1461,12 +1462,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } const ProStringList &l = values(map(args.at(0))); if (args.count() == 2) { - int t = 0; for (int i = 0; i < l.size(); ++i) { const ProString &val = l[i]; - if ((!regx.isEmpty() && regx.exactMatch(val.toQString(m_tmp[t]))) || val == qry) + if ((!regx.isEmpty() && regx.exactMatch(val.toQString(m_tmp[m_toggle ^= 1]))) || val == qry) return ReturnTrue; - t ^= 1; } } else { const auto mutuals = args.at(2).toQStringRef().split(QLatin1Char('|')); @@ -1475,7 +1474,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( for (int mut = 0; mut < mutuals.count(); mut++) { if (val.toQStringRef() == mutuals[mut].trimmed()) { return returnBool((!regx.isEmpty() - && regx.exactMatch(val.toQString(m_tmp2))) + && regx.exactMatch(val.toQString(m_tmp[m_toggle ^= 1]))) || val == qry); } } @@ -1712,7 +1711,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( #if QT_CONFIG(process) QProcess proc; proc.setProcessChannelMode(QProcess::ForwardedChannels); - runProcess(&proc, args.at(0).toQString(m_tmp2)); + runProcess(&proc, args.at(0).toQString()); return returnBool(proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0); #else int ec = system((QLatin1String("cd ") @@ -1749,8 +1748,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnTrue; int slsh = file.lastIndexOf(QLatin1Char('/')); QString fn = file.mid(slsh+1); + fn.detach(); if (fn.contains(QLatin1Char('*')) || fn.contains(QLatin1Char('?'))) { QString dirstr = file.left(slsh+1); + dirstr.detach(); if (!QDir(dirstr).entryList(QStringList(fn)).isEmpty()) return ReturnTrue; } @@ -1763,7 +1764,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnFalse; } #ifdef PROEVALUATOR_FULL - const QString &fn = resolvePath(args.at(0).toQString(m_tmp1)); + QString fn = resolvePath(args.at(0).toQString(m_tmp1)); + fn.detach(); if (!QDir::current().mkpath(fn)) { evalError(fL1S("Cannot create directory %1.").arg(QDir::toNativeSeparators(fn))); return ReturnFalse; @@ -1786,13 +1788,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( if (args.count() >= 3) { const auto opts = split_value_list(args.at(2).toQStringRef()); for (const ProString &opt : opts) { - opt.toQString(m_tmp3); - if (m_tmp3 == QLatin1String("append")) { + if (opt == QLatin1String("append")) { mode = QIODevice::Append; - } else if (m_tmp3 == QLatin1String("exe")) { + } else if (opt == QLatin1String("exe")) { exe = true; } else { - evalError(fL1S("write_file(): invalid flag %1.").arg(m_tmp3)); + evalError(fL1S("write_file(): invalid flag %1.").arg(opt.toQString(m_tmp3))); return ReturnFalse; } } @@ -1830,21 +1831,20 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( if (args.count() >= 2) { const auto opts = split_value_list(args.at(1).toQStringRef()); for (const ProString &opt : opts) { - opt.toQString(m_tmp3); - if (m_tmp3 == QLatin1String("transient")) { + if (opt == QLatin1String("transient")) { persist = false; - } else if (m_tmp3 == QLatin1String("super")) { + } else if (opt == QLatin1String("super")) { target = TargetSuper; - } else if (m_tmp3 == QLatin1String("stash")) { + } else if (opt == QLatin1String("stash")) { target = TargetStash; - } else if (m_tmp3 == QLatin1String("set")) { + } else if (opt == QLatin1String("set")) { mode = CacheSet; - } else if (m_tmp3 == QLatin1String("add")) { + } else if (opt == QLatin1String("add")) { mode = CacheAdd; - } else if (m_tmp3 == QLatin1String("sub")) { + } else if (opt == QLatin1String("sub")) { mode = CacheSub; } else { - evalError(fL1S("cache(): invalid flag %1.").arg(m_tmp3)); + evalError(fL1S("cache(): invalid flag %1.").arg(opt.toQString(m_tmp3))); return ReturnFalse; } } diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index a87155cdef..6e6c72de59 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -226,6 +226,7 @@ QMakeEvaluator::QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser, QMakeV m_skipLevel = 0; #endif m_listCount = 0; + m_toggle = 0; m_valuemapStack.push(ProValueMap()); m_valuemapInited = false; } @@ -775,7 +776,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( } infinite = true; } else { - const QString &itl = it_list.toQString(m_tmp1); + const QStringRef &itl = it_list.toQStringRef(); int dotdot = itl.indexOf(statics.strDotDot); if (dotdot != -1) { bool ok; @@ -872,13 +873,13 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable( ProStringList varVal; if (expandVariableReferences(tokPtr, sizeHint, &varVal, true) == ReturnError) return ReturnError; - const QString &val = varVal.at(0).toQString(m_tmp1); + const QStringRef &val = varVal.at(0).toQStringRef(); if (val.length() < 4 || val.at(0) != QLatin1Char('s')) { evalError(fL1S("The ~= operator can handle only the s/// function.")); return ReturnTrue; } QChar sep = val.at(1); - QStringList func = val.split(sep); + auto func = val.split(sep); if (func.count() < 3 || func.count() > 4) { evalError(fL1S("The s/// function expects 3 or 4 arguments.")); return ReturnTrue; @@ -890,8 +891,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable( case_sense = func[3].indexOf(QLatin1Char('i')) == -1; quote = func[3].indexOf(QLatin1Char('q')) != -1; } - QString pattern = func[1]; - QString replace = func[2]; + QString pattern = func[1].toString(); + QString replace = func[2].toString(); if (quote) pattern = QRegExp::escape(pattern); @@ -972,11 +973,9 @@ void QMakeEvaluator::setTemplate() values.erase(values.begin() + 1, values.end()); } if (!m_option->user_template_prefix.isEmpty()) { - QString val = values.first().toQString(m_tmp1); - if (!val.startsWith(m_option->user_template_prefix)) { - val.prepend(m_option->user_template_prefix); - values = ProStringList(ProString(val)); - } + ProString val = values.first(); + if (!val.startsWith(m_option->user_template_prefix)) + values = ProStringList(ProString(m_option->user_template_prefix + val)); } } @@ -1518,7 +1517,7 @@ void QMakeEvaluator::updateFeaturePaths() feature_roots += m_option->getPathListEnv(QLatin1String("QMAKEFEATURES")); feature_roots += m_qmakefeatures; feature_roots += m_option->splitPathList( - m_option->propertyValue(ProKey("QMAKEFEATURES")).toQString(m_mtmp)); + m_option->propertyValue(ProKey("QMAKEFEATURES")).toQString()); QStringList feature_bases; if (!m_buildRoot.isEmpty()) { @@ -1629,21 +1628,17 @@ bool QMakeEvaluator::isActiveConfig(const QStringRef &config, bool regex) return m_hostBuild; if (regex && (config.contains(QLatin1Char('*')) || config.contains(QLatin1Char('?')))) { - QString cfg = config.toString(); - cfg.detach(); // Keep m_tmp out of QRegExp's cache - QRegExp re(cfg, Qt::CaseSensitive, QRegExp::Wildcard); + QRegExp re(config.toString(), Qt::CaseSensitive, QRegExp::Wildcard); // mkspecs if (re.exactMatch(m_qmakespecName)) return true; // CONFIG variable - int t = 0; const auto configValues = values(statics.strCONFIG); for (const ProString &configValue : configValues) { - if (re.exactMatch(configValue.toQString(m_tmp[t]))) + if (re.exactMatch(configValue.toQString(m_tmp[m_toggle ^= 1]))) return true; - t ^= 1; } } else { // mkspecs @@ -1746,7 +1741,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBoolFunction( if (ret.at(0) == statics.strtrue) return ReturnTrue; bool ok; - int val = ret.at(0).toQString(m_tmp1).toInt(&ok); + int val = ret.at(0).toInt(&ok); if (ok) { if (val) return ReturnTrue; diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index fcac0388c7..7318664d46 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -286,6 +286,7 @@ public: QString m_outputDir; int m_listCount; + int m_toggle; bool m_valuemapInited; bool m_hostBuild; QString m_qmakespec; @@ -305,7 +306,6 @@ public: ProStringList m_returnValue; ProValueMapStack m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii. QString m_tmp1, m_tmp2, m_tmp3, m_tmp[2]; // Temporaries for efficient toQString - mutable QString m_mtmp; QMakeGlobals *m_option; QMakeParser *m_parser; diff --git a/qmake/library/qmakeevaluator_p.h b/qmake/library/qmakeevaluator_p.h index 42aaef70c3..f386a49108 100644 --- a/qmake/library/qmakeevaluator_p.h +++ b/qmake/library/qmakeevaluator_p.h @@ -43,7 +43,7 @@ r == ReturnNext ? "next" : \ r == ReturnReturn ? "return" : \ "<invalid>") -# define dbgKey(s) qPrintable(s.toString().toQString()) +# define dbgKey(s) s.toString().toQStringRef().toLocal8Bit().constData() # define dbgStr(s) qPrintable(formatValue(s, true)) # define dbgStrList(s) qPrintable(formatValueList(s)) # define dbgSepStrList(s) qPrintable(formatValueList(s, true)) |