about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--third_party/nix/src/libexpr/parser.cc140
-rw-r--r--third_party/nix/src/libexpr/parser.hh1
-rw-r--r--third_party/nix/src/libexpr/parser.y165
3 files changed, 156 insertions, 150 deletions
diff --git a/third_party/nix/src/libexpr/parser.cc b/third_party/nix/src/libexpr/parser.cc
index 50b7cc3ff8e3..a96d345cc126 100644
--- a/third_party/nix/src/libexpr/parser.cc
+++ b/third_party/nix/src/libexpr/parser.cc
@@ -1,5 +1,14 @@
 #include "libexpr/parser.hh"
 
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "libexpr/eval.hh"
+#include "libstore/download.hh"
+#include "libstore/store-api.hh"
+
 namespace nix {
 
 void addAttr(ExprAttrs* attrs, AttrPath& attrPath, Expr* e, const Pos& pos) {
@@ -182,5 +191,136 @@ Expr* stripIndentation(const Pos& pos, SymbolTable& symbols,
              : new ExprConcatStrings(pos, true, es2);
 }
 
+Path resolveExprPath(Path path) {
+  assert(path[0] == '/');
+
+  /* If `path' is a symlink, follow it.  This is so that relative
+     path references work. */
+  struct stat st;
+  while (true) {
+    if (lstat(path.c_str(), &st))
+      throw SysError(format("getting status of '%1%'") % path);
+    if (!S_ISLNK(st.st_mode)) {
+      break;
+    }
+    path = absPath(readLink(path), dirOf(path));
+  }
+
+  /* If `path' refers to a directory, append `/default.nix'. */
+  if (S_ISDIR(st.st_mode)) path = canonPath(path + "/default.nix");
+
+  return path;
+}
+
+// These methods are actually declared in eval.hh, and were - for some
+// reason - previously implemented in parser.y.
+
+Expr* EvalState::parseExprFromFile(const Path& path) {
+  return parseExprFromFile(path, staticBaseEnv);
+}
+
+Expr* EvalState::parseExprFromFile(const Path& path, StaticEnv& staticEnv) {
+  return parse(readFile(path).c_str(), path, dirOf(path), staticEnv);
+}
+
+Expr* EvalState::parseExprFromString(const std::string& s, const Path& basePath,
+                                     StaticEnv& staticEnv) {
+  return parse(s.c_str(), "(std::string)", basePath, staticEnv);
+}
+
+Expr* EvalState::parseExprFromString(const std::string& s,
+                                     const Path& basePath) {
+  return parseExprFromString(s, basePath, staticBaseEnv);
+}
+
+Expr* EvalState::parseStdin() {
+  // Activity act(*logger, lvlTalkative, format("parsing standard input"));
+  return parseExprFromString(drainFD(0), absPath("."));
+}
+
+void EvalState::addToSearchPath(const std::string& s) {
+  size_t pos = s.find('=');
+  std::string prefix;
+  Path path;
+  if (pos == std::string::npos) {
+    path = s;
+  } else {
+    prefix = std::string(s, 0, pos);
+    path = std::string(s, pos + 1);
+  }
+
+  searchPath.emplace_back(prefix, path);
+}
+
+Path EvalState::findFile(const std::string& path) {
+  return findFile(searchPath, path);
+}
+
+Path EvalState::findFile(SearchPath& searchPath, const std::string& path,
+                         const Pos& pos) {
+  for (auto& i : searchPath) {
+    std::string suffix;
+    if (i.first.empty())
+      suffix = "/" + path;
+    else {
+      auto s = i.first.size();
+      if (path.compare(0, s, i.first) != 0 ||
+          (path.size() > s && path[s] != '/'))
+        continue;
+      suffix = path.size() == s ? "" : "/" + std::string(path, s);
+    }
+    auto r = resolveSearchPathElem(i);
+    if (!r.first) {
+      continue;
+    }
+    Path res = r.second + suffix;
+    if (pathExists(res)) {
+      return canonPath(res);
+    }
+  }
+  format f = format(
+      "file '%1%' was not found in the Nix search path (add it using $NIX_PATH "
+      "or -I)" +
+      std::string(pos ? ", at %2%" : ""));
+  f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
+  throw ThrownError(f % path % pos);
+}
+
+std::pair<bool, std::string> EvalState::resolveSearchPathElem(
+    const SearchPathElem& elem) {
+  auto i = searchPathResolved.find(elem.second);
+  if (i != searchPathResolved.end()) {
+    return i->second;
+  }
+
+  std::pair<bool, std::string> res;
+
+  if (isUri(elem.second)) {
+    try {
+      CachedDownloadRequest request(elem.second);
+      request.unpack = true;
+      res = {true, getDownloader()->downloadCached(store, request).path};
+    } catch (DownloadError& e) {
+      LOG(WARNING) << "Nix search path entry '" << elem.second
+                   << "' cannot be downloaded, ignoring";
+      res = {false, ""};
+    }
+  } else {
+    auto path = absPath(elem.second);
+    if (pathExists(path)) {
+      res = {true, path};
+    } else {
+      LOG(WARNING) << "Nix search path entry '" << elem.second
+                   << "' does not exist, ignoring";
+      res = {false, ""};
+    }
+  }
+
+  DLOG(INFO) << "resolved search path element '" << elem.second << "' to '"
+             << res.second << "'";
+
+  searchPathResolved[elem.second] = res;
+  return res;
+}
 
 }  // namespace nix
diff --git a/third_party/nix/src/libexpr/parser.hh b/third_party/nix/src/libexpr/parser.hh
index 3de8280bf5f0..7f4c360b1bfd 100644
--- a/third_party/nix/src/libexpr/parser.hh
+++ b/third_party/nix/src/libexpr/parser.hh
@@ -53,5 +53,6 @@ void addFormal(const Pos& pos, Formals* formals, const Formal& formal);
 Expr* stripIndentation(const Pos& pos, SymbolTable& symbols,
                        std::vector<Expr*>& es);
 
+Path resolveExprPath(Path path);
 
 }  // namespace nix
