* Flags to indicate how values are specified on the command line

(--hash, --file, --name).
This commit is contained in:
Eelco Dolstra 2003-06-20 14:11:31 +00:00
parent 5079ccb455
commit 85effedca3
4 changed files with 137 additions and 64 deletions

View file

@ -1,3 +1,5 @@
#include <vector>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
@ -44,7 +46,7 @@ static void dumpEntries(const string & path, DumpSink & sink)
DIR * dir = opendir(path.c_str()); DIR * dir = opendir(path.c_str());
if (!dir) throw SysError("opening directory " + path); if (!dir) throw SysError("opening directory " + path);
Strings names; vector<string> names;
struct dirent * dirent; struct dirent * dirent;
while (errno = 0, dirent = readdir(dir)) { while (errno = 0, dirent = readdir(dir)) {
@ -56,7 +58,7 @@ static void dumpEntries(const string & path, DumpSink & sink)
sort(names.begin(), names.end()); sort(names.begin(), names.end());
for (Strings::iterator it = names.begin(); for (vector<string>::iterator it = names.begin();
it != names.end(); it++) it != names.end(); it++)
{ {
writeString("entry", sink); writeString("entry", sink);
@ -134,3 +136,8 @@ void dumpPath(const string & path, DumpSink & sink)
writeString(")", sink); writeString(")", sink);
} }
void restorePath(const string & path, ReadSource & source)
{
}

View file

@ -46,3 +46,13 @@ struct DumpSink
}; };
void dumpPath(const string & path, DumpSink & sink); 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;
};

View file

@ -11,34 +11,94 @@
typedef void (* Operation) (Strings opFlags, Strings opArgs); typedef void (* Operation) (Strings opFlags, Strings opArgs);
/* Parse a supposed value argument. This can be a hash (the simple typedef enum { atpHash, atpName, atpPath, atpUnknown } ArgType;
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) { };
if (s.find('/') != string::npos) { static ArgType argType = atpUnknown;
return addValue(s);
} else {
throw Error("not implemented"); /* 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. */ /* Evaluate values. */
static void opEvaluate(Strings opFlags, Strings opArgs) static void opEvaluate(Strings opFlags, Strings opArgs)
{ {
getArgType(opFlags);
if (!opFlags.empty()) throw UsageError("unknown flag"); if (!opFlags.empty()) throw UsageError("unknown flag");
for (Strings::iterator it = opArgs.begin(); for (Strings::iterator it = opArgs.begin();
it != opArgs.end(); it++) 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()); Expr e = ATmake("Deref(Hash(<str>))", ((string) hash).c_str());
cerr << printExpr(evalValue(e)) << endl; cerr << printExpr(evalValue(e)) << endl;
} }
@ -47,6 +107,8 @@ static void opEvaluate(Strings opFlags, Strings opArgs)
static void opDelete(Strings opFlags, Strings opArgs) static void opDelete(Strings opFlags, Strings opArgs)
{ {
getArgType(opFlags);
cerr << "delete!\n"; cerr << "delete!\n";
} }
@ -55,6 +117,7 @@ static void opDelete(Strings opFlags, Strings opArgs)
those values. */ those values. */
static void opAdd(Strings opFlags, Strings opArgs) static void opAdd(Strings opFlags, Strings opArgs)
{ {
getArgType(opFlags);
if (!opFlags.empty()) throw UsageError("unknown flag"); if (!opFlags.empty()) throw UsageError("unknown flag");
for (Strings::iterator it = opArgs.begin(); for (Strings::iterator it = opArgs.begin();
@ -78,11 +141,22 @@ struct StdoutSink : DumpSink
/* Dump a value to standard output */ /* Dump a value to standard output */
static void opDump(Strings opFlags, Strings opArgs) static void opDump(Strings opFlags, Strings opArgs)
{ {
getArgType(opFlags);
if (!opFlags.empty()) throw UsageError("unknown flag"); if (!opFlags.empty()) throw UsageError("unknown flag");
if (opArgs.size() != 1) throw UsageError("only one argument allowed"); if (opArgs.size() != 1) throw UsageError("only one argument allowed");
StdoutSink sink; 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 /* Initialize, process arguments, and dispatch to the right
operation. */ operation. */
void run(Strings::iterator argCur, Strings::iterator argEnd) void run(int argc, char * * argv)
{ {
Strings opFlags, opArgs;
Operation op = 0;
/* Setup Nix paths. */ /* Setup Nix paths. */
nixValues = NIX_VALUES_DIR; nixValues = NIX_VALUES_DIR;
nixLogDir = NIX_LOG_DIR; nixLogDir = NIX_LOG_DIR;
nixDB = (string) NIX_STATE_DIR + "/nixstate.db"; 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 /* Scan the arguments; find the operation, set global flags, put
all other flags in a list, and put all other arguments in all other flags in a list, and put all other arguments in
another list. */ another list. */
while (argCur != argEnd) { for (Strings::iterator it = args.begin();
string arg = *argCur++; it != args.end(); it++)
{
string arg = *it;
Operation oldOp = op; Operation oldOp = op;
@ -184,9 +242,7 @@ int main(int argc, char * * argv)
ATinit(argc, argv, &bottomOfStack); ATinit(argc, argv, &bottomOfStack);
try { try {
Strings args; run(argc, argv);
while (argc--) args.push_back(*argv++);
run(args.begin() + 1, args.end());
} catch (UsageError & e) { } catch (UsageError & e) {
cerr << "error: " << e.what() << endl cerr << "error: " << e.what() << endl
<< "Try `nix --help' for more information.\n"; << "Try `nix --help' for more information.\n";

View file

@ -2,7 +2,7 @@
#define __UTIL_H #define __UTIL_H
#include <string> #include <string>
#include <vector> #include <list>
#include <sstream> #include <sstream>
#include <unistd.h> #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. */ /* The canonical system name, as returned by config.guess. */