1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 08:31:16 +02:00

Refactor option handling

This commit is contained in:
Eelco Dolstra 2014-08-13 03:50:44 +02:00
parent 5bed74d1b0
commit 47e185847e
10 changed files with 503 additions and 531 deletions

View file

@ -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;
}
}