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();
|
||||
|
||||
static const char * const names[] = {
|
||||
"LITERAL_DOLLAR", "LITERAL_HASH", "LITERAL_WHITESPACE",
|
||||
"DIRLIST_SEPARATOR", "DIR_SEPARATOR",
|
||||
"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.version", "QMAKE_HOST.version_string",
|
||||
"_DATE_", "_QMAKE_CACHE_"
|
||||
@@ -1755,9 +1754,6 @@ ProStringList QMakeEvaluator::values(const ProString &variableName) const
|
||||
int vlidx = *vli;
|
||||
QString ret;
|
||||
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_)
|
||||
ret = m_outputDir;
|
||||
break;
|
||||
@@ -1771,12 +1767,6 @@ ProStringList QMakeEvaluator::values(const ProString &variableName) const
|
||||
case V_DIRLIST_SEPARATOR:
|
||||
ret = m_option->dirlist_sep;
|
||||
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
|
||||
ret = QDateTime::currentDateTime().toString();
|
||||
break;
|
||||
|
||||
@@ -203,10 +203,9 @@ public:
|
||||
QMakeHandler *m_handler;
|
||||
|
||||
enum VarName {
|
||||
V_LITERAL_DOLLAR, V_LITERAL_HASH, V_LITERAL_WHITESPACE,
|
||||
V_DIRLIST_SEPARATOR, V_DIR_SEPARATOR,
|
||||
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_version, V_QMAKE_HOST_version_string,
|
||||
V__DATE_, V__QMAKE_CACHE_
|
||||
|
||||
@@ -98,6 +98,11 @@ static struct {
|
||||
QString strfor;
|
||||
QString strdefineTest;
|
||||
QString strdefineReplace;
|
||||
QString strLINE;
|
||||
QString strFILE;
|
||||
QString strLITERAL_HASH;
|
||||
QString strLITERAL_DOLLAR;
|
||||
QString strLITERAL_WHITESPACE;
|
||||
} statics;
|
||||
|
||||
}
|
||||
@@ -111,6 +116,11 @@ void QMakeParser::initialize()
|
||||
statics.strfor = QLatin1String("for");
|
||||
statics.strdefineTest = QLatin1String("defineTest");
|
||||
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)
|
||||
@@ -268,7 +278,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
||||
// Expression precompiler buffer.
|
||||
QString xprBuff;
|
||||
xprBuff.reserve(tokBuff.capacity()); // Excessive, but simple
|
||||
ushort * const buf = (ushort *)xprBuff.constData();
|
||||
ushort *buf = (ushort *)xprBuff.constData();
|
||||
|
||||
// Parser state
|
||||
m_blockstack.clear();
|
||||
@@ -480,14 +490,18 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
||||
}
|
||||
tlen = ptr - xprPtr;
|
||||
if (rtok == TokVariable) {
|
||||
xprPtr[-4] = tok;
|
||||
uint hash = ProString::hash((const QChar *)xprPtr, tlen);
|
||||
xprPtr[-3] = (ushort)hash;
|
||||
xprPtr[-2] = (ushort)(hash >> 16);
|
||||
if (!resolveVariable(xprPtr, tlen, needSep, &ptr,
|
||||
&buf, &xprBuff, &tokPtr, &tokBuff, cur, in)) {
|
||||
xprPtr[-4] = tok;
|
||||
uint hash = ProString::hash((const QChar *)xprPtr, tlen);
|
||||
xprPtr[-3] = (ushort)hash;
|
||||
xprPtr[-2] = (ushort)(hash >> 16);
|
||||
xprPtr[-1] = tlen;
|
||||
}
|
||||
} else {
|
||||
xprPtr[-2] = tok;
|
||||
xprPtr[-1] = tlen;
|
||||
}
|
||||
xprPtr[-1] = tlen;
|
||||
if ((tok & TokMask) == TokFuncName) {
|
||||
cur++;
|
||||
funcCall:
|
||||
@@ -1017,6 +1031,57 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
|
||||
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
|
||||
{
|
||||
if (!m_inError && m_handler)
|
||||
|
||||
@@ -102,6 +102,10 @@ private:
|
||||
void putHashStr(ushort *&pTokPtr, const ushort *buf, uint len);
|
||||
void finalizeHashStr(ushort *buf, uint len);
|
||||
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 finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
|
||||
void finalizeTest(ushort *&tokPtr);
|
||||
|
||||
Reference in New Issue
Block a user