diff --git a/third_party/nix/src/libexpr/parser.y b/third_party/nix/src/libexpr/parser.y
index 2ec1cf6c558c..b272e4b03457 100644
--- a/third_party/nix/src/libexpr/parser.y
+++ b/third_party/nix/src/libexpr/parser.y
@@ -325,165 +325,30 @@ formal
 #include <unistd.h>
 
 #include "libexpr/eval.hh"
-#include "libstore/download.hh"
 #include "libstore/store-api.hh"
 
 
 namespace nix {
 
+Expr* EvalState::parse(const char* text, const Path& path, const Path& basePath,
+                       StaticEnv& staticEnv) {
+  yyscan_t scanner;
+  ParseData data(*this);
+  data.basePath = basePath;
+  data.path = data.symbols.Create(path);
 
-Expr * EvalState::parse(const char * text,
-    const Path & path, const Path & basePath, StaticEnv & staticEnv)
-{
-    yyscan_t scanner;
-    ParseData data(*this);
-    data.basePath = basePath;
-    data.path = data.symbols.Create(path);
+  yylex_init(&scanner);
+  yy_scan_string(text, scanner);
+  int res = yyparse(scanner, &data);
+  yylex_destroy(scanner);
 
-    yylex_init(&scanner);
-    yy_scan_string(text, scanner);
-    int res = yyparse(scanner, &data);
-    yylex_destroy(scanner);
-
-    if (res) { throw ParseError(data.error); }
-
-    data.result->bindVars(staticEnv);
-
-    return data.result;
-}
-
-
-Path resolveExprPath(Path path)
-{
-    assert(path[0] == '/');
-
-    /* If `path' is a symlink, follow it.  This is so that relative
-       path references work. */
-    struct stat st;
-    while (true) {
-        if (lstat(path.c_str(), &st))
-            throw SysError(format("getting status of '%1%'") % path);
-        if (!S_ISLNK(st.st_mode)) { break; }
-        path = absPath(readLink(path), dirOf(path));
-    }
-
-    /* If `path' refers to a directory, append `/default.nix'. */
-    if (S_ISDIR(st.st_mode))
-        path = canonPath(path + "/default.nix");
-
-    return path;
-}
-
-
-Expr * EvalState::parseExprFromFile(const Path & path)
-{
-    return parseExprFromFile(path, staticBaseEnv);
-}
-
-
-Expr * EvalState::parseExprFromFile(const Path & path, StaticEnv & staticEnv)
-{
-    return parse(readFile(path).c_str(), path, dirOf(path), staticEnv);
-}
-
-
-Expr * EvalState::parseExprFromString(const std::string & s, const Path & basePath, StaticEnv & staticEnv)
-{
-    return parse(s.c_str(), "(std::string)", basePath, staticEnv);
-}
-
-
-Expr * EvalState::parseExprFromString(const std::string & s, const Path & basePath)
-{
-    return parseExprFromString(s, basePath, staticBaseEnv);
-}
-
-
-Expr * EvalState::parseStdin()
-{
-    //Activity act(*logger, lvlTalkative, format("parsing standard input"));
-    return parseExprFromString(drainFD(0), absPath("."));
-}
-
-
-void EvalState::addToSearchPath(const std::string & s)
-{
-    size_t pos = s.find('=');
-    std::string prefix;
-    Path path;
-    if (pos == std::string::npos) {
-        path = s;
-    } else {
-        prefix = std::string(s, 0, pos);
-        path = std::string(s, pos + 1);
-    }
-
-    searchPath.emplace_back(prefix, path);
-}
-
-
-Path EvalState::findFile(const std::string & path)
-{
-    return findFile(searchPath, path);
-}
-
-
-Path EvalState::findFile(SearchPath & searchPath, const std::string & path, const Pos & pos)
-{
-    for (auto & i : searchPath) {
-        std::string suffix;
-        if (i.first.empty())
-            suffix = "/" + path;
-        else {
-            auto s = i.first.size();
-            if (path.compare(0, s, i.first) != 0 ||
-                (path.size() > s && path[s] != '/'))
-                continue;
-            suffix = path.size() == s ? "" : "/" + std::string(path, s);
-        }
-        auto r = resolveSearchPathElem(i);
-        if (!r.first) { continue; }
-        Path res = r.second + suffix;
-        if (pathExists(res)) { return canonPath(res); }
-    }
-    format f = format(
-        "file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)"
-        + std::string(pos ? ", at %2%" : ""));
-    f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
-    throw ThrownError(f % path % pos);
-}
-
-
-std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathElem & elem)
-{
-    auto i = searchPathResolved.find(elem.second);
-    if (i != searchPathResolved.end()) { return i->second; }
-
-    std::pair<bool, std::string> res;
-
-    if (isUri(elem.second)) {
-        try {
-            CachedDownloadRequest request(elem.second);
-            request.unpack = true;
-            res = { true, getDownloader()->downloadCached(store, request).path };
-        } catch (DownloadError & e) {
-          LOG(WARNING) << "Nix search path entry '" << elem.second << "' cannot be downloaded, ignoring";
-          res = { false, "" };
-        }
-    } else {
-        auto path = absPath(elem.second);
-        if (pathExists(path)) {
-            res = { true, path };
-        } else {
-          LOG(WARNING) << "Nix search path entry '" << elem.second << "' does not exist, ignoring";
-          res = { false, "" };
-        }
-    }
+  if (res) {
+    throw ParseError(data.error);
+  }
 
-    DLOG(INFO) << "resolved search path element '" << elem.second << "' to '" << res.second << "'";
+  data.result->bindVars(staticEnv);
 
-    searchPathResolved[elem.second] = res;
-    return res;
+  return data.result;
 }
 
 }  // namespace nix