{libutil,libexpr}: Move pos-idx,pos-table code to libutil

All of this code doesn't actually depend on anything from
libexpr. Because Pos is so tigtly coupled with Error, it
makes sense to have in the same library.

(cherry picked from commit a53b184e63)
This commit is contained in:
Sergei Zimmerman 2025-03-13 12:55:39 +00:00 committed by Mergify
parent 79828c12e0
commit 0033cf4270
7 changed files with 48 additions and 41 deletions

View File

@ -99,7 +99,6 @@
''^src/libexpr/nixexpr\.cc$''
''^src/libexpr/nixexpr\.hh$''
''^src/libexpr/parser-state\.hh$''
''^src/libexpr/pos-table\.hh$''
''^src/libexpr/primops\.cc$''
''^src/libexpr/primops\.hh$''
''^src/libexpr/primops/context\.cc$''

View File

@ -175,8 +175,6 @@ headers = [config_h] + files(
# internal: 'lexer-helpers.hh',
'nixexpr.hh',
'parser-state.hh',
'pos-idx.hh',
'pos-table.hh',
'primops.hh',
'print-ambiguous.hh',
'print-options.hh',

View File

@ -601,41 +601,6 @@ void ExprLambda::setDocComment(DocComment docComment) {
}
};
/* Position table. */
Pos PosTable::operator[](PosIdx p) const
{
auto origin = resolve(p);
if (!origin)
return {};
const auto offset = origin->offsetOf(p);
Pos result{0, 0, origin->origin};
auto lines = this->lines.lock();
auto linesForInput = (*lines)[origin->offset];
if (linesForInput.empty()) {
auto source = result.getSource().value_or("");
const char * begin = source.data();
for (Pos::LinesIterator it(source), end; it != end; it++)
linesForInput.push_back(it->data() - begin);
if (linesForInput.empty())
linesForInput.push_back(0);
}
// as above: the first line starts at byte 0 and is always present
auto lineStartOffset = std::prev(
std::upper_bound(linesForInput.begin(), linesForInput.end(), offset));
result.line = 1 + (lineStartOffset - linesForInput.begin());
result.column = 1 + (offset - *lineStartOffset);
return result;
}
/* Symbol table. */
size_t SymbolTable::totalSize() const

View File

@ -146,6 +146,7 @@ sources = files(
'logging.cc',
'memory-source-accessor.cc',
'position.cc',
'pos-table.cc',
'posix-source-accessor.cc',
'references.cc',
'serialise.cc',
@ -207,6 +208,8 @@ headers = [config_h] + files(
'memory-source-accessor.hh',
'muxable-pipe.hh',
'pool.hh',
'pos-idx.hh',
'pos-table.hh',
'position.hh',
'posix-source-accessor.hh',
'processes.hh',

View File

@ -1,4 +1,5 @@
#pragma once
///@file
#include <cinttypes>
#include <functional>

37
src/libutil/pos-table.cc Normal file
View File

@ -0,0 +1,37 @@
#include "pos-table.hh"
#include <algorithm>
namespace nix {
/* Position table. */
Pos PosTable::operator[](PosIdx p) const
{
auto origin = resolve(p);
if (!origin)
return {};
const auto offset = origin->offsetOf(p);
Pos result{0, 0, origin->origin};
auto lines = this->lines.lock();
auto linesForInput = (*lines)[origin->offset];
if (linesForInput.empty()) {
auto source = result.getSource().value_or("");
const char * begin = source.data();
for (Pos::LinesIterator it(source), end; it != end; it++)
linesForInput.push_back(it->data() - begin);
if (linesForInput.empty())
linesForInput.push_back(0);
}
// as above: the first line starts at byte 0 and is always present
auto lineStartOffset = std::prev(std::upper_bound(linesForInput.begin(), linesForInput.end(), offset));
result.line = 1 + (lineStartOffset - linesForInput.begin());
result.column = 1 + (offset - *lineStartOffset);
return result;
}
}

View File

@ -1,4 +1,5 @@
#pragma once
///@file
#include <cstdint>
#include <vector>
@ -18,9 +19,12 @@ public:
private:
uint32_t offset;
Origin(Pos::Origin origin, uint32_t offset, size_t size):
offset(offset), origin(origin), size(size)
{}
Origin(Pos::Origin origin, uint32_t offset, size_t size)
: offset(offset)
, origin(origin)
, size(size)
{
}
public:
const Pos::Origin origin;