inherit functions from the base config

the base config is read with a separate reader. we saved its variables,
but not its custom function definitions.
This commit is contained in:
Oswald Buddenhagen
2009-08-10 17:27:07 +02:00
parent 8e726a6d58
commit 94c4ea83bc
2 changed files with 71 additions and 24 deletions

View File

@@ -74,6 +74,25 @@ namespace {
} }
} // anon namespace } // anon namespace
static void refFunctions(QHash<QString, ProBlock *> *defs)
{
foreach (ProBlock *itm, *defs)
itm->ref();
}
static void clearFunctions(QHash<QString, ProBlock *> *defs)
{
foreach (ProBlock *itm, *defs)
itm->deref();
defs->clear();
}
static void clearFunctions(ProFileEvaluator::FunctionDefs *defs)
{
clearFunctions(&defs->replaceFunctions);
clearFunctions(&defs->testFunctions);
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
@@ -105,6 +124,11 @@ ProFileEvaluator::Option::Option()
field_sep = QLatin1String(" "); field_sep = QLatin1String(" ");
} }
ProFileEvaluator::Option::~Option()
{
clearFunctions(&base_functions);
}
QString ProFileEvaluator::Option::field_sep; QString ProFileEvaluator::Option::field_sep;
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
@@ -117,6 +141,7 @@ class ProFileEvaluator::Private : public AbstractProItemVisitor
{ {
public: public:
Private(ProFileEvaluator *q_, ProFileEvaluator::Option *option); Private(ProFileEvaluator *q_, ProFileEvaluator::Option *option);
~Private();
ProFileEvaluator *q; ProFileEvaluator *q;
int m_lineNo; // Error reporting int m_lineNo; // Error reporting
@@ -184,8 +209,10 @@ public:
ProItem::ProItemReturn evaluateConditionalFunction(const QString &function, const QString &arguments); ProItem::ProItemReturn evaluateConditionalFunction(const QString &function, const QString &arguments);
bool evaluateFile(const QString &fileName); bool evaluateFile(const QString &fileName);
bool evaluateFeatureFile(const QString &fileName, QHash<QString, QStringList> *values = 0); bool evaluateFeatureFile(const QString &fileName,
bool evaluateFileInto(const QString &fileName, QHash<QString, QStringList> *values); QHash<QString, QStringList> *values = 0, FunctionDefs *defs = 0);
bool evaluateFileInto(const QString &fileName,
QHash<QString, QStringList> *values, FunctionDefs *defs);
static inline ProItem::ProItemReturn returnBool(bool b) static inline ProItem::ProItemReturn returnBool(bool b)
{ return b ? ProItem::ReturnTrue : ProItem::ReturnFalse; } { return b ? ProItem::ReturnTrue : ProItem::ReturnFalse; }
@@ -220,8 +247,7 @@ public:
bool m_definingTest; bool m_definingTest;
QString m_definingFunc; QString m_definingFunc;
QHash<QString, ProBlock *> m_testFunctions; FunctionDefs m_functionDefs;
QHash<QString, ProBlock *> m_replaceFunctions;
QStringList m_returnValue; QStringList m_returnValue;
QStack<QHash<QString, QStringList> > m_valuemapStack; QStack<QHash<QString, QStringList> > m_valuemapStack;
QStack<QHash<const ProFile*, QHash<QString, QStringList> > > m_filevaluemapStack; QStack<QHash<const ProFile*, QHash<QString, QStringList> > > m_filevaluemapStack;
@@ -254,6 +280,11 @@ ProFileEvaluator::Private::Private(ProFileEvaluator *q_, ProFileEvaluator::Optio
m_definingFunc.clear(); m_definingFunc.clear();
} }
ProFileEvaluator::Private::~Private()
{
clearFunctions(&m_functionDefs);
}
////////// Parser /////////// ////////// Parser ///////////
bool ProFileEvaluator::Private::read(ProFile *pro) bool ProFileEvaluator::Private::read(ProFile *pro)
@@ -891,7 +922,8 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProBlock(ProBlock *b
if (!m_definingFunc.isEmpty()) { if (!m_definingFunc.isEmpty()) {
if (!m_skipLevel || m_cumulative) { if (!m_skipLevel || m_cumulative) {
QHash<QString, ProBlock *> *hash = QHash<QString, ProBlock *> *hash =
(m_definingTest ? &m_testFunctions : &m_replaceFunctions); (m_definingTest ? &m_functionDefs.testFunctions
: &m_functionDefs.replaceFunctions);
if (ProBlock *def = hash->value(m_definingFunc)) if (ProBlock *def = hash->value(m_definingFunc))
def->deref(); def->deref();
hash->insert(m_definingFunc, block); hash->insert(m_definingFunc, block);
@@ -1107,7 +1139,7 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProFile(ProFile * pr
} }
if (!qmake_cache.isEmpty()) { if (!qmake_cache.isEmpty()) {
qmake_cache = QDir::cleanPath(qmake_cache); qmake_cache = QDir::cleanPath(qmake_cache);
if (evaluateFileInto(qmake_cache, &m_option->cache_valuemap)) { if (evaluateFileInto(qmake_cache, &m_option->cache_valuemap, 0)) {
m_option->cachefile = qmake_cache; m_option->cachefile = qmake_cache;
if (m_option->qmakespec.isEmpty()) { if (m_option->qmakespec.isEmpty()) {
const QStringList &vals = m_option->cache_valuemap.value(QLatin1String("QMAKESPEC")); const QStringList &vals = m_option->cache_valuemap.value(QLatin1String("QMAKESPEC"));
@@ -1161,18 +1193,25 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProFile(ProFile * pr
m_option->qmakespec = QDir::cleanPath(qmakespec); m_option->qmakespec = QDir::cleanPath(qmakespec);
QString spec = m_option->qmakespec + QLatin1String("/qmake.conf"); QString spec = m_option->qmakespec + QLatin1String("/qmake.conf");
if (!evaluateFileInto(spec, &m_option->base_valuemap)) { if (!evaluateFileInto(spec,
&m_option->base_valuemap, &m_option->base_functions)) {
q->errorMessage(format("Could not read qmake configuration file %1").arg(spec)); q->errorMessage(format("Could not read qmake configuration file %1").arg(spec));
} else { } else {
updateHash(&m_option->base_valuemap, m_option->cache_valuemap); updateHash(&m_option->base_valuemap, m_option->cache_valuemap);
} }
} }
evaluateFeatureFile(QLatin1String("default_pre.prf"), &m_option->base_valuemap); evaluateFeatureFile(QLatin1String("default_pre.prf"),
&m_option->base_valuemap, &m_option->base_functions);
} }
m_valuemap = m_option->base_valuemap; m_valuemap = m_option->base_valuemap;
clearFunctions(&m_functionDefs);
m_functionDefs = m_option->base_functions;
refFunctions(&m_functionDefs.testFunctions);
refFunctions(&m_functionDefs.replaceFunctions);
QStringList &tgt = m_valuemap[QLatin1String("TARGET")]; QStringList &tgt = m_valuemap[QLatin1String("TARGET")];
if (tgt.isEmpty()) if (tgt.isEmpty())
tgt.append(QFileInfo(pro->fileName()).baseName()); tgt.append(QFileInfo(pro->fileName()).baseName());
@@ -1213,13 +1252,6 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
break; break;
} }
} }
foreach (ProBlock *itm, m_replaceFunctions)
itm->deref();
m_replaceFunctions.clear();
foreach (ProBlock *itm, m_testFunctions)
itm->deref();
m_testFunctions.clear();
} }
m_profileStack.pop(); m_profileStack.pop();
@@ -1669,7 +1701,7 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
{ {
QStringList argumentsList = split_arg_list(arguments); QStringList argumentsList = split_arg_list(arguments);
if (ProBlock *funcPtr = m_replaceFunctions.value(func, 0)) if (ProBlock *funcPtr = m_functionDefs.replaceFunctions.value(func, 0))
return evaluateFunction(funcPtr, argumentsList, 0); return evaluateFunction(funcPtr, argumentsList, 0);
QStringList args; QStringList args;
@@ -2079,7 +2111,7 @@ ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
{ {
QStringList argumentsList = split_arg_list(arguments); QStringList argumentsList = split_arg_list(arguments);
if (ProBlock *funcPtr = m_testFunctions.value(function, 0)) { if (ProBlock *funcPtr = m_functionDefs.testFunctions.value(function, 0)) {
bool ok; bool ok;
QStringList ret = evaluateFunction(funcPtr, argumentsList, &ok); QStringList ret = evaluateFunction(funcPtr, argumentsList, &ok);
if (ok) { if (ok) {
@@ -2176,15 +2208,15 @@ ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
} }
if (args.count() > 1) { if (args.count() > 1) {
if (args[1] == QLatin1String("test")) if (args[1] == QLatin1String("test"))
return returnBool(m_testFunctions.contains(args[0])); return returnBool(m_functionDefs.testFunctions.contains(args[0]));
else if (args[1] == QLatin1String("replace")) else if (args[1] == QLatin1String("replace"))
return returnBool(m_replaceFunctions.contains(args[0])); return returnBool(m_functionDefs.replaceFunctions.contains(args[0]));
q->logMessage(format("defined(function, type):" q->logMessage(format("defined(function, type):"
" unexpected type [%1].\n").arg(args[1])); " unexpected type [%1].\n").arg(args[1]));
return ProItem::ReturnFalse; return ProItem::ReturnFalse;
} }
return returnBool(m_replaceFunctions.contains(args[0]) return returnBool(m_functionDefs.replaceFunctions.contains(args[0])
|| m_testFunctions.contains(args[0])); || m_functionDefs.testFunctions.contains(args[0]));
case T_RETURN: case T_RETURN:
m_returnValue = args; m_returnValue = args;
// It is "safe" to ignore returns - due to qmake brokeness // It is "safe" to ignore returns - due to qmake brokeness
@@ -2761,7 +2793,7 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName)
} }
bool ProFileEvaluator::Private::evaluateFeatureFile( bool ProFileEvaluator::Private::evaluateFeatureFile(
const QString &fileName, QHash<QString, QStringList> *values) const QString &fileName, QHash<QString, QStringList> *values, FunctionDefs *funcs)
{ {
QString fn = fileName; QString fn = fileName;
if (!fn.endsWith(QLatin1String(".prf"))) if (!fn.endsWith(QLatin1String(".prf")))
@@ -2799,7 +2831,7 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(
} }
if (values) { if (values) {
return evaluateFileInto(fn, values); return evaluateFileInto(fn, values, funcs);
} else { } else {
bool cumulative = m_cumulative; bool cumulative = m_cumulative;
m_cumulative = false; m_cumulative = false;
@@ -2817,16 +2849,24 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(
} }
bool ProFileEvaluator::Private::evaluateFileInto( bool ProFileEvaluator::Private::evaluateFileInto(
const QString &fileName, QHash<QString, QStringList> *values) const QString &fileName, QHash<QString, QStringList> *values, FunctionDefs *funcs)
{ {
ProFileEvaluator visitor(m_option); ProFileEvaluator visitor(m_option);
visitor.d->m_cumulative = false; visitor.d->m_cumulative = false;
visitor.d->m_parsePreAndPostFiles = false; visitor.d->m_parsePreAndPostFiles = false;
visitor.d->m_verbose = m_verbose; visitor.d->m_verbose = m_verbose;
visitor.d->m_valuemap = *values; visitor.d->m_valuemap = *values;
if (funcs)
visitor.d->m_functionDefs = *funcs;
if (!visitor.d->evaluateFile(fileName)) if (!visitor.d->evaluateFile(fileName))
return false; return false;
*values = visitor.d->m_valuemap; *values = visitor.d->m_valuemap;
if (funcs) {
*funcs = visitor.d->m_functionDefs;
// So they are not unref'd
visitor.d->m_functionDefs.testFunctions.clear();
visitor.d->m_functionDefs.replaceFunctions.clear();
}
return true; return true;
} }

View File

@@ -45,10 +45,16 @@ class ProFileEvaluator
class Private; class Private;
public: public:
struct FunctionDefs {
QHash<QString, ProBlock *> testFunctions;
QHash<QString, ProBlock *> replaceFunctions;
};
// This struct is from qmake, but we are not using everything. // This struct is from qmake, but we are not using everything.
struct Option struct Option
{ {
Option(); Option();
~Option();
//simply global convenience //simply global convenience
//QString libtool_ext; //QString libtool_ext;
@@ -84,6 +90,7 @@ public:
static QString field_sep; // Just a cache for quick construction static QString field_sep; // Just a cache for quick construction
QHash<QString, QStringList> cache_valuemap; // Cached results of .qmake.cache QHash<QString, QStringList> cache_valuemap; // Cached results of .qmake.cache
QHash<QString, QStringList> base_valuemap; // ~ and qmake.conf and default_pre.prf QHash<QString, QStringList> base_valuemap; // ~ and qmake.conf and default_pre.prf
FunctionDefs base_functions;
QStringList feature_roots; QStringList feature_roots;
}; };