* Handle string contexts. `nix-instantiate' can now correctly compute
the `firefoxWrapper' attribute in Nixpkgs, and it's about 3 times faster than the trunk :-)
This commit is contained in:
		
							parent
							
								
									d8cd3115d8
								
							
						
					
					
						commit
						979f163615
					
				
					 3 changed files with 28 additions and 65 deletions
				
			
		|  | @ -178,7 +178,13 @@ void mkString(Value & v, const char * s) | ||||||
| void mkString(Value & v, const string & s, const PathSet & context) | void mkString(Value & v, const string & s, const PathSet & context) | ||||||
| { | { | ||||||
|     mkString(v, s.c_str()); |     mkString(v, s.c_str()); | ||||||
|     // !!! context
 |     if (!context.empty()) { | ||||||
|  |         unsigned int len = 0, n = 0; | ||||||
|  |         v.string.context = new const char *[context.size() + 1]; | ||||||
|  |         foreach (PathSet::const_iterator, i, context)  | ||||||
|  |             v.string.context[n++] = strdup(i->c_str()); | ||||||
|  |         v.string.context[n] = 0; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -471,7 +477,7 @@ void EvalState::eval(Env & env, Expr e, Value & v) | ||||||
|         if (isPath) |         if (isPath) | ||||||
|             mkPath(v, s.str().c_str()); |             mkPath(v, s.str().c_str()); | ||||||
|         else |         else | ||||||
|             mkString(v, s.str().c_str()); // !!! context
 |             mkString(v, s.str(), context); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /* Conditionals. */ |     /* Conditionals. */ | ||||||
|  | @ -727,6 +733,17 @@ string EvalState::forceString(Value & v) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | string EvalState::forceString(Value & v, PathSet & context) | ||||||
|  | { | ||||||
|  |     string s = forceString(v); | ||||||
|  |     if (v.string.context) { | ||||||
|  |         for (const char * * p = v.string.context; *p; ++p)  | ||||||
|  |             context.insert(*p); | ||||||
|  |     } | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| string EvalState::forceStringNoCtx(Value & v) | string EvalState::forceStringNoCtx(Value & v) | ||||||
| { | { | ||||||
|     string s = forceString(v); |     string s = forceString(v); | ||||||
|  | @ -744,7 +761,12 @@ string EvalState::coerceToString(Value & v, PathSet & context, | ||||||
| 
 | 
 | ||||||
|     string s; |     string s; | ||||||
| 
 | 
 | ||||||
|     if (v.type == tString) return v.string.s; |     if (v.type == tString) { | ||||||
|  |         if (v.string.context)  | ||||||
|  |             for (const char * * p = v.string.context; *p; ++p)  | ||||||
|  |                 context.insert(*p); | ||||||
|  |         return v.string.s; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (v.type == tPath) { |     if (v.type == tPath) { | ||||||
|         Path path(canonPath(v.path)); |         Path path(canonPath(v.path)); | ||||||
|  | @ -1142,66 +1164,6 @@ LocalNoInline(Expr evalWith(EvalState & state, Expr defs, Expr body, ATerm pos)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| LocalNoInline(Expr evalPlusConcat(EvalState & state, Expr e)) |  | ||||||
| { |  | ||||||
|     Expr e1, e2; |  | ||||||
|     ATermList es; |  | ||||||
|      |  | ||||||
|     ATermVector args; |  | ||||||
|      |  | ||||||
|     if (matchOpPlus(e, e1, e2)) { |  | ||||||
| 
 |  | ||||||
|         /* !!! Awful compatibility hack for `drv + /path'.
 |  | ||||||
|            According to regular concatenation, /path should be |  | ||||||
|            copied to the store and its store path should be |  | ||||||
|            appended to the string.  However, in Nix <= 0.10, /path |  | ||||||
|            was concatenated.  So handle that case separately, but |  | ||||||
|            do print out a warning.  This code can go in Nix 0.12, |  | ||||||
|            maybe. */ |  | ||||||
|         e1 = evalExpr(state, e1); |  | ||||||
|         e2 = evalExpr(state, e2); |  | ||||||
| 
 |  | ||||||
|         ATermList as; |  | ||||||
|         ATerm p; |  | ||||||
|         if (matchAttrs(e1, as) && matchPath(e2, p)) { |  | ||||||
|             static bool haveWarned = false; |  | ||||||
|             warnOnce(haveWarned, format( |  | ||||||
|                     "concatenation of a derivation and a path is deprecated; " |  | ||||||
|                     "you should write `drv + \"%1%\"' instead of `drv + %1%'") |  | ||||||
|                 % aterm2String(p)); |  | ||||||
|             PathSet context; |  | ||||||
|             return makeStr( |  | ||||||
|                 coerceToString(state, makeSelect(e1, toATerm("outPath")), context) |  | ||||||
|                 + aterm2String(p), context); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         args.push_back(e1); |  | ||||||
|         args.push_back(e2); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     else if (matchConcatStrings(e, es)) |  | ||||||
|         for (ATermIterator i(es); i; ++i) args.push_back(*i); |  | ||||||
|          |  | ||||||
|     try { |  | ||||||
|         return concatStrings(state, args); |  | ||||||
|     } catch (Error & e) { |  | ||||||
|         addErrorPrefix(e, "in a string concatenation:\n"); |  | ||||||
|         throw; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| LocalNoInline(Expr evalSubPath(EvalState & state, Expr e1, Expr e2)) |  | ||||||
| { |  | ||||||
|     static bool haveWarned = false; |  | ||||||
|     warnOnce(haveWarned, "the subpath operator (~) is deprecated, use string concatenation (+) instead"); |  | ||||||
|     ATermVector args; |  | ||||||
|     args.push_back(e1); |  | ||||||
|     args.push_back(e2); |  | ||||||
|     return concatStrings(state, args, "/"); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /* Implementation of the `==' and `!=' operators. */ | /* Implementation of the `==' and `!=' operators. */ | ||||||
| LocalNoInline(bool areEqual(EvalState & state, Expr e1, Expr e2)) | LocalNoInline(bool areEqual(EvalState & state, Expr e1, Expr e2)) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -172,6 +172,7 @@ public: | ||||||
|     void forceList(Value & v); |     void forceList(Value & v); | ||||||
|     void forceFunction(Value & v); // either lambda or primop
 |     void forceFunction(Value & v); // either lambda or primop
 | ||||||
|     string forceString(Value & v); |     string forceString(Value & v); | ||||||
|  |     string forceString(Value & v, PathSet & context); | ||||||
|     string forceStringNoCtx(Value & v); |     string forceStringNoCtx(Value & v); | ||||||
| 
 | 
 | ||||||
|     /* String coercion.  Converts strings, paths and derivations to a
 |     /* String coercion.  Converts strings, paths and derivations to a
 | ||||||
|  |  | ||||||
|  | @ -588,7 +588,7 @@ static void prim_toFile(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string name = state.forceStringNoCtx(*args[0]); |     string name = state.forceStringNoCtx(*args[0]); | ||||||
|     string contents = state.forceString(*args[1]); // !!! context
 |     string contents = state.forceString(*args[1], context); | ||||||
| 
 | 
 | ||||||
|     PathSet refs; |     PathSet refs; | ||||||
| 
 | 
 | ||||||
|  | @ -928,7 +928,7 @@ static void prim_toString(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string s = state.coerceToString(*args[0], context, true, false); |     string s = state.coerceToString(*args[0], context, true, false); | ||||||
|     mkString(v, s.c_str()); // !!! context
 |     mkString(v, s, context); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue