* Implemented the primops necessary for generating the NixOS manual.
This commit is contained in:
		
							parent
							
								
									a353aef0b1
								
							
						
					
					
						commit
						fc92244ba8
					
				
					 8 changed files with 160 additions and 146 deletions
				
			
		|  | @ -16,7 +16,8 @@ void doTest(string s) | ||||||
|     Expr e = parseExprFromString(state, s, absPath(".")); |     Expr e = parseExprFromString(state, s, absPath(".")); | ||||||
|     printMsg(lvlError, format(">>>>> %1%") % e); |     printMsg(lvlError, format(">>>>> %1%") % e); | ||||||
|     Value v; |     Value v; | ||||||
|     state.strictEval(e, v); |     state.eval(e, v); | ||||||
|  |     state.strictForceValue(v); | ||||||
|     printMsg(lvlError, format("result: %1%") % v); |     printMsg(lvlError, format("result: %1%") % v); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -76,6 +77,8 @@ void run(Strings args) | ||||||
|     doTest("let x = 1; as = rec { inherit x; y = as.x; }; in as.y"); |     doTest("let x = 1; as = rec { inherit x; y = as.x; }; in as.y"); | ||||||
|     doTest("let as = { x = 1; }; bs = rec { inherit (as) x; y = x; }; in bs.y"); |     doTest("let as = { x = 1; }; bs = rec { inherit (as) x; y = x; }; in bs.y"); | ||||||
|     doTest("let as = rec { inherit (y) x; y = { x = 1; }; }; in as.x"); |     doTest("let as = rec { inherit (y) x; y = { x = 1; }; }; in as.x"); | ||||||
|  |     doTest("builtins.toXML 123"); | ||||||
|  |     doTest("builtins.toXML { a.b = \"x\" + \"y\"; c = [ 1 2 ] ++ [ 3 4 ]; }"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -302,6 +302,8 @@ void EvalState::eval(Env & env, Expr e, Value & v) | ||||||
|      |      | ||||||
|     //debug(format("eval: %1%") % e);
 |     //debug(format("eval: %1%") % e);
 | ||||||
| 
 | 
 | ||||||
|  |     checkInterrupt(); | ||||||
|  | 
 | ||||||
|     nrEvaluated++; |     nrEvaluated++; | ||||||
| 
 | 
 | ||||||
|     Sym name; |     Sym name; | ||||||
|  | @ -639,28 +641,6 @@ bool EvalState::evalBool(Env & env, Expr e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void EvalState::strictEval(Env & env, Expr e, Value & v) |  | ||||||
| { |  | ||||||
|     eval(env, e, v); |  | ||||||
|      |  | ||||||
|     if (v.type == tAttrs) { |  | ||||||
|         foreach (Bindings::iterator, i, *v.attrs) |  | ||||||
|             forceValue(i->second); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     else if (v.type == tList) { |  | ||||||
|         for (unsigned int n = 0; n < v.list.length; ++n) |  | ||||||
|             forceValue(v.list.elems[n]); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void EvalState::strictEval(Expr e, Value & v) |  | ||||||
| { |  | ||||||
|     strictEval(baseEnv, e, v); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void EvalState::forceValue(Value & v) | void EvalState::forceValue(Value & v) | ||||||
| { | { | ||||||
|     if (v.type == tThunk) { |     if (v.type == tThunk) { | ||||||
|  | @ -678,6 +658,22 @@ void EvalState::forceValue(Value & v) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | void EvalState::strictForceValue(Value & v) | ||||||
|  | { | ||||||
|  |     forceValue(v); | ||||||
|  |      | ||||||
|  |     if (v.type == tAttrs) { | ||||||
|  |         foreach (Bindings::iterator, i, *v.attrs) | ||||||
|  |             strictForceValue(i->second); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     else if (v.type == tList) { | ||||||
|  |         for (unsigned int n = 0; n < v.list.length; ++n) | ||||||
|  |             strictForceValue(v.list.elems[n]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| int EvalState::forceInt(Value & v) | int EvalState::forceInt(Value & v) | ||||||
| { | { | ||||||
|     forceValue(v); |     forceValue(v); | ||||||
|  | @ -750,6 +746,14 @@ string EvalState::forceStringNoCtx(Value & v) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | bool EvalState::isDerivation(Value & v) | ||||||
|  | { | ||||||
|  |     if (v.type != tAttrs) return false; | ||||||
|  |     Bindings::iterator i = v.attrs->find(toATerm("type")); | ||||||
|  |     return i != v.attrs->end() && forceStringNoCtx(i->second) == "derivation"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| string EvalState::coerceToString(Value & v, PathSet & context, | string EvalState::coerceToString(Value & v, PathSet & context, | ||||||
|     bool coerceMore, bool copyToStore) |     bool coerceMore, bool copyToStore) | ||||||
| { | { | ||||||
|  | @ -769,7 +773,7 @@ string EvalState::coerceToString(Value & v, PathSet & context, | ||||||
| 
 | 
 | ||||||
|         if (!copyToStore) return path; |         if (!copyToStore) return path; | ||||||
|          |          | ||||||
|         if (isDerivation(path)) |         if (nix::isDerivation(path)) | ||||||
|             throw EvalError(format("file names are not allowed to end in `%1%'") |             throw EvalError(format("file names are not allowed to end in `%1%'") | ||||||
|                 % drvExtension); |                 % drvExtension); | ||||||
| 
 | 
 | ||||||
|  | @ -1415,5 +1419,5 @@ void EvalState::printStats() | ||||||
|         printATermMapStats(); |         printATermMapStats(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|   | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -169,17 +169,16 @@ public: | ||||||
|        type. */ |        type. */ | ||||||
|     bool evalBool(Env & env, Expr e); |     bool evalBool(Env & env, Expr e); | ||||||
| 
 | 
 | ||||||
|     /* Evaluate an expression, and recursively evaluate list elements
 |  | ||||||
|        and attributes. */ |  | ||||||
|     void strictEval(Expr e, Value & v); |  | ||||||
|     void strictEval(Env & env, Expr e, Value & v); |  | ||||||
| 
 |  | ||||||
|     /* If `v' is a thunk, enter it and overwrite `v' with the result
 |     /* If `v' is a thunk, enter it and overwrite `v' with the result
 | ||||||
|        of the evaluation of the thunk.  If `v' is a delayed function |        of the evaluation of the thunk.  If `v' is a delayed function | ||||||
|        application, call the function and overwrite `v' with the |        application, call the function and overwrite `v' with the | ||||||
|        result.  Otherwise, this is a no-op. */ |        result.  Otherwise, this is a no-op. */ | ||||||
|     void forceValue(Value & v); |     void forceValue(Value & v); | ||||||
| 
 | 
 | ||||||
|  |     /* Force a value, then recursively force list elements and
 | ||||||
|  |        attributes. */ | ||||||
|  |     void strictForceValue(Value & v); | ||||||
|  | 
 | ||||||
|     /* Force `v', and then verify that it has the expected type. */ |     /* Force `v', and then verify that it has the expected type. */ | ||||||
|     int forceInt(Value & v); |     int forceInt(Value & v); | ||||||
|     bool forceBool(Value & v); |     bool forceBool(Value & v); | ||||||
|  | @ -190,6 +189,10 @@ public: | ||||||
|     string forceString(Value & v, PathSet & context); |     string forceString(Value & v, PathSet & context); | ||||||
|     string forceStringNoCtx(Value & v); |     string forceStringNoCtx(Value & v); | ||||||
| 
 | 
 | ||||||
|  |     /* Return true iff the value `v' denotes a derivation (i.e. a
 | ||||||
|  |        set with attribute `type = "derivation"'). */ | ||||||
|  |     bool isDerivation(Value & v); | ||||||
|  | 
 | ||||||
|     /* String coercion.  Converts strings, paths and derivations to a
 |     /* String coercion.  Converts strings, paths and derivations to a
 | ||||||
|        string.  If `coerceMore' is set, also converts nulls, integers, |        string.  If `coerceMore' is set, also converts nulls, integers, | ||||||
|        booleans and lists to a string.  If `copyToStore' is set, |        booleans and lists to a string.  If `copyToStore' is set, | ||||||
|  | @ -219,10 +222,10 @@ private: | ||||||
|        elements and attributes are compared recursively. */ |        elements and attributes are compared recursively. */ | ||||||
|     bool eqValues(Value & v1, Value & v2); |     bool eqValues(Value & v1, Value & v2); | ||||||
| 
 | 
 | ||||||
|     void callFunction(Value & fun, Value & arg, Value & v); |  | ||||||
| 
 |  | ||||||
| public: | public: | ||||||
|      |      | ||||||
|  |     void callFunction(Value & fun, Value & arg, Value & v); | ||||||
|  | 
 | ||||||
|     /* Allocation primitives. */ |     /* Allocation primitives. */ | ||||||
|     Value * allocValues(unsigned int count); |     Value * allocValues(unsigned int count); | ||||||
|     Env & allocEnv(); |     Env & allocEnv(); | ||||||
|  | @ -237,6 +240,10 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /* Return a string representing the type of the value `v'. */ | ||||||
|  | string showType(Value & v); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| #if 0 | #if 0 | ||||||
| /* Evaluate an expression to normal form. */ | /* Evaluate an expression to normal form. */ | ||||||
| Expr evalExpr(EvalState & state, Expr e); | Expr evalExpr(EvalState & state, Expr e); | ||||||
|  |  | ||||||
|  | @ -18,24 +18,19 @@ static XMLAttrs singletonAttrs(const string & name, const string & value) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* set<Expr> is safe because all the expressions are also reachable
 | static void printValueAsXML(EvalState & state, bool strict, Value & v, | ||||||
|    from the stack, therefore can't be garbage-collected. */ |     XMLWriter & doc, PathSet & context, PathSet & drvsSeen); | ||||||
| typedef set<Expr> ExprSet; |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context, | static void showAttrs(EvalState & state, bool strict, Bindings & attrs, | ||||||
|     ExprSet & drvsSeen); |     XMLWriter & doc, PathSet & context, PathSet & drvsSeen) | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static void showAttrs(const ATermMap & attrs, XMLWriter & doc, |  | ||||||
|     PathSet & context, ExprSet & drvsSeen) |  | ||||||
| { | { | ||||||
|     StringSet names; |     StringSet names; | ||||||
|     for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i) |     foreach (Bindings::iterator, i, attrs) | ||||||
|         names.insert(aterm2String(i->key)); |         names.insert(aterm2String(i->first)); | ||||||
|     for (StringSet::iterator i = names.begin(); i != names.end(); ++i) { |     foreach (StringSet::iterator, i, names) { | ||||||
|         XMLOpenElement _(doc, "attr", singletonAttrs("name", *i)); |         XMLOpenElement _(doc, "attr", singletonAttrs("name", *i)); | ||||||
|         printTermAsXML(attrs.get(toATerm(*i)), doc, context, drvsSeen); |         printValueAsXML(state, strict, attrs[toATerm(*i)], doc, context, drvsSeen); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -61,91 +56,93 @@ static void printPatternAsXML(Pattern pat, XMLWriter & doc) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context, | static void printValueAsXML(EvalState & state, bool strict, Value & v, | ||||||
|     ExprSet & drvsSeen) |     XMLWriter & doc, PathSet & context, PathSet & drvsSeen) | ||||||
| { | { | ||||||
|     XMLAttrs attrs; |  | ||||||
|     string s; |  | ||||||
|     ATerm s2; |  | ||||||
|     int i; |  | ||||||
|     ATermList as, es; |  | ||||||
|     ATerm pat, body, pos; |  | ||||||
| 
 |  | ||||||
|     checkInterrupt(); |     checkInterrupt(); | ||||||
| 
 | 
 | ||||||
|     if (matchStr(e, s, context)) /* !!! show the context? */ |     if (strict) state.forceValue(v); | ||||||
|         doc.writeEmptyElement("string", singletonAttrs("value", s)); |          | ||||||
|  |     switch (v.type) { | ||||||
| 
 | 
 | ||||||
|     else if (matchPath(e, s2)) |         case tInt: | ||||||
|         doc.writeEmptyElement("path", singletonAttrs("value", aterm2String(s2))); |             doc.writeEmptyElement("int", singletonAttrs("value", (format("%1%") % v.integer).str())); | ||||||
|  |             break; | ||||||
| 
 | 
 | ||||||
|     else if (matchNull(e)) |         case tBool: | ||||||
|         doc.writeEmptyElement("null"); |             doc.writeEmptyElement("bool", singletonAttrs("value", v.boolean ? "true" : "false")); | ||||||
|  |             break; | ||||||
| 
 | 
 | ||||||
|     else if (matchInt(e, i)) |         case tString: | ||||||
|         doc.writeEmptyElement("int", singletonAttrs("value", (format("%1%") % i).str())); |             /* !!! show the context? */ | ||||||
|  |             doc.writeEmptyElement("string", singletonAttrs("value", v.string.s)); | ||||||
|  |             break; | ||||||
| 
 | 
 | ||||||
|     else if (e == eTrue) |         case tPath: | ||||||
|         doc.writeEmptyElement("bool", singletonAttrs("value", "true")); |             doc.writeEmptyElement("path", singletonAttrs("value", v.path)); | ||||||
|  |             break; | ||||||
| 
 | 
 | ||||||
|     else if (e == eFalse) |         case tNull: | ||||||
|         doc.writeEmptyElement("bool", singletonAttrs("value", "false")); |             doc.writeEmptyElement("null"); | ||||||
|  |             break; | ||||||
| 
 | 
 | ||||||
|     else if (matchAttrs(e, as)) { |         case tAttrs: | ||||||
|         ATermMap attrs; |             if (state.isDerivation(v)) { | ||||||
|         queryAllAttrs(e, attrs); |                 XMLAttrs xmlAttrs; | ||||||
| 
 |  | ||||||
|         Expr a = attrs.get(toATerm("type")); |  | ||||||
|         if (a && matchStr(a, s, context) && s == "derivation") { |  | ||||||
| 
 |  | ||||||
|             XMLAttrs xmlAttrs; |  | ||||||
|             Path outPath, drvPath; |  | ||||||
|              |              | ||||||
|             a = attrs.get(toATerm("drvPath")); |                 Bindings::iterator a = v.attrs->find(toATerm("derivation")); | ||||||
|             if (matchStr(a, drvPath, context)) |  | ||||||
|                 xmlAttrs["drvPath"] = drvPath; |  | ||||||
|          |  | ||||||
|             a = attrs.get(toATerm("outPath")); |  | ||||||
|             if (matchStr(a, outPath, context)) |  | ||||||
|                 xmlAttrs["outPath"] = outPath; |  | ||||||
|          |  | ||||||
|             XMLOpenElement _(doc, "derivation", xmlAttrs); |  | ||||||
| 
 | 
 | ||||||
|             if (drvsSeen.find(e) == drvsSeen.end()) { |                 Path drvPath; | ||||||
|                 drvsSeen.insert(e); |                 a = v.attrs->find(toATerm("drvPath")); | ||||||
|                 showAttrs(attrs, doc, context, drvsSeen); |                 if (a != v.attrs->end() && a->second.type == tString) | ||||||
|             } else |                     xmlAttrs["drvPath"] = drvPath = a->second.string.s; | ||||||
|                 doc.writeEmptyElement("repeated"); |          | ||||||
|  |                 a = v.attrs->find(toATerm("outPath")); | ||||||
|  |                 if (a != v.attrs->end() && a->second.type == tString) | ||||||
|  |                     xmlAttrs["outPath"] = a->second.string.s; | ||||||
|  | 
 | ||||||
|  |                 XMLOpenElement _(doc, "derivation", xmlAttrs); | ||||||
|  | 
 | ||||||
|  |                 if (drvPath != "" && drvsSeen.find(drvPath) == drvsSeen.end()) { | ||||||
|  |                     drvsSeen.insert(drvPath); | ||||||
|  |                     showAttrs(state, strict, *v.attrs, doc, context, drvsSeen); | ||||||
|  |                 } else | ||||||
|  |                     doc.writeEmptyElement("repeated"); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             else { | ||||||
|  |                 XMLOpenElement _(doc, "attrs"); | ||||||
|  |                 showAttrs(state, strict, *v.attrs, doc, context, drvsSeen); | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             break; | ||||||
|  | 
 | ||||||
|  |         case tList: { | ||||||
|  |             XMLOpenElement _(doc, "list"); | ||||||
|  |             for (unsigned int n = 0; n < v.list.length; ++n) | ||||||
|  |                 printValueAsXML(state, strict, v.list.elems[n], doc, context, drvsSeen); | ||||||
|  |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         else { |         case tLambda: { | ||||||
|             XMLOpenElement _(doc, "attrs"); |             XMLOpenElement _(doc, "function"); | ||||||
|             showAttrs(attrs, doc, context, drvsSeen); |             printPatternAsXML(v.lambda.pat, doc); | ||||||
|  |             break; | ||||||
|         } |         } | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     else if (matchList(e, es)) { |         default: | ||||||
|         XMLOpenElement _(doc, "list"); |             doc.writeEmptyElement("unevaluated"); | ||||||
|         for (ATermIterator i(es); i; ++i) |  | ||||||
|             printTermAsXML(*i, doc, context, drvsSeen); |  | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     else if (matchFunction(e, pat, body, pos)) { |  | ||||||
|         XMLOpenElement _(doc, "function"); |  | ||||||
|         printPatternAsXML(pat, doc); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     else |  | ||||||
|         doc.writeEmptyElement("unevaluated"); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void printTermAsXML(Expr e, std::ostream & out, PathSet & context) | void printValueAsXML(EvalState & state, bool strict, | ||||||
|  |     Value & v, std::ostream & out, PathSet & context) | ||||||
| { | { | ||||||
|     XMLWriter doc(true, out); |     XMLWriter doc(true, out); | ||||||
|     XMLOpenElement root(doc, "expr"); |     XMLOpenElement root(doc, "expr"); | ||||||
|     ExprSet drvsSeen;     |     PathSet drvsSeen;     | ||||||
|     printTermAsXML(e, doc, context, drvsSeen); |     printValueAsXML(state, strict, v, doc, context, drvsSeen); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|   |   | ||||||
|  |  | ||||||
|  | @ -5,11 +5,12 @@ | ||||||
| #include <map> | #include <map> | ||||||
| 
 | 
 | ||||||
| #include "nixexpr.hh" | #include "nixexpr.hh" | ||||||
| #include "aterm.hh" | #include "eval.hh" | ||||||
| 
 | 
 | ||||||
| namespace nix { | namespace nix { | ||||||
| 
 | 
 | ||||||
| void printTermAsXML(Expr e, std::ostream & out, PathSet & context); | void printValueAsXML(EvalState & state, bool strict, | ||||||
|  |     Value & v, std::ostream & out, PathSet & context); | ||||||
|      |      | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -105,10 +105,7 @@ static bool getDerivation(EvalState & state, Value & v, | ||||||
| { | { | ||||||
|     try { |     try { | ||||||
|         state.forceValue(v); |         state.forceValue(v); | ||||||
|         if (v.type != tAttrs) return true; |         if (!state.isDerivation(v)) return true; | ||||||
| 
 |  | ||||||
|         Bindings::iterator i = v.attrs->find(toATerm("type")); |  | ||||||
|         if (i == v.attrs->end() || state.forceStringNoCtx(i->second) != "derivation") return true; |  | ||||||
| 
 | 
 | ||||||
|         /* Remove spurious duplicates (e.g., an attribute set like
 |         /* Remove spurious duplicates (e.g., an attribute set like
 | ||||||
|            `rec { x = derivation {...}; y = x;}'. */ |            `rec { x = derivation {...}; y = x;}'. */ | ||||||
|  | @ -117,7 +114,7 @@ static bool getDerivation(EvalState & state, Value & v, | ||||||
| 
 | 
 | ||||||
|         DrvInfo drv; |         DrvInfo drv; | ||||||
|      |      | ||||||
|         i = v.attrs->find(toATerm("name")); |         Bindings::iterator i = v.attrs->find(toATerm("name")); | ||||||
|         /* !!! We really would like to have a decent back trace here. */ |         /* !!! We really would like to have a decent back trace here. */ | ||||||
|         if (i == v.attrs->end()) throw TypeError("derivation name missing"); |         if (i == v.attrs->end()) throw TypeError("derivation name missing"); | ||||||
|         drv.name = state.forceStringNoCtx(i->second); |         drv.name = state.forceStringNoCtx(i->second); | ||||||
|  |  | ||||||
|  | @ -538,7 +538,6 @@ static void prim_readFile(EvalState & state, Value * * args, Value & v) | ||||||
|  *************************************************************/ |  *************************************************************/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #if 0 |  | ||||||
| /* Convert the argument (which can be any Nix expression) to an XML
 | /* Convert the argument (which can be any Nix expression) to an XML
 | ||||||
|    representation returned in a string.  Not all Nix expressions can |    representation returned in a string.  Not all Nix expressions can | ||||||
|    be sensibly or completely represented (e.g., functions). */ |    be sensibly or completely represented (e.g., functions). */ | ||||||
|  | @ -546,10 +545,9 @@ static void prim_toXML(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     std::ostringstream out; |     std::ostringstream out; | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     printTermAsXML(strictEvalExpr(state, args[0]), out, context); |     printValueAsXML(state, true, *args[0], out, context); | ||||||
|     return makeStr(out.str(), context); |     mkString(v, out.str(), context); | ||||||
| } | } | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Store a string in the Nix store as a source file that can be used
 | /* Store a string in the Nix store as a source file that can be used
 | ||||||
|  | @ -582,13 +580,12 @@ static void prim_toFile(EvalState & state, Value * * args, Value & v) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #if 0 |  | ||||||
| struct FilterFromExpr : PathFilter | struct FilterFromExpr : PathFilter | ||||||
| { | { | ||||||
|     EvalState & state; |     EvalState & state; | ||||||
|     Expr filter; |     Value & filter; | ||||||
|      |      | ||||||
|     FilterFromExpr(EvalState & state, Expr filter) |     FilterFromExpr(EvalState & state, Value & filter) | ||||||
|         : state(state), filter(filter) |         : state(state), filter(filter) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|  | @ -599,17 +596,25 @@ struct FilterFromExpr : PathFilter | ||||||
|         if (lstat(path.c_str(), &st)) |         if (lstat(path.c_str(), &st)) | ||||||
|             throw SysError(format("getting attributes of path `%1%'") % path); |             throw SysError(format("getting attributes of path `%1%'") % path); | ||||||
| 
 | 
 | ||||||
|         Expr call = |         /* Call the filter function.  The first argument is the path,
 | ||||||
|             makeCall( |            the second is a string indicating the type of the file. */ | ||||||
|                 makeCall(filter, makeStr(path)), |         Value arg1; | ||||||
|                 makeStr( |         mkString(arg1, path); | ||||||
|                     S_ISREG(st.st_mode) ? "regular" : | 
 | ||||||
|                     S_ISDIR(st.st_mode) ? "directory" : |         Value fun2; | ||||||
|                     S_ISLNK(st.st_mode) ? "symlink" : |         state.callFunction(filter, arg1, fun2); | ||||||
|                     "unknown" /* not supported, will fail! */ | 
 | ||||||
|                     )); |         Value arg2; | ||||||
|                  |         mkString(arg2,  | ||||||
|         return evalBool(state, call); |             S_ISREG(st.st_mode) ? "regular" : | ||||||
|  |             S_ISDIR(st.st_mode) ? "directory" : | ||||||
|  |             S_ISLNK(st.st_mode) ? "symlink" : | ||||||
|  |             "unknown" /* not supported, will fail! */); | ||||||
|  |          | ||||||
|  |         Value res; | ||||||
|  |         state.callFunction(fun2, arg2, res); | ||||||
|  | 
 | ||||||
|  |         return state.forceBool(res); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -617,19 +622,22 @@ struct FilterFromExpr : PathFilter | ||||||
| static void prim_filterSource(EvalState & state, Value * * args, Value & v) | static void prim_filterSource(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     Path path = coerceToPath(state, args[1], context); |     Path path = state.coerceToPath(*args[1], context); | ||||||
|     if (!context.empty()) |     if (!context.empty()) | ||||||
|         throw EvalError(format("string `%1%' cannot refer to other paths") % path); |         throw EvalError(format("string `%1%' cannot refer to other paths") % path); | ||||||
| 
 | 
 | ||||||
|     FilterFromExpr filter(state, args[0]); |     state.forceValue(*args[0]); | ||||||
|  |     if (args[0]->type != tLambda) | ||||||
|  |         throw TypeError(format("first argument in call to `filterSource' is not a function but %1%") % showType(*args[0])); | ||||||
|  | 
 | ||||||
|  |     FilterFromExpr filter(state, *args[0]); | ||||||
| 
 | 
 | ||||||
|     Path dstPath = readOnlyMode |     Path dstPath = readOnlyMode | ||||||
|         ? computeStorePathForPath(path, true, htSHA256, filter).first |         ? computeStorePathForPath(path, true, htSHA256, filter).first | ||||||
|         : store->addToStore(path, true, htSHA256, filter); |         : store->addToStore(path, true, htSHA256, filter); | ||||||
| 
 | 
 | ||||||
|     return makeStr(dstPath, singleton<PathSet>(dstPath)); |     mkString(v, dstPath, singleton<PathSet>(dstPath)); | ||||||
| } | } | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*************************************************************
 | /*************************************************************
 | ||||||
|  | @ -927,15 +935,15 @@ static void prim_stringLength(EvalState & state, Value * * args, Value & v) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #if 0 |  | ||||||
| static void prim_unsafeDiscardStringContext(EvalState & state, Value * * args, Value & v) | static void prim_unsafeDiscardStringContext(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string s = coerceToString(state, args[0], context); |     string s = state.coerceToString(*args[0], context); | ||||||
|     return makeStr(s, PathSet()); |     mkString(v, s, PathSet()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | #if 0 | ||||||
| /* Sometimes we want to pass a derivation path (i.e. pkg.drvPath) to a
 | /* Sometimes we want to pass a derivation path (i.e. pkg.drvPath) to a
 | ||||||
|    builder without causing the derivation to be built (for instance, |    builder without causing the derivation to be built (for instance, | ||||||
|    in the derivation that builds NARs in nix-push, when doing |    in the derivation that builds NARs in nix-push, when doing | ||||||
|  | @ -1053,13 +1061,9 @@ void EvalState::createBaseEnv() | ||||||
|     addPrimOp("__readFile", 1, prim_readFile); |     addPrimOp("__readFile", 1, prim_readFile); | ||||||
| 
 | 
 | ||||||
|     // Creating files
 |     // Creating files
 | ||||||
| #if 0 |  | ||||||
|     addPrimOp("__toXML", 1, prim_toXML); |     addPrimOp("__toXML", 1, prim_toXML); | ||||||
| #endif |  | ||||||
|     addPrimOp("__toFile", 2, prim_toFile); |     addPrimOp("__toFile", 2, prim_toFile); | ||||||
| #if 0 |  | ||||||
|     addPrimOp("__filterSource", 2, prim_filterSource); |     addPrimOp("__filterSource", 2, prim_filterSource); | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
|     // Attribute sets
 |     // Attribute sets
 | ||||||
|     addPrimOp("__attrNames", 1, prim_attrNames); |     addPrimOp("__attrNames", 1, prim_attrNames); | ||||||
|  | @ -1091,8 +1095,8 @@ void EvalState::createBaseEnv() | ||||||
|     addPrimOp("toString", 1, prim_toString); |     addPrimOp("toString", 1, prim_toString); | ||||||
|     addPrimOp("__substring", 3, prim_substring); |     addPrimOp("__substring", 3, prim_substring); | ||||||
|     addPrimOp("__stringLength", 1, prim_stringLength); |     addPrimOp("__stringLength", 1, prim_stringLength); | ||||||
| #if 0    
 |  | ||||||
|     addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext); |     addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext); | ||||||
|  | #if 0    
 | ||||||
|     addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency); |     addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -75,7 +75,8 @@ void processExpr(EvalState & state, const Strings & attrPaths, | ||||||
|         std::cout << format("%1%\n") % canonicaliseExpr(e); |         std::cout << format("%1%\n") % canonicaliseExpr(e); | ||||||
|     else { |     else { | ||||||
|         Value v; |         Value v; | ||||||
|         if (strict) state.strictEval(e, v); else state.eval(e, v); |         state.eval(e, v); | ||||||
|  |         if (strict) state.strictForceValue(v); | ||||||
|         if (evalOnly) |         if (evalOnly) | ||||||
|             std::cout << v << std::endl; |             std::cout << v << std::endl; | ||||||
|         else { |         else { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue