aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-08-13 03:50:44 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-08-13 03:50:44 +0200
commit47e185847e729d49e6aa376e8299fd66ef834a0a (patch)
tree6abfc9e9d5744e78b123c73182c30253c9a39681 /src
parent5bed74d1b0acd8d8083fb82a31d907ad2348a91b (diff)
Refactor option handling
Diffstat (limited to 'src')
-rw-r--r--src/download-via-ssh/download-via-ssh.cc80
-rw-r--r--src/libexpr/common-opts.cc45
-rw-r--r--src/libexpr/common-opts.hh9
-rw-r--r--src/libmain/shared.cc82
-rw-r--r--src/libmain/shared.hh35
-rw-r--r--src/nix-daemon/nix-daemon.cc33
-rw-r--r--src/nix-env/nix-env.cc292
-rw-r--r--src/nix-hash/nix-hash.cc83
-rw-r--r--src/nix-instantiate/nix-instantiate.cc202
-rw-r--r--src/nix-store/nix-store.cc185
10 files changed, 509 insertions, 537 deletions
diff --git a/src/download-via-ssh/download-via-ssh.cc b/src/download-via-ssh/download-via-ssh.cc
index 688fb523a..ac0f5826d 100644
--- a/src/download-via-ssh/download-via-ssh.cc
+++ b/src/download-via-ssh/download-via-ssh.cc
@@ -91,55 +91,49 @@ static void query(std::pair<FdSink, FdSource> & pipes)
}
-void run(Strings args)
+int main(int argc, char * * argv)
{
- if (args.empty())
- throw UsageError("download-via-ssh requires an argument");
+ return handleExceptions(argv[0], [&]() {
+ initNix();
- if (settings.sshSubstituterHosts.empty())
- return;
+ if (argc < 2)
+ throw UsageError("download-via-ssh requires an argument");
- std::cout << std::endl;
-
- /* Pass on the location of the daemon client's SSH authentication
- socket. */
- string sshAuthSock = settings.get("ssh-auth-sock", "");
- if (sshAuthSock != "") setenv("SSH_AUTH_SOCK", sshAuthSock.c_str(), 1);
+ if (settings.sshSubstituterHosts.empty())
+ return;
- string host = settings.sshSubstituterHosts.front();
- std::pair<FdSink, FdSource> pipes = connect(host);
-
- /* Exchange the greeting */
- writeInt(SERVE_MAGIC_1, pipes.first);
- pipes.first.flush();
- unsigned int magic = readInt(pipes.second);
- if (magic != SERVE_MAGIC_2)
- throw Error("protocol mismatch");
- readInt(pipes.second); // Server version, unused for now
- writeInt(SERVE_PROTOCOL_VERSION, pipes.first);
- pipes.first.flush();
+ std::cout << std::endl;
- Strings::iterator i = args.begin();
- if (*i == "--query")
- query(pipes);
- else if (*i == "--substitute")
- if (args.size() != 3)
- throw UsageError("download-via-ssh: --substitute takes exactly two arguments");
- else {
- Path storePath = *++i;
- Path destPath = *++i;
+ /* Pass on the location of the daemon client's SSH
+ authentication socket. */
+ string sshAuthSock = settings.get("ssh-auth-sock", "");
+ if (sshAuthSock != "") setenv("SSH_AUTH_SOCK", sshAuthSock.c_str(), 1);
+
+ string host = settings.sshSubstituterHosts.front();
+ std::pair<FdSink, FdSource> pipes = connect(host);
+
+ /* Exchange the greeting */
+ writeInt(SERVE_MAGIC_1, pipes.first);
+ pipes.first.flush();
+ unsigned int magic = readInt(pipes.second);
+ if (magic != SERVE_MAGIC_2)
+ throw Error("protocol mismatch");
+ readInt(pipes.second); // Server version, unused for now
+ writeInt(SERVE_PROTOCOL_VERSION, pipes.first);
+ pipes.first.flush();
+
+ string arg = argv[1];
+ if (arg == "--query")
+ query(pipes);
+ else if (arg == "--substitute") {
+ if (argc != 4)
+ throw UsageError("download-via-ssh: --substitute takes exactly two arguments");
+ Path storePath = argv[2];
+ Path destPath = argv[3];
printMsg(lvlError, format("downloading `%1%' via SSH from `%2%'...") % storePath % host);
substitute(pipes, storePath, destPath);
}
- else
- throw UsageError(format("download-via-ssh: unknown command `%1%'") % *i);
-}
-
-
-void printHelp()
-{
- std::cerr << "Usage: download-via-ssh --query|--substitute store-path dest-path" << std::endl;
+ else
+ throw UsageError(format("download-via-ssh: unknown command `%1%'") % arg);
+ });
}
-
-
-string programId = "download-via-ssh";
diff --git a/src/libexpr/common-opts.cc b/src/libexpr/common-opts.cc
index a3ea202e8..2e8bb29c7 100644
--- a/src/libexpr/common-opts.cc
+++ b/src/libexpr/common-opts.cc
@@ -6,40 +6,45 @@
namespace nix {
-bool parseOptionArg(const string & arg, Strings::iterator & i,
- const Strings::iterator & argsEnd, EvalState & state,
- Bindings & autoArgs)
+bool parseAutoArgs(Strings::iterator & i,
+ const Strings::iterator & argsEnd, std::map<string, string> & res)
{
+ string arg = *i;
if (arg != "--arg" && arg != "--argstr") return false;
UsageError error(format("`%1%' requires two arguments") % arg);
- if (i == argsEnd) throw error;
- string name = *i++;
- if (i == argsEnd) throw error;
- string value = *i++;
+ if (++i == argsEnd) throw error;
+ string name = *i;
+ if (++i == argsEnd) throw error;
+ string value = *i;
- /* !!! check for duplicates! */
- Value * v = state.allocValue();
- autoArgs.push_back(Attr(state.symbols.create(name), v));
+ res[name] = (arg == "--arg" ? 'E' : 'S') + value;
- if (arg == "--arg")
- state.mkThunk_(*v, state.parseExprFromString(value, absPath(".")));
- else
- mkString(*v, value);
+ return true;
+}
- autoArgs.sort(); // !!! inefficient
- return true;
+void evalAutoArgs(EvalState & state, std::map<string, string> & in, Bindings & out)
+{
+ for (auto & i: in) {
+ Value * v = state.allocValue();
+ if (i.second[0] == 'E')
+ state.mkThunk_(*v, state.parseExprFromString(string(i.second, 1), absPath(".")));
+ else
+ mkString(*v, string(i.second, 1));
+ out.push_back(Attr(state.symbols.create(i.first), v));
+ }
+ out.sort();
}
-bool parseSearchPathArg(const string & arg, Strings::iterator & i,
+bool parseSearchPathArg(Strings::iterator & i,
const Strings::iterator & argsEnd, Strings & searchPath)
{
- if (arg != "-I") return false;
- if (i == argsEnd) throw UsageError(format("`%1%' requires an argument") % arg);;
- searchPath.push_back(*i++);
+ if (*i != "-I") return false;
+ if (++i == argsEnd) throw UsageError("`-I' requires an argument");
+ searchPath.push_back(*i);
return true;
}
diff --git a/src/libexpr/common-opts.hh b/src/libexpr/common-opts.hh
index 759358950..bb6d399a8 100644
--- a/src/libexpr/common-opts.hh
+++ b/src/libexpr/common-opts.hh
@@ -5,11 +5,12 @@
namespace nix {
/* Some common option parsing between nix-env and nix-instantiate. */
-bool parseOptionArg(const string & arg, Strings::iterator & i,
- const Strings::iterator & argsEnd, EvalState & state,
- Bindings & autoArgs);
+bool parseAutoArgs(Strings::iterator & i,
+ const Strings::iterator & argsEnd, std::map<string, string> & res);
-bool parseSearchPathArg(const string & arg, Strings::iterator & i,
+void evalAutoArgs(EvalState & state, std::map<string, string> & in, Bindings & out);
+
+bool parseSearchPathArg(Strings::iterator & i,
const Strings::iterator & argsEnd, Strings & searchPath);
Path lookupFileArg(EvalState & state, string s);
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index 467a15e76..ec05db0a6 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -100,10 +100,16 @@ string getArg(const string & opt,
void detectStackOverflow();
-/* Initialize and reorder arguments, then call the actual argument
- processor. */
-static void initAndRun(int argc, char * * argv)
+void initNix()
{
+ /* Turn on buffering for cerr. */
+#if HAVE_PUBSETBUF
+ static char buf[1024];
+ std::cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));
+#endif
+
+ std::ios::sync_with_stdio(false);
+
settings.processEnvironment();
settings.loadConfFile();
@@ -144,6 +150,14 @@ static void initAndRun(int argc, char * * argv)
gettimeofday(&tv, 0);
srandom(tv.tv_usec);
+ if (char *pack = getenv("_NIX_OPTIONS"))
+ settings.unpack(pack);
+}
+
+
+void parseCmdLine(int argc, char * * argv,
+ std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
+{
/* Put the arguments in a vector. */
Strings args, remaining;
while (argc--) args.push_back(*argv++);
@@ -164,7 +178,6 @@ static void initAndRun(int argc, char * * argv)
} else remaining.push_back(arg);
}
args = remaining;
- remaining.clear();
/* Process default options. */
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
@@ -179,14 +192,6 @@ static void initAndRun(int argc, char * * argv)
settings.buildVerbosity = lvlVomit;
else if (arg == "--print-build-trace")
settings.printBuildTrace = true;
- else if (arg == "--help") {
- printHelp();
- return;
- }
- else if (arg == "--version") {
- std::cout << format("%1% (Nix) %2%") % programId % nixVersion << std::endl;
- return;
- }
else if (arg == "--keep-failed" || arg == "-K")
settings.keepFailed = true;
else if (arg == "--keep-going" || arg == "-k")
@@ -216,25 +221,20 @@ static void initAndRun(int argc, char * * argv)
string value = *i;
settings.set(name, value);
}
- else if (arg == "--arg" || arg == "--argstr") {
- remaining.push_back(arg);
- ++i; if (i == args.end()) throw UsageError(format("`%1%' requires two arguments") % arg);
- remaining.push_back(*i);
- ++i; if (i == args.end()) throw UsageError(format("`%1%' requires two arguments") % arg);
- remaining.push_back(*i);
+ else {
+ if (!parseArg(i, args.end()))
+ throw UsageError(format("unrecognised option `%1%'") % *i);
}
- else remaining.push_back(arg);
}
- if (char *pack = getenv("_NIX_OPTIONS"))
- settings.unpack(pack);
-
settings.update();
+}
- run(remaining);
- /* Close the Nix database. */
- store.reset((StoreAPI *) 0);
+void printVersion(const string & programName)
+{
+ std::cout << format("%1% (Nix) %2%") % programName % nixVersion << std::endl;
+ throw Exit();
}
@@ -246,30 +246,11 @@ void showManPage(const string & name)
}
-int exitCode = 0;
-char * * argvSaved = 0;
-
-}
-
-
-static char buf[1024];
-
-int main(int argc, char * * argv)
+int handleExceptions(const string & programName, std::function<void()> fun)
{
- using namespace nix;
-
- argvSaved = argv;
-
- /* Turn on buffering for cerr. */
-#if HAVE_PUBSETBUF
- std::cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));
-#endif
-
- std::ios::sync_with_stdio(false);
-
try {
try {
- initAndRun(argc, argv);
+ fun();
} catch (...) {
/* Subtle: we have to make sure that any `interrupted'
condition is discharged before we reach printMsg()
@@ -279,12 +260,14 @@ int main(int argc, char * * argv)
_isInterrupted = 0;
throw;
}
+ } catch (Exit & e) {
+ return e.status;
} catch (UsageError & e) {
printMsg(lvlError,
format(
"error: %1%\n"
"Try `%2% --help' for more information.")
- % e.what() % programId);
+ % e.what() % programName);
return 1;
} catch (BaseError & e) {
printMsg(lvlError, format("error: %1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
@@ -299,5 +282,8 @@ int main(int argc, char * * argv)
return 1;
}
- return exitCode;
+ return 0;
+}
+
+
}
diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh
index b29b08bb5..c74e7cbc1 100644
--- a/src/libmain/shared.hh
+++ b/src/libmain/shared.hh
@@ -7,25 +7,28 @@
#include <locale>
-/* These are not implemented here, but must be implemented by a
- program linking against libmain. */
+namespace nix {
-/* Main program. Called by main() after the ATerm library has been
- initialised and some default arguments have been processed (and
- removed from `args'). main() will catch all exceptions. */
-void run(nix::Strings args);
+MakeError(UsageError, nix::Error);
-/* Should print a help message to stdout and return. */
-void printHelp();
+class Exit : public std::exception
+{
+public:
+ int status;
+ Exit() : status(0) { }
+ Exit(int status) : status(status) { }
+};
-extern std::string programId;
+class StoreAPI;
+int handleExceptions(const string & programName, std::function<void()> fun);
-namespace nix {
+void initNix();
-MakeError(UsageError, nix::Error);
+void parseCmdLine(int argc, char * * argv,
+ std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
-class StoreAPI;
+void printVersion(const string & programName);
/* Ugh. No better place to put this. */
void printGCWarning();
@@ -36,6 +39,9 @@ void printMissing(const PathSet & willBuild,
const PathSet & willSubstitute, const PathSet & unknown,
unsigned long long downloadSize, unsigned long long narSize);
+string getArg(const string & opt,
+ Strings::iterator & i, const Strings::iterator & end);
+
template<class N> N getIntArg(const string & opt,
Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
{
@@ -65,9 +71,4 @@ void showManPage(const string & name);
extern volatile ::sig_atomic_t blockInt;
-/* Exit code of the program. */
-extern int exitCode;
-
-extern char * * argvSaved;
-
}
diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc
index 69d5fd84e..3e6d6b2b1 100644
--- a/src/nix-daemon/nix-daemon.cc
+++ b/src/nix-daemon/nix-daemon.cc
@@ -645,8 +645,10 @@ bool matchUser(const string & user, const string & group, const Strings & users)
#define SD_LISTEN_FDS_START 3
-static void daemonLoop()
+static void daemonLoop(char * * argv)
{
+ chdir("/");
+
/* Get rid of children automatically; don't let them become
zombies. */
setSigChldAction(true);
@@ -766,9 +768,9 @@ static void daemonLoop()
setSigChldAction(false);
/* For debugging, stuff the pid into argv[1]. */
- if (clientPid != -1 && argvSaved[1]) {
+ if (clientPid != -1 && argv[1]) {
string processName = int2String(clientPid);
- strncpy(argvSaved[1], processName.c_str(), strlen(argvSaved[1]));
+ strncpy(argv[1], processName.c_str(), strlen(argv[1]));
}
/* Handle the connection. */
@@ -792,18 +794,27 @@ void run(Strings args)
{
for (Strings::iterator i = args.begin(); i != args.end(); ) {
string arg = *i++;
- if (arg == "--daemon") /* ignored for backwards compatibility */;
}
- chdir("/");
- daemonLoop();
}
-void printHelp()
+int main(int argc, char * * argv)
{
- showManPage("nix-daemon");
+ return handleExceptions(argv[0], [&]() {
+ initNix();
+
+ parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
+ if (*arg == "--daemon")
+ ; /* ignored for backwards compatibility */
+ else if (*arg == "--help")
+ showManPage("nix-daemon");
+ else if (*arg == "--version")
+ printVersion("nix-daemon");
+ else return false;
+ return true;
+ });
+
+ daemonLoop(argv);
+ });
}
-
-
-string programId = "nix-daemon";
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 062118d8a..e65dc4e51 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -52,24 +52,17 @@ struct Globals
{
InstallSourceInfo instSource;
Path profile;
- EvalState state;
+ std::shared_ptr<EvalState> state;
bool dryRun;
bool preserveInstalled;
bool removeAll;
string forceName;
bool prebuiltOnly;
- Globals(const Strings & searchPath) : state(searchPath) { }
};
typedef void (* Operation) (Globals & globals,
- Strings args, Strings opFlags, Strings opArgs);
-
-
-void printHelp()
-{
- showManPage("nix-env");
-}
+ Strings opFlags, Strings opArgs);
static string needArg(Strings::iterator & i,
@@ -467,11 +460,11 @@ static void installDerivations(Globals & globals,
/* Get the set of user environment elements to be installed. */
DrvInfos newElems, newElemsTmp;
- queryInstSources(globals.state, globals.instSource, args, newElemsTmp, true);
+ queryInstSources(*globals.state, globals.instSource, args, newElemsTmp, true);
/* If --prebuilt-only is given, filter out source-only packages. */
foreach (DrvInfos::iterator, i, newElemsTmp)
- if (!globals.prebuiltOnly || isPrebuilt(globals.state, *i))
+ if (!globals.prebuiltOnly || isPrebuilt(*globals.state, *i))
newElems.push_back(*i);
StringSet newNames;
@@ -494,7 +487,7 @@ static void installDerivations(Globals & globals,
/* Add in the already installed derivations, unless they have
the same name as a to-be-installed element. */
if (!globals.removeAll) {
- DrvInfos installedElems = queryInstalled(globals.state, profile);
+ DrvInfos installedElems = queryInstalled(*globals.state, profile);
foreach (DrvInfos::iterator, i, installedElems) {
DrvName drvName(i->name);
@@ -510,18 +503,17 @@ static void installDerivations(Globals & globals,
printMsg(lvlInfo, format("installing `%1%'") % i->name);
}
- printMissing(globals.state, newElems);
+ printMissing(*globals.state, newElems);
if (globals.dryRun) return;
- if (createUserEnv(globals.state, allElems,
+ if (createUserEnv(*globals.state, allElems,
profile, settings.envKeepDerivations, lockToken)) break;
}
}
-static void opInstall(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
{
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
string arg = *i++;
@@ -553,11 +545,11 @@ static void upgradeDerivations(Globals & globals,
while (true) {
string lockToken = optimisticLockProfile(globals.profile);
- DrvInfos installedElems = queryInstalled(globals.state, globals.profile);
+ DrvInfos installedElems = queryInstalled(*globals.state, globals.profile);
/* Fetch all derivations from the input file. */
DrvInfos availElems;
- queryInstSources(globals.state, globals.instSource, args, availElems, false);
+ queryInstSources(*globals.state, globals.instSource, args, availElems, false);
/* Go through all installed derivations. */
DrvInfos newElems;
@@ -582,7 +574,7 @@ static void upgradeDerivations(Globals & globals,
foreach (DrvInfos::iterator, j, availElems) {
DrvName newName(j->name);
if (newName.name == drvName.name) {
- int d = comparePriorities(globals.state, *i, *j);
+ int d = comparePriorities(*globals.state, *i, *j);
if (d == 0) d = compareVersions(drvName.version, newName.version);
if ((upgradeType == utLt && d < 0) ||
(upgradeType == utLeq && d <= 0) ||
@@ -591,10 +583,10 @@ static void upgradeDerivations(Globals & globals,
{
int d2 = -1;
if (bestElem != availElems.end()) {
- d2 = comparePriorities(globals.state, *bestElem, *j);
+ d2 = comparePriorities(*globals.state, *bestElem, *j);
if (d2 == 0) d2 = compareVersions(bestName.version, newName.version);
}
- if (d2 < 0 && (!globals.prebuiltOnly || isPrebuilt(globals.state, *j))) {
+ if (d2 < 0 && (!globals.prebuiltOnly || isPrebuilt(*globals.state, *j))) {
bestElem = j;
bestName = newName;
}
@@ -618,18 +610,17 @@ static void upgradeDerivations(Globals & globals,
}
}
- printMissing(globals.state, newElems);
+ printMissing(*globals.state, newElems);
if (globals.dryRun) return;
- if (createUserEnv(globals.state, newElems,
+ if (createUserEnv(*globals.state, newElems,
globals.profile, settings.envKeepDerivations, lockToken)) break;
}
}
-static void opUpgrade(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opUpgrade(Globals & globals, Strings opFlags, Strings opArgs)
{
UpgradeType upgradeType = utLt;
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
@@ -655,8 +646,7 @@ static void setMetaFlag(EvalState & state, DrvInfo & drv,
}
-static void opSetFlag(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@@ -671,7 +661,7 @@ static void opSetFlag(Globals & globals,
while (true) {
string lockToken = optimisticLockProfile(globals.profile);
- DrvInfos installedElems = queryInstalled(globals.state, globals.profile);
+ DrvInfos installedElems = queryInstalled(*globals.state, globals.profile);
/* Update all matching derivations. */
foreach (DrvInfos::iterator, i, installedElems) {
@@ -680,7 +670,7 @@ static void opSetFlag(Globals & globals,
if (j->matches(drvName)) {
printMsg(lvlInfo, format("setting flag on `%1%'") % i->name);
j->hits++;
- setMetaFlag(globals.state, *i, flagName, flagValue);
+ setMetaFlag(*globals.state, *i, flagName, flagValue);
break;
}
}
@@ -688,14 +678,13 @@ static void opSetFlag(Globals & globals,
checkSelectorUse(selectors);
/* Write the new user environment. */
- if (createUserEnv(globals.state, installedElems,
+ if (createUserEnv(*globals.state, installedElems,
globals.profile, settings.envKeepDerivations, lockToken)) break;
}
}
-static void opSet(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
{
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
string arg = *i++;
@@ -704,7 +693,7 @@ static void opSet(Globals & globals,
}
DrvInfos elems;
- queryInstSources(globals.state, globals.instSource, opArgs, elems, true);
+ queryInstSources(*globals.state, globals.instSource, opArgs, elems, true);
if (elems.size() != 1)
throw Error("--set requires exactly one derivation");
@@ -715,7 +704,7 @@ static void opSet(Globals & globals,
PathSet paths = singleton<PathSet>(drv.queryDrvPath());
printMissing(*store, paths);
if (globals.dryRun) return;
- store->buildPaths(paths, globals.state.repair ? bmRepair : bmNormal);
+ store->buildPaths(paths, globals.state->repair ? bmRepair : bmNormal);
}
else {
printMissing(*store, singleton<PathSet>(drv.queryOutPath()));
@@ -735,7 +724,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
while (true) {
string lockToken = optimisticLockProfile(profile);
- DrvInfos installedElems = queryInstalled(globals.state, profile);
+ DrvInfos installedElems = queryInstalled(*globals.state, profile);
DrvInfos newElems;
foreach (DrvInfos::iterator, i, installedElems) {
@@ -756,14 +745,13 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
if (globals.dryRun) return;
- if (createUserEnv(globals.state, newElems,
+ if (createUserEnv(*globals.state, newElems,
profile, settings.envKeepDerivations, lockToken)) break;
}
}
-static void opUninstall(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opUninstall(Globals & globals, Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@@ -887,15 +875,14 @@ static void queryJSON(Globals & globals, vector<DrvInfo> & elems)
cout << "null";
} else {
PathSet context;
- printValueAsJSON(globals.state, true, *v, cout, context);
+ printValueAsJSON(*globals.state, true, *v, cout, context);
}
}
}
}
-static void opQuery(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
{
Strings remaining;
string attrPath;
@@ -916,7 +903,7 @@ static void opQuery(Globals & globals,
settings.readOnlyMode = true; /* makes evaluation a bit faster */
- for (Strings::iterator i = args.begin(); i != args.end(); ) {
+ for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
string arg = *i++;
if (arg == "--status" || arg == "-s") printStatus = true;
else if (arg == "--no-name") printName = false;
@@ -932,10 +919,9 @@ static void opQuery(Globals & globals,
else if (arg == "--json") jsonOutput = true;
else if (arg == "--attr-path" || arg == "-P") printAttrPath = true;
else if (arg == "--attr" || arg == "-A")
- attrPath = needArg(i, args, arg);
- else if (arg[0] == '-')
+ attrPath = needArg(i, opFlags, arg);
+ else
throw UsageError(format("unknown flag `%1%'") % arg);
- else remaining.push_back(arg);
}
@@ -943,16 +929,16 @@ static void opQuery(Globals & globals,
DrvInfos availElems, installedElems;
if (source == sInstalled || compareVersions || printStatus)
- installedElems = queryInstalled(globals.state, globals.profile);
+ installedElems = queryInstalled(*globals.state, globals.profile);
if (source == sAvailable || compareVersions)
- loadDerivations(globals.state, globals.instSource.nixExprPath,
+ loadDerivations(*globals.state, globals.instSource.nixExprPath,
globals.instSource.systemFilter, globals.instSource.autoArgs,
attrPath, availElems);
- DrvInfos elems_ = filterBySelector(globals.state,
+ DrvInfos elems_ = filterBySelector(*globals.state,
source == sInstalled ? installedElems : availElems,
- remaining, false);
+ opArgs, false);
DrvInfos & otherElems(source == sInstalled ? availElems : installedElems);
@@ -1173,8 +1159,7 @@ static void opQuery(Globals & globals,
}
-static void opSwitchProfile(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@@ -1222,8 +1207,7 @@ static void switchGeneration(Globals & globals, int dstGen)
}
-static void opSwitchGeneration(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@@ -1238,8 +1222,7 @@ static void opSwitchGeneration(Globals & globals,
}
-static void opRollback(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opRollback(Globals & globals, Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@@ -1250,8 +1233,7 @@ static void opRollback(Globals & globals,
}
-static void opListGenerations(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@@ -1288,8 +1270,7 @@ static void deleteGeneration2(Globals & globals, unsigned int gen)
}
-static void opDeleteGenerations(Globals & globals,
- Strings args, Strings opFlags, Strings opArgs)
+static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@@ -1348,110 +1329,115 @@ static void opDeleteGenerations(Globals & globals,
}
-void run(Strings args)
+int main(int argc, char * * argv)
{
- Strings opFlags, opArgs, remaining;
- Operation op = 0;
-
- /* FIXME: hack. */
- Strings searchPath;
- Strings args2;
- for (Strings::iterator i = args.begin(); i != args.end(); ) {
- string arg = *i++;
- if (!parseSearchPathArg(arg, i, args.end(), searchPath))
- args2.push_back(arg);
- }
- args = args2;
-
- Globals globals(searchPath);
+ return handleExceptions(argv[0], [&]() {
+ initNix();
+
+ Strings opFlags, opArgs, searchPath;
+ std::map<string, string> autoArgs_;
+ Operation op = 0;
+ bool repair = false;
+ string file;
+
+ Globals globals;
+
+ globals.instSource.type = srcUnknown;
+ globals.instSource.nixExprPath = getDefNixExprPath();
+ globals.instSource.systemFilter = "*";
+
+ globals.dryRun = false;
+ globals.preserveInstalled = false;
+ globals.removeAll = false;
+ globals.prebuiltOnly = false;
+
+ parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
+ Operation oldOp = op;
+
+ if (*arg == "--help")
+ showManPage("nix-env");
+ else if (*arg == "--version")
+ printVersion("nix-env");
+ else if (*arg == "--install" || *arg == "-i")
+ op = opInstall;
+ else if (parseAutoArgs(arg, end, autoArgs_))
+ ;
+ else if (parseSearchPathArg(arg, end, searchPath))
+ ;
+ else if (*arg == "--force-name") // undocumented flag for nix-install-package
+ globals.forceName = getArg(*arg, arg, end);
+ else if (*arg == "--uninstall" || *arg == "-e")
+ op = opUninstall;
+ else if (*arg == "--upgrade" || *arg == "-u")
+ op = opUpgrade;
+ else if (*arg == "--set-flag")
+ op = opSetFlag;
+ else if (*arg == "--set")
+ op = opSet;
+ else if (*arg == "--query" || *arg == "-q")
+ op = opQuery;
+ else if (*arg == "--profile" || *arg == "-p")
+ globals.profile = absPath(getArg(*arg, arg, end));
+ else if (*arg == "--file" || *arg == "-f")
+ file = getArg(*arg, arg, end);
+ else if (*arg == "--switch-profile" || *arg == "-S")
+ op = opSwitchProfile;
+ else if (*arg == "--switch-generation" || *arg == "-G")
+ op = opSwitchGeneration;
+ else if (*arg == "--rollback")
+ op = opRollback;
+ else if (*arg == "--list-generations")
+ op = opListGenerations;
+ else if (*arg == "--delete-generations")
+ op = opDeleteGenerations;
+ else if (*arg == "--dry-run") {
+ printMsg(lvlInfo, "(dry run; not doing anything)");
+ globals.dryRun = true;
+ }
+ else if (*arg == "--system-filter")
+ globals.instSource.systemFilter = getArg(*arg, arg, end);
+ else if (*arg == "--prebuilt-only" || *arg == "-b")
+ globals.prebuiltOnly = true;
+ else if (*arg == "--repair")
+ repair = true;
+ else if (*arg != "" && arg->at(0) == '-') {
+ opFlags.push_back(*arg);
+ if (*arg == "--from-profile" || *arg == "--atr" || *arg == "-A") /* !!! hack */
+ opFlags.push_back(getArg(*arg, arg, end));
+ }
+ else
+ opArgs.push_back(*arg);
- globals.instSource.type = srcUnknown;
- globals.instSource.nixExprPath = getDefNixExprPath();
- globals.instSource.systemFilter = "*";
+ if (oldOp && oldOp != op)
+ throw UsageError("only one operation may be specified");
- globals.dryRun = false;
- globals.preserveInstalled = false;
- globals.removeAll = false;
- globals.prebuiltOnly = false;
+ return true;
+ });
- for (Strings::iterator i = args.begin(); i != args.end(); ) {
- string arg = *i++;
+ if (!op) throw UsageError("no operation specified");
- Operation oldOp = op;
-
- if (arg == "--install" || arg == "-i")
- op = opInstall;
- else if (parseOptionArg(arg, i, args.end(),
- globals.state, globals.instSource.autoArgs))
- ;
- else if (arg == "--force-name") // undocumented flag for nix-install-package
- globals.forceName = needArg(i, args, arg);
- else if (arg == "--uninstall" || arg == "-e")
- op = opUninstall;
- else if (arg == "--upgrade" || arg == "-u")
- op = opUpgrade;
- else if (arg == "--set-flag")
- op = opSetFlag;
- else if (arg == "--set")
- op = opSet;
- else if (arg == "--query" || arg == "-q")
- op = opQuery;
- else if (arg == "--profile" || arg == "-p")
- globals.profile = absPath(needArg(i, args, arg));
- else if (arg == "--file" || arg == "-f")
- globals.instSource.nixExprPath = lookupFileArg(globals.state, needArg(i, args, arg));
- else if (arg == "--switch-profile" || arg == "-S")
- op = opSwitchProfile;
- else if (arg == "--switch-generation" || arg == "-G")
- op = opSwitchGeneration;
- else if (arg == "--rollback")
- op = opRollback;
- else if (arg == "--list-generations")
- op = opListGenerations;
- else if (arg == "--delete-generations")
- op = opDeleteGenerations;
- else if (arg == "--dry-run") {
- printMsg(lvlInfo, "(dry run; not doing anything)");
- globals.dryRun = true;
- }
- else if (arg == "--system-filter")
- globals.instSource.systemFilter = needArg(i, args, arg);
- else if (arg == "--prebuilt-only" || arg == "-b")
- globals.prebuiltOnly = true;
- else if (arg == "--repair")
- globals.state.repair = true;
- else {
- remaining.push_back(arg);
- if (arg[0] == '-') {
- opFlags.push_back(arg);
- if (arg == "--from-profile") { /* !!! hack */
- if (i != args.end()) opFlags.push_back(*i++);
- }
- } else opArgs.push_back(arg);
- }
+ globals.state = std::shared_ptr<EvalState>(new EvalState(searchPath));
+ globals.state->repair = repair;
- if (oldOp && oldOp != op)
- throw UsageError("only one operation may be specified");
- }
+ if (file != "")
+ globals.instSource.nixExprPath = lookupFileArg(*globals.state, file);
- if (!op) throw UsageError("no operation specified");
+ evalAutoArgs(*globals.state, autoArgs_, globals.instSource.autoArgs);
- if (globals.profile == "")
- globals.profile = getEnv("NIX_PROFILE", "");
+ if (globals.profile == "")
+ globals.profile = getEnv("NIX_PROFILE", "");
- if (globals.profile == "") {
- Path profileLink = getHomeDir() + "/.nix-profile";
- globals.profile = pathExists(profileLink)
- ? absPath(readLink(profileLink), dirOf(profileLink))
- : canonPath(settings.nixStateDir + "/profiles/default");
- }
+ if (globals.profile == "") {
+ Path profileLink = getHomeDir() + "/.nix-profile";
+ globals.profile = pathExists(profileLink)
+ ? absPath(readLink(profileLink), dirOf(profileLink))
+ : canonPath(settings.nixStateDir + "/profiles/default");
+ }
- store = openStore();
+ store = openStore();
- op(globals, remaining, opFlags, opArgs);
+ op(globals, opFlags, opArgs);
- globals.state.printStats();
+ globals.state->printStats();
+ });
}
-
-
-string programId = "nix-env";
diff --git a/src/nix-hash/nix-hash.cc b/src/nix-hash/nix-hash.cc
index af3dda4ad..b08f0b0b1 100644
--- a/src/nix-hash/nix-hash.cc
+++ b/src/nix-hash/nix-hash.cc
@@ -3,17 +3,10 @@
#include <iostream>
-
using namespace nix;
-void printHelp()
-{
- showManPage("nix-hash");
-}
-
-
-void run(Strings args)
+int main(int argc, char * * argv)
{
HashType ht = htMD5;
bool flat = false;
@@ -23,42 +16,48 @@ void run(Strings args)
Strings ss;
- for (Strings::iterator i = args.begin();
- i != args.end(); i++)
- {
- if (*i == "--flat") flat = true;
- else if (*i == "--base32") base32 = true;
- else if (*i == "--truncate") truncate = true;
- else if (*i == "--type") {
- ++i;
- if (i == args.end()) throw UsageError("`--type' requires an argument");
- ht = parseHashType(*i);
- if (ht == htUnknown)
- throw UsageError(format("unknown hash type `%1%'") % *i);
+ return handleExceptions(argv[0], [&]() {
+ initNix();
+
+ parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
+ if (*arg == "--help")
+ showManPage("nix-hash");
+ else if (*arg == "--version")
+ printVersion("nix-hash");
+ else if (*arg == "--flat") flat = true;
+ else if (*arg == "--base32") base32 = true;
+ else if (*arg == "--truncate") truncate = true;
+ else if (*arg == "--type") {
+ string s = getArg(*arg, arg, end);
+ ht = parseHashType(s);
+ if (ht == htUnknown)
+ throw UsageError(format("unknown hash type `%1%'") % s);
+ }
+ else if (*arg == "--to-base16") op = opTo16;
+ else if (*arg == "--to-base32") op = opTo32;
+ else if (*arg != "" && arg->at(0) == '-')
+ return false;
+ else
+ ss.push_back(*arg);
+ return true;
+ });
+
+ if (op == opHash) {
+ for (auto & i : ss) {
+ Hash h = flat ? hashFile(ht, i) : hashPath(ht, i).first;
+ if (truncate && h.hashSize > 20) h = compressHash(h, 20);
+ std::cout << format("%1%\n") %
+ (base32 ? printHash32(h) : printHash(h));
+ }
}
- else if (*i == "--to-base16") op = opTo16;
- else if (*i == "--to-base32") op = opTo32;
- else ss.push_back(*i);
- }
- if (op == opHash) {
- foreach (Strings::iterator, i, ss) {
- Hash h = flat ? hashFile(ht, *i) : hashPath(ht, *i).first;
- if (truncate && h.hashSize > 20) h = compressHash(h, 20);
- std::cout << format("%1%\n") %
- (base32 ? printHash32(h) : printHash(h));
+ else {
+ for (auto & i : ss) {
+ Hash h = parseHash16or32(ht, i);
+ std::cout << format("%1%\n") %
+ (op == opTo16 ? printHash(h) : printHash32(h));
+ }
}
- }
-
- else {
- foreach (Strings::iterator, i, ss) {
- Hash h = parseHash16or32(ht, *i);
- std::cout << format("%1%\n") %
- (op == opTo16 ? printHash(h) : printHash32(h));
- }
- }
+ });
}
-
-string programId = "nix-hash";
-
diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc
index a188b28fe..e9f942769 100644
--- a/src/nix-instantiate/nix-instantiate.cc
+++ b/src/nix-instantiate/nix-instantiate.cc
@@ -18,12 +18,6 @@
using namespace nix;
-void printHelp()
-{
- showManPage("nix-instantiate");
-}
-
-
static Expr * parseStdin(EvalState & state)
{
startNest(nest, lvlTalkative, format("parsing standard input"));
@@ -95,112 +89,108 @@ void processExpr(EvalState & state, const Strings & attrPaths,
}
-void run(Strings args)
+int main(int argc, char * * argv)
{
- /* FIXME: hack. */
- Strings searchPath;
- Strings args2;
- for (Strings::iterator i = args.begin(); i != args.end(); ) {
- string arg = *i++;
- if (!parseSearchPathArg(arg, i, args.end(), searchPath))
- args2.push_back(arg);
- }
- args = args2;
-
- EvalState state(searchPath);
- Strings files;
- bool readStdin = false;
- bool fromArgs = false;
- bool findFile = false;
- bool evalOnly = false;
- bool parseOnly = false;
- OutputKind outputKind = okPlain;
- bool xmlOutputSourceLocation = true;
- bool strict = false;
- Strings attrPaths;
- Bindings autoArgs;
- bool wantsReadWrite = false;
-
- for (Strings::iterator i = args.begin(); i != args.end(); ) {
- string arg = *i++;
-
- if (arg == "-")
- readStdin = true;
- else if (arg == "--expr" || arg == "-E")
- fromArgs = true;
- else if (arg == "--eval" || arg == "--eval-only")
- evalOnly = true;
- else if (arg == "--read-write-mode")
- wantsReadWrite = true;
- else if (arg == "--parse" || arg == "--parse-only")
- parseOnly = evalOnly = true;
- else if (arg == "--find-file")
- findFile = true;
- else if (arg == "--attr" || arg == "-A") {
- if (i == args.end())
- throw UsageError("`--attr' requires an argument");
- attrPaths.push_back(*i++);
- }
- else if (parseOptionArg(arg, i, args.end(), state, autoArgs))
- ;
- else if (arg == "--add-root") {
- if (i == args.end())
- throw UsageError("`--add-root' requires an argument");
- gcRoot = absPath(*i++);
- }
- else if (arg == "--indirect")
- indirectRoot = true;
- else if (arg == "--xml")
- outputKind = okXML;
- else if (arg == "--json")
- outputKind = okJSON;
- else if (arg == "--no-location")
- xmlOutputSourceLocation = false;
- else if (arg == "--strict")
- strict = true;
- else if (arg == "--repair")
- state.repair = true;
- else if (arg == "--dry-run")
- settings.readOnlyMode = true;
- else if (arg[0] == '-')
- throw UsageError(format("unknown flag `%1%'") % arg);
- else
- files.push_back(arg);
- }
+ return handleExceptions(argv[0], [&]() {
+ initNix();
+
+ Strings files, searchPath;
+ bool readStdin = false;
+ bool fromArgs = false;
+ bool findFile = false;
+ bool evalOnly = false;
+ bool parseOnly = false;
+ OutputKind outputKind = okPlain;
+ bool xmlOutputSourceLocation = true;
+ bool strict = false;
+ Strings attrPaths;
+ bool wantsReadWrite = false;
+ std::map<string, string> autoArgs_;
+ bool repair = false;
+
+ parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
+ if (*arg == "--help")
+ showManPage("nix-instantiate");
+ else if (*arg == "--version")
+ printVersion("nix-instantiate");
+ else if (*arg == "-")
+ readStdin = true;
+ else if (*arg == "--expr" || *arg == "-E")
+ fromArgs = true;
+ else if (*arg == "--eval" || *arg == "--eval-only")
+ evalOnly = true;
+ else if (*arg == "--read-write-mode")
+ wantsReadWrite = true;
+ else if (*arg == "--parse" || *arg == "--parse-only")
+ parseOnly = evalOnly = true;
+ else if (*arg == "--find-file")
+ findFile = true;
+ else if (*arg == "--attr" || *arg == "-A")
+ attrPaths.push_back(getArg(*arg, arg, end));
+ else if (parseAutoArgs(arg, end, autoArgs_))
+ ;
+ else if (parseSearchPathArg(arg, end, searchPath))
+ ;
+ else if (*arg == "--add-root")
+ gcRoot = getArg(*arg, arg, end);
+ else if (*arg == "--indirect")
+ indirectRoot = true;
+ else if (*arg == "--xml")
+ outputKind = okXML;
+ else if (*arg == "--json")
+ outputKind = okJSON;
+ else if (*arg == "--no-location")
+ xmlOutputSourceLocation = false;
+ else if (*arg == "--strict")
+ strict = true;
+ else if (*arg == "--repair")
+ repair = true;
+ else if (*arg == "--dry-run")
+ settings.readOnlyMode = true;
+ else if (*arg != "" && arg->at(0) == '-')
+ return false;
+ else
+ files.push_back(*arg);
+ return true;
+ });
- if (evalOnly && !wantsReadWrite)
- settings.readOnlyMode = true;
+ EvalState state(searchPath);
+ state.repair = repair;
- if (attrPaths.empty()) attrPaths.push_back("");
+ Bindings autoArgs;
+ evalAutoArgs(state, autoArgs_, autoArgs);
- if (findFile) {
- foreach (Strings::iterator, i, files) {
- Path p = state.findFile(*i);
- if (p == "") throw Error(format("unable to find `%1%'") % *i);
- std::cout << p << std::endl;
+ if (evalOnly && !wantsReadWrite)
+ settings.readOnlyMode = true;
+
+ if (attrPaths.empty()) attrPaths.push_back("");
+
+ if (findFile) {
+ foreach (Strings::iterator, i, files) {
+ Path p = state.findFile(*i);
+ if (p == "") throw Error(format("unable to find `%1%'") % *i);
+ std::cout << p << std::endl;
+ }
+ return;
}
- return;
- }
- store = openStore();
-
- if (readStdin) {
- Expr * e = parseStdin(state);
- processExpr(state, attrPaths, parseOnly, strict, autoArgs,
- evalOnly, outputKind, xmlOutputSourceLocation, e);
- } else if (files.empty() && !fromArgs)
- files.push_back("./default.nix");
-
- foreach (Strings::iterator, i, files) {
- Expr * e = fromArgs
- ? state.parseExprFromString(*i, absPath("."))
- : state.parseExprFromFile(resolveExprPath(lookupFileArg(state, *i)));
- processExpr(state, attrPaths, parseOnly, strict, autoArgs,
- evalOnly, outputKind, xmlOutputSourceLocation, e);
- }
+ store = openStore();
- state.printStats();
-}
+ if (readStdin) {
+ Expr * e = parseStdin(state);
+ processExpr(state, attrPaths, parseOnly, strict, autoArgs,
+ evalOnly, outputKind, xmlOutputSourceLocation, e);
+ } else if (files.empty() && !fromArgs)
+ files.push_back("./default.nix");
+ foreach (Strings::iterator, i, files) {
+ Expr * e = fromArgs
+ ? state.parseExprFromString(*i, absPath("."))
+ : state.parseExprFromFile(resolveExprPath(lookupFileArg(state, *i)));
+ processExpr(state, attrPaths, parseOnly, strict, autoArgs,
+ evalOnly, outputKind, xmlOutputSourceLocation, e);
+ }
-string programId = "nix-instantiate";
+ state.printStats();
+ });
+}
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 932789f2c..6a297b429 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -29,12 +29,6 @@ using std::cout;
typedef void (* Operation) (Strings opFlags, Strings opArgs);
-void printHelp()
-{
- showManPage("nix-store");
-}
-
-
static Path gcRoot;
static int rootNr = 0;
static bool indirectRoot = false;
@@ -782,7 +776,7 @@ static void opVerify(Strings opFlags, Strings opArgs)
if (ensureLocalStore().verifyStore(checkContents, repair)) {
printMsg(lvlError, "warning: not all errors were fixed");
- exitCode = 1;
+ throw Exit(1);
}
}
@@ -793,6 +787,8 @@ static void opVerifyPath(Strings opFlags, Strings opArgs)
if (!opFlags.empty())
throw UsageError("no flags expected");
+ int status = 0;
+
foreach (Strings::iterator, i, opArgs) {
Path path = followLinksToStorePath(*i);
printMsg(lvlTalkative, format("checking path `%1%'...") % path);
@@ -802,9 +798,11 @@ static void opVerifyPath(Strings opFlags, Strings opArgs)
printMsg(lvlError,
format("path `%1%' was modified! expected hash `%2%', got `%3%'")
% path % printHash(info.hash) % printHash(current.first));
- exitCode = 1;
+ status = 1;
}
}
+
+ throw Exit(status);
}
@@ -1017,95 +1015,96 @@ static void opServe(Strings opFlags, Strings opArgs)
/* Scan the arguments; find the operation, set global flags, put all
other flags in a list, and put all other arguments in another
list. */
-void run(Strings args)
+int main(int argc, char * * argv)
{
- Strings opFlags, opArgs;
- Operation op = 0;
-
- for (Strings::iterator i = args.begin(); i != args.end(); ) {
- string arg = *i++;
-
- Operation oldOp = op;
-
- if (arg == "--realise" || arg == "--realize" || arg == "-r")
- op = opRealise;
- else if (arg == "--add" || arg == "-A")
- op = opAdd;
- else if (arg == "--add-fixed")
- op = opAddFixed;
- else if (arg == "--print-fixed-path")
- op = opPrintFixedPath;
- else if (arg == "--delete")
- op = opDelete;
- else if (arg == "--query" || arg == "-q")
- op = opQuery;
- else if (arg == "--print-env")
- op = opPrintEnv;
- else if (arg == "--read-log" || arg == "-l")
- op = opReadLog;
- else if (arg == "--dump-db")
- op = opDumpDB;
- else if (arg == "--load-db")
- op = opLoadDB;
- else if (arg == "--register-validity")
- op = opRegisterValidity;
- else if (arg == "--check-validity")
- op = opCheckValidity;
- else if (arg == "--gc")
- op = opGC;
- else if (arg == "--dump")
- op = opDump;
- else if (arg == "--restore")
- op = opRestore;
- else if (arg == "--export")
- op = opExport;
- else if (arg == "--import")
- op = opImport;
- else if (arg == "--init")
- op = opInit;
- else if (arg == "--verify")
- op = opVerify;
- else if (arg == "--verify-path")
- op = opVerifyPath;
- else if (arg == "--repair-path")
- op = opRepairPath;
- else if (arg == "--optimise" || arg == "--optimize")
- op = opOptimise;
- else if (arg == "--query-failed-paths")
- op = opQueryFailedPaths;
- else if (arg == "--clear-failed-paths")
- op = opClearFailedPaths;
- else if (arg == "--add-root") {
- if (i == args.end())
- throw UsageError("`--add-root requires an argument");
- gcRoot = absPath(*i++);
- }
- else if (arg == "--indirect")
- indirectRoot = true;
- else if (arg == "--no-output")
- noOutput = true;
- else if (arg == "--serve")
- op = opServe;
- else if (arg[0] == '-') {
- opFlags.push_back(arg);
- if (arg == "--max-freed" || arg == "--max-links" || arg == "--max-atime") { /* !!! hack */
- if (i != args.end()) opFlags.push_back(*i++);
+ return handleExceptions(argv[0], [&]() {
+ initNix();
+
+ Strings opFlags, opArgs;
+ Operation op = 0;
+
+ parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
+ Operation oldOp = op;
+
+ if (*arg == "--help")
+ showManPage("nix-store");
+ else if (*arg == "--version")
+ printVersion("nix-store");
+ else if (*arg == "--realise" || *arg == "--realize" || *arg == "-r")
+ op = opRealise;
+ else if (*arg == "--add" || *arg == "-A")
+ op = opAdd;
+ else if (*arg == "--add-fixed")
+ op = opAddFixed;
+ else if (*arg == "--print-fixed-path")
+ op = opPrintFixedPath;
+ else if (*arg == "--delete")
+ op = opDelete;
+ else if (*arg == "--query" || *arg == "-q")
+ op = opQuery;
+ else if (*arg == "--print-env")
+ op = opPrintEnv;
+ else if (*arg == "--read-log" || *arg == "-l")
+ op = opReadLog;
+ else if (*arg == "--dump-db")
+ op = opDumpDB;
+ else if (*arg == "--load-db")
+ op = opLoadDB;
+ else if (*arg == "--register-validity")
+ op = opRegisterValidity;
+ else if (*arg == "--check-validity")
+ op = opCheckValidity;
+ else if (*arg == "--gc")
+ op = opGC;
+ else if (*arg == "--dump")
+ op = opDump;
+ else if (*arg == "--restore")
+ op = opRestore;
+ else if (*arg == "--export")
+ op = opExport;
+ else if (*arg == "--import")
+ op = opImport;
+ else if (*arg == "--init")
+ op = opInit;
+ else if (*arg == "--verify")
+ op = opVerify;
+ else if (*arg == "--verify-path")
+ op = opVerifyPath;
+ else if (*arg == "--repair-path")
+ op = opRepairPath;
+ else if (*arg == "--optimise" || *arg == "--optimize")
+ op = opOptimise;
+ else if (*arg == "--query-failed-paths")
+ op = opQueryFailedPaths;
+ else if (*arg == "--clear-failed-paths")
+ op = opClearFailedPaths;
+ else if (*arg == "--add-root")
+ gcRoot = absPath(getArg(*arg, arg, end));
+ else if (*arg == "--indirect")
+ indirectRoot = true;
+ else if (*arg == "--no-output")
+ noOutput = true;
+ else if (*arg == "--serve")
+ op = opServe;
+ else if (*arg != "" && arg->at(0) == '-') {
+ opFlags.push_back(*arg);
+ if (*arg == "--max-freed" || *arg == "--max-links" || *arg == "--max-atime") /* !!! hack */
+ opFlags.push_back(getArg(*arg, arg, end));
}
- }
- else
- opArgs.push_back(arg);
-
- if (oldOp && oldOp != op)
- throw UsageError("only one operation may be specified");
- }
+ else
+ opArgs.push_back(*arg);
- if (!op) throw UsageError("no operation specified");
+ if (oldOp && oldOp != op)
+ throw UsageError("only one operation may be specified");
- if (op != opDump && op != opRestore) /* !!! hack */
- store = openStore(op != opGC);
+ return true;
+ });
- op(opFlags, opArgs);
-}
+ if (!op) throw UsageError("no operation specified");
+ if (op != opDump && op != opRestore) /* !!! hack */
+ store = openStore(op != opGC);
-string programId = "nix-store";
+ op(opFlags, opArgs);
+ });
+}