aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-01-17 22:47:31 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-01-17 22:47:31 +0000
commit69fdaf47471e5c0e35ac6eae352ac8fd05336cfd (patch)
treebac6f4bf119effdaedf40562d103a4c76d50e371
parentbc67d7b709d16a0b0dd0618953d1102a192f566f (diff)
downloadpaludis-69fdaf47471e5c0e35ac6eae352ac8fd05336cfd.tar.gz
paludis-69fdaf47471e5c0e35ac6eae352ac8fd05336cfd.tar.xz
USE flag goodness
-rw-r--r--paludis/default_config.cc56
-rw-r--r--paludis/default_config.hh58
-rw-r--r--paludis/default_environment.cc63
-rw-r--r--paludis/default_environment.hh2
-rw-r--r--paludis/dep_list.cc9
-rw-r--r--paludis/environment.hh4
-rw-r--r--paludis/fake_repository.cc6
-rw-r--r--paludis/fake_repository.hh2
-rw-r--r--paludis/files.m41
-rw-r--r--paludis/key_value_config_file.cc78
-rw-r--r--paludis/key_value_config_file.hh6
-rw-r--r--paludis/portage_repository.cc60
-rw-r--r--paludis/portage_repository.hh2
-rw-r--r--paludis/repository.hh9
-rw-r--r--paludis/test_environment.cc2
-rw-r--r--paludis/test_environment.hh2
-rw-r--r--paludis/use_flag_state.cc4
-rw-r--r--paludis/use_flag_state.hh37
-rw-r--r--src/install.cc2
19 files changed, 367 insertions, 36 deletions
diff --git a/paludis/default_config.cc b/paludis/default_config.cc
index 6848505..74c995d 100644
--- a/paludis/default_config.cc
+++ b/paludis/default_config.cc
@@ -108,11 +108,8 @@ DefaultConfig::DefaultConfig()
if (tokens.empty())
continue;
if ("*" == tokens.at(0))
- {
- _default_keywords.clear();
std::copy(++(tokens.begin()), tokens.end(),
create_inserter<KeywordName>(std::back_inserter(_default_keywords)));
- }
else
{
PackageDepAtom::ConstPointer a(new PackageDepAtom(tokens.at(0)));
@@ -195,5 +192,58 @@ DefaultConfig::DefaultConfig()
}
}
}
+
+ /* use */
+ {
+ std::list<FSEntry> files;
+ if (! getenv_with_default("PALUDIS_CONFIG_DIR", "").empty())
+ files.push_back(FSEntry(getenv_or_error("PALUDIS_CONFIG_DIR")) / "use.conf");
+ else
+ {
+ files.push_back(FSEntry(getenv_with_default("ROOT", "/") + "" SYSCONFDIR)
+ / "paludis" / "use.conf");
+ files.push_back(FSEntry(getenv_or_error("HOME")) / ".paludis" / "use.conf");
+ }
+
+ for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
+ file != file_end ; ++file)
+ {
+ Context local_context("When reading use file '" + stringify(*file) + "':");
+
+ if (! file->is_regular_file())
+ continue;
+
+ std::ifstream kf(stringify(*file).c_str());
+ if (! kf)
+ throw DefaultConfigError("Couldn't open " + stringify(*file));
+
+ LineConfigFile f(&kf);
+ for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ line != line_end ; ++line)
+ {
+ std::vector<std::string> tokens;
+ tokeniser.tokenise(*line, std::back_inserter(tokens));
+ if (tokens.empty())
+ continue;
+
+ if ("*" == tokens.at(0))
+ for (std::vector<std::string>::const_iterator t(++(tokens.begin())), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ {
+ if ('-' == t->at(0))
+ _default_use.push_back(std::make_pair(UseFlagName(t->substr(1)), use_disabled));
+ else
+ _default_use.push_back(std::make_pair(UseFlagName(*t), use_enabled));
+ }
+ else
+ {
+ }
+ }
+ }
+
+ if (_default_keywords.empty())
+ throw DefaultConfigError("No default keywords specified (a keywords.conf file should "
+ "contain an entry in the form '* keyword')");
+ }
}
diff --git a/paludis/default_config.hh b/paludis/default_config.hh
index f8c54f6..2c20eb8 100644
--- a/paludis/default_config.hh
+++ b/paludis/default_config.hh
@@ -28,6 +28,8 @@
#include <paludis/package_dep_atom.hh>
#include <paludis/keyword_name.hh>
#include <paludis/indirect_iterator.hh>
+#include <paludis/use_flag_state.hh>
+#include <paludis/use_flag_name.hh>
#include <map>
#include <vector>
@@ -49,8 +51,26 @@ namespace paludis
{
};
+ enum UseConfigEntryKeys
+ {
+ uce_dep_atom,
+ uce_flag_name,
+ uce_flag_state
+ };
+
+ struct UseConfigEntryTag :
+ SmartRecordTag<comparison_mode::NoComparisonTag, void>,
+ SmartRecordKeys<UseConfigEntryKeys, 3>,
+ SmartRecordKey<uce_dep_atom, DepAtom::ConstPointer>,
+ SmartRecordKey<uce_flag_name, UseFlagName>,
+ SmartRecordKey<uce_flag_state, UseFlagState>
+ {
+ };
+
typedef MakeSmartRecord<RepositoryConfigEntryTag>::Type RepositoryConfigEntry;
+ typedef MakeSmartRecord<UseConfigEntryTag>::Type UseConfigEntry;
+
class DefaultConfig :
public InstantiationPolicy<DefaultConfig, instantiation_method::SingletonAsNeededTag>
{
@@ -74,6 +94,12 @@ namespace paludis
std::vector<PackageDepAtom::ConstPointer> _empty_masks;
+ std::map<QualifiedPackageName, std::vector<UseConfigEntry> > _use;
+
+ std::vector<UseConfigEntry> _empty_use;
+
+ std::vector<std::pair<UseFlagName, UseFlagState> > _default_use;
+
public:
typedef std::list<RepositoryConfigEntry>::const_iterator RepositoryIterator;
@@ -163,6 +189,38 @@ namespace paludis
else
return _empty_masks.end();
}
+
+ typedef std::vector<UseConfigEntry>::const_iterator UseConfigIterator;
+
+ UseConfigIterator begin_use_config(const QualifiedPackageName & q) const
+ {
+ std::map<QualifiedPackageName, std::vector<UseConfigEntry> >::const_iterator r;
+ if (_use.end() != ((r = _use.find(q))))
+ return r->second.begin();
+ else
+ return _empty_use.begin();
+ }
+
+ UseConfigIterator end_use_config(const QualifiedPackageName & q) const
+ {
+ std::map<QualifiedPackageName, std::vector<UseConfigEntry> >::const_iterator r;
+ if (_use.end() != ((r = _use.find(q))))
+ return r->second.end();
+ else
+ return _empty_use.end();
+ }
+
+ typedef std::vector<std::pair<UseFlagName, UseFlagState> >::const_iterator DefaultUseIterator;
+
+ DefaultUseIterator begin_default_use() const
+ {
+ return _default_use.begin();
+ }
+
+ DefaultUseIterator end_default_use() const
+ {
+ return _default_use.end();
+ }
};
}
diff --git a/paludis/default_environment.cc b/paludis/default_environment.cc
index 29f0bd6..53b2980 100644
--- a/paludis/default_environment.cc
+++ b/paludis/default_environment.cc
@@ -23,6 +23,7 @@
#include "portage_repository.hh"
#include "default_config.hh"
#include "stringify.hh"
+#include "internal_error.hh"
#include <list>
#include <vector>
@@ -53,10 +54,68 @@ DefaultEnvironment::~DefaultEnvironment()
}
bool
-DefaultEnvironment::query_use(const UseFlagName &, const PackageDatabaseEntry * const) const
+DefaultEnvironment::query_use(const UseFlagName & f, const PackageDatabaseEntry & e) const
{
/// \todo
- return false;
+ /* prefer user masks, then profile, then disabled */
+ do
+ {
+#if 0
+ switch (DefaultConfig::get_instance()->query_use(f, e))
+ {
+ case use_enabled:
+ return true;
+
+ case use_disabled:
+ return false;
+
+ case use_unspecified:
+ continue;
+ }
+
+ throw InternalError(__PRETTY_FUNCTION__, "bad state");
+
+#endif
+ } while (false);
+
+
+ do
+ {
+ UseFlagState state(use_unspecified);
+
+ for (DefaultConfig::DefaultUseIterator
+ u(DefaultConfig::get_instance()->begin_default_use()),
+ u_end(DefaultConfig::get_instance()->end_default_use()) ;
+ u != u_end ; ++u)
+ if (f == u->first)
+ state = u->second;
+
+ switch (state)
+ {
+ case use_enabled:
+ return true;
+
+ case use_disabled:
+ return false;
+
+ case use_unspecified:
+ continue;
+ }
+
+ throw InternalError(__PRETTY_FUNCTION__, "bad state " + stringify(state));
+ } while (false);
+
+ switch (package_db()->fetch_repository(e.get<pde_repository>())->query_use(f))
+ {
+ case use_disabled:
+ case use_unspecified:
+ return false;
+
+ case use_enabled:
+ return true;
+ }
+
+ throw InternalError(__PRETTY_FUNCTION__, "bad state");
}
bool
diff --git a/paludis/default_environment.hh b/paludis/default_environment.hh
index 9aaea81..d5eaca1 100644
--- a/paludis/default_environment.hh
+++ b/paludis/default_environment.hh
@@ -49,7 +49,7 @@ namespace paludis
~DefaultEnvironment();
protected:
- virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry * const) const;
+ virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry &) const;
virtual bool accept_keyword(const KeywordName &, const PackageDatabaseEntry * const) const;
diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc
index c911f5c..c879c18 100644
--- a/paludis/dep_list.cc
+++ b/paludis/dep_list.cc
@@ -306,8 +306,11 @@ DepList::visit(const PackageDepAtom * const p)
void
DepList::visit(const UseDepAtom * const u)
{
+ if (! _implementation->current_package)
+ throw InternalError(__PRETTY_FUNCTION__, "current_package is 0");
+
if (_implementation->environment->query_use(u->flag(),
- _implementation->current_package) ^ u->inverse())
+ *_implementation->current_package) ^ u->inverse())
std::for_each(u->begin(), u->end(), std::bind1st(std::mem_fun(&DepList::add), this));
}
@@ -327,7 +330,7 @@ struct IsViable :
const UseDepAtom * u(0);
if (0 != ((u = dynamic_cast<const UseDepAtom *>(a.raw_pointer()))))
return _impl.environment->query_use(u->flag(),
- _impl.current_package) ^ u->inverse();
+ *_impl.current_package) ^ u->inverse();
else
return true;
}
@@ -348,6 +351,8 @@ DepList::visit(const AnyDepAtom * const a)
*/
std::list<DepAtom::ConstPointer> viable_children;
+ if (0 == _implementation->current_package)
+ throw InternalError(__PRETTY_FUNCTION__, "current_package is 0");
std::copy(a->begin(), a->end(), filter_inserter(
std::back_inserter(viable_children), IsViable(*_implementation)));
diff --git a/paludis/environment.hh b/paludis/environment.hh
index 5b0e4f4..57a2aa8 100644
--- a/paludis/environment.hh
+++ b/paludis/environment.hh
@@ -60,10 +60,10 @@ namespace paludis
public:
/**
- * Does the user want the specified USE flag set, possibly for a
+ * Does the user want the specified USE flag set for a
* particular package?
*/
- virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry * const) const = 0;
+ virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry &) const = 0;
/**
* Is the specified KEYWORD accepted?
diff --git a/paludis/fake_repository.cc b/paludis/fake_repository.cc
index b7a202d..bc71b1c 100644
--- a/paludis/fake_repository.cc
+++ b/paludis/fake_repository.cc
@@ -180,11 +180,11 @@ FakeRepository::do_query_profile_masks(const CategoryNamePart &,
return false;
}
-bool
-FakeRepository::do_query_use(const UseFlagName &, const bool & d) const
+UseFlagState
+FakeRepository::do_query_use(const UseFlagName &) const
{
/// \todo?
- return d;
+ return use_unspecified;
}
bool
diff --git a/paludis/fake_repository.hh b/paludis/fake_repository.hh
index 8abfcfa..4f0fe66 100644
--- a/paludis/fake_repository.hh
+++ b/paludis/fake_repository.hh
@@ -67,7 +67,7 @@ namespace paludis
virtual bool do_query_profile_masks(const CategoryNamePart &,
const PackageNamePart &, const VersionSpec &) const;
- virtual bool do_query_use(const UseFlagName &, const bool &) const;
+ virtual UseFlagState do_query_use(const UseFlagName &) const;
virtual bool do_query_use_mask(const UseFlagName &) const;
diff --git a/paludis/files.m4 b/paludis/files.m4
index 7d1431a..c62bf8c 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -110,6 +110,7 @@ add(`use_dep_atom', `hh', `cc')
add(`use_flag_name', `hh', `cc')
add(`use_flag_name_error', `hh', `cc')
add(`use_flag_name_validator', `hh', `cc')
+add(`use_flag_state', `hh', `cc')
add(`validated', `hh', `cc', `test')
add(`version_metadata', `hh', `cc')
add(`version_operator', `hh', `cc', `test')
diff --git a/paludis/key_value_config_file.cc b/paludis/key_value_config_file.cc
index 221747f..c2e3895 100644
--- a/paludis/key_value_config_file.cc
+++ b/paludis/key_value_config_file.cc
@@ -1,6 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
#include "key_value_config_file.hh"
+#include "internal_error.hh"
using namespace paludis;
@@ -21,6 +22,81 @@ KeyValueConfigFile::accept_line(const std::string & line) const
std::string key(line.substr(0, p)), value(line.substr(p + 1));
normalise_line(key);
normalise_line(value);
- _entries[key] = value;
+ _entries[key] = replace_variables(strip_quotes(value));
}
}
+
+std::string
+KeyValueConfigFile::replace_variables(const std::string & s) const
+{
+ std::string r;
+ std::string::size_type p(0), old_p(0);
+
+ while (p < s.length())
+ {
+ old_p = p;
+
+ if ('\\' == s[p])
+ {
+ if (++p >= s.length())
+ throw InternalError(__PRETTY_FUNCTION__, "todo");
+ r += s[p++];
+ }
+ else if ('$' != s[p])
+ r += s[p++];
+ else
+ {
+ std::string name;
+ if (++p >= s.length())
+ throw InternalError(__PRETTY_FUNCTION__, "todo"); /// \bug
+
+ if ('{' == s[p])
+ {
+ std::string::size_type q;
+ if (std::string::npos == ((q = s.find("}", p))))
+ throw InternalError(__PRETTY_FUNCTION__, "todo");
+
+ name = s.substr(p + 1, q - p - 1);
+ p = q + 1;
+ }
+ else
+ {
+ std::string::size_type q;
+ if (std::string::npos == ((q = s.find_first_not_of(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "_0123456789", p))))
+ q = s.length();
+
+ name = s.substr(p, q - p - 1);
+ if (name.empty())
+ throw InternalError(__PRETTY_FUNCTION__, "todo");
+ p = q;
+ }
+
+ r += get(name);
+ }
+
+ if (p <= old_p)
+ throw InternalError(__PRETTY_FUNCTION__, "Infinite loop");
+ }
+
+ return r;
+}
+
+std::string
+KeyValueConfigFile::strip_quotes(const std::string & s) const
+{
+ if (s.empty())
+ return s;
+ if (std::string::npos != std::string("'\"").find(s[0]))
+ {
+ if (s.length() < 2)
+ throw InternalError(__PRETTY_FUNCTION__, "todo");
+ if (s[s.length() - 1] != s[0])
+ throw InternalError(__PRETTY_FUNCTION__, "todo");
+ return s.substr(1, s.length() - 2);
+ }
+ else
+ return s;
+}
diff --git a/paludis/key_value_config_file.hh b/paludis/key_value_config_file.hh
index cf5aa84..b086198 100644
--- a/paludis/key_value_config_file.hh
+++ b/paludis/key_value_config_file.hh
@@ -29,6 +29,10 @@ namespace paludis
protected:
void accept_line(const std::string &) const;
+ std::string replace_variables(const std::string &) const;
+
+ std::string strip_quotes(const std::string &) const;
+
public:
KeyValueConfigFile(std::istream * const);
@@ -44,7 +48,7 @@ namespace paludis
return _entries.end();
}
- std::string get(const std::string & key)
+ std::string get(const std::string & key) const
{
return _entries[key];
}
diff --git a/paludis/portage_repository.cc b/paludis/portage_repository.cc
index 7662bd2..fc29a1d 100644
--- a/paludis/portage_repository.cc
+++ b/paludis/portage_repository.cc
@@ -27,6 +27,8 @@
#include "filter_insert_iterator.hh"
#include "translate_insert_iterator.hh"
#include "line_config_file.hh"
+#include "key_value_config_file.hh"
+#include "tokeniser.hh"
#include "indirect_iterator.hh"
#include "package_dep_atom.hh"
#include <map>
@@ -78,7 +80,11 @@ namespace paludis
/// Use mask.
mutable std::set<UseFlagName> use_mask;
- mutable bool has_use_mask;
+ /// Use.
+ mutable std::map<UseFlagName, UseFlagState> use;
+
+ /// Have we loaded our profile yet?
+ mutable bool has_profile;
/// Constructor.
Implementation(const FSEntry & l, const FSEntry & p) :
@@ -89,13 +95,13 @@ namespace paludis
{
}
- /// Add a use.mask file from a profile directory, recursive.
- void add_use_mask(const FSEntry & f) const;
+ /// Add a use.mask, use from a profile directory, recursive.
+ void add_profile(const FSEntry & f) const;
};
}
void
-Implementation<PortageRepository>::add_use_mask(const FSEntry & f) const
+Implementation<PortageRepository>::add_profile(const FSEntry & f) const
{
Context context("When reading profile directory '" + stringify(f) + "':");
@@ -109,11 +115,31 @@ Implementation<PortageRepository>::add_use_mask(const FSEntry & f) const
throw InternalError(__PRETTY_FUNCTION__, "todo"); /// \bug exception
LineConfigFile parent(&parent_file);
if (parent.begin() != parent.end())
- add_use_mask((f / *parent.begin()).realpath());
+ add_profile((f / *parent.begin()).realpath());
else
throw InternalError(__PRETTY_FUNCTION__, "todo"); /// \bug exception
}
+ if ((f / "make.defaults").exists())
+ {
+ static Tokeniser<delim_kind::AnyOfTag, delim_mode::DelimiterTag> tokeniser(" \t\n");
+
+ std::ifstream make_defaults_file(stringify(f / "make.defaults").c_str());
+ if (! make_defaults_file)
+ throw InternalError(__PRETTY_FUNCTION__, "todo"); /// \bug exception
+ KeyValueConfigFile make_defaults_f(&make_defaults_file);
+ std::vector<std::string> uses;
+ tokeniser.tokenise(make_defaults_f.get("USE"), std::back_inserter(uses));
+ for (std::vector<std::string>::const_iterator u(uses.begin()), u_end(uses.end()) ;
+ u != u_end ; ++u)
+ {
+ if ('-' == u->at(0))
+ use[UseFlagName(u->substr(1))] = use_disabled;
+ else
+ use[UseFlagName(*u)] = use_enabled;
+ }
+ }
+
if ((f / "use.mask").exists())
{
std::ifstream use_mask_file(stringify(f / "use.mask").c_str());
@@ -447,21 +473,31 @@ PortageRepository::do_query_profile_masks(const CategoryNamePart &,
return false;
}
-bool
-PortageRepository::do_query_use(const UseFlagName &, const bool & d) const
+UseFlagState
+PortageRepository::do_query_use(const UseFlagName & f) const
{
- /// \todo;
- return d;
+ if (! _implementation->has_profile)
+ {
+ Context context("When checking USE state for '" + stringify(f) + "':");
+ _implementation->add_profile(_implementation->profile.realpath());
+ _implementation->has_profile = true;
+ }
+
+ std::map<UseFlagName, UseFlagState>::const_iterator p;
+ if (_implementation->use.end() == ((p = _implementation->use.find(f))))
+ return use_unspecified;
+ else
+ return p->second;
}
bool
PortageRepository::do_query_use_mask(const UseFlagName & u) const
{
- if (! _implementation->has_use_mask)
+ if (! _implementation->has_profile)
{
Context context("When checking USE mask for '" + stringify(u) + "':");
- _implementation->add_use_mask(_implementation->profile.realpath());
- _implementation->has_use_mask = true;
+ _implementation->add_profile(_implementation->profile.realpath());
+ _implementation->has_profile = true;
}
return _implementation->use_mask.end() != _implementation->use_mask.find(u);
diff --git a/paludis/portage_repository.hh b/paludis/portage_repository.hh
index 9f43d12..dde847a 100644
--- a/paludis/portage_repository.hh
+++ b/paludis/portage_repository.hh
@@ -73,7 +73,7 @@ namespace paludis
virtual bool do_query_profile_masks(const CategoryNamePart &,
const PackageNamePart &, const VersionSpec &) const;
- virtual bool do_query_use(const UseFlagName &, const bool &) const;
+ virtual UseFlagState do_query_use(const UseFlagName &) const;
virtual bool do_query_use_mask(const UseFlagName &) const;
diff --git a/paludis/repository.hh b/paludis/repository.hh
index 00fcd2b..9de635d 100644
--- a/paludis/repository.hh
+++ b/paludis/repository.hh
@@ -29,6 +29,7 @@
#include <paludis/version_spec_collection.hh>
#include <paludis/counted_ptr.hh>
#include <paludis/version_metadata.hh>
+#include <paludis/use_flag_state.hh>
#include <map>
#include <string>
@@ -113,7 +114,7 @@ namespace paludis
/**
* Override in descendents: get use.
*/
- virtual bool do_query_use(const UseFlagName &, const bool &) const = 0;
+ virtual UseFlagState do_query_use(const UseFlagName &) const = 0;
/**
* Override in descendents: get use mask.
@@ -275,12 +276,12 @@ namespace paludis
return _info.end();
}
- bool query_use(const UseFlagName & u, const bool & def) const
+ UseFlagState query_use(const UseFlagName & u) const
{
if (do_query_use_mask(u))
- return false;
+ return use_disabled;
else
- return do_query_use(u, def);
+ return do_query_use(u);
}
bool query_use_mask(const UseFlagName & u) const
diff --git a/paludis/test_environment.cc b/paludis/test_environment.cc
index 0c8336a..7d947a3 100644
--- a/paludis/test_environment.cc
+++ b/paludis/test_environment.cc
@@ -28,7 +28,7 @@ TestEnvironment::TestEnvironment() :
}
bool
-TestEnvironment::query_use(const UseFlagName &, const PackageDatabaseEntry * const) const
+TestEnvironment::query_use(const UseFlagName &, const PackageDatabaseEntry &) const
{
/// \todo
return false;
diff --git a/paludis/test_environment.hh b/paludis/test_environment.hh
index f471c17..0d7bd57 100644
--- a/paludis/test_environment.hh
+++ b/paludis/test_environment.hh
@@ -38,7 +38,7 @@ namespace paludis
*/
TestEnvironment();
- virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry * const) const;
+ virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry &) const;
virtual bool accept_keyword(const KeywordName &, const PackageDatabaseEntry * const) const;
diff --git a/paludis/use_flag_state.cc b/paludis/use_flag_state.cc
new file mode 100644
index 0000000..66e7cc4
--- /dev/null
+++ b/paludis/use_flag_state.cc
@@ -0,0 +1,4 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+#include "use_flag_state.hh"
+
diff --git a/paludis/use_flag_state.hh b/paludis/use_flag_state.hh
new file mode 100644
index 0000000..b4c775f
--- /dev/null
+++ b/paludis/use_flag_state.hh
@@ -0,0 +1,37 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_USE_FLAG_STATE_HH
+#define PALUDIS_GUARD_PALUDIS_USE_FLAG_STATE_HH 1
+
+namespace paludis
+{
+ /**
+ * A USE flag can be on, off or unspecified.
+ */
+ enum UseFlagState
+ {
+ use_unspecified, /// unspecified
+ use_disabled, /// disabled
+ use_enabled /// enabled
+ };
+}
+
+#endif
diff --git a/src/install.cc b/src/install.cc
index 77b54b5..cc39d83 100644
--- a/src/install.cc
+++ b/src/install.cc
@@ -107,7 +107,7 @@ do_install()
for (p::VersionMetadata::IuseIterator i(metadata->begin_iuse()),
i_end(metadata->end_iuse()) ; i != i_end ; ++i)
{
- if (env->query_use(*i, &p))
+ if (env->query_use(*i, p))
cout << " " << colour(cl_flag_on, *i);
else if (env->package_db()->fetch_repository(dep->get<p::dle_repository>())->query_use_mask(*i))
cout << " " << colour(cl_flag_off, "(-" + p::stringify(*i) + ")");