diff --git a/src/archive.cc b/src/archive.cc index 2fdbfb4764..591939bb6a 100644 --- a/src/archive.cc +++ b/src/archive.cc @@ -1,3 +1,5 @@ +#include + #include #include #include @@ -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 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::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 bfd96b45c0..d351c6bf63 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 4f0b97854b..8380abc20e 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())", ((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 5b41fcea89..45719e701f 100644 --- a/src/util.hh +++ b/src/util.hh @@ -2,7 +2,7 @@ #define __UTIL_H #include -#include +#include #include #include @@ -34,7 +34,7 @@ public: }; -typedef vector Strings; +typedef list Strings; /* The canonical system name, as returned by config.guess. */