aboutsummaryrefslogtreecommitdiff
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 2fdbfb476..591939bb6 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 bfd96b45c..d351c6bf6 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 4f0b97854..8380abc20 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 5b41fcea8..45719e701 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. */