forked from qt-creator/qt-creator
implement qmake language and deprecation warnings
Change-Id: Ia5dd0c408ace4e779da898ffb60e9ca12a383225 Reviewed-by: Daniel Teske <daniel.teske@nokia.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
This commit is contained in:
@@ -216,8 +216,11 @@ ProStringList QMakeEvaluator::evaluateExpandFunction(
|
|||||||
if (func_t == 0) {
|
if (func_t == 0) {
|
||||||
const QString &fn = func.toQString(m_tmp1);
|
const QString &fn = func.toQString(m_tmp1);
|
||||||
const QString &lfn = fn.toLower();
|
const QString &lfn = fn.toLower();
|
||||||
if (!fn.isSharedWith(lfn))
|
if (!fn.isSharedWith(lfn)) {
|
||||||
func_t = ExpandFunc(statics.expands.value(ProString(lfn)));
|
func_t = ExpandFunc(statics.expands.value(ProString(lfn)));
|
||||||
|
if (func_t)
|
||||||
|
deprecationWarning(fL1S("Using uppercased builtin functions is deprecated."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProStringList ret;
|
ProStringList ret;
|
||||||
@@ -974,23 +977,25 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
|
|||||||
case T_INCLUDE: {
|
case T_INCLUDE: {
|
||||||
if (m_skipLevel && !m_cumulative)
|
if (m_skipLevel && !m_cumulative)
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
QString parseInto;
|
if (args.count() < 1 || args.count() > 3) {
|
||||||
// the third optional argument to include() controls warnings
|
evalError(fL1S("include(file, [into, [silent]]) requires one, two or three arguments."));
|
||||||
// and is not used here
|
|
||||||
if ((args.count() == 2) || (args.count() == 3) ) {
|
|
||||||
parseInto = args.at(1).toQString(m_tmp2);
|
|
||||||
} else if (args.count() != 1) {
|
|
||||||
evalError(fL1S("include(file, into, silent) requires one, two or three arguments."));
|
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
|
QString parseInto;
|
||||||
|
LoadFlags flags = 0;
|
||||||
|
if (args.count() >= 2) {
|
||||||
|
parseInto = args.at(1).toQString(m_tmp2);
|
||||||
|
if (args.count() >= 3 && isTrue(args.at(2), m_tmp3))
|
||||||
|
flags = LoadSilent;
|
||||||
|
}
|
||||||
QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
|
QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
|
||||||
fn.detach();
|
fn.detach();
|
||||||
bool ok;
|
bool ok;
|
||||||
if (parseInto.isEmpty()) {
|
if (parseInto.isEmpty()) {
|
||||||
ok = evaluateFile(fn, QMakeHandler::EvalIncludeFile, LoadProOnly);
|
ok = evaluateFile(fn, QMakeHandler::EvalIncludeFile, LoadProOnly | flags);
|
||||||
} else {
|
} else {
|
||||||
ProValueMap symbols;
|
ProValueMap symbols;
|
||||||
if ((ok = evaluateFileInto(fn, QMakeHandler::EvalAuxFile, &symbols, LoadAll))) {
|
if ((ok = evaluateFileInto(fn, QMakeHandler::EvalAuxFile, &symbols, LoadAll | flags))) {
|
||||||
ProValueMap newMap;
|
ProValueMap newMap;
|
||||||
for (ProValueMap::ConstIterator
|
for (ProValueMap::ConstIterator
|
||||||
it = m_valuemapStack.top().constBegin(),
|
it = m_valuemapStack.top().constBegin(),
|
||||||
@@ -1011,20 +1016,20 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
|
|||||||
m_valuemapStack.top() = newMap;
|
m_valuemapStack.top() = newMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnBool(ok);
|
return returnBool(ok || (flags & LoadSilent));
|
||||||
}
|
}
|
||||||
case T_LOAD: {
|
case T_LOAD: {
|
||||||
if (m_skipLevel && !m_cumulative)
|
if (m_skipLevel && !m_cumulative)
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
// bool ignore_error = false;
|
bool ignore_error = false;
|
||||||
if (args.count() == 2) {
|
if (args.count() == 2) {
|
||||||
// ignore_error = isTrue(args.at(1), m_tmp2);
|
ignore_error = isTrue(args.at(1), m_tmp2);
|
||||||
} else if (args.count() != 1) {
|
} else if (args.count() != 1) {
|
||||||
evalError(fL1S("load(feature) requires one or two arguments."));
|
evalError(fL1S("load(feature) requires one or two arguments."));
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
// XXX ignore_error unused
|
return returnBool(evaluateFeatureFile(m_option->expandEnvVars(args.at(0).toQString()),
|
||||||
return returnBool(evaluateFeatureFile(m_option->expandEnvVars(args.at(0).toQString())));
|
ignore_error) || ignore_error);
|
||||||
}
|
}
|
||||||
case T_DEBUG:
|
case T_DEBUG:
|
||||||
// Yup - do nothing. Nothing is going to enable debug output anyway.
|
// Yup - do nothing. Nothing is going to enable debug output anyway.
|
||||||
|
|||||||
@@ -138,7 +138,11 @@ void QMakeEvaluator::initStatics()
|
|||||||
const ProString &QMakeEvaluator::map(const ProString &var)
|
const ProString &QMakeEvaluator::map(const ProString &var)
|
||||||
{
|
{
|
||||||
QHash<ProString, ProString>::ConstIterator it = statics.varMap.constFind(var);
|
QHash<ProString, ProString>::ConstIterator it = statics.varMap.constFind(var);
|
||||||
return (it != statics.varMap.constEnd()) ? it.value() : var;
|
if (it == statics.varMap.constEnd())
|
||||||
|
return var;
|
||||||
|
deprecationWarning(fL1S("Variable %s is deprecated; use %s instead.")
|
||||||
|
.arg(var.toQString(), it.value().toQString()));
|
||||||
|
return it.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -239,7 +243,8 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil
|
|||||||
ushort unicode;
|
ushort unicode;
|
||||||
const QChar *vals_data = vals.data();
|
const QChar *vals_data = vals.data();
|
||||||
const int vals_len = vals.length();
|
const int vals_len = vals.length();
|
||||||
for (int x = 0, parens = 0; x < vals_len; x++) {
|
int parens = 0;
|
||||||
|
for (int x = 0; x < vals_len; x++) {
|
||||||
unicode = vals_data[x].unicode();
|
unicode = vals_data[x].unicode();
|
||||||
if (x != (int)vals_len-1 && unicode == BACKSLASH &&
|
if (x != (int)vals_len-1 && unicode == BACKSLASH &&
|
||||||
(vals_data[x+1].unicode() == SINGLEQUOTE || vals_data[x+1].unicode() == DOUBLEQUOTE)) {
|
(vals_data[x+1].unicode() == SINGLEQUOTE || vals_data[x+1].unicode() == DOUBLEQUOTE)) {
|
||||||
@@ -263,6 +268,8 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil
|
|||||||
}
|
}
|
||||||
if (!build.isEmpty())
|
if (!build.isEmpty())
|
||||||
ret << ProString(build, NoHash).setSource(source);
|
ret << ProString(build, NoHash).setSource(source);
|
||||||
|
if (parens)
|
||||||
|
deprecationWarning(fL1S("Unmatched parentheses are deprecated."));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -780,6 +787,8 @@ void QMakeEvaluator::visitProVariable(
|
|||||||
if (!m_cumulative) {
|
if (!m_cumulative) {
|
||||||
if (!m_skipLevel) {
|
if (!m_skipLevel) {
|
||||||
zipEmpty(&varVal);
|
zipEmpty(&varVal);
|
||||||
|
// FIXME: add check+warning about accidental value removal.
|
||||||
|
// This may be a bit too noisy, though.
|
||||||
m_valuemapStack.top()[varName] = varVal;
|
m_valuemapStack.top()[varName] = varVal;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1210,7 +1219,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
|
|||||||
if (!processed.contains(config)) {
|
if (!processed.contains(config)) {
|
||||||
config.detach();
|
config.detach();
|
||||||
processed.insert(config);
|
processed.insert(config);
|
||||||
if (evaluateFeatureFile(config)) {
|
if (evaluateFeatureFile(config, true)) {
|
||||||
finished = false;
|
finished = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1892,6 +1901,8 @@ bool QMakeEvaluator::evaluateFileDirect(
|
|||||||
#endif
|
#endif
|
||||||
return ok;
|
return ok;
|
||||||
} else {
|
} else {
|
||||||
|
if (!(flags & LoadSilent) && IoUtils::exists(fileName))
|
||||||
|
languageWarning(fL1S("Include file %1 not found").arg(fileName));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1909,7 +1920,7 @@ bool QMakeEvaluator::evaluateFile(
|
|||||||
return evaluateFileDirect(fileName, type, flags);
|
return evaluateFileDirect(fileName, type, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName)
|
bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName, bool silent)
|
||||||
{
|
{
|
||||||
QString fn = fileName;
|
QString fn = fileName;
|
||||||
if (!fn.endsWith(QLatin1String(".prf")))
|
if (!fn.endsWith(QLatin1String(".prf")))
|
||||||
@@ -1938,13 +1949,18 @@ bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName)
|
|||||||
if (QFileInfo(fn).exists())
|
if (QFileInfo(fn).exists())
|
||||||
goto cool;
|
goto cool;
|
||||||
#endif
|
#endif
|
||||||
|
if (!silent)
|
||||||
|
languageWarning(fL1S("Cannot find feature %1").arg(fileName));
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
cool:
|
cool:
|
||||||
ProStringList &already = valuesRef(ProString("QMAKE_INTERNAL_INCLUDED_FEATURES"));
|
ProStringList &already = valuesRef(ProString("QMAKE_INTERNAL_INCLUDED_FEATURES"));
|
||||||
ProString afn(fn, NoHash);
|
ProString afn(fn, NoHash);
|
||||||
if (already.contains(afn))
|
if (already.contains(afn)) {
|
||||||
|
if (!silent)
|
||||||
|
languageWarning(fL1S("Feature %1 already included").arg(fileName));
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
already.append(afn);
|
already.append(afn);
|
||||||
|
|
||||||
#ifdef PROEVALUATOR_CUMULATIVE
|
#ifdef PROEVALUATOR_CUMULATIVE
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ public:
|
|||||||
enum {
|
enum {
|
||||||
SourceEvaluator = 0x10,
|
SourceEvaluator = 0x10,
|
||||||
|
|
||||||
|
EvalWarnLanguage = SourceEvaluator | WarningMessage | WarnLanguage,
|
||||||
|
EvalWarnDeprecated = SourceEvaluator | WarningMessage | WarnDeprecated,
|
||||||
|
|
||||||
EvalError = ErrorMessage | SourceEvaluator
|
EvalError = ErrorMessage | SourceEvaluator
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,7 +74,8 @@ public:
|
|||||||
LoadProOnly = 0,
|
LoadProOnly = 0,
|
||||||
LoadPreFiles = 1,
|
LoadPreFiles = 1,
|
||||||
LoadPostFiles = 2,
|
LoadPostFiles = 2,
|
||||||
LoadAll = LoadPreFiles|LoadPostFiles
|
LoadAll = LoadPreFiles|LoadPostFiles,
|
||||||
|
LoadSilent = 0x10
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(LoadFlags, LoadFlag)
|
Q_DECLARE_FLAGS(LoadFlags, LoadFlag)
|
||||||
|
|
||||||
@@ -120,7 +124,7 @@ public:
|
|||||||
void visitProFunctionDef(ushort tok, const ProString &name, const ushort *tokPtr);
|
void visitProFunctionDef(ushort tok, const ProString &name, const ushort *tokPtr);
|
||||||
void visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr);
|
void visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr);
|
||||||
|
|
||||||
static const ProString &map(const ProString &var);
|
const ProString &map(const ProString &var);
|
||||||
ProValueMap *findValues(const ProString &variableName, ProValueMap::Iterator *it);
|
ProValueMap *findValues(const ProString &variableName, ProValueMap::Iterator *it);
|
||||||
|
|
||||||
void setTemplate();
|
void setTemplate();
|
||||||
@@ -139,13 +143,17 @@ public:
|
|||||||
LoadFlags flags);
|
LoadFlags flags);
|
||||||
bool evaluateFile(const QString &fileName, QMakeHandler::EvalFileType type,
|
bool evaluateFile(const QString &fileName, QMakeHandler::EvalFileType type,
|
||||||
LoadFlags flags);
|
LoadFlags flags);
|
||||||
bool evaluateFeatureFile(const QString &fileName);
|
bool evaluateFeatureFile(const QString &fileName, bool silent = false);
|
||||||
bool evaluateFileInto(const QString &fileName, QMakeHandler::EvalFileType type,
|
bool evaluateFileInto(const QString &fileName, QMakeHandler::EvalFileType type,
|
||||||
ProValueMap *values, // output-only
|
ProValueMap *values, // output-only
|
||||||
LoadFlags flags);
|
LoadFlags flags);
|
||||||
void message(int type, const QString &msg) const;
|
void message(int type, const QString &msg) const;
|
||||||
void evalError(const QString &msg) const
|
void evalError(const QString &msg) const
|
||||||
{ message(QMakeHandler::EvalError, msg); }
|
{ message(QMakeHandler::EvalError, msg); }
|
||||||
|
void languageWarning(const QString &msg) const
|
||||||
|
{ message(QMakeHandler::EvalWarnLanguage, msg); }
|
||||||
|
void deprecationWarning(const QString &msg) const
|
||||||
|
{ message(QMakeHandler::EvalWarnDeprecated, msg); }
|
||||||
|
|
||||||
QList<ProStringList> prepareFunctionArgs(const ushort *&tokPtr);
|
QList<ProStringList> prepareFunctionArgs(const ushort *&tokPtr);
|
||||||
QList<ProStringList> prepareFunctionArgs(const ProString &arguments);
|
QList<ProStringList> prepareFunctionArgs(const ProString &arguments);
|
||||||
|
|||||||
@@ -309,6 +309,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
|||||||
int parens = 0; // Braces in value context
|
int parens = 0; // Braces in value context
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
int wordCount = 0; // Number of words in currently accumulated expression
|
int wordCount = 0; // Number of words in currently accumulated expression
|
||||||
|
int lastIndent = 0; // Previous line's indentation, to detect accidental continuation abuse
|
||||||
bool putSpace = false; // Only ever true inside quoted string
|
bool putSpace = false; // Only ever true inside quoted string
|
||||||
bool lineMarked = true; // For in-expression markers
|
bool lineMarked = true; // For in-expression markers
|
||||||
ushort needSep = TokNewStr; // Complementary to putSpace: separator outside quotes
|
ushort needSep = TokNewStr; // Complementary to putSpace: separator outside quotes
|
||||||
@@ -372,7 +373,8 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
|||||||
ushort c;
|
ushort c;
|
||||||
|
|
||||||
// First, skip leading whitespace
|
// First, skip leading whitespace
|
||||||
for (;; ++cur) {
|
int indent;
|
||||||
|
for (indent = 0; ; ++cur, ++indent) {
|
||||||
c = *cur;
|
c = *cur;
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
++cur;
|
++cur;
|
||||||
@@ -556,12 +558,14 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
|||||||
needSep = 0;
|
needSep = 0;
|
||||||
goto nextChr;
|
goto nextChr;
|
||||||
}
|
}
|
||||||
} else if (c == '\\' && cur != end) {
|
} else if (c == '\\') {
|
||||||
static const char symbols[] = "[]{}()$\\'\"";
|
static const char symbols[] = "[]{}()$\\'\"";
|
||||||
ushort c2 = *cur;
|
ushort c2;
|
||||||
if (!(c2 & 0xff00) && strchr(symbols, c2)) {
|
if (cur != end && !((c2 = *cur) & 0xff00) && strchr(symbols, c2)) {
|
||||||
c = c2;
|
c = c2;
|
||||||
cur++;
|
cur++;
|
||||||
|
} else {
|
||||||
|
deprecationWarning(fL1S("Unescaped backslashes are deprecated"));
|
||||||
}
|
}
|
||||||
} else if (quote) {
|
} else if (quote) {
|
||||||
if (c == quote) {
|
if (c == quote) {
|
||||||
@@ -722,6 +726,9 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
|||||||
goto closeScope;
|
goto closeScope;
|
||||||
}
|
}
|
||||||
--parens;
|
--parens;
|
||||||
|
} else if (c == '=') {
|
||||||
|
if (indent < lastIndent)
|
||||||
|
languageWarning(fL1S("Possible accidental line continuation"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (putSpace) {
|
if (putSpace) {
|
||||||
@@ -771,6 +778,8 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
|||||||
}
|
}
|
||||||
} else if (context == CtxValue) {
|
} else if (context == CtxValue) {
|
||||||
FLUSH_VALUE_LIST();
|
FLUSH_VALUE_LIST();
|
||||||
|
if (parens)
|
||||||
|
languageWarning(fL1S("Possible braces mismatch"));
|
||||||
} else {
|
} else {
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
}
|
}
|
||||||
@@ -780,6 +789,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
|||||||
goto freshLine;
|
goto freshLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastIndent = indent;
|
||||||
lineMarked = false;
|
lineMarked = false;
|
||||||
ignore:
|
ignore:
|
||||||
cur = cptr;
|
cur = cptr;
|
||||||
|
|||||||
@@ -46,11 +46,19 @@ class QMAKE_EXPORT QMakeParserHandler
|
|||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
CategoryMask = 0xf00,
|
CategoryMask = 0xf00,
|
||||||
|
WarningMessage = 0x000,
|
||||||
ErrorMessage = 0x100,
|
ErrorMessage = 0x100,
|
||||||
|
|
||||||
SourceMask = 0xf0,
|
SourceMask = 0xf0,
|
||||||
SourceParser = 0,
|
SourceParser = 0,
|
||||||
|
|
||||||
|
CodeMask = 0xf,
|
||||||
|
WarnLanguage = 0,
|
||||||
|
WarnDeprecated,
|
||||||
|
|
||||||
|
ParserWarnLanguage = SourceParser | WarningMessage | WarnLanguage,
|
||||||
|
ParserWarnDeprecated = SourceParser | WarningMessage | WarnDeprecated,
|
||||||
|
|
||||||
ParserIoError = ErrorMessage | SourceParser,
|
ParserIoError = ErrorMessage | SourceParser,
|
||||||
ParserError
|
ParserError
|
||||||
};
|
};
|
||||||
@@ -123,6 +131,10 @@ private:
|
|||||||
void message(int type, const QString &msg) const;
|
void message(int type, const QString &msg) const;
|
||||||
void parseError(const QString &msg) const
|
void parseError(const QString &msg) const
|
||||||
{ message(QMakeParserHandler::ParserError, msg); }
|
{ message(QMakeParserHandler::ParserError, msg); }
|
||||||
|
void languageWarning(const QString &msg) const
|
||||||
|
{ message(QMakeParserHandler::ParserWarnLanguage, msg); }
|
||||||
|
void deprecationWarning(const QString &msg) const
|
||||||
|
{ message(QMakeParserHandler::ParserWarnDeprecated, msg); }
|
||||||
|
|
||||||
// Current location
|
// Current location
|
||||||
ProFile *m_proFile;
|
ProFile *m_proFile;
|
||||||
|
|||||||
@@ -43,18 +43,20 @@
|
|||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
|
|
||||||
static void print(const QString &fileName, int lineNo, const QString &msg)
|
static void print(const QString &fileName, int lineNo, int type, const QString &msg)
|
||||||
{
|
{
|
||||||
|
QString pfx = ((type & QMakeHandler::CategoryMask) == QMakeHandler::WarningMessage)
|
||||||
|
? QString::fromLatin1("WARNING: ") : QString();
|
||||||
if (lineNo)
|
if (lineNo)
|
||||||
qWarning("%s(%d): %s", qPrintable(fileName), lineNo, qPrintable(msg));
|
qWarning("%s%s:%d: %s", qPrintable(pfx), qPrintable(fileName), lineNo, qPrintable(msg));
|
||||||
else
|
else
|
||||||
qWarning("%s", qPrintable(msg));
|
qWarning("%s%s", qPrintable(pfx), qPrintable(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
class EvalHandler : public QMakeHandler {
|
class EvalHandler : public QMakeHandler {
|
||||||
public:
|
public:
|
||||||
virtual void message(int /* type */, const QString &msg, const QString &fileName, int lineNo)
|
virtual void message(int type, const QString &msg, const QString &fileName, int lineNo)
|
||||||
{ print(fileName, lineNo, msg); }
|
{ print(fileName, lineNo, type, msg); }
|
||||||
|
|
||||||
virtual void fileMessage(const QString &msg)
|
virtual void fileMessage(const QString &msg)
|
||||||
{ qWarning("%s", qPrintable(msg)); }
|
{ qWarning("%s", qPrintable(msg)); }
|
||||||
|
|||||||
Reference in New Issue
Block a user