forked from qt-creator/qt-creator
resolve some variables already at parse time
they are "compiler defines", with no dependency on the evaluation context. Change-Id: I25bf006347ecd2edb501a344820e2ac11ff389e9 Reviewed-by: Daniel Teske <daniel.teske@nokia.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
This commit is contained in:
@@ -102,10 +102,9 @@ void QMakeEvaluator::initStatics()
|
|||||||
initFunctionStatics();
|
initFunctionStatics();
|
||||||
|
|
||||||
static const char * const names[] = {
|
static const char * const names[] = {
|
||||||
"LITERAL_DOLLAR", "LITERAL_HASH", "LITERAL_WHITESPACE",
|
|
||||||
"DIRLIST_SEPARATOR", "DIR_SEPARATOR",
|
"DIRLIST_SEPARATOR", "DIR_SEPARATOR",
|
||||||
"OUT_PWD", "PWD",
|
"OUT_PWD", "PWD",
|
||||||
"_FILE_", "_LINE_", "_PRO_FILE_", "_PRO_FILE_PWD_",
|
"_PRO_FILE_", "_PRO_FILE_PWD_",
|
||||||
"QMAKE_HOST.arch", "QMAKE_HOST.name", "QMAKE_HOST.os",
|
"QMAKE_HOST.arch", "QMAKE_HOST.name", "QMAKE_HOST.os",
|
||||||
"QMAKE_HOST.version", "QMAKE_HOST.version_string",
|
"QMAKE_HOST.version", "QMAKE_HOST.version_string",
|
||||||
"_DATE_", "_QMAKE_CACHE_"
|
"_DATE_", "_QMAKE_CACHE_"
|
||||||
@@ -1755,9 +1754,6 @@ ProStringList QMakeEvaluator::values(const ProString &variableName) const
|
|||||||
int vlidx = *vli;
|
int vlidx = *vli;
|
||||||
QString ret;
|
QString ret;
|
||||||
switch ((VarName)vlidx) {
|
switch ((VarName)vlidx) {
|
||||||
case V_LITERAL_WHITESPACE: ret = QLatin1String("\t"); break;
|
|
||||||
case V_LITERAL_DOLLAR: ret = QLatin1String("$"); break;
|
|
||||||
case V_LITERAL_HASH: ret = QLatin1String("#"); break;
|
|
||||||
case V_OUT_PWD: // the outgoing dir (shadow of _PRO_FILE_PWD_)
|
case V_OUT_PWD: // the outgoing dir (shadow of _PRO_FILE_PWD_)
|
||||||
ret = m_outputDir;
|
ret = m_outputDir;
|
||||||
break;
|
break;
|
||||||
@@ -1771,12 +1767,6 @@ ProStringList QMakeEvaluator::values(const ProString &variableName) const
|
|||||||
case V_DIRLIST_SEPARATOR:
|
case V_DIRLIST_SEPARATOR:
|
||||||
ret = m_option->dirlist_sep;
|
ret = m_option->dirlist_sep;
|
||||||
break;
|
break;
|
||||||
case V__LINE_: // currently executed line number
|
|
||||||
ret = QString::number(m_current.line);
|
|
||||||
break;
|
|
||||||
case V__FILE_: // currently executed file
|
|
||||||
ret = m_current.pro->fileName();
|
|
||||||
break;
|
|
||||||
case V__DATE_: //current date/time
|
case V__DATE_: //current date/time
|
||||||
ret = QDateTime::currentDateTime().toString();
|
ret = QDateTime::currentDateTime().toString();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -203,10 +203,9 @@ public:
|
|||||||
QMakeHandler *m_handler;
|
QMakeHandler *m_handler;
|
||||||
|
|
||||||
enum VarName {
|
enum VarName {
|
||||||
V_LITERAL_DOLLAR, V_LITERAL_HASH, V_LITERAL_WHITESPACE,
|
|
||||||
V_DIRLIST_SEPARATOR, V_DIR_SEPARATOR,
|
V_DIRLIST_SEPARATOR, V_DIR_SEPARATOR,
|
||||||
V_OUT_PWD, V_PWD,
|
V_OUT_PWD, V_PWD,
|
||||||
V__FILE_, V__LINE_, V__PRO_FILE_, V__PRO_FILE_PWD_,
|
V__PRO_FILE_, V__PRO_FILE_PWD_,
|
||||||
V_QMAKE_HOST_arch, V_QMAKE_HOST_name, V_QMAKE_HOST_os,
|
V_QMAKE_HOST_arch, V_QMAKE_HOST_name, V_QMAKE_HOST_os,
|
||||||
V_QMAKE_HOST_version, V_QMAKE_HOST_version_string,
|
V_QMAKE_HOST_version, V_QMAKE_HOST_version_string,
|
||||||
V__DATE_, V__QMAKE_CACHE_
|
V__DATE_, V__QMAKE_CACHE_
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ static struct {
|
|||||||
QString strfor;
|
QString strfor;
|
||||||
QString strdefineTest;
|
QString strdefineTest;
|
||||||
QString strdefineReplace;
|
QString strdefineReplace;
|
||||||
|
QString strLINE;
|
||||||
|
QString strFILE;
|
||||||
|
QString strLITERAL_HASH;
|
||||||
|
QString strLITERAL_DOLLAR;
|
||||||
|
QString strLITERAL_WHITESPACE;
|
||||||
} statics;
|
} statics;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -111,6 +116,11 @@ void QMakeParser::initialize()
|
|||||||
statics.strfor = QLatin1String("for");
|
statics.strfor = QLatin1String("for");
|
||||||
statics.strdefineTest = QLatin1String("defineTest");
|
statics.strdefineTest = QLatin1String("defineTest");
|
||||||
statics.strdefineReplace = QLatin1String("defineReplace");
|
statics.strdefineReplace = QLatin1String("defineReplace");
|
||||||
|
statics.strLINE = QLatin1String("_LINE_");
|
||||||
|
statics.strFILE = QLatin1String("_FILE_");
|
||||||
|
statics.strLITERAL_HASH = QLatin1String("LITERAL_HASH");
|
||||||
|
statics.strLITERAL_DOLLAR = QLatin1String("LITERAL_DOLLAR");
|
||||||
|
statics.strLITERAL_WHITESPACE = QLatin1String("LITERAL_WHITESPACE");
|
||||||
}
|
}
|
||||||
|
|
||||||
QMakeParser::QMakeParser(ProFileCache *cache, QMakeParserHandler *handler)
|
QMakeParser::QMakeParser(ProFileCache *cache, QMakeParserHandler *handler)
|
||||||
@@ -268,7 +278,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
|||||||
// Expression precompiler buffer.
|
// Expression precompiler buffer.
|
||||||
QString xprBuff;
|
QString xprBuff;
|
||||||
xprBuff.reserve(tokBuff.capacity()); // Excessive, but simple
|
xprBuff.reserve(tokBuff.capacity()); // Excessive, but simple
|
||||||
ushort * const buf = (ushort *)xprBuff.constData();
|
ushort *buf = (ushort *)xprBuff.constData();
|
||||||
|
|
||||||
// Parser state
|
// Parser state
|
||||||
m_blockstack.clear();
|
m_blockstack.clear();
|
||||||
@@ -480,14 +490,18 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
|||||||
}
|
}
|
||||||
tlen = ptr - xprPtr;
|
tlen = ptr - xprPtr;
|
||||||
if (rtok == TokVariable) {
|
if (rtok == TokVariable) {
|
||||||
xprPtr[-4] = tok;
|
if (!resolveVariable(xprPtr, tlen, needSep, &ptr,
|
||||||
uint hash = ProString::hash((const QChar *)xprPtr, tlen);
|
&buf, &xprBuff, &tokPtr, &tokBuff, cur, in)) {
|
||||||
xprPtr[-3] = (ushort)hash;
|
xprPtr[-4] = tok;
|
||||||
xprPtr[-2] = (ushort)(hash >> 16);
|
uint hash = ProString::hash((const QChar *)xprPtr, tlen);
|
||||||
|
xprPtr[-3] = (ushort)hash;
|
||||||
|
xprPtr[-2] = (ushort)(hash >> 16);
|
||||||
|
xprPtr[-1] = tlen;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
xprPtr[-2] = tok;
|
xprPtr[-2] = tok;
|
||||||
|
xprPtr[-1] = tlen;
|
||||||
}
|
}
|
||||||
xprPtr[-1] = tlen;
|
|
||||||
if ((tok & TokMask) == TokFuncName) {
|
if ((tok & TokMask) == TokFuncName) {
|
||||||
cur++;
|
cur++;
|
||||||
funcCall:
|
funcCall:
|
||||||
@@ -1017,6 +1031,57 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
|
|||||||
putBlock(tokPtr, uc, ptr - uc);
|
putBlock(tokPtr, uc, ptr - uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
QString out;
|
||||||
|
m_tmp.setRawData((const QChar *)xprPtr, tlen);
|
||||||
|
if (m_tmp == statics.strLINE) {
|
||||||
|
out.setNum(m_lineNo);
|
||||||
|
} else if (m_tmp == statics.strFILE) {
|
||||||
|
out = m_proFile->fileName();
|
||||||
|
// The string is typically longer than the variable reference, so we need
|
||||||
|
// to ensure that there is enough space in the output buffer - as unlikely
|
||||||
|
// as an overflow is to actually happen in practice.
|
||||||
|
int need = (in.length() - (cur - (const ushort *)in.constData()) + 2) * 5 + out.length();
|
||||||
|
int tused = *tokPtr - (ushort *)tokBuff->constData();
|
||||||
|
int xused;
|
||||||
|
int total;
|
||||||
|
bool ptrFinal = xprPtr >= (ushort *)tokBuff->constData()
|
||||||
|
&& xprPtr < (ushort *)tokBuff->constData() + tokBuff->capacity();
|
||||||
|
if (ptrFinal) {
|
||||||
|
xused = xprPtr - (ushort *)tokBuff->constData();
|
||||||
|
total = xused + need;
|
||||||
|
} else {
|
||||||
|
xused = xprPtr - *buf;
|
||||||
|
total = tused + xused + need;
|
||||||
|
}
|
||||||
|
if (tokBuff->capacity() < total) {
|
||||||
|
tokBuff->reserve(total);
|
||||||
|
*tokPtr = (ushort *)tokBuff->constData() + tused;
|
||||||
|
xprBuff->reserve(total);
|
||||||
|
*buf = (ushort *)xprBuff->constData();
|
||||||
|
xprPtr = (ptrFinal ? (ushort *)tokBuff->constData() : *buf) + xused;
|
||||||
|
}
|
||||||
|
} else if (m_tmp == statics.strLITERAL_HASH) {
|
||||||
|
out = QLatin1String("#");
|
||||||
|
} else if (m_tmp == statics.strLITERAL_DOLLAR) {
|
||||||
|
out = QLatin1String("$");
|
||||||
|
} else if (m_tmp == statics.strLITERAL_WHITESPACE) {
|
||||||
|
out = QLatin1String("\t");
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
xprPtr -= 2; // Was set up for variable reference
|
||||||
|
xprPtr[-2] = TokLiteral | needSep;
|
||||||
|
xprPtr[-1] = out.length();
|
||||||
|
memcpy(xprPtr, out.constData(), out.length() * 2);
|
||||||
|
*ptr = xprPtr + out.length();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void QMakeParser::parseError(const QString &msg) const
|
void QMakeParser::parseError(const QString &msg) const
|
||||||
{
|
{
|
||||||
if (!m_inError && m_handler)
|
if (!m_inError && m_handler)
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ private:
|
|||||||
void putHashStr(ushort *&pTokPtr, const ushort *buf, uint len);
|
void putHashStr(ushort *&pTokPtr, const ushort *buf, uint len);
|
||||||
void finalizeHashStr(ushort *buf, uint len);
|
void finalizeHashStr(ushort *buf, uint len);
|
||||||
void putLineMarker(ushort *&tokPtr);
|
void putLineMarker(ushort *&tokPtr);
|
||||||
|
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);
|
||||||
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
|
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
|
||||||
void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
|
void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
|
||||||
void finalizeTest(ushort *&tokPtr);
|
void finalizeTest(ushort *&tokPtr);
|
||||||
|
|||||||
Reference in New Issue
Block a user