diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/common-opts.cc | 12 | ||||
-rw-r--r-- | src/libexpr/common-opts.hh | 3 | ||||
-rw-r--r-- | src/libexpr/eval.cc | 6 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 8 | ||||
-rw-r--r-- | src/libexpr/lexer.l | 2 | ||||
-rw-r--r-- | src/libexpr/parser.y | 47 | ||||
-rw-r--r-- | src/nix-env/nix-env.cc | 2 | ||||
-rw-r--r-- | src/nix-instantiate/nix-instantiate.cc | 2 |
8 files changed, 76 insertions, 6 deletions
diff --git a/src/libexpr/common-opts.cc b/src/libexpr/common-opts.cc index bab31f493..d029d2ec3 100644 --- a/src/libexpr/common-opts.cc +++ b/src/libexpr/common-opts.cc @@ -33,5 +33,15 @@ bool parseOptionArg(const string & arg, Strings::iterator & i, return true; } - + +bool parseSearchPathArg(const string & arg, Strings::iterator & i, + const Strings::iterator & argsEnd, EvalState & state) +{ + if (arg != "-I") return false; + if (i == argsEnd) throw UsageError(format("`%1%' requires an argument") % arg);; + state.addToSearchPath(*i++); + return true; +} + + } diff --git a/src/libexpr/common-opts.hh b/src/libexpr/common-opts.hh index 80298ce55..6b7247fc3 100644 --- a/src/libexpr/common-opts.hh +++ b/src/libexpr/common-opts.hh @@ -11,6 +11,9 @@ bool parseOptionArg(const string & arg, Strings::iterator & i, const Strings::iterator & argsEnd, EvalState & state, Bindings & autoArgs); +bool parseSearchPathArg(const string & arg, Strings::iterator & i, + const Strings::iterator & argsEnd, EvalState & state); + } diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 5701452f9..674fa96f0 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -181,6 +181,12 @@ EvalState::EvalState() gcInitialised = true; } #endif + + /* Initialise the Nix expression search path. */ + searchPathInsertionPoint = searchPath.end(); + Strings paths = tokenizeString(getEnv("NIX_PATH", ""), ":"); + foreach (Strings::iterator, i, paths) addToSearchPath(*i); + searchPathInsertionPoint = searchPath.begin(); } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index e900217fa..1583665ba 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -213,11 +213,16 @@ private: std::map<Path, Expr *> parseTrees; + Paths searchPath; + Paths::iterator searchPathInsertionPoint; + public: EvalState(); ~EvalState(); + void addToSearchPath(const string & s); + /* Parse a Nix expression from the specified file. If `path' refers to a directory, then "/default.nix" is appended. */ Expr * parseExprFromFile(Path path); @@ -229,6 +234,9 @@ public: form. */ void evalFile(const Path & path, Value & v); + /* Look up a file in the search path. */ + Path findFile(const string & path); + /* Evaluate an expression to normal form, storing the result in value `v'. */ void eval(Expr * e, Value & v); diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l index 330c2bd54..d46b66d9f 100644 --- a/src/libexpr/lexer.l +++ b/src/libexpr/lexer.l @@ -81,6 +81,7 @@ static Expr * unescapeStr(SymbolTable & symbols, const char * s) ID [a-zA-Z\_][a-zA-Z0-9\_\']* INT [0-9]+ PATH [a-zA-Z0-9\.\_\-\+]*(\/[a-zA-Z0-9\.\_\-\+]+)+ +SPATH \<[a-zA-Z0-9\.\_\-\+]+(\/[a-zA-Z0-9\.\_\-\+]+)*\> URI [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']+ @@ -153,6 +154,7 @@ or { return OR_KW; } <IND_STRING>. return yytext[0]; /* just in case: shouldn't be reached */ {PATH} { yylval->path = strdup(yytext); return PATH; } +{SPATH} { yylval->path = strdup(yytext); return SPATH; } {URI} { yylval->uri = strdup(yytext); return URI; } [ \t\r\n]+ /* eat up whitespace */ diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index a64d327b4..cd63666dc 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -17,19 +17,22 @@ #include "util.hh" #include "nixexpr.hh" +#include "eval.hh" namespace nix { struct ParseData { + EvalState & state; SymbolTable & symbols; Expr * result; Path basePath; Path path; string error; Symbol sLetBody; - ParseData(SymbolTable & symbols) - : symbols(symbols) + ParseData(EvalState & state) + : state(state) + , symbols(state.symbols) , sLetBody(symbols.create("<let-body>")) { }; }; @@ -253,7 +256,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err %token <id> ID ATTRPATH %token <e> STR IND_STR %token <n> INT -%token <path> PATH +%token <path> PATH SPATH %token <uri> URI %token IF THEN ELSE ASSERT WITH LET IN REC INHERIT EQ NEQ AND OR IMPL OR_KW %token DOLLAR_CURLY /* == ${ */ @@ -350,6 +353,20 @@ expr_simple $$ = stripIndentation(data->symbols, *$2); } | PATH { $$ = new ExprPath(absPath($1, data->basePath)); } + | SPATH { + string path($1 + 1, strlen($1) - 2); + Path path2 = data->state.findFile(path); + /* The file wasn't found in the search path. However, we can't + throw an error here, because the expression might never be + evaluated. So return an expression that lazily calls + ‘abort’. */ + $$ = path2 == "" + ? (Expr * ) new ExprApp( + new ExprVar(data->symbols.create("throw")), + new ExprString(data->symbols.create( + (format("file `%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)") % path).str()))) + : (Expr * ) new ExprPath(path2); + } | URI { $$ = new ExprString(data->symbols.create($1)); } | '(' expr ')' { $$ = $2; } /* Let expressions `let {..., body = ...}' are just desugared @@ -454,7 +471,7 @@ Expr * EvalState::parse(const char * text, const Path & path, const Path & basePath) { yyscan_t scanner; - ParseData data(symbols); + ParseData data(*this); data.basePath = basePath; data.path = path; @@ -510,5 +527,25 @@ Expr * EvalState::parseExprFromString(const string & s, const Path & basePath) return parse(s.c_str(), "(string)", basePath); } - + +void EvalState::addToSearchPath(const string & s) +{ + Path path = absPath(s); + if (pathExists(path)) { + debug(format("adding path `%1%' to the search path") % path); + searchPath.insert(searchPathInsertionPoint, path); + } +} + + +Path EvalState::findFile(const string & path) +{ + foreach (Paths::iterator, i, searchPath) { + Path res = *i + "/" + path; + if (pathExists(res)) return canonPath(res); + } + return ""; +} + + } diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 4ea301def..731f91bba 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -1253,6 +1253,8 @@ void run(Strings args) else if (parseOptionArg(arg, i, args.end(), globals.state, globals.instSource.autoArgs)) ; + else if (parseSearchPathArg(arg, i, args.end(), globals.state)) + ; else if (arg == "--force-name") // undocumented flag for nix-install-package globals.forceName = needArg(i, args, arg); else if (arg == "--uninstall" || arg == "-e") diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc index 1f9059539..05b9d5479 100644 --- a/src/nix-instantiate/nix-instantiate.cc +++ b/src/nix-instantiate/nix-instantiate.cc @@ -107,6 +107,8 @@ void run(Strings args) } else if (parseOptionArg(arg, i, args.end(), state, autoArgs)) ; + else if (parseSearchPathArg(arg, i, args.end(), state)) + ; else if (arg == "--add-root") { if (i == args.end()) throw UsageError("`--add-root' requires an argument"); |