about summary refs log tree commit diff
path: root/src/libmain/shared.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-08-13T01·50+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-08-13T01·50+0200
commit47e185847e729d49e6aa376e8299fd66ef834a0a (patch)
tree6abfc9e9d5744e78b123c73182c30253c9a39681 /src/libmain/shared.cc
parent5bed74d1b0acd8d8083fb82a31d907ad2348a91b (diff)
Refactor option handling
Diffstat (limited to 'src/libmain/shared.cc')
-rw-r--r--src/libmain/shared.cc82
1 files changed, 34 insertions, 48 deletions
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index 467a15e760..ec05db0a66 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;
+}
+
+
 }