From 09958bdb72e1ae4627c67485d94ae3b5e794a68c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 23 Aug 2016 14:05:54 +0200 Subject: [PATCH] add discard_from() function this function discards all values that come from a specific file. it will be needed for configure bootstrapping, but is too obscure to document it for general use. Change-Id: I62c18aeb1847712e33d0599dbb0b90ffa1722438 Reviewed-by: Lars Knoll (cherry picked from qtbase/12bb328bb0be8efe54aae750c21938aab4d17539) Reviewed-by: Jake Petroules --- src/linguist/shared/qmakebuiltins.cpp | 37 ++++++++++++++++++++++++++- src/linguist/shared/qmakeparser.cpp | 10 +++++--- src/linguist/shared/qmakeparser.h | 3 ++- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/linguist/shared/qmakebuiltins.cpp b/src/linguist/shared/qmakebuiltins.cpp index b19c890791..19fc6d639c 100644 --- a/src/linguist/shared/qmakebuiltins.cpp +++ b/src/linguist/shared/qmakebuiltins.cpp @@ -52,6 +52,8 @@ # include #endif +#include + #ifdef Q_OS_UNIX #include #include @@ -97,7 +99,7 @@ enum ExpandFunc { enum TestFunc { T_INVALID = 0, T_REQUIRES, T_GREATERTHAN, T_LESSTHAN, T_EQUALS, T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM, - T_DEFINED, T_CONTAINS, T_INFILE, + T_DEFINED, T_DISCARD_FROM, T_CONTAINS, T_INFILE, T_COUNT, T_ISEMPTY, T_PARSE_JSON, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF, T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE }; @@ -178,6 +180,7 @@ void QMakeEvaluator::initFunctionStatics() { "if", T_IF }, { "isActiveConfig", T_CONFIG }, { "system", T_SYSTEM }, + { "discard_from", T_DISCARD_FROM }, { "defined", T_DEFINED }, { "contains", T_CONTAINS }, { "infile", T_INFILE }, @@ -1294,6 +1297,38 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } return ReturnTrue; } + case T_DISCARD_FROM: { + if (args.count() != 1 || args.at(0).isEmpty()) { + evalError(fL1S("discard_from(file) requires one argument.")); + return ReturnFalse; + } + if (m_valuemapStack.count() != 1) { + evalError(fL1S("discard_from() cannot be called from functions.")); + return ReturnFalse; + } + QString fn = resolvePath(args.at(0).toQString(m_tmp1)); + ProFile *pro = m_parser->parsedProFile(fn, QMakeParser::ParseOnlyCached); + if (!pro) + return ReturnFalse; + ProValueMap &vmap = m_valuemapStack.first(); + for (auto vit = vmap.begin(); vit != vmap.end(); ) { + if (!vit->isEmpty()) { + auto isFrom = [pro](const ProString &s) { + return s.sourceFile() == pro; + }; + vit->erase(std::remove_if(vit->begin(), vit->end(), isFrom), vit->end()); + if (vit->isEmpty()) { + // When an initially non-empty variable becomes entirely empty, + // undefine it altogether. + vit = vmap.erase(vit); + continue; + } + } + ++vit; + } + pro->deref(); + return ReturnTrue; + } case T_INFILE: if (args.count() < 2 || args.count() > 3) { evalError(fL1S("infile(file, var, [values]) requires two or three arguments.")); diff --git a/src/linguist/shared/qmakeparser.cpp b/src/linguist/shared/qmakeparser.cpp index b50f91a7a8..6f0047bf58 100644 --- a/src/linguist/shared/qmakeparser.cpp +++ b/src/linguist/shared/qmakeparser.cpp @@ -165,7 +165,7 @@ QMakeParser::QMakeParser(ProFileCache *cache, QMakeVfs *vfs, QMakeParserHandler ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags) { ProFile *pro; - if ((flags & ParseUseCache) && m_cache) { + if ((flags & (ParseUseCache|ParseOnlyCached)) && m_cache) { ProFileCache::Entry *ent; #ifdef PROPARSER_THREAD_SAFE QMutexLocker locker(&m_cache->mutex); @@ -187,7 +187,7 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags) #endif if ((pro = ent->pro)) pro->ref(); - } else { + } else if (!(flags & ParseOnlyCached)) { ent = &m_cache->parsed_files[fileName]; #ifdef PROPARSER_THREAD_SAFE ent->locker = new ProFileCache::Entry::Locker; @@ -212,13 +212,17 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags) ent->locker = 0; } #endif + } else { + pro = 0; } - } else { + } else if (!(flags & ParseOnlyCached)) { pro = new ProFile(fileName); if (!read(pro, flags)) { delete pro; pro = 0; } + } else { + pro = 0; } return pro; } diff --git a/src/linguist/shared/qmakeparser.h b/src/linguist/shared/qmakeparser.h index c923c4a052..0b25ade90e 100644 --- a/src/linguist/shared/qmakeparser.h +++ b/src/linguist/shared/qmakeparser.h @@ -78,7 +78,8 @@ class QMAKE_EXPORT QMakeParser enum ParseFlag { ParseDefault = 0, ParseUseCache = 1, - ParseReportMissing = 2 + ParseOnlyCached = 2, + ParseReportMissing = 4 }; Q_DECLARE_FLAGS(ParseFlags, ParseFlag)