* Added parsing of manifests in ATerm format.
This commit is contained in:
		
							parent
							
								
									b7ff69eb7c
								
							
						
					
					
						commit
						55b5ddd3ca
					
				
					 3 changed files with 165 additions and 13 deletions
				
			
		|  | @ -7,7 +7,7 @@ namespace nix { | ||||||
| 
 | 
 | ||||||
| string DrvInfo::queryDrvPath(EvalState & state) const | string DrvInfo::queryDrvPath(EvalState & state) const | ||||||
| { | { | ||||||
|     if (drvPath == "") { |     if (drvPath == "" && attrs) { | ||||||
|         Bindings::iterator i = attrs->find(state.sDrvPath); |         Bindings::iterator i = attrs->find(state.sDrvPath); | ||||||
|         PathSet context; |         PathSet context; | ||||||
|         (string &) drvPath = i != attrs->end() ? state.coerceToPath(i->second, context) : ""; |         (string &) drvPath = i != attrs->end() ? state.coerceToPath(i->second, context) : ""; | ||||||
|  | @ -18,7 +18,7 @@ string DrvInfo::queryDrvPath(EvalState & state) const | ||||||
| 
 | 
 | ||||||
| string DrvInfo::queryOutPath(EvalState & state) const | string DrvInfo::queryOutPath(EvalState & state) const | ||||||
| { | { | ||||||
|     if (outPath == "") { |     if (outPath == "" && attrs) { | ||||||
|         Bindings::iterator i = attrs->find(state.sOutPath); |         Bindings::iterator i = attrs->find(state.sOutPath); | ||||||
|         PathSet context; |         PathSet context; | ||||||
|         (string &) outPath = i != attrs->end() ? state.coerceToPath(i->second, context) : ""; |         (string &) outPath = i != attrs->end() ? state.coerceToPath(i->second, context) : ""; | ||||||
|  | @ -29,7 +29,9 @@ string DrvInfo::queryOutPath(EvalState & state) const | ||||||
| 
 | 
 | ||||||
| MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const | MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const | ||||||
| { | { | ||||||
|     MetaInfo meta; |     if (metaInfoRead) return meta; | ||||||
|  |      | ||||||
|  |     (bool &) metaInfoRead = true; | ||||||
|      |      | ||||||
|     Bindings::iterator a = attrs->find(state.sMeta); |     Bindings::iterator a = attrs->find(state.sMeta); | ||||||
|     if (a == attrs->end()) return meta; /* fine, empty meta information */ |     if (a == attrs->end()) return meta; /* fine, empty meta information */ | ||||||
|  | @ -50,7 +52,7 @@ MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const | ||||||
|             for (unsigned int j = 0; j < i->second.list.length; ++j) |             for (unsigned int j = 0; j < i->second.list.length; ++j) | ||||||
|                 value.stringValues.push_back(state.forceStringNoCtx(*i->second.list.elems[j])); |                 value.stringValues.push_back(state.forceStringNoCtx(*i->second.list.elems[j])); | ||||||
|         } else continue; |         } else continue; | ||||||
|         meta[i->first] = value; |         ((MetaInfo &) meta)[i->first] = value; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return meta; |     return meta; | ||||||
|  | @ -66,9 +68,11 @@ MetaValue DrvInfo::queryMetaInfo(EvalState & state, const string & name) const | ||||||
| 
 | 
 | ||||||
| void DrvInfo::setMetaInfo(const MetaInfo & meta) | void DrvInfo::setMetaInfo(const MetaInfo & meta) | ||||||
| { | { | ||||||
|     throw Error("not implemented"); |     metaInfoRead = true; | ||||||
|  |     this->meta = meta; | ||||||
|  |      | ||||||
| #if 0 | #if 0 | ||||||
|     ATermMap metaAttrs; |     Value * metaAttrs = state.allocValues(1); | ||||||
|     foreach (MetaInfo::const_iterator, i, meta) { |     foreach (MetaInfo::const_iterator, i, meta) { | ||||||
|         Expr e; |         Expr e; | ||||||
|         switch (i->second.type) { |         switch (i->second.type) { | ||||||
|  |  | ||||||
|  | @ -29,6 +29,9 @@ struct DrvInfo | ||||||
| private: | private: | ||||||
|     string drvPath; |     string drvPath; | ||||||
|     string outPath; |     string outPath; | ||||||
|  | 
 | ||||||
|  |     bool metaInfoRead; | ||||||
|  |     MetaInfo meta; | ||||||
|      |      | ||||||
| public: | public: | ||||||
|     string name; |     string name; | ||||||
|  | @ -38,6 +41,8 @@ public: | ||||||
|     /* !!! make this private */ |     /* !!! make this private */ | ||||||
|     Bindings * attrs; |     Bindings * attrs; | ||||||
| 
 | 
 | ||||||
|  |     DrvInfo() : metaInfoRead(false) { }; | ||||||
|  | 
 | ||||||
|     string queryDrvPath(EvalState & state) const; |     string queryDrvPath(EvalState & state) const; | ||||||
|     string queryOutPath(EvalState & state) const; |     string queryOutPath(EvalState & state) const; | ||||||
|     MetaInfo queryMetaInfo(EvalState & state) const; |     MetaInfo queryMetaInfo(EvalState & state) const; | ||||||
|  |  | ||||||
|  | @ -5,22 +5,165 @@ | ||||||
| namespace nix { | namespace nix { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | static void readLegacyManifest(const Path & path, DrvInfos & elems); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| DrvInfos queryInstalled(EvalState & state, const Path & userEnv) | DrvInfos queryInstalled(EvalState & state, const Path & userEnv) | ||||||
| { | { | ||||||
|  |     DrvInfos elems; | ||||||
|  |      | ||||||
|     Path path = userEnv + "/manifest"; |     Path path = userEnv + "/manifest"; | ||||||
| 
 | 
 | ||||||
|     if (!pathExists(path)) |     if (!pathExists(path)) | ||||||
|         return DrvInfos(); /* not an error, assume nothing installed */ |         return DrvInfos(); /* not an error, assume nothing installed */ | ||||||
| 
 | 
 | ||||||
|     throw Error("not implemented"); |     readLegacyManifest(path, elems); | ||||||
| #if 0 |  | ||||||
|     Expr e = ATreadFromNamedFile(path.c_str()); |  | ||||||
|     if (!e) throw Error(format("cannot read Nix expression from `%1%'") % path); |  | ||||||
| 
 | 
 | ||||||
|     DrvInfos elems; |  | ||||||
|     // !!! getDerivations(state, e, "", ATermMap(1), elems);
 |  | ||||||
|     return 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, ")"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue