forked from qt-creator/qt-creator
fix execution location tracking
function calls need to change _FILE_ - but none of the other context-indicating variables.
This commit is contained in:
@@ -126,7 +126,6 @@ public:
|
|||||||
~Private();
|
~Private();
|
||||||
|
|
||||||
ProFileEvaluator *q;
|
ProFileEvaluator *q;
|
||||||
int m_lineNo; // Error reporting
|
|
||||||
|
|
||||||
enum VisitReturn {
|
enum VisitReturn {
|
||||||
ReturnFalse,
|
ReturnFalse,
|
||||||
@@ -145,6 +144,7 @@ public:
|
|||||||
void skipExpression(const ushort *&tokPtr);
|
void skipExpression(const ushort *&tokPtr);
|
||||||
|
|
||||||
VisitReturn visitProFile(ProFile *pro, ProFileEvaluatorHandler::EvalFileType type);
|
VisitReturn visitProFile(ProFile *pro, ProFileEvaluatorHandler::EvalFileType type);
|
||||||
|
VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr);
|
||||||
VisitReturn visitProBlock(const ushort *tokPtr);
|
VisitReturn visitProBlock(const ushort *tokPtr);
|
||||||
VisitReturn visitProLoop(const ProString &variable, const ushort *exprPtr,
|
VisitReturn visitProLoop(const ProString &variable, const ushort *exprPtr,
|
||||||
const ushort *tokPtr);
|
const ushort *tokPtr);
|
||||||
@@ -200,8 +200,17 @@ public:
|
|||||||
int m_skipLevel;
|
int m_skipLevel;
|
||||||
int m_loopLevel; // To report unexpected break() and next()s
|
int m_loopLevel; // To report unexpected break() and next()s
|
||||||
bool m_cumulative;
|
bool m_cumulative;
|
||||||
QStack<ProFile*> m_profileStack; // To handle 'include(a.pri), so we can track back to 'a.pro' when finished with 'a.pri'
|
|
||||||
QStack<QString> m_stringStack; // To handle token string refcounting
|
struct Location {
|
||||||
|
Location() : pro(0), line(0) {}
|
||||||
|
Location(ProFile *_pro, int _line) : pro(_pro), line(_line) {}
|
||||||
|
ProFile *pro;
|
||||||
|
int line;
|
||||||
|
};
|
||||||
|
|
||||||
|
Location m_current; // Currently evaluated location
|
||||||
|
QStack<Location> m_locationStack; // All execution location changes
|
||||||
|
QStack<ProFile *> m_profileStack; // Includes only
|
||||||
|
|
||||||
QString m_outputDir;
|
QString m_outputDir;
|
||||||
|
|
||||||
@@ -448,7 +457,7 @@ uint ProFileEvaluator::Private::getBlockLen(const ushort *&tokPtr)
|
|||||||
|
|
||||||
ProString ProFileEvaluator::Private::getStr(const ushort *&tokPtr)
|
ProString ProFileEvaluator::Private::getStr(const ushort *&tokPtr)
|
||||||
{
|
{
|
||||||
const QString &str(m_stringStack.top());
|
const QString &str(m_current.pro->items());
|
||||||
uint len = *tokPtr++;
|
uint len = *tokPtr++;
|
||||||
ProString ret(str, tokPtr - (const ushort *)str.constData(), len, NoHash);
|
ProString ret(str, tokPtr - (const ushort *)str.constData(), len, NoHash);
|
||||||
tokPtr += len;
|
tokPtr += len;
|
||||||
@@ -459,7 +468,7 @@ ProString ProFileEvaluator::Private::getHashStr(const ushort *&tokPtr)
|
|||||||
{
|
{
|
||||||
uint hash = getBlockLen(tokPtr);
|
uint hash = getBlockLen(tokPtr);
|
||||||
uint len = *tokPtr++;
|
uint len = *tokPtr++;
|
||||||
const QString &str(m_stringStack.top());
|
const QString &str(m_current.pro->items());
|
||||||
ProString ret(str, tokPtr - (const ushort *)str.constData(), len, hash);
|
ProString ret(str, tokPtr - (const ushort *)str.constData(), len, hash);
|
||||||
tokPtr += len;
|
tokPtr += len;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -670,7 +679,7 @@ void ProFileEvaluator::Private::evaluateExpression(
|
|||||||
ushort maskedTok = tok & TokMask;
|
ushort maskedTok = tok & TokMask;
|
||||||
switch (maskedTok) {
|
switch (maskedTok) {
|
||||||
case TokLine:
|
case TokLine:
|
||||||
m_lineNo = *tokPtr++;
|
m_current.line = *tokPtr++;
|
||||||
break;
|
break;
|
||||||
case TokLiteral:
|
case TokLiteral:
|
||||||
addStr(getStr(tokPtr), ret, pending, joined);
|
addStr(getStr(tokPtr), ret, pending, joined);
|
||||||
@@ -707,7 +716,7 @@ void ProFileEvaluator::Private::skipExpression(const ushort *&pTokPtr)
|
|||||||
ushort tok = *tokPtr++;
|
ushort tok = *tokPtr++;
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case TokLine:
|
case TokLine:
|
||||||
m_lineNo = *tokPtr++;
|
m_current.line = *tokPtr++;
|
||||||
break;
|
break;
|
||||||
case TokValueTerminator:
|
case TokValueTerminator:
|
||||||
case TokFuncTerminator:
|
case TokFuncTerminator:
|
||||||
@@ -740,6 +749,14 @@ void ProFileEvaluator::Private::skipExpression(const ushort *&pTokPtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProBlock(
|
||||||
|
ProFile *pro, const ushort *tokPtr)
|
||||||
|
{
|
||||||
|
m_current.pro = pro;
|
||||||
|
m_current.line = 0;
|
||||||
|
return visitProBlock(tokPtr);
|
||||||
|
}
|
||||||
|
|
||||||
ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProBlock(
|
ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProBlock(
|
||||||
const ushort *tokPtr)
|
const ushort *tokPtr)
|
||||||
{
|
{
|
||||||
@@ -750,7 +767,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProBlock(
|
|||||||
while (ushort tok = *tokPtr++) {
|
while (ushort tok = *tokPtr++) {
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case TokLine:
|
case TokLine:
|
||||||
m_lineNo = *tokPtr++;
|
m_current.line = *tokPtr++;
|
||||||
continue;
|
continue;
|
||||||
case TokAssign:
|
case TokAssign:
|
||||||
case TokAppend:
|
case TokAppend:
|
||||||
@@ -897,10 +914,8 @@ void ProFileEvaluator::Private::visitProFunctionDef(
|
|||||||
(tok == TokTestDef
|
(tok == TokTestDef
|
||||||
? &m_functionDefs.testFunctions
|
? &m_functionDefs.testFunctions
|
||||||
: &m_functionDefs.replaceFunctions);
|
: &m_functionDefs.replaceFunctions);
|
||||||
FunctionDef def;
|
hash->insert(name, FunctionDef(m_current.pro,
|
||||||
def.string = m_stringStack.top();
|
tokPtr - (const ushort *)m_current.pro->items().constData()));
|
||||||
def.offset = tokPtr - (const ushort *)def.string.constData();
|
|
||||||
hash->insert(name, def);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProLoop(
|
ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProLoop(
|
||||||
@@ -1104,7 +1119,6 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile(
|
|||||||
ProFile *pro, ProFileEvaluatorHandler::EvalFileType type)
|
ProFile *pro, ProFileEvaluatorHandler::EvalFileType type)
|
||||||
{
|
{
|
||||||
m_handler->aboutToEval(currentProFile(), pro, type);
|
m_handler->aboutToEval(currentProFile(), pro, type);
|
||||||
m_lineNo = 0;
|
|
||||||
m_profileStack.push(pro);
|
m_profileStack.push(pro);
|
||||||
if (m_profileStack.count() == 1) {
|
if (m_profileStack.count() == 1) {
|
||||||
// Do this only for the initial profile we visit, since
|
// Do this only for the initial profile we visit, since
|
||||||
@@ -1269,9 +1283,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stringStack.push(pro->items());
|
visitProBlock(pro, (const ushort *)pro->items().constData());
|
||||||
visitProBlock((const ushort *)pro->items().constData());
|
|
||||||
m_stringStack.pop();
|
|
||||||
|
|
||||||
if (m_profileStack.count() == 1) {
|
if (m_profileStack.count() == 1) {
|
||||||
if (m_parsePreAndPostFiles) {
|
if (m_parsePreAndPostFiles) {
|
||||||
@@ -1825,13 +1837,12 @@ ProStringList ProFileEvaluator::Private::evaluateFunction(
|
|||||||
bool oki;
|
bool oki;
|
||||||
ProStringList ret;
|
ProStringList ret;
|
||||||
|
|
||||||
const ushort *tokPtr = (const ushort *)func.string.constData() + func.offset;
|
|
||||||
if (m_valuemapStack.count() >= 100) {
|
if (m_valuemapStack.count() >= 100) {
|
||||||
evalError(fL1S("ran into infinite recursion (depth > 100)."));
|
evalError(fL1S("ran into infinite recursion (depth > 100)."));
|
||||||
oki = false;
|
oki = false;
|
||||||
} else {
|
} else {
|
||||||
m_valuemapStack.push(QHash<ProString, ProStringList>());
|
m_valuemapStack.push(QHash<ProString, ProStringList>());
|
||||||
m_stringStack.push(func.string);
|
m_locationStack.push(m_current);
|
||||||
int loopLevel = m_loopLevel;
|
int loopLevel = m_loopLevel;
|
||||||
m_loopLevel = 0;
|
m_loopLevel = 0;
|
||||||
|
|
||||||
@@ -1841,12 +1852,12 @@ ProStringList ProFileEvaluator::Private::evaluateFunction(
|
|||||||
m_valuemapStack.top()[ProString(QString::number(i+1))] = argumentsList[i];
|
m_valuemapStack.top()[ProString(QString::number(i+1))] = argumentsList[i];
|
||||||
}
|
}
|
||||||
m_valuemapStack.top()[statics.strARGS] = args;
|
m_valuemapStack.top()[statics.strARGS] = args;
|
||||||
oki = (visitProBlock(tokPtr) != ReturnFalse); // True || Return
|
oki = (visitProBlock(func.pro(), func.tokPtr()) != ReturnFalse); // True || Return
|
||||||
ret = m_returnValue;
|
ret = m_returnValue;
|
||||||
m_returnValue.clear();
|
m_returnValue.clear();
|
||||||
|
|
||||||
m_loopLevel = loopLevel;
|
m_loopLevel = loopLevel;
|
||||||
m_stringStack.pop();
|
m_current = m_locationStack.pop();
|
||||||
m_valuemapStack.pop();
|
m_valuemapStack.pop();
|
||||||
}
|
}
|
||||||
if (ok)
|
if (ok)
|
||||||
@@ -2408,9 +2419,9 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit
|
|||||||
args.join(statics.field_sep));
|
args.join(statics.field_sep));
|
||||||
if (!pro)
|
if (!pro)
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
m_stringStack.push(pro->items());
|
m_locationStack.push(m_current);
|
||||||
VisitReturn ret = visitProBlock((const ushort *)pro->items().constData());
|
VisitReturn ret = visitProBlock(pro, (const ushort *)pro->items().constData());
|
||||||
m_stringStack.pop();
|
m_current = m_locationStack.pop();
|
||||||
pro->deref();
|
pro->deref();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -2832,10 +2843,10 @@ ProStringList ProFileEvaluator::Private::values(const ProString &variableName) c
|
|||||||
case V_LITERAL_WHITESPACE: ret = QLatin1String("\t"); break;
|
case V_LITERAL_WHITESPACE: ret = QLatin1String("\t"); break;
|
||||||
case V_LITERAL_DOLLAR: ret = QLatin1String("$"); break;
|
case V_LITERAL_DOLLAR: ret = QLatin1String("$"); break;
|
||||||
case V_LITERAL_HASH: ret = QLatin1String("#"); break;
|
case V_LITERAL_HASH: ret = QLatin1String("#"); break;
|
||||||
case V_OUT_PWD: //the outgoing dir
|
case V_OUT_PWD: // the outgoing dir (shadow of _PRO_FILE_PWD_)
|
||||||
ret = m_outputDir;
|
ret = m_outputDir;
|
||||||
break;
|
break;
|
||||||
case V_PWD: //current working dir (of _FILE_)
|
case V_PWD: // containing directory of most nested project/include file
|
||||||
case V_IN_PWD:
|
case V_IN_PWD:
|
||||||
ret = currentDirectory();
|
ret = currentDirectory();
|
||||||
break;
|
break;
|
||||||
@@ -2845,11 +2856,11 @@ ProStringList ProFileEvaluator::Private::values(const ProString &variableName) c
|
|||||||
case V_DIRLIST_SEPARATOR:
|
case V_DIRLIST_SEPARATOR:
|
||||||
ret = m_option->dirlist_sep;
|
ret = m_option->dirlist_sep;
|
||||||
break;
|
break;
|
||||||
case V__LINE_: //parser line number
|
case V__LINE_: // currently executed line number
|
||||||
ret = QString::number(m_lineNo);
|
ret = QString::number(m_current.line);
|
||||||
break;
|
break;
|
||||||
case V__FILE_: //parser file
|
case V__FILE_: // currently executed file
|
||||||
ret = currentFileName();
|
ret = m_current.pro->fileName();
|
||||||
break;
|
break;
|
||||||
case V__DATE_: //current date/time
|
case V__DATE_: //current date/time
|
||||||
ret = QDateTime::currentDateTime().toString();
|
ret = QDateTime::currentDateTime().toString();
|
||||||
@@ -2950,14 +2961,13 @@ ProStringList ProFileEvaluator::Private::values(const ProString &variableName) c
|
|||||||
bool ProFileEvaluator::Private::evaluateFileDirect(
|
bool ProFileEvaluator::Private::evaluateFileDirect(
|
||||||
const QString &fileName, ProFileEvaluatorHandler::EvalFileType type)
|
const QString &fileName, ProFileEvaluatorHandler::EvalFileType type)
|
||||||
{
|
{
|
||||||
int lineNo = m_lineNo;
|
|
||||||
if (ProFile *pro = m_parser->parsedProFile(fileName, true)) {
|
if (ProFile *pro = m_parser->parsedProFile(fileName, true)) {
|
||||||
|
m_locationStack.push(m_current);
|
||||||
bool ok = (visitProFile(pro, type) == ReturnTrue);
|
bool ok = (visitProFile(pro, type) == ReturnTrue);
|
||||||
|
m_current = m_locationStack.pop();
|
||||||
pro->deref();
|
pro->deref();
|
||||||
m_lineNo = lineNo;
|
|
||||||
return ok;
|
return ok;
|
||||||
} else {
|
} else {
|
||||||
m_lineNo = lineNo;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3046,7 +3056,7 @@ bool ProFileEvaluator::Private::evaluateFileInto(
|
|||||||
void ProFileEvaluator::Private::evalError(const QString &message) const
|
void ProFileEvaluator::Private::evalError(const QString &message) const
|
||||||
{
|
{
|
||||||
if (!m_skipLevel)
|
if (!m_skipLevel)
|
||||||
m_handler->evalError(currentFileName(), m_lineNo, message);
|
m_handler->evalError(m_current.pro->fileName(), m_current.line, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -65,9 +65,26 @@ class ProFileEvaluator
|
|||||||
class Private;
|
class Private;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct FunctionDef {
|
class FunctionDef {
|
||||||
QString string;
|
public:
|
||||||
int offset;
|
FunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); }
|
||||||
|
FunctionDef(const FunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); }
|
||||||
|
~FunctionDef() { m_pro->deref(); }
|
||||||
|
FunctionDef &operator=(const FunctionDef &o)
|
||||||
|
{
|
||||||
|
if (this != &o) {
|
||||||
|
m_pro->deref();
|
||||||
|
m_pro = o.m_pro;
|
||||||
|
m_pro->ref();
|
||||||
|
m_offset = o.m_offset;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
ProFile *pro() const { return m_pro; }
|
||||||
|
const ushort *tokPtr() const { return (const ushort *)m_pro->items().constData() + m_offset; }
|
||||||
|
private:
|
||||||
|
ProFile *m_pro;
|
||||||
|
int m_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionDefs {
|
struct FunctionDefs {
|
||||||
|
|||||||
Reference in New Issue
Block a user