about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/archive.cc11
-rw-r--r--src/archive.hh10
-rw-r--r--src/nix.cc176
-rw-r--r--src/util.hh4
4 files changed, 137 insertions, 64 deletions
diff --git a/src/archive.cc b/src/archive.cc
index 2fdbfb47649c..591939bb6ad2 100644
--- a/src/archive.cc
+++ b/src/archive.cc
@@ -1,3 +1,5 @@
+#include <vector>
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -44,7 +46,7 @@ static void dumpEntries(const string & path, DumpSink & sink)
     DIR * dir = opendir(path.c_str());
     if (!dir) throw SysError("opening directory " + path);
 
-    Strings names;
+    vector<string> names;
 
     struct dirent * dirent;
     while (errno = 0, dirent = readdir(dir)) {
@@ -56,7 +58,7 @@ static void dumpEntries(const string & path, DumpSink & sink)
 
     sort(names.begin(), names.end());
 
-    for (Strings::iterator it = names.begin();
+    for (vector<string>::iterator it = names.begin();
          it != names.end(); it++)
     {
         writeString("entry", sink);
@@ -134,3 +136,8 @@ void dumpPath(const string & path, DumpSink & sink)
 
     writeString(")", sink);
 }
+
+
+void restorePath(const string & path, ReadSource & source)
+{
+}
diff --git a/src/archive.hh b/src/archive.hh
index bfd96b45c03e..d351c6bf63f4 100644
--- a/src/archive.hh
+++ b/src/archive.hh
@@ -46,3 +46,13 @@ struct DumpSink
 };
 
 void dumpPath(const string & path, DumpSink & sink);
+
+
+struct ReadSource
+{
+    /* The callee should store exactly *len bytes in the buffer
+       pointed to by data.  It should block if that much data is not
+       yet available, or throw an error if it is not going to be
+       available. */
+    virtual void operator () (const unsigned char * data, unsigned int len) = 0;
+};
diff --git a/src/nix.cc b/src/nix.cc
index 4f0b97854b67..8380abc20e37 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -11,34 +11,94 @@
 typedef void (* Operation) (Strings opFlags, Strings opArgs);
 
 
-/* Parse a supposed value argument.  This can be a hash (the simple
-   case), a symbolic name (in which case we do a lookup to obtain the
-   hash), or a file name (which we import to obtain the hash).  Note
-   that in order to disambiguate between symbolic names and file
-   names, a file name should contain at least one `/'. */
-Hash parseValueArg(string s)
-{
-    try {
-        return parseHash(s);
-    } catch (BadRefError e) { };
+typedef enum { atpHash, atpName, atpPath, atpUnknown } ArgType;
 
-    if (s.find('/') != string::npos) {
-        return addValue(s);
-    } else {
-        throw Error("not implemented");
+static ArgType argType = atpUnknown;
+
+
+/* Nix syntax:
+
+   nix [OPTIONS...] [ARGUMENTS...]
+
+   Operations:
+
+     --evaluate / -e: evaluate values
+     --delete / -d: delete values
+     --query / -q: query stored values
+     --add: add values
+     --verify: verify Nix structures
+     --dump: dump a file or value
+     --init: initialise the Nix database
+     --version: output version information
+     --help: display help
+
+   Source selection for operations that work on values:
+
+     --file / -f: by file name
+     --hash / -h: by hash
+     --name / -n: by symbolic name
+
+   Query suboptions:
+
+     Selection:
+
+     --all / -a: query all stored values, otherwise given values
+
+     Information:
+
+     --info / -i: general value information
+
+   Options:
+
+     --verbose / -v: verbose operation
+*/
+
+
+/* Parse the `-f' / `-h' / `-n' flags, i.e., the type of value
+   arguments.  These flags are deleted from the referenced vector. */
+void getArgType(Strings & flags)
+{
+    for (Strings::iterator it = flags.begin();
+         it != flags.end(); )
+    {
+        string arg = *it;
+        ArgType tp;
+        if (arg == "--hash" || arg == "-h")
+            tp = atpHash;
+        else if (arg == "--name" || arg == "-n")
+            tp = atpName;
+        else if (arg == "--file" || arg == "-f")
+            tp = atpPath;
+        else {
+            it++;
+            continue;
+        }
+        if (argType != atpUnknown)
+            throw UsageError("only one argument type specified may be specified");
+        argType = tp;
+        it = flags.erase(it);
     }
+    if (argType == atpUnknown)
+        throw UsageError("argument type not specified");
 }
 
 
 /* Evaluate values. */
 static void opEvaluate(Strings opFlags, Strings opArgs)
 {
+    getArgType(opFlags);
     if (!opFlags.empty()) throw UsageError("unknown flag");
 
     for (Strings::iterator it = opArgs.begin();
          it != opArgs.end(); it++)
     {
-        Hash hash = parseValueArg(*it);
+        Hash hash;
+        if (argType == atpHash)
+            hash = parseHash(*it);
+        else if (argType == atpName)
+            throw Error("not implemented");
+        else if (argType == atpPath)
+            hash = addValue(*it);
         Expr e = ATmake("Deref(Hash(<str>))", ((string) hash).c_str());
         cerr << printExpr(evalValue(e)) << endl;
     }
@@ -47,6 +107,8 @@ static void opEvaluate(Strings opFlags, Strings opArgs)
 
 static void opDelete(Strings opFlags, Strings opArgs)
 {
+    getArgType(opFlags);
+
     cerr << "delete!\n";
 }
 
@@ -55,6 +117,7 @@ static void opDelete(Strings opFlags, Strings opArgs)
    those values. */
 static void opAdd(Strings opFlags, Strings opArgs)
 {
+    getArgType(opFlags);
     if (!opFlags.empty()) throw UsageError("unknown flag");
 
     for (Strings::iterator it = opArgs.begin();
@@ -78,11 +141,22 @@ struct StdoutSink : DumpSink
 /* Dump a value to standard output */
 static void opDump(Strings opFlags, Strings opArgs)
 {
+    getArgType(opFlags);
     if (!opFlags.empty()) throw UsageError("unknown flag");
     if (opArgs.size() != 1) throw UsageError("only one argument allowed");
 
     StdoutSink sink;
-    dumpPath(opArgs[0], sink);
+    string arg = *opArgs.begin();
+    string path;
+    
+    if (argType == atpHash)
+        path = queryValuePath(parseHash(arg));
+    else if (argType == atpName)
+        throw Error("not implemented");
+    else if (argType == atpPath)
+        path = arg;
+
+    dumpPath(*opArgs.begin(), sink);
 }
 
 
@@ -96,59 +170,43 @@ static void opInit(Strings opFlags, Strings opArgs)
 }
 
 
-/* Nix syntax:
-
-   nix [OPTIONS...] [ARGUMENTS...]
-
-   Operations:
-
-     --evaluate / -e: evaluate values
-     --delete / -d: delete values
-     --query / -q: query stored values
-     --add: add values
-     --verify: verify Nix structures
-     --dump: dump a file or value
-     --init: initialise the Nix database
-     --version: output version information
-     --help: display help
-
-   Operations that work on values accept the hash code of a value, the
-   symbolic name of a value, or a file name of a external value that
-   will be added prior to the operation.
-
-   Query suboptions:
-
-     Selection:
-
-     --all / -a: query all stored values, otherwise given values
-
-     Information:
-
-     --info / -i: general value information
-
-   Options:
-
-     --verbose / -v: verbose operation
-*/
-
 /* Initialize, process arguments, and dispatch to the right
    operation. */
-void run(Strings::iterator argCur, Strings::iterator argEnd)
+void run(int argc, char * * argv)
 {
-    Strings opFlags, opArgs;
-    Operation op = 0;
-
     /* Setup Nix paths. */
     nixValues = NIX_VALUES_DIR;
     nixLogDir = NIX_LOG_DIR;
     nixDB = (string) NIX_STATE_DIR + "/nixstate.db";
 
+    /* Put the arguments in a vector. */
+    Strings args;
+    while (argc--) args.push_back(*argv++);
+    args.erase(args.begin());
+    
+    /* Expand compound dash options (i.e., `-qlf' -> `-q -l -f'). */
+    for (Strings::iterator it = args.begin();
+         it != args.end(); )
+    {
+        string arg = *it;
+        if (arg.length() > 2 && arg[0] == '-' && arg[1] != '-') {
+            for (unsigned int i = 1; i < arg.length(); i++)
+                args.insert(it, (string) "-" + arg[i]);
+            it = args.erase(it);
+        } else it++;
+    }
+
+    Strings opFlags, opArgs;
+    Operation op = 0;
+
     /* Scan the arguments; find the operation, set global flags, put
        all other flags in a list, and put all other arguments in
        another list. */
 
-    while (argCur != argEnd) {
-        string arg = *argCur++;
+    for (Strings::iterator it = args.begin();
+         it != args.end(); it++)
+    {
+        string arg = *it;
 
         Operation oldOp = op;
 
@@ -184,9 +242,7 @@ int main(int argc, char * * argv)
     ATinit(argc, argv, &bottomOfStack);
 
     try {
-        Strings args;
-        while (argc--) args.push_back(*argv++);
-        run(args.begin() + 1, args.end());
+        run(argc, argv);
     } catch (UsageError & e) {
         cerr << "error: " << e.what() << endl
              << "Try `nix --help' for more information.\n";
diff --git a/src/util.hh b/src/util.hh
index 5b41fcea895b..45719e701ff6 100644
--- a/src/util.hh
+++ b/src/util.hh
@@ -2,7 +2,7 @@
 #define __UTIL_H
 
 #include <string>
-#include <vector>
+#include <list>
 #include <sstream>
 
 #include <unistd.h>
@@ -34,7 +34,7 @@ public:
 };
 
 
-typedef vector<string> Strings;
+typedef list<string> Strings;
 
 
 /* The canonical system name, as returned by config.guess. */