0
0
Fork 0
forked from lix-project/lix

* Refactoring: move derivation evaluation to libexpr.

This commit is contained in:
Eelco Dolstra 2006-02-08 13:21:16 +00:00
parent 4db4b61380
commit 39f50db731
4 changed files with 209 additions and 187 deletions

View file

@ -3,7 +3,8 @@ lib_LTLIBRARIES = libexpr.la
libexpr_la_SOURCES = nixexpr.cc nixexpr.hh parser.cc parser.hh \ libexpr_la_SOURCES = nixexpr.cc nixexpr.hh parser.cc parser.hh \
eval.cc eval.hh primops.cc \ eval.cc eval.hh primops.cc \
lexer-tab.c lexer-tab.h parser-tab.c parser-tab.h \ lexer-tab.c lexer-tab.h parser-tab.c parser-tab.h \
nixexpr-ast.hh nixexpr-ast.hh \
get-drvs.cc get-drvs.hh
EXTRA_DIST = lexer.l parser.y nixexpr-ast.def nixexpr-ast.cc EXTRA_DIST = lexer.l parser.y nixexpr-ast.def nixexpr-ast.cc

67
src/libexpr/get-drvs.cc Normal file
View file

@ -0,0 +1,67 @@
#include "get-drvs.hh"
#include "nixexpr-ast.hh"
bool getDerivation(EvalState & state, Expr e, DrvInfo & drv)
{
ATermList es;
e = evalExpr(state, e);
if (!matchAttrs(e, es)) return false;
ATermMap attrs;
queryAllAttrs(e, attrs, false);
Expr a = attrs.get("type");
if (!a || evalString(state, a) != "derivation") return false;
a = attrs.get("name");
if (!a) throw badTerm("derivation name missing", e);
drv.name = evalString(state, a);
a = attrs.get("system");
if (!a)
drv.system = "unknown";
else
drv.system = evalString(state, a);
drv.attrs = attrs;
return true;
}
void getDerivations(EvalState & state, Expr e, DrvInfos & drvs)
{
ATermList es;
DrvInfo drv;
e = evalExpr(state, e);
if (getDerivation(state, e, drv))
drvs.push_back(drv);
else if (matchAttrs(e, es)) {
ATermMap drvMap;
queryAllAttrs(e, drvMap);
for (ATermIterator i(drvMap.keys()); i; ++i) {
debug(format("evaluating attribute `%1%'") % aterm2String(*i));
if (getDerivation(state, drvMap.get(*i), drv))
drvs.push_back(drv);
else
;
// parseDerivations(state, drvMap.get(*i), drvs);
}
}
else if (matchList(e, es)) {
for (ATermIterator i(es); i; ++i) {
debug(format("evaluating list element"));
if (getDerivation(state, *i, drv))
drvs.push_back(drv);
else
getDerivations(state, *i, drvs);
}
}
}

64
src/libexpr/get-drvs.hh Normal file
View file

@ -0,0 +1,64 @@
#ifndef __GET_DRVS_H
#define __GET_DRVS_H
#include <string>
#include <map>
#include "eval.hh"
struct DrvInfo
{
private:
string drvPath;
string outPath;
public:
string name;
string system;
ATermMap attrs;
string queryDrvPath(EvalState & state) const
{
if (drvPath == "") {
Expr a = attrs.get("drvPath");
(string &) drvPath = a ? evalPath(state, a) : "";
}
return drvPath;
}
string queryOutPath(EvalState & state) const
{
if (outPath == "") {
Expr a = attrs.get("outPath");
if (!a) throw Error("output path missing");
(string &) outPath = evalPath(state, a);
}
return outPath;
}
void setDrvPath(const string & s)
{
drvPath = s;
}
void setOutPath(const string & s)
{
outPath = s;
}
};
typedef list<DrvInfo> DrvInfos;
/* Evaluate expression `e'. If it evaluates to a derivation, store
information about the derivation in `drv' and return true.
Otherwise, return false. */
bool getDerivation(EvalState & state, Expr e, DrvInfo & drv);
void getDerivations(EvalState & state, Expr e, DrvInfos & drvs);
#endif /* !__GET_DRVS_H */

View file

