mirror of
https://github.com/NixOS/nix.git
synced 2025-11-11 04:56:01 +01:00
Refactor option handling
This commit is contained in:
parent
5bed74d1b0
commit
47e185847e
10 changed files with 503 additions and 531 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,26 +7,29 @@
|
|||
#include <locale>
|
||||
|
||||
|
||||
/* These are not implemented here, but must be implemented by a
|
||||
program linking against libmain. */
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Should print a help message to stdout and return. */
|
||||
void printHelp();
|
||||
|
||||
extern std::string programId;
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
MakeError(UsageError, nix::Error);
|
||||
|
||||
class Exit : public std::exception
|
||||
{
|
||||
public:
|
||||
int status;
|
||||
Exit() : status(0) { }
|
||||
Exit(int status) : status(status) { }
|
||||
};
|
||||
|
||||
class StoreAPI;
|
||||
|
||||
int handleExceptions(const string & programName, std::function<void()> fun);
|
||||
|
||||
void initNix();
|
||||
|
||||
void parseCmdLine(int argc, char * * argv,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue