aboutsummaryrefslogtreecommitdiff
path: root/src/nix-env/user-env.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-19 12:10:04 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-19 12:10:04 +0000
commit55b5ddd3ca1ff4dfe4cfbfab92a4025d88ef6443 (patch)
treed9377895a711709f73ceabb10b511b91b0d3b4e5 /src/nix-env/user-env.cc
parentb7ff69eb7c3f97c33ec18c51ab87b7f3dd967052 (diff)
* Added parsing of manifests in ATerm format.
Diffstat (limited to 'src/nix-env/user-env.cc')
-rw-r--r--src/nix-env/user-env.cc157
1 files changed, 150 insertions, 7 deletions
diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc
index 0e1fce650..8bb760094 100644
--- a/src/nix-env/user-env.cc
+++ b/src/nix-env/user-env.cc
@@ -5,22 +5,165 @@
namespace nix {
+static void readLegacyManifest(const Path & path, DrvInfos & elems);
+
+
DrvInfos queryInstalled(EvalState & state, const Path & userEnv)
{
+ DrvInfos elems;
+
Path path = userEnv + "/manifest";
if (!pathExists(path))
return DrvInfos(); /* not an error, assume nothing installed */
- throw Error("not implemented");
-#if 0
- Expr e = ATreadFromNamedFile(path.c_str());
- if (!e) throw Error(format("cannot read Nix expression from `%1%'") % path);
+ readLegacyManifest(path, elems);
- DrvInfos elems;
- // !!! getDerivations(state, e, "", ATermMap(1), elems);
return elems;
-#endif
+}
+
+
+/* Code for parsing manifests in the old textual ATerm format. */
+
+static void expect(std::istream & str, const string & s)
+{
+ char s2[s.size()];
+ str.read(s2, s.size());
+ if (string(s2, s.size()) != s)
+ throw Error(format("expected string `%1%'") % s);
+}
+
+
+static string parseString(std::istream & str)
+{
+ string res;
+ expect(str, "\"");
+ int c;
+ while ((c = str.get()) != '"')
+ if (c == '\\') {
+ c = str.get();
+ if (c == 'n') res += '\n';
+ else if (c == 'r') res += '\r';
+ else if (c == 't') res += '\t';
+ else res += c;
+ }
+ else res += c;
+ return res;
+}
+
+
+static string parseStr(std::istream & str)
+{
+ expect(str, "Str(");
+ string s = parseString(str);
+ expect(str, ",[])");
+ return s;
+}
+
+
+static string parseWord(std::istream & str)
+{
+ string res;
+ while (isalpha(str.peek()))
+ res += str.get();
+ return res;
+}
+
+
+static bool endOfList(std::istream & str)
+{
+ if (str.peek() == ',') {
+ str.get();
+ return false;
+ }
+ if (str.peek() == ']') {
+ str.get();
+ return true;
+ }
+ return false;
+}
+
+
+static MetaInfo parseMeta(std::istream & str)
+{
+ MetaInfo meta;
+
+ expect(str, "Attrs([");
+ while (!endOfList(str)) {
+ expect(str, "Bind(");
+
+ MetaValue value;
+
+ string name = parseString(str);
+ expect(str, ",");
+
+ string type = parseWord(str);
+
+ if (type == "Str") {
+ expect(str, "(");
+ value.type = MetaValue::tpString;
+ value.stringValue = parseString(str);
+ expect(str, ",[])");
+ }
+
+ else if (type == "List") {
+ expect(str, "([");
+ value.type = MetaValue::tpStrings;
+ while (!endOfList(str))
+ value.stringValues.push_back(parseStr(str));
+ expect(str, ")");
+ }
+
+ else throw Error(format("unexpected token `%1%'") % type);
+
+ expect(str, ",NoPos)");
+ meta[name] = value;
+ }
+
+ expect(str, ")");
+
+ return meta;
+}
+
+
+static void readLegacyManifest(const Path & path, DrvInfos & elems)
+{
+ string manifest = readFile(path);
+ std::istringstream str(manifest);
+ expect(str, "List([");
+
+ unsigned int n = 0;
+
+ while (!endOfList(str)) {
+ DrvInfo elem;
+ expect(str, "Attrs([");
+
+ while (!endOfList(str)) {
+ expect(str, "Bind(");
+ string name = parseString(str);
+ expect(str, ",");
+
+ if (name == "meta") elem.setMetaInfo(parseMeta(str));
+ else {
+ string value = parseStr(str);
+ if (name == "name") elem.name = value;
+ else if (name == "outPath") elem.setOutPath(value);
+ else if (name == "drvPath") elem.setDrvPath(value);
+ else if (name == "system") elem.system = value;
+ }
+
+ expect(str, ",NoPos)");
+ }
+
+ expect(str, ")");
+
+ if (elem.name != "") {
+ elem.attrPath = int2String(n++);
+ elems.push_back(elem);
+ }
+ }
+
+ expect(str, ")");
}