summaryrefslogtreecommitdiffstats
path: root/qmake/library
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2016-05-13 15:32:50 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2016-05-24 12:38:59 +0000
commitad17a35853fe21a93fc34f7b2d9262c5ac992b29 (patch)
tree668279d86081849c0cfd01933ebf687694d93f46 /qmake/library
parent11d957d04381c7162dd5621c61f9963580ec7041 (diff)
make QMakeParser take a QStringRef as input
the only place where this actually saves a deep copy is the evaluation of if(), but as a side effect the parser is now able to deal with not null-terminated strings, which is kinda nice as well. Change-Id: Ib6d08617aa79d2f9eaecd4906d4d548f34bf377d Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'qmake/library')
-rw-r--r--qmake/library/qmakebuiltins.cpp5
-rw-r--r--qmake/library/qmakeevaluator.cpp6
-rw-r--r--qmake/library/qmakeevaluator.h2
-rw-r--r--qmake/library/qmakeparser.cpp36
-rw-r--r--qmake/library/qmakeparser.h6
5 files changed, 29 insertions, 26 deletions
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 9d35a31ffc..c5ea26977e 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -1210,7 +1210,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnFalse; // Another qmake breakage
case T_EVAL: {
VisitReturn ret = ReturnFalse;
- ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep),
+ QString contents = args.join(statics.field_sep);
+ ProFile *pro = m_parser->parsedProBlock(QStringRef(&contents),
m_current.pro->fileName(), m_current.line);
if (m_cumulative || pro->isOk()) {
m_locationStack.push(m_current);
@@ -1226,7 +1227,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
evalError(fL1S("if(condition) requires one argument."));
return ReturnFalse;
}
- return returnBool(evaluateConditional(args.at(0).toQString(),
+ return returnBool(evaluateConditional(args.at(0).toQStringRef(),
m_current.pro->fileName(), m_current.line));
}
case T_CONFIG: {
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 4ce7b0c4b8..6182e4bf3e 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -1277,7 +1277,7 @@ void QMakeEvaluator::setupProject()
void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
{
if (!cmds.isEmpty()) {
- ProFile *pro = m_parser->parsedProBlock(cmds, where, -1);
+ ProFile *pro = m_parser->parsedProBlock(QStringRef(&cmds), where, -1);
if (pro->isOk()) {
m_locationStack.push(m_current);
visitProBlock(pro, pro->tokPtr());
@@ -1760,7 +1760,7 @@ ProStringList QMakeEvaluator::evaluateExpandFunction(
return ProStringList();
}
-bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &where, int line)
+bool QMakeEvaluator::evaluateConditional(const QStringRef &cond, const QString &where, int line)
{
bool ret = false;
ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar);
@@ -1778,7 +1778,7 @@ void QMakeEvaluator::checkRequirements(const ProStringList &deps)
{
ProStringList &failed = valuesRef(ProKey("QMAKE_FAILED_REQUIREMENTS"));
for (const ProString &dep : deps)
- if (!evaluateConditional(dep.toQString(), m_current.pro->fileName(), m_current.line))
+ if (!evaluateConditional(dep.toQStringRef(), m_current.pro->fileName(), m_current.line))
failed << dep;
}
#endif
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index 8a87108c91..48dd631b19 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -216,7 +216,7 @@ public:
ProStringList evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args);
VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args);
- bool evaluateConditional(const QString &cond, const QString &where, int line = -1);
+ bool evaluateConditional(const QStringRef &cond, const QString &where, int line = -1);
#ifdef PROEVALUATOR_FULL
void checkRequirements(const ProStringList &deps);
#endif
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index 2a48103147..90bc64bd2b 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -224,7 +224,7 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
}
ProFile *QMakeParser::parsedProBlock(
- const QString &contents, const QString &name, int line, SubGrammar grammar)
+ const QStringRef &contents, const QString &name, int line, SubGrammar grammar)
{
ProFile *pro = new ProFile(name);
read(pro, contents, line, grammar);
@@ -247,7 +247,7 @@ bool QMakeParser::read(ProFile *pro, ParseFlags flags)
fL1S("Cannot read %1: %2").arg(pro->fileName(), errStr));
return false;
}
- read(pro, content, 1, FullGrammar);
+ read(pro, QStringRef(&content), 1, FullGrammar);
return true;
}
@@ -289,7 +289,7 @@ void QMakeParser::finalizeHashStr(ushort *buf, uint len)
buf[-2] = (ushort)(hash >> 16);
}
-void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar)
+void QMakeParser::read(ProFile *pro, const QStringRef &in, int line, SubGrammar grammar)
{
m_proFile = pro;
m_lineNo = line;
@@ -334,8 +334,8 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
QStack<ParseCtx> xprStack;
xprStack.reserve(10);
- // We rely on QStrings being null-terminated, so don't maintain a global end pointer.
const ushort *cur = (const ushort *)in.unicode();
+ const ushort *inend = cur + in.length();
m_canElse = false;
freshLine:
m_state = StNew;
@@ -418,7 +418,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
int indent;
if (context == CtxPureValue) {
- end = (const ushort *)in.unicode() + in.length();
+ end = inend;
cptr = 0;
lineCont = false;
indent = 0; // just gcc being stupid
@@ -430,24 +430,30 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
// First, skip leading whitespace
for (indent = 0; ; ++cur, ++indent) {
+ if (cur == inend) {
+ cur = 0;
+ goto flushLine;
+ }
c = *cur;
if (c == '\n') {
++cur;
goto flushLine;
- } else if (!c) {
- cur = 0;
- goto flushLine;
- } else if (c != ' ' && c != '\t' && c != '\r') {
- break;
}
+ if (c != ' ' && c != '\t' && c != '\r')
+ break;
}
// Then strip comments. Yep - no escaping is possible.
for (cptr = cur;; ++cptr) {
+ if (cptr == inend) {
+ end = cptr;
+ break;
+ }
c = *cptr;
if (c == '#') {
- for (end = cptr; (c = *++cptr);) {
- if (c == '\n') {
+ end = cptr;
+ while (++cptr < inend) {
+ if (*cptr == '\n') {
++cptr;
break;
}
@@ -460,10 +466,6 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
}
break;
}
- if (!c) {
- end = cptr;
- break;
- }
if (c == '\n') {
end = cptr++;
break;
@@ -1215,7 +1217,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
bool QMakeParser::resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr,
ushort **buf, QString *xprBuff,
ushort **tokPtr, QString *tokBuff,
- const ushort *cur, const QString &in)
+ const ushort *cur, const QStringRef &in)
{
QString out;
m_tmp.setRawData((const QChar *)xprPtr, tlen);
diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h
index f78b3215bb..f8ff2fc3cc 100644
--- a/qmake/library/qmakeparser.h
+++ b/qmake/library/qmakeparser.h
@@ -87,7 +87,7 @@ public:
enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar };
// fileName is expected to be absolute and cleanPath()ed.
ProFile *parsedProFile(const QString &fileName, ParseFlags flags = ParseDefault);
- ProFile *parsedProBlock(const QString &contents, const QString &name, int line = 0,
+ ProFile *parsedProBlock(const QStringRef &contents, const QString &name, int line = 0,
SubGrammar grammar = FullGrammar);
void discardFileFromCache(const QString &fileName);
@@ -130,7 +130,7 @@ private:
};
bool read(ProFile *pro, ParseFlags flags);
- void read(ProFile *pro, const QString &content, int line, SubGrammar grammar);
+ void read(ProFile *pro, const QStringRef &content, int line, SubGrammar grammar);
ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok);
ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len);
@@ -141,7 +141,7 @@ private:
ALWAYS_INLINE bool resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr,
ushort **buf, QString *xprBuff,
ushort **tokPtr, QString *tokBuff,
- const ushort *cur, const QString &in);
+ const ushort *cur, const QStringRef &in);
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
void warnOperator(const char *msg);