about summary refs log tree commit diff
path: root/src/nix-env
diff options
context:
space:
mode:
Diffstat (limited to 'src/nix-env')
-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 0e1fce650ca4..8bb760094dab 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, ")");
 }