* When something goes wrong in the evaluation of a Nix expression,
print a nice backtrace of the stack, rather than vomiting a gigantic
  (and useless) aterm on the screen.  Example:
    error: while evaluating file `.../pkgs/system/test.nix':
    while evaluating attribute `subversion' at `.../pkgs/system/all-packages-generic.nix', line 533:
    while evaluating function at `.../pkgs/applications/version-management/subversion/default.nix', line 1:
    assertion failed at `.../pkgs/applications/version-management/subversion/default.nix', line 13
  Since the Nix expression language is lazy, the trace may be
  misleading.  The purpose is to provide a hint as to the location of
  the problem.
			
			
This commit is contained in:
		
							parent
							
								
									a520b1cbc3
								
							
						
					
					
						commit
						59b94ee18a
					
				
					 8 changed files with 201 additions and 90 deletions
				
			
		|  | @ -12,8 +12,8 @@ | |||
| struct ParseData  | ||||
| { | ||||
|     Expr result; | ||||
|     string basePath; | ||||
|     string location; | ||||
|     Path basePath; | ||||
|     Path path; | ||||
|     string error; | ||||
| }; | ||||
| 
 | ||||
|  | @ -39,8 +39,8 @@ ATerm absParsedPath(ParseData * data, ATerm t) | |||
|      | ||||
| void parseError(ParseData * data, char * error, int line, int column) | ||||
| { | ||||
|     data->error = (format("%1%, at line %2%, column %3%, of %4%") | ||||
|         % error % line % column % data->location).str(); | ||||
|     data->error = (format("%1%, at `%2%':%3%:%4%") | ||||
|         % error % data->path % line % column).str(); | ||||
| } | ||||
|          | ||||
| ATerm fixAttrs(int recursive, ATermList as) | ||||
|  | @ -51,13 +51,15 @@ ATerm fixAttrs(int recursive, ATermList as) | |||
|     for (ATermIterator i(as); i; ++i) { | ||||
|         ATermList names; | ||||
|         Expr src; | ||||
|         if (atMatch(m, *i) >> "Inherit" >> src >> names) { | ||||
|         ATerm pos; | ||||
|         if (atMatch(m, *i) >> "Inherit" >> src >> names >> pos) { | ||||
|             bool fromScope = atMatch(m, src) >> "Scope"; | ||||
|             for (ATermIterator j(names); j; ++j) { | ||||
|                 Expr rhs = fromScope | ||||
|                     ? ATmake("Var(<term>)", *j) | ||||
|                     : ATmake("Select(<term>, <term>)", src, *j); | ||||
|                 *is = ATinsert(*is, ATmake("Bind(<term>, <term>)", *j, rhs)); | ||||
|                 *is = ATinsert(*is, ATmake("Bind(<term>, <term>, <term>)", | ||||
|                                    *j, rhs, pos)); | ||||
|             } | ||||
|         } else bs = ATinsert(bs, *i); | ||||
|     } | ||||
|  | @ -67,18 +69,23 @@ ATerm fixAttrs(int recursive, ATermList as) | |||
|         return ATmake("Attrs(<term>)", bs); | ||||
| } | ||||
| 
 | ||||
| const char * getPath(ParseData * data) | ||||
| { | ||||
|     return data->path.c_str(); | ||||
| } | ||||
| 
 | ||||
| int yyparse(yyscan_t scanner, ParseData * data); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static Expr parse(EvalState & state, | ||||
|     const char * text, const string & location, | ||||
|     const char * text, const Path & path, | ||||
|     const Path & basePath) | ||||
| { | ||||
|     yyscan_t scanner; | ||||
|     ParseData data; | ||||
|     data.basePath = basePath; | ||||
|     data.location = location; | ||||
|     data.path = path; | ||||
| 
 | ||||
|     yylex_init(&scanner); | ||||
|     yy_scan_string(text, scanner); | ||||
|  | @ -90,7 +97,7 @@ static Expr parse(EvalState & state, | |||
|     try { | ||||
|         checkVarDefs(state.primOpsAll, data.result); | ||||
|     } catch (Error & e) { | ||||
|         throw Error(format("%1%, in %2%") % e.msg() % location); | ||||
|         throw Error(format("%1%, in `%2%'") % e.msg() % path); | ||||
|     } | ||||
| 
 | ||||
|     return data.result; | ||||
|  | @ -133,7 +140,7 @@ Expr parseExprFromFile(EvalState & state, Path path) | |||
|     readFull(fd, (unsigned char *) text, st.st_size); | ||||
|     text[st.st_size] = 0; | ||||
| 
 | ||||
|     return parse(state, text, "`" + path + "'", dirOf(path)); | ||||
|     return parse(state, text, path, dirOf(path)); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue