aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-06 05:24:35 +0100
committereldritch horrors <pennae@lix.systems>2024-03-05 23:46:18 -0700
commit89e99d94e4ae492db09c0ebc0c35e4890ef7db25 (patch)
treeeab2defee911a6c0e39d4b073062690bd9a3a058 /src
parente9b5929b22116cb714adfe88ba39a817e89b019c (diff)
Merge pull request #9634 from 9999years/combine-abstract-pos-and-pos
Combine `AbstractPos`, `PosAdapter`, and `Pos` (cherry picked from commit 113499d16fc87d53b73fb62fe6242154909756ed) === this is a bit cursed because originally it was based on InputAccessor code that we don't have and moved/patched features we likewise don't have (fetchToStore caching, all the individual accessors, ContentAddressMethod). the commit is adjusted accordingly to match (remove caching, ignore accessors, use FileIngestionMethod). note that `state.rootPath . CanonPath == abs` and computeStorePathForPath works relative to cwd, so the slight rewrite in the moved fetchToStore is legal. Change-Id: I05fd340c273f0bcc8ffabfebdc4a88b98083bce5
Diffstat (limited to 'src')
-rw-r--r--src/libcmd/editor-for.cc1
-rw-r--r--src/libcmd/editor-for.hh2
-rw-r--r--src/libcmd/installable-value.cc3
-rw-r--r--src/libcmd/repl.cc2
-rw-r--r--src/libexpr/eval.cc9
-rw-r--r--src/libexpr/eval.hh2
-rw-r--r--src/libexpr/nixexpr.cc63
-rw-r--r--src/libexpr/nixexpr.hh26
-rw-r--r--src/libexpr/primops.cc6
-rw-r--r--src/libexpr/value.hh1
-rw-r--r--src/libfetchers/fetch-to-store.cc26
-rw-r--r--src/libfetchers/fetch-to-store.hh22
-rw-r--r--src/libfetchers/fetchers.cc2
-rw-r--r--src/libstore/store-api.hh1
-rw-r--r--src/libutil/error.cc55
-rw-r--r--src/libutil/error.hh42
-rw-r--r--src/libutil/input-accessor.hh35
-rw-r--r--src/libutil/logging.cc6
-rw-r--r--src/libutil/position.cc112
-rw-r--r--src/libutil/position.hh74
-rw-r--r--src/libutil/ref.hh1
-rw-r--r--src/libutil/repair-flag.hh (renamed from src/libstore/repair-flag.hh)0
-rw-r--r--src/libutil/source-path.cc (renamed from src/libfetchers/input-accessor.cc)15
-rw-r--r--src/libutil/source-path.hh (renamed from src/libfetchers/input-accessor.hh)46
24 files changed, 311 insertions, 241 deletions
diff --git a/src/libcmd/editor-for.cc b/src/libcmd/editor-for.cc
index a17c6f12a..e5f762104 100644
--- a/src/libcmd/editor-for.cc
+++ b/src/libcmd/editor-for.cc
@@ -1,5 +1,6 @@
#include "util.hh"
#include "editor-for.hh"
+#include "source-path.hh"
namespace nix {
diff --git a/src/libcmd/editor-for.hh b/src/libcmd/editor-for.hh
index fbf4307c9..8acd7011e 100644
--- a/src/libcmd/editor-for.hh
+++ b/src/libcmd/editor-for.hh
@@ -2,7 +2,7 @@
///@file
#include "types.hh"
-#include "input-accessor.hh"
+#include "source-path.hh"
namespace nix {
diff --git a/src/libcmd/installable-value.cc b/src/libcmd/installable-value.cc
index 08ad35105..c8a3e1b21 100644
--- a/src/libcmd/installable-value.cc
+++ b/src/libcmd/installable-value.cc
@@ -1,5 +1,6 @@
#include "installable-value.hh"
#include "eval-cache.hh"
+#include "fetch-to-store.hh"
namespace nix {
@@ -44,7 +45,7 @@ ref<InstallableValue> InstallableValue::require(ref<Installable> installable)
std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx)
{
if (v.type() == nPath) {
- auto storePath = v.path().fetchToStore(state->store);
+ auto storePath = fetchToStore(*state->store, v.path());
return {{
.path = DerivedPath::Opaque {
.path = std::move(storePath),
diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc
index 6181e3eb2..83d719bfe 100644
--- a/src/libcmd/repl.cc
+++ b/src/libcmd/repl.cc
@@ -218,7 +218,7 @@ static std::ostream & showDebugTrace(std::ostream & out, const PosTable & positi
// prefer direct pos, but if noPos then try the expr.
auto pos = dt.pos
? dt.pos
- : static_cast<std::shared_ptr<AbstractPos>>(positions[dt.expr.getPos() ? dt.expr.getPos() : noPos]);
+ : positions[dt.expr.getPos() ? dt.expr.getPos() : noPos];
if (pos) {
out << *pos;
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index debeaf75f..8e3077a67 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -14,6 +14,7 @@
#include "profiles.hh"
#include "print.hh"
#include "gc-small-vector.hh"
+#include "fetch-to-store.hh"
#include <algorithm>
#include <chrono>
@@ -879,7 +880,7 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr &
? std::make_unique<DebugTraceStacker>(
*this,
DebugTrace {
- .pos = error->info().errPos ? error->info().errPos : static_cast<std::shared_ptr<AbstractPos>>(positions[expr.getPos()]),
+ .pos = error->info().errPos ? error->info().errPos : positions[expr.getPos()],
.expr = expr,
.env = env,
.hint = error->info().msg,
@@ -916,7 +917,7 @@ static std::unique_ptr<DebugTraceStacker> makeDebugTraceStacker(
EvalState & state,
Expr & expr,
Env & env,
- std::shared_ptr<AbstractPos> && pos,
+ std::shared_ptr<Pos> && pos,
const char * s,
const std::string & s2)
{
@@ -1214,7 +1215,7 @@ void EvalState::cacheFile(
*this,
*e,
this->baseEnv,
- e->getPos() ? static_cast<std::shared_ptr<AbstractPos>>(positions[e->getPos()]) : nullptr,
+ e->getPos() ? std::make_shared<Pos>(positions[e->getPos()]) : nullptr,
"while evaluating the file '%1%':", resolvedPath.to_string())
: nullptr;
@@ -2388,7 +2389,7 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
auto dstPath = i != srcToStore.end()
? i->second
: [&]() {
- auto dstPath = path.fetchToStore(store, path.baseName(), nullptr, repair);
+ auto dstPath = fetchToStore(*store, path, path.baseName(), FileIngestionMethod::Recursive, nullptr, repair);
allowPath(dstPath);
srcToStore.insert_or_assign(path, dstPath);
printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, store->printStorePath(dstPath));
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 9cf50ba6c..d070fdab8 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -141,7 +141,7 @@ struct RegexCache;
std::shared_ptr<RegexCache> makeRegexCache();
struct DebugTrace {
- std::shared_ptr<AbstractPos> pos;
+ std::shared_ptr<Pos> pos;
const Expr & expr;
const Env & env;
hintformat hint;
diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc
index b34112be1..eb5d0d3d4 100644
--- a/src/libexpr/nixexpr.cc
+++ b/src/libexpr/nixexpr.cc
@@ -11,58 +11,6 @@ namespace nix {
ExprBlackHole eBlackHole;
-struct PosAdapter : AbstractPos
-{
- Pos::Origin origin;
-
- PosAdapter(Pos::Origin origin)
- : origin(std::move(origin))
- {
- }
-
- std::optional<std::string> getSource() const override
- {
- return std::visit(overloaded {
- [](const Pos::none_tag &) -> std::optional<std::string> {
- return std::nullopt;
- },
- [](const Pos::Stdin & s) -> std::optional<std::string> {
- // Get rid of the null terminators added by the parser.
- return std::string(s.source->c_str());
- },
- [](const Pos::String & s) -> std::optional<std::string> {
- // Get rid of the null terminators added by the parser.
- return std::string(s.source->c_str());
- },
- [](const SourcePath & path) -> std::optional<std::string> {
- try {
- return path.readFile();
- } catch (Error &) {
- return std::nullopt;
- }
- }
- }, origin);
- }
-
- void print(std::ostream & out) const override
- {
- std::visit(overloaded {
- [&](const Pos::none_tag &) { out << "«none»"; },
- [&](const Pos::Stdin &) { out << "«stdin»"; },
- [&](const Pos::String & s) { out << "«string»"; },
- [&](const SourcePath & path) { out << path; }
- }, origin);
- }
-};
-
-Pos::operator std::shared_ptr<AbstractPos>() const
-{
- auto pos = std::make_shared<PosAdapter>(origin);
- pos->line = line;
- pos->column = column;
- return pos;
-}
-
// FIXME: remove, because *symbols* are abstract and do not have a single
// textual representation; see printIdentifier()
std::ostream & operator <<(std::ostream & str, const SymbolStr & symbol)
@@ -268,17 +216,6 @@ void ExprPos::show(const SymbolTable & symbols, std::ostream & str) const
}
-std::ostream & operator << (std::ostream & str, const Pos & pos)
-{
- if (auto pos2 = (std::shared_ptr<AbstractPos>) pos) {
- str << *pos2;
- } else
- str << "undefined position";
-
- return str;
-}
-
-
std::string showAttrPath(const SymbolTable & symbols, const AttrPath & attrPath)
{
std::ostringstream out;
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index b38f19b41..6f2a4c0f9 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -8,6 +8,7 @@
#include "symbol-table.hh"
#include "error.hh"
#include "chunked-vector.hh"
+#include "position.hh"
namespace nix {
@@ -29,27 +30,6 @@ public:
using EvalError::EvalError;
};
-/**
- * Position objects.
- */
-struct Pos
-{
- uint32_t line;
- uint32_t column;
-
- struct none_tag { };
- struct Stdin { ref<std::string> source; };
- struct String { ref<std::string> source; };
-
- typedef std::variant<none_tag, Stdin, String, SourcePath> Origin;
-
- Origin origin;
-
- explicit operator bool() const { return line > 0; }
-
- operator std::shared_ptr<AbstractPos>() const;
-};
-
class PosIdx {
friend class PosTable;
@@ -82,7 +62,7 @@ public:
mutable uint32_t idx = std::numeric_limits<uint32_t>::max();
// Used for searching in PosTable::[].
- explicit Origin(uint32_t idx): idx(idx), origin{Pos::none_tag()} {}
+ explicit Origin(uint32_t idx): idx(idx), origin{std::monostate()} {}
public:
const Pos::Origin origin;
@@ -133,8 +113,6 @@ public:
inline PosIdx noPos = {};
-std::ostream & operator << (std::ostream & str, const Pos & pos);
-
struct Env;
struct Value;
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index d64f2d51e..1a961582f 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -14,6 +14,7 @@
#include "value-to-json.hh"
#include "value-to-xml.hh"
#include "primops.hh"
+#include "fetch-to-store.hh"
#include <boost/container/small_vector.hpp>
#include <nlohmann/json.hpp>
@@ -2235,9 +2236,8 @@ static void addPath(
});
if (!expectedHash || !state.store->isValidPath(*expectedStorePath)) {
- StorePath dstPath = settings.readOnlyMode
- ? state.store->computeStorePathForPath(name, path, method, htSHA256, filter).first
- : state.store->addToStore(name, path, method, htSHA256, filter, state.repair, refs);
+ auto dstPath = fetchToStore(
+ *state.store, state.rootPath(CanonPath(path)), name, method, &filter, state.repair);
if (expectedHash && expectedStorePath != dstPath)
state.debugThrowLastTrace(Error("store path mismatch in (possibly filtered) path added from '%s'", path));
state.allowAndSetStorePathString(dstPath, v);
diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh
index 224ffac9c..f90082e61 100644
--- a/src/libexpr/value.hh
+++ b/src/libexpr/value.hh
@@ -7,6 +7,7 @@
#include "symbol-table.hh"
#include "value/context.hh"
#include "input-accessor.hh"
+#include "source-path.hh"
#if HAVE_BOEHMGC
#include <gc/gc_allocator.h>
diff --git a/src/libfetchers/fetch-to-store.cc b/src/libfetchers/fetch-to-store.cc
new file mode 100644
index 000000000..f830a4963
--- /dev/null
+++ b/src/libfetchers/fetch-to-store.cc
@@ -0,0 +1,26 @@
+#include "fetch-to-store.hh"
+#include "fetchers.hh"
+#include "cache.hh"
+
+namespace nix {
+
+StorePath fetchToStore(
+ Store & store,
+ const SourcePath & path,
+ std::string_view name,
+ FileIngestionMethod method,
+ PathFilter * filter,
+ RepairFlag repair)
+{
+ Activity act(*logger, lvlChatty, actUnknown, fmt("copying '%s' to the store", path));
+
+ auto filter2 = filter ? *filter : defaultPathFilter;
+
+ return
+ settings.readOnlyMode
+ ? store.computeStorePathForPath(name, path.path.abs(), method, htSHA256, filter2).first
+ : store.addToStore(name, path.path.abs(), method, htSHA256, filter2, repair);
+}
+
+
+}
diff --git a/src/libfetchers/fetch-to-store.hh b/src/libfetchers/fetch-to-store.hh
new file mode 100644
index 000000000..eef269071
--- /dev/null
+++ b/src/libfetchers/fetch-to-store.hh
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "source-path.hh"
+#include "store-api.hh"
+#include "util.hh"
+#include "repair-flag.hh"
+#include "content-address.hh"
+
+namespace nix {
+
+/**
+ * Copy the `path` to the Nix store.
+ */
+StorePath fetchToStore(
+ Store & store,
+ const SourcePath & path,
+ std::string_view name = "source",
+ FileIngestionMethod method = FileIngestionMethod::Recursive,
+ PathFilter * filter = nullptr,
+ RepairFlag repair = NoRepair);
+
+}
diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc
index e683b9f80..530473023 100644
--- a/src/libfetchers/fetchers.cc
+++ b/src/libfetchers/fetchers.cc
@@ -1,5 +1,7 @@
#include "fetchers.hh"
#include "store-api.hh"
+#include "source-path.hh"
+#include "fetch-to-store.hh"
#include <nlohmann/json.hpp>
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 3e49c3d95..88c182b94 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -14,6 +14,7 @@
#include "config.hh"
#include "path-info.hh"
#include "repair-flag.hh"
+#include "source-path.hh"
#include <nlohmann/json_fwd.hpp>
#include <atomic>
diff --git a/src/libutil/error.cc b/src/libutil/error.cc
index 36afb22ae..a9e3b168f 100644
--- a/src/libutil/error.cc
+++ b/src/libutil/error.cc
@@ -1,4 +1,5 @@
#include "error.hh"
+#include "position.hh"
#include <iostream>
#include <optional>
@@ -9,7 +10,7 @@ namespace nix {
const std::string nativeSystem = SYSTEM;
-void BaseError::addTrace(std::shared_ptr<AbstractPos> && e, hintformat hint, bool frame)
+void BaseError::addTrace(std::shared_ptr<Pos> && e, hintformat hint, bool frame)
{
err.traces.push_front(Trace { .pos = std::move(e), .hint = hint, .frame = frame });
}
@@ -40,15 +41,6 @@ std::ostream & operator <<(std::ostream & os, const hintformat & hf)
return os << hf.str();
}
-std::ostream & operator <<(std::ostream & str, const AbstractPos & pos)
-{
- pos.print(str);
- str << ":" << pos.line;
- if (pos.column > 0)
- str << ":" << pos.column;
- return str;
-}
-
/**
* An arbitrarily defined value comparison for the purpose of using traces in the key of a sorted container.
*/
@@ -75,49 +67,10 @@ inline bool operator> (const Trace& lhs, const Trace& rhs) { return rhs < lhs; }
inline bool operator<=(const Trace& lhs, const Trace& rhs) { return !(lhs > rhs); }
inline bool operator>=(const Trace& lhs, const Trace& rhs) { return !(lhs < rhs); }
-std::optional<LinesOfCode> AbstractPos::getCodeLines() const
-{
- if (line == 0)
- return std::nullopt;
-
- if (auto source = getSource()) {
-
- std::istringstream iss(*source);
- // count the newlines.
- int count = 0;
- std::string curLine;
- int pl = line - 1;
-
- LinesOfCode loc;
-
- do {
- std::getline(iss, curLine);
- ++count;
- if (count < pl)
- ;
- else if (count == pl) {
- loc.prevLineOfCode = curLine;
- } else if (count == pl + 1) {
- loc.errLineOfCode = curLine;
- } else if (count == pl + 2) {
- loc.nextLineOfCode = curLine;
- break;
- }
-
- if (!iss.good())
- break;
- } while (true);
-
- return loc;
- }
-
- return std::nullopt;
-}
-
// print lines of code to the ostream, indicating the error column.
void printCodeLines(std::ostream & out,
const std::string & prefix,
- const AbstractPos & errPos,
+ const Pos & errPos,
const LinesOfCode & loc)
{
// previous line of code.
@@ -195,7 +148,7 @@ static bool printUnknownLocations = getEnv("_NIX_DEVELOPER_SHOW_UNKNOWN_LOCATION
*
* @return true if a position was printed.
*/
-static bool printPosMaybe(std::ostream & oss, std::string_view indent, const std::shared_ptr<AbstractPos> & pos) {
+static bool printPosMaybe(std::ostream & oss, std::string_view indent, const std::shared_ptr<Pos> & pos) {
bool hasPos = pos && *pos;
if (hasPos) {
oss << indent << ANSI_BLUE << "at " ANSI_WARNING << *pos << ANSI_NORMAL << ":";
diff --git a/src/libutil/error.hh b/src/libutil/error.hh
index baffca128..234cbe1f6 100644
--- a/src/libutil/error.hh
+++ b/src/libutil/error.hh
@@ -63,45 +63,15 @@ struct LinesOfCode {
std::optional<std::string> nextLineOfCode;
};
-/**
- * An abstract type that represents a location in a source file.
- */
-struct AbstractPos
-{
- uint32_t line = 0;
- uint32_t column = 0;
-
- /**
- * An AbstractPos may be a "null object", representing an unknown position.
- *
- * Return true if this position is known.
- */
- inline operator bool() const { return line != 0; };
-
- /**
- * Return the contents of the source file.
- */
- virtual std::optional<std::string> getSource() const
- { return std::nullopt; };
-
- virtual void print(std::ostream & out) const = 0;
-
- std::optional<LinesOfCode> getCodeLines() const;
-
- virtual ~AbstractPos() = default;
-
- inline auto operator<=>(const AbstractPos& rhs) const = default;
-};
-
-std::ostream & operator << (std::ostream & str, const AbstractPos & pos);
+struct Pos;
void printCodeLines(std::ostream & out,
const std::string & prefix,
- const AbstractPos & errPos,
+ const Pos & errPos,
const LinesOfCode & loc);
struct Trace {
- std::shared_ptr<AbstractPos> pos;
+ std::shared_ptr<Pos> pos;
hintformat hint;
bool frame;
};
@@ -114,7 +84,7 @@ inline bool operator>=(const Trace& lhs, const Trace& rhs);
struct ErrorInfo {
Verbosity level;
hintformat msg;
- std::shared_ptr<AbstractPos> errPos;
+ std::shared_ptr<Pos> errPos;
std::list<Trace> traces;
Suggestions suggestions;
@@ -185,12 +155,12 @@ public:
}
template<typename... Args>
- void addTrace(std::shared_ptr<AbstractPos> && e, std::string_view fs, const Args & ... args)
+ void addTrace(std::shared_ptr<Pos> && e, std::string_view fs, const Args & ... args)
{
addTrace(std::move(e), hintfmt(std::string(fs), args...));
}
- void addTrace(std::shared_ptr<AbstractPos> && e, hintformat hint, bool frame = false);
+ void addTrace(std::shared_ptr<Pos> && e, hintformat hint, bool frame = false);
bool hasTrace() const { return !err.traces.empty(); }
diff --git a/src/libutil/input-accessor.hh b/src/libutil/input-accessor.hh
new file mode 100644
index 000000000..740175af0
--- /dev/null
+++ b/src/libutil/input-accessor.hh
@@ -0,0 +1,35 @@
+#pragma once
+///@file
+
+#include "types.hh"
+#include "archive.hh"
+
+namespace nix {
+
+struct InputAccessor
+{
+ enum Type {
+ tRegular, tSymlink, tDirectory,
+ /**
+ Any other node types that may be encountered on the file system, such as device nodes, sockets, named pipe, and possibly even more exotic things.
+
+ Responsible for `"unknown"` from `builtins.readFileType "/dev/null"`.
+
+ Unlike `DT_UNKNOWN`, this must not be used for deferring the lookup of types.
+ */
+ tMisc
+ };
+
+ struct Stat
+ {
+ Type type = tMisc;
+ //uint64_t fileSize = 0; // regular files only
+ bool isExecutable = false; // regular files only
+ };
+
+ typedef std::optional<Type> DirEntry;
+
+ typedef std::map<std::string, DirEntry> DirEntries;
+};
+
+}
diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc
index 9d7a141b3..b4b180760 100644
--- a/src/libutil/logging.cc
+++ b/src/libutil/logging.cc
@@ -1,6 +1,8 @@
#include "logging.hh"
#include "util.hh"
#include "config.hh"
+#include "source-path.hh"
+#include "position.hh"
#include <atomic>
#include <nlohmann/json.hpp>
@@ -133,13 +135,13 @@ Activity::Activity(Logger & logger, Verbosity lvl, ActivityType type,
logger.startActivity(id, lvl, type, s, fields, parent);
}
-void to_json(nlohmann::json & json, std::shared_ptr<AbstractPos> pos)
+void to_json(nlohmann::json & json, std::shared_ptr<Pos> pos)
{
if (pos) {
json["line"] = pos->line;
json["column"] = pos->column;
std::ostringstream str;
- pos->print(str);
+ pos->print(str, true);
json["file"] = str.str();
} else {
json["line"] = nullptr;
diff --git a/src/libutil/position.cc b/src/libutil/position.cc
new file mode 100644
index 000000000..b39a5a1d4
--- /dev/null
+++ b/src/libutil/position.cc
@@ -0,0 +1,112 @@
+#include "position.hh"
+
+namespace nix {
+
+Pos::Pos(const Pos * other)
+{
+ if (!other) {
+ return;
+ }
+ line = other->line;
+ column = other->column;
+ origin = std::move(other->origin);
+}
+
+Pos::operator std::shared_ptr<Pos>() const
+{
+ return std::make_shared<Pos>(&*this);
+}
+
+bool Pos::operator<(const Pos &rhs) const
+{
+ return std::forward_as_tuple(line, column, origin)
+ < std::forward_as_tuple(rhs.line, rhs.column, rhs.origin);
+}
+
+std::optional<LinesOfCode> Pos::getCodeLines() const
+{
+ if (line == 0)
+ return std::nullopt;
+
+ if (auto source = getSource()) {
+
+ std::istringstream iss(*source);
+ // count the newlines.
+ int count = 0;
+ std::string curLine;
+ int pl = line - 1;
+
+ LinesOfCode loc;
+
+ do {
+ std::getline(iss, curLine);
+ ++count;
+ if (count < pl)
+ ;
+ else if (count == pl) {
+ loc.prevLineOfCode = curLine;
+ } else if (count == pl + 1) {
+ loc.errLineOfCode = curLine;
+ } else if (count == pl + 2) {
+ loc.nextLineOfCode = curLine;
+ break;
+ }
+
+ if (!iss.good())
+ break;
+ } while (true);
+
+ return loc;
+ }
+
+ return std::nullopt;
+}
+
+
+std::optional<std::string> Pos::getSource() const
+{
+ return std::visit(overloaded {
+ [](const std::monostate &) -> std::optional<std::string> {
+ return std::nullopt;
+ },
+ [](const Pos::Stdin & s) -> std::optional<std::string> {
+ // Get rid of the null terminators added by the parser.
+ return std::string(s.source->c_str());
+ },
+ [](const Pos::String & s) -> std::optional<std::string> {
+ // Get rid of the null terminators added by the parser.
+ return std::string(s.source->c_str());
+ },
+ [](const SourcePath & path) -> std::optional<std::string> {
+ try {
+ return path.readFile();
+ } catch (Error &) {
+ return std::nullopt;
+ }
+ }
+ }, origin);
+}
+
+void Pos::print(std::ostream & out, bool showOrigin) const
+{
+ if (showOrigin) {
+ std::visit(overloaded {
+ [&](const std::monostate &) { out << "«none»"; },
+ [&](const Pos::Stdin &) { out << "«stdin»"; },
+ [&](const Pos::String & s) { out << "«string»"; },
+ [&](const SourcePath & path) { out << path; }
+ }, origin);
+ out << ":";
+ }
+ out << line;
+ if (column > 0)
+ out << ":" << column;
+}
+
+std::ostream & operator<<(std::ostream & str, const Pos & pos)
+{
+ pos.print(str, true);
+ return str;
+}
+
+}
diff --git a/src/libutil/position.hh b/src/libutil/position.hh
new file mode 100644
index 000000000..a184997ed
--- /dev/null
+++ b/src/libutil/position.hh
@@ -0,0 +1,74 @@
+#pragma once
+/**
+ * @file
+ *
+ * @brief Pos and AbstractPos
+ */
+
+#include <cstdint>
+#include <string>
+
+#include "source-path.hh"
+
+namespace nix {
+
+/**
+ * A position and an origin for that position (like a source file).
+ */
+struct Pos
+{
+ uint32_t line = 0;
+ uint32_t column = 0;
+
+ struct Stdin {
+ ref<std::string> source;
+ bool operator==(const Stdin & rhs) const
+ { return *source == *rhs.source; }
+ bool operator!=(const Stdin & rhs) const
+ { return *source != *rhs.source; }
+ bool operator<(const Stdin & rhs) const
+ { return *source < *rhs.source; }
+ };
+ struct String {
+ ref<std::string> source;
+ bool operator==(const String & rhs) const
+ { return *source == *rhs.source; }
+ bool operator!=(const String & rhs) const
+ { return *source != *rhs.source; }
+ bool operator<(const String & rhs) const
+ { return *source < *rhs.source; }
+ };
+
+ typedef std::variant<std::monostate, Stdin, String, SourcePath> Origin;
+
+ Origin origin = std::monostate();
+
+ Pos() { }
+ Pos(uint32_t line, uint32_t column, Origin origin)
+ : line(line), column(column), origin(origin) { }
+ Pos(Pos & other) = default;
+ Pos(const Pos & other) = default;
+ Pos(Pos && other) = default;
+ Pos(const Pos * other);
+
+ explicit operator bool() const { return line > 0; }
+
+ operator std::shared_ptr<Pos>() const;
+
+ /**
+ * Return the contents of the source file.
+ */
+ std::optional<std::string> getSource() const;
+
+ void print(std::ostream & out, bool showOrigin) const;
+
+ std::optional<LinesOfCode> getCodeLines() const;
+
+ bool operator==(const Pos & rhs) const = default;
+ bool operator!=(const Pos & rhs) const = default;
+ bool operator<(const Pos & rhs) const;
+};
+
+std::ostream & operator<<(std::ostream & str, const Pos & pos);
+
+}
diff --git a/src/libutil/ref.hh b/src/libutil/ref.hh
index af5f8304c..5d0c3696d 100644
--- a/src/libutil/ref.hh
+++ b/src/libutil/ref.hh
@@ -1,6 +1,7 @@
#pragma once
///@file
+#include <compare>
#include <memory>
#include <exception>
#include <stdexcept>
diff --git a/src/libstore/repair-flag.hh b/src/libutil/repair-flag.hh
index f412d6a20..f412d6a20 100644
--- a/src/libstore/repair-flag.hh
+++ b/src/libutil/repair-flag.hh
diff --git a/src/libfetchers/input-accessor.cc b/src/libutil/source-path.cc
index f37a8058b..b6563ee90 100644
--- a/src/libfetchers/input-accessor.cc
+++ b/src/libutil/source-path.cc
@@ -1,5 +1,4 @@
-#include "input-accessor.hh"
-#include "store-api.hh"
+#include "source-path.hh"
namespace nix {
@@ -57,18 +56,6 @@ InputAccessor::DirEntries SourcePath::readDirectory() const
return res;
}
-StorePath SourcePath::fetchToStore(
- ref<Store> store,
- std::string_view name,
- PathFilter * filter,
- RepairFlag repair) const
-{
- return
- settings.readOnlyMode
- ? store->computeStorePathForPath(name, path.abs(), FileIngestionMethod::Recursive, htSHA256, filter ? *filter : defaultPathFilter).first
- : store->addToStore(name, path.abs(), FileIngestionMethod::Recursive, htSHA256, filter ? *filter : defaultPathFilter, repair);
-}
-
SourcePath SourcePath::resolveSymlinks() const
{
SourcePath res(CanonPath::root);
diff --git a/src/libfetchers/input-accessor.hh b/src/libutil/source-path.hh
index 5a2f17f62..54698de77 100644
--- a/src/libfetchers/input-accessor.hh
+++ b/src/libutil/source-path.hh
@@ -1,42 +1,17 @@
#pragma once
+/**
+ * @file
+ *
+ * @brief SourcePath
+ */
#include "ref.hh"
-#include "types.hh"
-#include "archive.hh"
#include "canon-path.hh"
#include "repair-flag.hh"
+#include "input-accessor.hh"
namespace nix {
-class StorePath;
-class Store;
-
-struct InputAccessor
-{
- enum Type {
- tRegular, tSymlink, tDirectory,
- /**
- Any other node types that may be encountered on the file system, such as device nodes, sockets, named pipe, and possibly even more exotic things.
-
- Responsible for `"unknown"` from `builtins.readFileType "/dev/null"`.
-
- Unlike `DT_UNKNOWN`, this must not be used for deferring the lookup of types.
- */
- tMisc
- };
-
- struct Stat
- {
- Type type = tMisc;
- //uint64_t fileSize = 0; // regular files only
- bool isExecutable = false; // regular files only
- };
-
- typedef std::optional<Type> DirEntry;
-
- typedef std::map<std::string, DirEntry> DirEntries;
-};
-
/**
* An abstraction for accessing source files during
* evaluation. Currently, it's just a wrapper around `CanonPath` that
@@ -107,15 +82,6 @@ struct SourcePath
{ return nix::dumpPath(path.abs(), sink, filter); }
/**
- * Copy this `SourcePath` to the Nix store.
- */
- StorePath fetchToStore(
- ref<Store> store,
- std::string_view name = "source",
- PathFilter * filter = nullptr,
- RepairFlag repair = NoRepair) const;
-
- /**
* Return the location of this path in the "real" filesystem, if
* it has a physical location.
*/