summaryrefslogtreecommitdiffstats
path: root/qmake/library
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/library')
-rw-r--r--qmake/library/qmakebuiltins.cpp5
-rw-r--r--qmake/library/qmakeevaluator.cpp73
-rw-r--r--qmake/library/qmakeevaluator_p.h1
-rw-r--r--qmake/library/qmakeglobals.cpp1
-rw-r--r--qmake/library/qmakeparser.cpp29
5 files changed, 61 insertions, 48 deletions
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index f46d66ba89..0dedd64e6e 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -467,8 +467,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
QString tmp = args.at(0).toQString(m_tmp1);
for (int i = 1; i < args.count(); ++i)
tmp = tmp.arg(args.at(i).toQString(m_tmp2));
- // Note: this depends on split_value_list() making a deep copy
- ret = split_value_list(tmp);
+ ret << ProString(tmp);
}
break;
case E_FORMAT_NUMBER:
@@ -561,7 +560,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
src = s;
break;
}
- ret = split_value_list(before + var.join(glue) + after, src);
+ ret << ProString(before + var.join(glue) + after).setSource(src);
}
}
break;
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 8b6a0f8598..4f4e5854f1 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -126,6 +126,7 @@ void QMakeEvaluator::initStatics()
statics.strforever = QLatin1String("forever");
statics.strhost_build = QLatin1String("host_build");
statics.strTEMPLATE = ProKey("TEMPLATE");
+ statics.strQMAKE_PLATFORM = ProKey("QMAKE_PLATFORM");
#ifdef PROEVALUATOR_FULL
statics.strREQUIRES = ProKey("REQUIRES");
#endif
@@ -263,48 +264,55 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil
{
QString build;
ProStringList ret;
- QStack<char> quote;
-
- const ushort SPACE = ' ';
- const ushort LPAREN = '(';
- const ushort RPAREN = ')';
- const ushort SINGLEQUOTE = '\'';
- const ushort DOUBLEQUOTE = '"';
- const ushort BACKSLASH = '\\';
if (!source)
source = currentProFile();
- ushort unicode;
const QChar *vals_data = vals.data();
const int vals_len = vals.length();
- int parens = 0;
+ ushort quote = 0;
+ bool hadWord = false;
for (int x = 0; x < vals_len; x++) {
- unicode = vals_data[x].unicode();
- if (x != (int)vals_len-1 && unicode == BACKSLASH &&
- (vals_data[x+1].unicode() == SINGLEQUOTE || vals_data[x+1].unicode() == DOUBLEQUOTE)) {
- build += vals_data[x++]; //get that 'escape'
- } else if (!quote.isEmpty() && unicode == quote.top()) {
- quote.pop();
- } else if (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE) {
- quote.push(unicode);
- } else if (unicode == RPAREN) {
- --parens;
- } else if (unicode == LPAREN) {
- ++parens;
+ ushort unicode = vals_data[x].unicode();
+ if (unicode == quote) {
+ quote = 0;
+ continue;
}
-
- if (!parens && quote.isEmpty() && vals_data[x] == SPACE) {
- ret << ProString(build).setSource(source);
- build.clear();
- } else {
- build += vals_data[x];
+ switch (unicode) {
+ case '"':
+ case '\'':
+ quote = unicode;
+ hadWord = true;
+ continue;
+ case ' ':
+ case '\t':
+ if (!quote) {
+ if (hadWord) {
+ ret << ProString(build).setSource(source);
+ build.clear();
+ hadWord = false;
+ }
+ continue;
+ }
+ build += QChar(unicode);
+ break;
+ case '\\':
+ if (x + 1 != vals_len) {
+ ushort next = vals_data[++x].unicode();
+ if (next == '\'' || next == '"' || next == '\\')
+ unicode = next;
+ else
+ --x;
+ }
+ // fallthrough
+ default:
+ hadWord = true;
+ build += QChar(unicode);
+ break;
}
}
- if (!build.isEmpty())
+ if (hadWord)
ret << ProString(build).setSource(source);
- if (parens)
- deprecationWarning(fL1S("Unmatched parentheses are deprecated."));
return ret;
}
@@ -924,6 +932,8 @@ void QMakeEvaluator::visitProVariable(
if (varName == statics.strTEMPLATE)
setTemplate();
+ else if (varName == statics.strQMAKE_PLATFORM)
+ updateFeaturePaths();
#ifdef PROEVALUATOR_FULL
else if (varName == statics.strREQUIRES)
checkRequirements(values(varName));
@@ -1217,7 +1227,6 @@ bool QMakeEvaluator::loadSpec()
}
if (!loadSpecInternal())
return false;
- updateFeaturePaths(); // The spec extends the feature search path, so rebuild the cache.
if (!m_conffile.isEmpty()
&& evaluateFile(m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue) {
return false;
diff --git a/qmake/library/qmakeevaluator_p.h b/qmake/library/qmakeevaluator_p.h
index 9830496424..935f112f52 100644
--- a/qmake/library/qmakeevaluator_p.h
+++ b/qmake/library/qmakeevaluator_p.h
@@ -89,6 +89,7 @@ struct QMakeStatics {
QString strforever;
QString strhost_build;
ProKey strTEMPLATE;
+ ProKey strQMAKE_PLATFORM;
#ifdef PROEVALUATOR_FULL
ProKey strREQUIRES;
#endif
diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp
index ac9a0856ff..42bb85bb02 100644
--- a/qmake/library/qmakeglobals.cpp
+++ b/qmake/library/qmakeglobals.cpp
@@ -115,7 +115,6 @@ QMakeGlobals::QMakeGlobals()
dirlist_sep = QLatin1Char(':');
dir_sep = QLatin1Char('/');
#endif
- qmakespec = getEnv(QLatin1String("QMAKESPEC"));
}
QMakeGlobals::~QMakeGlobals()
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index f32267cf59..557a779717 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -1024,7 +1024,6 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
m_tmp.setRawData((QChar *)uc + 4, nlen);
const QString *defName;
ushort defType;
- uchar nest;
if (m_tmp == statics.strfor) {
if (m_invert || m_operator == OrOperator) {
// '|' could actually work reasonably, but qmake does nonsense here.
@@ -1101,13 +1100,20 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
parseError(fL1S("%1(function) requires one literal argument.").arg(*defName));
return;
} else if (m_tmp == statics.strreturn) {
- if (argc > 1) {
- parseError(fL1S("return() requires zero or one argument."));
- bogusTest(tokPtr);
- return;
+ if (m_blockstack.top().nest & NestFunction) {
+ if (argc > 1) {
+ parseError(fL1S("return() requires zero or one argument."));
+ bogusTest(tokPtr);
+ return;
+ }
+ } else {
+ if (*uce != TokFuncTerminator) {
+ parseError(fL1S("Top-level return() requires zero arguments."));
+ bogusTest(tokPtr);
+ return;
+ }
}
defType = TokReturn;
- nest = NestFunction;
goto ctrlstm2;
} else if (m_tmp == statics.strnext) {
defType = TokNext;
@@ -1120,15 +1126,14 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
bogusTest(tokPtr);
return;
}
- nest = NestLoop;
- ctrlstm2:
- if (m_invert) {
- parseError(fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
+ if (!(m_blockstack.top().nest & NestLoop)) {
+ parseError(fL1S("Unexpected %1().").arg(m_tmp));
bogusTest(tokPtr);
return;
}
- if (!(m_blockstack.top().nest & nest)) {
- parseError(fL1S("Unexpected %1().").arg(m_tmp));
+ ctrlstm2:
+ if (m_invert) {
+ parseError(fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
bogusTest(tokPtr);
return;
}