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) {
|
||||
const QString &fn = func.toQString(m_tmp1);
|
||||
const QString &lfn = fn.toLower();
|
||||
if (!fn.isSharedWith(lfn))
|
||||
if (!fn.isSharedWith(lfn)) {
|
||||
func_t = ExpandFunc(statics.expands.value(ProString(lfn)));
|
||||
if (func_t)
|
||||
deprecationWarning(fL1S("Using uppercased builtin functions is deprecated."));
|
||||
}
|
||||
}
|
||||
|
||||
ProStringList ret;
|
||||
@@ -974,23 +977,25 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
|
||||
case T_INCLUDE: {
|
||||
if (m_skipLevel && !m_cumulative)
|
||||
return ReturnFalse;
|
||||
QString parseInto;
|
||||
// the third optional argument to include() controls warnings
|
||||
// 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."));
|
||||
if (args.count() < 1 || args.count() > 3) {
|
||||
evalError(fL1S("include(file, [into, [silent]]) requires one, two or three arguments."));
|
||||
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)));
|
||||
fn.detach();
|
||||
bool ok;
|
||||
if (parseInto.isEmpty()) {
|
||||
ok = evaluateFile(fn, QMakeHandler::EvalIncludeFile, LoadProOnly);
|
||||
ok = evaluateFile(fn, QMakeHandler::EvalIncludeFile, LoadProOnly | flags);
|
||||
} else {
|
||||
ProValueMap symbols;
|
||||
if ((ok = evaluateFileInto(fn, QMakeHandler::EvalAuxFile, &symbols, LoadAll))) {
|
||||
if ((ok = evaluateFileInto(fn, QMakeHandler::EvalAuxFile, &symbols, LoadAll | flags))) {
|
||||
ProValueMap newMap;
|
||||
for (ProValueMap::ConstIterator
|
||||
it = m_valuemapStack.top().constBegin(),
|
||||
@@ -1011,20 +1016,20 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
|
||||
m_valuemapStack.top() = newMap;
|
||||
}
|
||||
}
|
||||
return returnBool(ok);
|
||||
return returnBool(ok || (flags & LoadSilent));
|
||||
}
|
||||
case T_LOAD: {
|
||||
if (m_skipLevel && !m_cumulative)
|
||||
return ReturnFalse;
|
||||
// bool ignore_error = false;
|
||||
bool ignore_error = false;
|
||||
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) {
|
||||
evalError(fL1S("load(feature) requires one or two arguments."));
|
||||
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:
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
const QChar *vals_data = vals.data();
|
||||
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();
|
||||
if (x != (int)vals_len-1 && unicode == BACKSLASH &&
|
||||
(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())
|
||||
ret << ProString(build, NoHash).setSource(source);
|
||||
if (parens)
|
||||
deprecationWarning(fL1S("Unmatched parentheses are deprecated."));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -780,6 +787,8 @@ void QMakeEvaluator::visitProVariable(
|
||||
if (!m_cumulative) {
|
||||
if (!m_skipLevel) {
|
||||
zipEmpty(&varVal);
|
||||
// FIXME: add check+warning about accidental value removal.
|
||||
// This may be a bit too noisy, though.
|
||||
m_valuemapStack.top()[varName] = varVal;
|
||||
}
|
||||
} else {
|
||||
@@ -1210,7 +1219,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
|
||||
if (!processed.contains(config)) {
|
||||
config.detach();
|
||||
processed.insert(config);
|
||||
if (evaluateFeatureFile(config)) {
|
||||
if (evaluateFeatureFile(config, true)) {
|
||||
finished = false;
|
||||
break;
|
||||
}
|
||||
@@ -1892,6 +1901,8 @@ bool QMakeEvaluator::evaluateFileDirect(
|
||||
#endif
|
||||
return ok;
|
||||
} else {
|
||||
if (!(flags & LoadSilent) && IoUtils::exists(fileName))
|
||||
languageWarning(fL1S("Include file %1 not found").arg(fileName));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1909,7 +1920,7 @@ bool QMakeEvaluator::evaluateFile(
|
||||
return evaluateFileDirect(fileName, type, flags);
|
||||
}
|
||||
|
||||
bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName)
|
||||
bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName, bool silent)
|
||||
{
|
||||
QString fn = fileName;
|
||||
if (!fn.endsWith(QLatin1String(".prf")))
|
||||
@@ -1938,13 +1949,18 @@ bool QMakeEvaluator::evaluateFeatureFile(const QString &fileName)
|
||||
if (QFileInfo(fn).exists())
|
||||
goto cool;
|
||||
#endif
|
||||
if (!silent)
|
||||
languageWarning(fL1S("Cannot find feature %1").arg(fileName));
|
||||
return false;
|
||||
|
||||
cool:
|
||||
ProStringList &already = valuesRef(ProString("QMAKE_INTERNAL_INCLUDED_FEATURES"));
|
||||
ProString afn(fn, NoHash);
|
||||
if (already.contains(afn))
|
||||
if (already.contains(afn)) {
|
||||
if (!silent)
|
||||
languageWarning(fL1S("Feature %1 already included").arg(fileName));
|
||||
return true;
|
||||
}
|
||||
already.append(afn);
|
||||
|
||||
#ifdef PROEVALUATOR_CUMULATIVE
|
||||
|
||||
@@ -53,6 +53,9 @@ public:
|
||||
enum {
|
||||
SourceEvaluator = 0x10,
|
||||
|
||||
EvalWarnLanguage = SourceEvaluator | WarningMessage | WarnLanguage,
|
||||
EvalWarnDeprecated = SourceEvaluator | WarningMessage | WarnDeprecated,
|
||||
|
||||
EvalError = ErrorMessage | SourceEvaluator
|
||||
};
|
||||
|
||||
@@ -71,7 +74,8 @@ public:
|
||||
LoadProOnly = 0,
|
||||
LoadPreFiles = 1,
|
||||
LoadPostFiles = 2,
|
||||
LoadAll = LoadPreFiles|LoadPostFiles
|
||||
LoadAll = LoadPreFiles|LoadPostFiles,
|
||||
LoadSilent = 0x10
|
||||
};
|
||||
Q_DECLARE_FLAGS(LoadFlags, LoadFlag)
|
||||
|
||||
@@ -120,7 +124,7 @@ public:
|
||||
void visitProFunctionDef(ushort tok, const ProString &name, 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);
|
||||
|
||||
void setTemplate();
|
||||
@@ -139,13 +143,17 @@ public:
|
||||
LoadFlags flags);
|
||||
bool evaluateFile(const QString &fileName, QMakeHandler::EvalFileType type,
|
||||
LoadFlags flags);
|
||||
bool evaluateFeatureFile(const QString &fileName);
|
||||
bool evaluateFeatureFile(const QString &fileName, bool silent = false);
|
||||
bool evaluateFileInto(const QString &fileName, QMakeHandler::EvalFileType type,
|
||||
ProValueMap *values, // output-only
|
||||
LoadFlags flags);
|
||||
void message(int type, const QString &msg) const;
|
||||
void evalError(const QString &msg) const
|
||||
{ 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 ProString &arguments);
|
||||
|
||||
@@ -309,6 +309,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
||||
int parens = 0; // Braces in value context
|
||||
int argc = 0;
|
||||
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 lineMarked = true; // For in-expression markers
|
||||
ushort needSep = TokNewStr; // Complementary to putSpace: separator outside quotes
|
||||
@@ -372,7 +373,8 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
||||
ushort c;
|
||||
|
||||
// First, skip leading whitespace
|
||||
for (;; ++cur) {
|
||||
int indent;
|
||||
for (indent = 0; ; ++cur, ++indent) {
|
||||
c = *cur;
|
||||
if (c == '\n') {
|
||||
++cur;
|
||||
@@ -556,12 +558,14 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
||||
needSep = 0;
|
||||
goto nextChr;
|
||||
}
|
||||
} else if (c == '\\' && cur != end) {
|
||||
} else if (c == '\\') {
|
||||
static const char symbols[] = "[]{}()$\\'\"";
|
||||
ushort c2 = *cur;
|
||||
if (!(c2 & 0xff00) && strchr(symbols, c2)) {
|
||||
ushort c2;
|
||||
if (cur != end && !((c2 = *cur) & 0xff00) && strchr(symbols, c2)) {
|
||||
c = c2;
|
||||
cur++;
|
||||
} else {
|
||||
deprecationWarning(fL1S("Unescaped backslashes are deprecated"));
|
||||
}
|
||||
} else if (quote) {
|
||||
if (c == quote) {
|
||||
@@ -722,6 +726,9 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
||||
goto closeScope;
|
||||
}
|
||||
--parens;
|
||||
} else if (c == '=') {
|
||||
if (indent < lastIndent)
|
||||
languageWarning(fL1S("Possible accidental line continuation"));
|
||||
}
|
||||
}
|
||||
if (putSpace) {
|
||||
@@ -771,6 +778,8 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
||||
}
|
||||
} else if (context == CtxValue) {
|
||||
FLUSH_VALUE_LIST();
|
||||
if (parens)
|
||||
languageWarning(fL1S("Possible braces mismatch"));
|
||||
} else {
|
||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||
}
|
||||
@@ -780,6 +789,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in)
|
||||
goto freshLine;
|
||||
}
|
||||
|
||||
lastIndent = indent;
|
||||
lineMarked = false;
|
||||
ignore:
|
||||
cur = cptr;
|
||||
|
||||
@@ -46,11 +46,19 @@ class QMAKE_EXPORT QMakeParserHandler
|
||||
public:
|
||||
enum {
|
||||
CategoryMask = 0xf00,
|
||||
WarningMessage = 0x000,
|
||||
ErrorMessage = 0x100,
|
||||
|
||||
SourceMask = 0xf0,
|
||||
SourceParser = 0,
|
||||
|
||||
CodeMask = 0xf,
|
||||
WarnLanguage = 0,
|
||||
WarnDeprecated,
|
||||
|
||||
ParserWarnLanguage = SourceParser | WarningMessage | WarnLanguage,
|
||||
ParserWarnDeprecated = SourceParser | WarningMessage | WarnDeprecated,
|
||||
|
||||
ParserIoError = ErrorMessage | SourceParser,
|
||||
ParserError
|
||||
};
|
||||
@@ -123,6 +131,10 @@ private:
|
||||
void message(int type, const QString &msg) const;
|
||||
void parseError(const QString &msg) const
|
||||
{ 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
|
||||
ProFile *m_proFile;
|
||||
|
||||
@@ -43,18 +43,20 @@
|
||||
#include <QStringList>
|
||||
#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)
|
||||
qWarning("%s(%d): %s", qPrintable(fileName), lineNo, qPrintable(msg));
|
||||
qWarning("%s%s:%d: %s", qPrintable(pfx), qPrintable(fileName), lineNo, qPrintable(msg));
|
||||
else
|
||||
qWarning("%s", qPrintable(msg));
|
||||
qWarning("%s%s", qPrintable(pfx), qPrintable(msg));
|
||||
}
|
||||
|
||||
class EvalHandler : public QMakeHandler {
|
||||
public:
|
||||
virtual void message(int /* type */, const QString &msg, const QString &fileName, int lineNo)
|
||||
{ print(fileName, lineNo, msg); }
|
||||
virtual void message(int type, const QString &msg, const QString &fileName, int lineNo)
|
||||
{ print(fileName, lineNo, type, msg); }
|
||||
|
||||
virtual void fileMessage(const QString &msg)
|
||||
{ qWarning("%s", qPrintable(msg)); }
|
||||
|
||||
Reference in New Issue
Block a user