@ -8,6 +8,7 @@
#include "eval.hh" #include "eval.hh"
#include "help.txt.hh" #include "help.txt.hh"
#include "nixexpr-ast.hh" #include "nixexpr-ast.hh"
#include "get-drvs.hh"
#include <cerrno> #include <cerrno>
#include <ctime> #include <ctime>
@ -49,133 +50,23 @@ typedef void (* Operation) (Globals & globals,
Strings opFlags, Strings opArgs); Strings opFlags, Strings opArgs);
struct UserEnvElem
{
private:
string drvPath;
string outPath;
public:
string name;
string system;
ATermMap attrs;
string queryDrvPath(EvalState & state) const
{
if (drvPath == "") {
Expr a = attrs.get("drvPath");
(string &) drvPath = a ? evalPath(state, a) : "";
}
return drvPath;
}
string queryOutPath(EvalState & state) const
{
if (outPath == "") {
Expr a = attrs.get("outPath");
if (!a) throw Error("output path missing");
(string &) outPath = evalPath(state, a);
}
return outPath;
}
void setDrvPath(const string & s)
{
drvPath = s;
}
void setOutPath(const string & s)
{
outPath = s;
}
};
typedef map<unsigned int, UserEnvElem> UserEnvElems;
void printHelp() void printHelp()
{ {
cout << string((char *) helpText, sizeof helpText); cout << string((char *) helpText, sizeof helpText);
} }
static bool parseDerivation(EvalState & state, Expr e, UserEnvElem & elem)
{
ATermList es;
e = evalExpr(state, e);
if (!matchAttrs(e, es)) return false;
ATermMap attrs;
queryAllAttrs(e, attrs, false);
Expr a = attrs.get("type");
if (!a || evalString(state, a) != "derivation") return false;
a = attrs.get("name");
if (!a) throw badTerm("derivation name missing", e);
elem.name = evalString(state, a);
a = attrs.get("system");
if (!a)
elem.system = "unknown";
else
elem.system = evalString(state, a);
elem.attrs = attrs;
return true;
}
static unsigned int elemCounter = 0;
static void parseDerivations(EvalState & state, Expr e, UserEnvElems & elems)
{
ATermList es;
UserEnvElem elem;
e = evalExpr(state, e);
if (parseDerivation(state, e, elem))
elems[elemCounter++] = elem;
else if (matchAttrs(e, es)) {
ATermMap drvMap;
queryAllAttrs(e, drvMap);
for (ATermIterator i(drvMap.keys()); i; ++i) {
debug(format("evaluating attribute `%1%'") % aterm2String(*i));
if (parseDerivation(state, drvMap.get(*i), elem))
elems[elemCounter++] = elem;
else
parseDerivations(state, drvMap.get(*i), elems);
}
}
else if (matchList(e, es)) {
for (ATermIterator i(es); i; ++i) {
debug(format("evaluating list element"));
if (parseDerivation(state, *i, elem))
elems[elemCounter++] = elem;
else
parseDerivations(state, *i, elems);
}
}
}
static void loadDerivations(EvalState & state, Path nixExprPath, static void loadDerivations(EvalState & state, Path nixExprPath,
string systemFilter, UserEnvElems & elems) string systemFilter, DrvInfos & elems)
{ {
parseDerivations(state, getDerivations(state,
parseExprFromFile(state, absPath(nixExprPath)), elems); parseExprFromFile(state, absPath(nixExprPath)), elems);
/* Filter out all derivations not applicable to the current /* Filter out all derivations not applicable to the current
system. */ system. */
for (UserEnvElems::iterator i = elems.begin(), j; i != elems.end(); i = j) { for (DrvInfos::iterator i = elems.begin(), j; i != elems.end(); i = j) {
j = i; j++; j = i; j++;
if (systemFilter != "*" && i->second.system != systemFilter) if (systemFilter != "*" && i->system != systemFilter)
elems.erase(i); elems.erase(i);
} }
} }
@ -208,12 +99,12 @@ struct AddPos : TermFun
}; };
static UserEnvElems queryInstalled(EvalState & state, const Path & userEnv) static DrvInfos queryInstalled(EvalState & state, const Path & userEnv)
{ {
Path path = userEnv + "/manifest"; Path path = userEnv + "/manifest";
if (!pathExists(path)) if (!pathExists(path))
return UserEnvElems(); /* not an error, assume nothing installed */ return DrvInfos(); /* not an error, assume nothing installed */
Expr e = ATreadFromNamedFile(path.c_str()); Expr e = ATreadFromNamedFile(path.c_str());
if (!e) throw Error(format("cannot read Nix expression from `%1%'") % path); if (!e) throw Error(format("cannot read Nix expression from `%1%'") % path);
@ -222,25 +113,25 @@ static UserEnvElems queryInstalled(EvalState & state, const Path & userEnv)
AddPos addPos; AddPos addPos;
e = bottomupRewrite(addPos, e); e = bottomupRewrite(addPos, e);
UserEnvElems elems; DrvInfos elems;
parseDerivations(state, e, elems); getDerivations(state, e, elems);
return elems; return elems;
} }
static void createUserEnv(EvalState & state, const UserEnvElems & elems, static void createUserEnv(EvalState & state, const DrvInfos & elems,
const Path & profile, bool keepDerivations) const Path & profile, bool keepDerivations)
{ {
/* Build the components in the user environment, if they don't /* Build the components in the user environment, if they don't
exist already. */ exist already. */
PathSet drvsToBuild; PathSet drvsToBuild;
for (UserEnvElems::const_iterator i = elems.begin(); for (DrvInfos::const_iterator i = elems.begin();
i != elems.end(); ++i) i != elems.end(); ++i)
/* Call to `isDerivation' is for compatibility with Nix <= 0.7 /* Call to `isDerivation' is for compatibility with Nix <= 0.7
user environments. */ user environments. */
if (i->second.queryDrvPath(state) != "" && if (i->queryDrvPath(state) != "" &&
isDerivation(i->second.queryDrvPath(state))) isDerivation(i->queryDrvPath(state)))
drvsToBuild.insert(i->second.queryDrvPath(state)); drvsToBuild.insert(i->queryDrvPath(state));
debug(format("building user environment dependencies")); debug(format("building user environment dependencies"));
buildDerivations(drvsToBuild); buildDerivations(drvsToBuild);
@ -253,31 +144,31 @@ static void createUserEnv(EvalState & state, const UserEnvElems & elems,
PathSet references; PathSet references;
ATermList manifest = ATempty; ATermList manifest = ATempty;
ATermList inputs = ATempty; ATermList inputs = ATempty;
for (UserEnvElems::const_iterator i = elems.begin(); for (DrvInfos::const_iterator i = elems.begin();
i != elems.end(); ++i) i != elems.end(); ++i)
{ {
Path drvPath = keepDerivations ? i->second.queryDrvPath(state) : ""; Path drvPath = keepDerivations ? i->queryDrvPath(state) : "";
ATerm t = makeAttrs(ATmakeList5( ATerm t = makeAttrs(ATmakeList5(
makeBind(toATerm("type"), makeBind(toATerm("type"),
makeStr(toATerm("derivation")), makeNoPos()), makeStr(toATerm("derivation")), makeNoPos()),
makeBind(toATerm("name"), makeBind(toATerm("name"),
makeStr(toATerm(i->second.name)), makeNoPos()), makeStr(toATerm(i->name)), makeNoPos()),
makeBind(toATerm("system"), makeBind(toATerm("system"),
makeStr(toATerm(i->second.system)), makeNoPos()), makeStr(toATerm(i->system)), makeNoPos()),
makeBind(toATerm("drvPath"), makeBind(toATerm("drvPath"),
makePath(toATerm(drvPath)), makeNoPos()), makePath(toATerm(drvPath)), makeNoPos()),
makeBind(toATerm("outPath"), makeBind(toATerm("outPath"),
makePath(toATerm(i->second.queryOutPath(state))), makeNoPos()) makePath(toATerm(i->queryOutPath(state))), makeNoPos())
)); ));
manifest = ATinsert(manifest, t); manifest = ATinsert(manifest, t);
inputs = ATinsert(inputs, makeStr(toATerm(i->second.queryOutPath(state)))); inputs = ATinsert(inputs, makeStr(toATerm(i->queryOutPath(state))));
/* This is only necessary when installing store paths, e.g., /* This is only necessary when installing store paths, e.g.,
`nix-env -i /nix/store/abcd...-foo'. */ `nix-env -i /nix/store/abcd...-foo'. */
addTempRoot(i->second.queryOutPath(state)); addTempRoot(i->queryOutPath(state));
ensurePath(i->second.queryOutPath(state)); ensurePath(i->queryOutPath(state));
references.insert(i->second.queryOutPath(state)); references.insert(i->queryOutPath(state));
if (drvPath != "") references.insert(drvPath); if (drvPath != "") references.insert(drvPath);
} }
@ -302,8 +193,8 @@ static void createUserEnv(EvalState & state, const UserEnvElems & elems,
/* Instantiate it. */ /* Instantiate it. */
debug(format("evaluating builder expression `%1%'") % topLevel); debug(format("evaluating builder expression `%1%'") % topLevel);
UserEnvElem topLevelDrv; DrvInfo topLevelDrv;
if (!parseDerivation(state, topLevel, topLevelDrv)) if (!getDerivation(state, topLevel, topLevelDrv))
abort(); abort();
/* Realise the resulting store expression. */ /* Realise the resulting store expression. */
@ -317,24 +208,24 @@ static void createUserEnv(EvalState & state, const UserEnvElems & elems,
} }
static UserEnvElems filterBySelector(const UserEnvElems & allElems, static DrvInfos filterBySelector(const DrvInfos & allElems,
const Strings & args) const Strings & args)
{ {
DrvNames selectors = drvNamesFromArgs(args); DrvNames selectors = drvNamesFromArgs(args);
UserEnvElems elems; DrvInfos elems;
/* Filter out the ones we're not interested in. */ /* Filter out the ones we're not interested in. */
for (UserEnvElems::const_iterator i = allElems.begin(); for (DrvInfos::const_iterator i = allElems.begin();
i != allElems.end(); ++i) i != allElems.end(); ++i)
{ {
DrvName drvName(i->second.name); DrvName drvName(i->name);
for (DrvNames::iterator j = selectors.begin(); for (DrvNames::iterator j = selectors.begin();
j != selectors.end(); ++j) j != selectors.end(); ++j)
{ {
if (j->matches(drvName)) { if (j->matches(drvName)) {
j->hits++; j->hits++;
elems.insert(*i); elems.push_back(*i);
} }
} }
} }
@ -352,7 +243,7 @@ static UserEnvElems filterBySelector(const UserEnvElems & allElems,
static void queryInstSources(EvalState & state, static void queryInstSources(EvalState & state,
const InstallSourceInfo & instSource, const Strings & args, const InstallSourceInfo & instSource, const Strings & args,
UserEnvElems & elems) DrvInfos & elems)
{ {
InstallSourceType type = instSource.type; InstallSourceType type = instSource.type;
if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/') if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/')
@ -368,7 +259,7 @@ static void queryInstSources(EvalState & state,
/* Load the derivations from the (default or specified) /* Load the derivations from the (default or specified)
Nix expression. */ Nix expression. */
UserEnvElems allElems; DrvInfos allElems;
loadDerivations(state, instSource.nixExprPath, loadDerivations(state, instSource.nixExprPath,
instSource.systemFilter, allElems); instSource.systemFilter, allElems);
@ -394,7 +285,7 @@ static void queryInstSources(EvalState & state,
{ {
Expr e2 = parseExprFromString(state, *i, absPath(".")); Expr e2 = parseExprFromString(state, *i, absPath("."));
Expr call = makeCall(e2, e1); Expr call = makeCall(e2, e1);
parseDerivations(state, call, elems); getDerivations(state, call, elems);
} }
break; break;
@ -410,7 +301,7 @@ static void queryInstSources(EvalState & state,
{ {
assertStorePath(*i); assertStorePath(*i);
UserEnvElem elem; DrvInfo elem;
string name = baseNameOf(*i); string name = baseNameOf(*i);
unsigned int dash = name.find('-'); unsigned int dash = name.find('-');
if (dash != string::npos) if (dash != string::npos)
@ -426,8 +317,6 @@ static void queryInstSources(EvalState & state,
else elem.setOutPath(*i); else elem.setOutPath(*i);
elem.name = name; elem.name = name;
elems[elemCounter++] = elem;
} }
break; break;
@ -451,30 +340,30 @@ static void installDerivations(Globals & globals,
debug(format("installing derivations")); debug(format("installing derivations"));
/* Get the set of user environment elements to be installed. */ /* Get the set of user environment elements to be installed. */
UserEnvElems newElems; DrvInfos newElems;
queryInstSources(globals.state, globals.instSource, args, newElems); queryInstSources(globals.state, globals.instSource, args, newElems);
StringSet newNames; StringSet newNames;
for (UserEnvElems::iterator i = newElems.begin(); i != newElems.end(); ++i) { for (DrvInfos::iterator i = newElems.begin(); i != newElems.end(); ++i) {
printMsg(lvlInfo, printMsg(lvlInfo,
format("installing `%1%'") % i->second.name); format("installing `%1%'") % i->name);
newNames.insert(DrvName(i->second.name).name); newNames.insert(DrvName(i->name).name);
} }
/* Add in the already installed derivations, unless they have the /* Add in the already installed derivations, unless they have the
same name as a to-be-installed element. */ same name as a to-be-installed element. */
UserEnvElems installedElems = queryInstalled(globals.state, profile); DrvInfos installedElems = queryInstalled(globals.state, profile);
for (UserEnvElems::iterator i = installedElems.begin(); for (DrvInfos::iterator i = installedElems.begin();
i != installedElems.end(); ++i) i != installedElems.end(); ++i)
{ {
DrvName drvName(i->second.name); DrvName drvName(i->name);
if (!globals.preserveInstalled && if (!globals.preserveInstalled &&
newNames.find(drvName.name) != newNames.end()) newNames.find(drvName.name) != newNames.end())
printMsg(lvlInfo, printMsg(lvlInfo,
format("uninstalling `%1%'") % i->second.name); format("uninstalling `%1%'") % i->name);
else else
newElems.insert(*i); newElems.push_back(*i);
} }
if (globals.dryRun) return; if (globals.dryRun) return;
@ -509,29 +398,29 @@ static void upgradeDerivations(Globals & globals,
name and a higher version number. */ name and a higher version number. */
/* Load the currently installed derivations. */ /* Load the currently installed derivations. */
UserEnvElems installedElems = queryInstalled(globals.state, profile); DrvInfos installedElems = queryInstalled(globals.state, profile);
/* Fetch all derivations from the input file. */ /* Fetch all derivations from the input file. */
UserEnvElems availElems; DrvInfos availElems;
queryInstSources(globals.state, globals.instSource, args, availElems); queryInstSources(globals.state, globals.instSource, args, availElems);
/* Go through all installed derivations. */ /* Go through all installed derivations. */
UserEnvElems newElems; DrvInfos newElems;
for (UserEnvElems::iterator i = installedElems.begin(); for (DrvInfos::iterator i = installedElems.begin();
i != installedElems.end(); ++i) i != installedElems.end(); ++i)
{ {
DrvName drvName(i->second.name); DrvName drvName(i->name);
/* Find the derivation in the input Nix expression with the /* Find the derivation in the input Nix expression with the
same name and satisfying the version constraints specified same name and satisfying the version constraints specified
by upgradeType. If there are multiple matches, take the by upgradeType. If there are multiple matches, take the
one with highest version. */ one with highest version. */
UserEnvElems::iterator bestElem = availElems.end(); DrvInfos::iterator bestElem = availElems.end();
DrvName bestName; DrvName bestName;
for (UserEnvElems::iterator j = availElems.begin(); for (DrvInfos::iterator j = availElems.begin();
j != availElems.end(); ++j) j != availElems.end(); ++j)
{ {
DrvName newName(j->second.name); DrvName newName(j->name);
if (newName.name == drvName.name) { if (newName.name == drvName.name) {
int d = compareVersions(drvName.version, newName.version); int d = compareVersions(drvName.version, newName.version);
if (upgradeType == utLt && d < 0 || if (upgradeType == utLt && d < 0 ||
@ -550,14 +439,14 @@ static void upgradeDerivations(Globals & globals,
} }
if (bestElem != availElems.end() && if (bestElem != availElems.end() &&
i->second.queryOutPath(globals.state) != i->queryOutPath(globals.state) !=
bestElem->second.queryOutPath(globals.state)) bestElem->queryOutPath(globals.state))
{ {
printMsg(lvlInfo, printMsg(lvlInfo,
format("upgrading `%1%' to `%2%'") format("upgrading `%1%' to `%2%'")
% i->second.name % bestElem->second.name); % i->name % bestElem->name);
newElems.insert(*bestElem); newElems.push_back(*bestElem);
} else newElems.insert(*i); } else newElems.push_back(*i);
} }
if (globals.dryRun) return; if (globals.dryRun) return;
@ -585,23 +474,23 @@ static void opUpgrade(Globals & globals,
static void uninstallDerivations(Globals & globals, DrvNames & selectors, static void uninstallDerivations(Globals & globals, DrvNames & selectors,
Path & profile) Path & profile)
{ {
UserEnvElems installedElems = queryInstalled(globals.state, profile); DrvInfos installedElems = queryInstalled(globals.state, profile);
UserEnvElems newElems; DrvInfos newElems;
for (UserEnvElems::iterator i = installedElems.begin(); for (DrvInfos::iterator i = installedElems.begin();
i != installedElems.end(); ++i) i != installedElems.end(); ++i)
{ {
DrvName drvName(i->second.name); DrvName drvName(i->name);
bool found = false; bool found = false;
for (DrvNames::iterator j = selectors.begin(); for (DrvNames::iterator j = selectors.begin();
j != selectors.end(); ++j) j != selectors.end(); ++j)
if (j->matches(drvName)) { if (j->matches(drvName)) {
printMsg(lvlInfo, printMsg(lvlInfo,
format("uninstalling `%1%'") % i->second.name); format("uninstalling `%1%'") % i->name);
found = true; found = true;
break; break;
} }
if (!found) newElems.insert(*i); if (!found) newElems.push_back(*i);
} }
if (globals.dryRun) return; if (globals.dryRun) return;
@ -630,7 +519,7 @@ static bool cmpChars(char a, char b)
} }
static bool cmpElemByName(const UserEnvElem & a, const UserEnvElem & b) static bool cmpElemByName(const DrvInfo & a, const DrvInfo & b)
{ {
return lexicographical_compare( return lexicographical_compare(
a.name.begin(), a.name.end(), a.name.begin(), a.name.end(),
@ -680,15 +569,15 @@ void printTable(Table & table)
typedef enum { cvLess, cvEqual, cvGreater, cvUnavail } VersionDiff; typedef enum { cvLess, cvEqual, cvGreater, cvUnavail } VersionDiff;
static VersionDiff compareVersionAgainstSet( static VersionDiff compareVersionAgainstSet(
const UserEnvElem & elem, const UserEnvElems & elems, string & version) const DrvInfo & elem, const DrvInfos & elems, string & version)
{ {
DrvName name(elem.name); DrvName name(elem.name);
VersionDiff diff = cvUnavail; VersionDiff diff = cvUnavail;
version = "?"; version = "?";
for (UserEnvElems::const_iterator i = elems.begin(); i != elems.end(); ++i) { for (DrvInfos::const_iterator i = elems.begin(); i != elems.end(); ++i) {
DrvName name2(i->second.name); DrvName name2(i->name);
if (name.name == name2.name) { if (name.name == name2.name) {
int d = compareVersions(name.version, name2.version); int d = compareVersions(name.version, name2.version);
if (d < 0) { if (d < 0) {
@ -748,7 +637,7 @@ static void opQuery(Globals & globals,
/* Obtain derivation information from the specified source. */ /* Obtain derivation information from the specified source. */
UserEnvElems availElems, installedElems; DrvInfos availElems, installedElems;
if (source == sInstalled || compareVersions || printStatus) { if (source == sInstalled || compareVersions || printStatus) {
installedElems = queryInstalled(globals.state, globals.profile); installedElems = queryInstalled(globals.state, globals.profile);
@ -759,14 +648,15 @@ static void opQuery(Globals & globals,
globals.instSource.systemFilter, availElems); globals.instSource.systemFilter, availElems);
} }
UserEnvElems & elems(source == sInstalled ? installedElems : availElems); DrvInfos & elems(source == sInstalled ? installedElems : availElems);
UserEnvElems & otherElems(source == sInstalled ? availElems : installedElems); DrvInfos & otherElems(source == sInstalled ? availElems : installedElems);
/* Sort them by name. */ /* Sort them by name. */
vector<UserEnvElem> elems2; /* !!! */
for (UserEnvElems::iterator i = elems.begin(); i != elems.end(); ++i) vector<DrvInfo> elems2;
elems2.push_back(i->second); for (DrvInfos::iterator i = elems.begin(); i != elems.end(); ++i)
elems2.push_back(*i);
sort(elems2.begin(), elems2.end(), cmpElemByName); sort(elems2.begin(), elems2.end(), cmpElemByName);
@ -775,16 +665,16 @@ static void opQuery(Globals & globals,
PathSet installed; /* installed paths */ PathSet installed; /* installed paths */
if (printStatus) { if (printStatus) {
for (UserEnvElems::iterator i = installedElems.begin(); for (DrvInfos::iterator i = installedElems.begin();
i != installedElems.end(); ++i) i != installedElems.end(); ++i)
installed.insert(i->second.queryOutPath(globals.state)); installed.insert(i->queryOutPath(globals.state));
} }
/* Print the desired columns. */ /* Print the desired columns. */
Table table; Table table;
for (vector<UserEnvElem>::iterator i = elems2.begin(); for (vector<DrvInfo>::iterator i = elems2.begin();
i != elems2.end(); ++i) i != elems2.end(); ++i)
{ {
Strings columns; Strings columns;