Compare commits
3 Commits
structured
...
string-dat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddca102f8b | ||
|
|
351e3870c9 | ||
|
|
1ea6a71b0c |
@@ -656,7 +656,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
|||||||
+ "\n\n";
|
+ "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
markdown += stripIndentation(doc->doc);
|
markdown += stripIndentation(doc->doc.view());
|
||||||
|
|
||||||
logger->cout(trim(renderMarkdownToTerminal(markdown)));
|
logger->cout(trim(renderMarkdownToTerminal(markdown)));
|
||||||
} else if (fallbackPos) {
|
} else if (fallbackPos) {
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ PrimOp * nix_alloc_primop(
|
|||||||
.name = name,
|
.name = name,
|
||||||
.args = {},
|
.args = {},
|
||||||
.arity = (size_t) arity,
|
.arity = (size_t) arity,
|
||||||
.doc = doc,
|
.doc = &nix::StringData::make(doc),
|
||||||
.fun = std::bind(nix_c_primop_wrapper, fun, user_data, _1, _2, _3, _4)};
|
.fun = std::bind(nix_c_primop_wrapper, fun, user_data, _1, _2, _3, _4)};
|
||||||
if (args)
|
if (args)
|
||||||
for (size_t i = 0; args[i]; i++)
|
for (size_t i = 0; args[i]; i++)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "nix/expr/tests/libexpr.hh"
|
#include "nix/expr/tests/libexpr.hh"
|
||||||
#include "nix/expr/value-to-json.hh"
|
#include "nix/expr/value-to-json.hh"
|
||||||
#include "nix/expr/static-string-data.hh"
|
#include "nix/expr/string-data-static.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
// Testing the conversion to JSON
|
// Testing the conversion to JSON
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "nix/expr/tests/libexpr.hh"
|
#include "nix/expr/tests/libexpr.hh"
|
||||||
#include "nix/expr/static-string-data.hh"
|
#include "nix/expr/string-data-static.hh"
|
||||||
|
|
||||||
#include "nix/expr/value.hh"
|
#include "nix/expr/value.hh"
|
||||||
#include "nix/expr/print.hh"
|
#include "nix/expr/print.hh"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "nix/expr/value.hh"
|
#include "nix/expr/value.hh"
|
||||||
#include "nix/expr/static-string-data.hh"
|
#include "nix/expr/string-data-static.hh"
|
||||||
|
|
||||||
#include "nix/store/tests/libstore.hh"
|
#include "nix/store/tests/libstore.hh"
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|||||||
@@ -51,36 +51,6 @@ using json = nlohmann::json;
|
|||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
/**
|
|
||||||
* Just for doc strings. Not for regular string values.
|
|
||||||
*/
|
|
||||||
static char * allocString(size_t size)
|
|
||||||
{
|
|
||||||
char * t;
|
|
||||||
t = (char *) GC_MALLOC_ATOMIC(size);
|
|
||||||
if (!t)
|
|
||||||
throw std::bad_alloc();
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When there's no need to write to the string, we can optimize away empty
|
|
||||||
// string allocations.
|
|
||||||
// This function handles makeImmutableString(std::string_view()) by returning
|
|
||||||
// the empty string.
|
|
||||||
/**
|
|
||||||
* Just for doc strings. Not for regular string values.
|
|
||||||
*/
|
|
||||||
static const char * makeImmutableString(std::string_view s)
|
|
||||||
{
|
|
||||||
const size_t size = s.size();
|
|
||||||
if (size == 0)
|
|
||||||
return "";
|
|
||||||
auto t = allocString(size + 1);
|
|
||||||
memcpy(t, s.data(), size);
|
|
||||||
t[size] = '\0';
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringData & StringData::alloc(size_t size)
|
StringData & StringData::alloc(size_t size)
|
||||||
{
|
{
|
||||||
void * t = GC_MALLOC_ATOMIC(sizeof(StringData) + size + 1);
|
void * t = GC_MALLOC_ATOMIC(sizeof(StringData) + size + 1);
|
||||||
@@ -571,7 +541,7 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
|
|||||||
.name = v2->primOp()->name,
|
.name = v2->primOp()->name,
|
||||||
.arity = v2->primOp()->arity,
|
.arity = v2->primOp()->arity,
|
||||||
.args = v2->primOp()->args,
|
.args = v2->primOp()->args,
|
||||||
.doc = doc,
|
.doc = *doc,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (v.isLambda()) {
|
if (v.isLambda()) {
|
||||||
@@ -613,9 +583,8 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
|
|||||||
.name = name,
|
.name = name,
|
||||||
.arity = 0, // FIXME: figure out how deep by syntax only? It's not semantically useful though...
|
.arity = 0, // FIXME: figure out how deep by syntax only? It's not semantically useful though...
|
||||||
.args = {},
|
.args = {},
|
||||||
/* N.B. Can't use StringData here, because that would lead to an interior pointer.
|
/* NOTE: memory leak when compiled without GC. */
|
||||||
NOTE: memory leak when compiled without GC. */
|
.doc = StringData::make(s.view()),
|
||||||
.doc = makeImmutableString(s.view()),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (isFunctor(v)) {
|
if (isFunctor(v)) {
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ struct PrimOp
|
|||||||
/**
|
/**
|
||||||
* Optional free-form documentation about the primop.
|
* Optional free-form documentation about the primop.
|
||||||
*/
|
*/
|
||||||
const char * doc = nullptr;
|
const StringData * doc = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a trace item, while calling the `<name>` builtin.
|
* Add a trace item, while calling the `<name>` builtin.
|
||||||
@@ -156,7 +156,7 @@ struct Constant
|
|||||||
/**
|
/**
|
||||||
* Optional free-form documentation about the constant.
|
* Optional free-form documentation about the constant.
|
||||||
*/
|
*/
|
||||||
const char * doc = nullptr;
|
const StringData * doc = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the constant is impure, and not available in pure mode.
|
* Whether the constant is impure, and not available in pure mode.
|
||||||
@@ -837,11 +837,7 @@ public:
|
|||||||
std::optional<std::string> name;
|
std::optional<std::string> name;
|
||||||
size_t arity;
|
size_t arity;
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
/**
|
const StringData & doc;
|
||||||
* Unlike the other `doc` fields in this file, this one should never be
|
|
||||||
* `null`.
|
|
||||||
*/
|
|
||||||
const char * doc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ headers = [ config_pub_h ] + files(
|
|||||||
'print.hh',
|
'print.hh',
|
||||||
'repl-exit-status.hh',
|
'repl-exit-status.hh',
|
||||||
'search-path.hh',
|
'search-path.hh',
|
||||||
'static-string-data.hh',
|
'string-data.hh',
|
||||||
|
'string-data-static.hh',
|
||||||
'symbol-table.hh',
|
'symbol-table.hh',
|
||||||
'value-to-json.hh',
|
'value-to-json.hh',
|
||||||
'value-to-xml.hh',
|
'value-to-xml.hh',
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include "nix/expr/value.hh"
|
#include "nix/expr/value.hh"
|
||||||
#include "nix/expr/symbol-table.hh"
|
#include "nix/expr/symbol-table.hh"
|
||||||
#include "nix/expr/eval-error.hh"
|
#include "nix/expr/eval-error.hh"
|
||||||
#include "nix/expr/static-string-data.hh"
|
#include "nix/expr/string-data-static.hh"
|
||||||
#include "nix/util/pos-idx.hh"
|
#include "nix/util/pos-idx.hh"
|
||||||
#include "nix/expr/counter.hh"
|
#include "nix/expr/counter.hh"
|
||||||
#include "nix/util/pos-table.hh"
|
#include "nix/util/pos-table.hh"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "nix/expr/eval.hh"
|
#include "nix/expr/eval.hh"
|
||||||
#include "nix/expr/value.hh"
|
#include "nix/expr/value.hh"
|
||||||
#include "nix/expr/static-string-data.hh"
|
#include "nix/expr/string-data-static.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
#include "nix/expr/value.hh"
|
#include "nix/expr/string-data.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
96
src/libexpr/include/nix/expr/string-data.hh
Normal file
96
src/libexpr/include/nix/expr/string-data.hh
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#pragma once
|
||||||
|
///@file
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory_resource>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
class StringData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using size_type = std::size_t;
|
||||||
|
|
||||||
|
size_type size_;
|
||||||
|
char data_[];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This in particular ensures that we cannot have a `StringData`
|
||||||
|
* that we use by value, which is just what we want!
|
||||||
|
*
|
||||||
|
* Dynamically sized types aren't a thing in C++ and even flexible array
|
||||||
|
* members are a language extension and beyond the realm of standard C++.
|
||||||
|
* Technically, sizeof data_ member is 0 and the intended way to use flexible
|
||||||
|
* array members is to allocate sizeof(StrindData) + count * sizeof(char) bytes
|
||||||
|
* and the compiler will consider alignment restrictions for the FAM.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
StringData(StringData &&) = delete;
|
||||||
|
StringData & operator=(StringData &&) = delete;
|
||||||
|
StringData(const StringData &) = delete;
|
||||||
|
StringData & operator=(const StringData &) = delete;
|
||||||
|
~StringData() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StringData() = delete;
|
||||||
|
|
||||||
|
explicit StringData(size_type size)
|
||||||
|
: size_(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Allocate StringData on the (possibly) GC-managed heap and copy
|
||||||
|
* the contents of s to it.
|
||||||
|
*/
|
||||||
|
static const StringData & make(std::string_view s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate StringData on the (possibly) GC-managed heap.
|
||||||
|
* @param size Length of the string (without the NUL terminator).
|
||||||
|
*/
|
||||||
|
static StringData & alloc(size_t size);
|
||||||
|
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * data() noexcept
|
||||||
|
{
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * data() const noexcept
|
||||||
|
{
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * c_str() const noexcept
|
||||||
|
{
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr std::string_view view() const noexcept
|
||||||
|
{
|
||||||
|
return std::string_view(data_, size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
struct Static;
|
||||||
|
|
||||||
|
static StringData & make(std::pmr::memory_resource & resource, std::string_view s)
|
||||||
|
{
|
||||||
|
auto & res =
|
||||||
|
*new (resource.allocate(sizeof(StringData) + s.size() + 1, alignof(StringData))) StringData(s.size());
|
||||||
|
std::memcpy(res.data_, s.data(), s.size());
|
||||||
|
res.data_[s.size()] = '\0';
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace nix
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <memory_resource>
|
#include <memory_resource>
|
||||||
#include "nix/expr/value.hh"
|
#include "nix/expr/value.hh"
|
||||||
#include "nix/expr/static-string-data.hh"
|
#include "nix/expr/string-data-static.hh"
|
||||||
#include "nix/util/chunked-vector.hh"
|
#include "nix/util/chunked-vector.hh"
|
||||||
#include "nix/util/error.hh"
|
#include "nix/util/error.hh"
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,14 @@
|
|||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
|
||||||
#include <cstring>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <memory_resource>
|
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
|
||||||
#include "nix/expr/eval-gc.hh"
|
#include "nix/expr/eval-gc.hh"
|
||||||
|
#include "nix/expr/string-data.hh"
|
||||||
#include "nix/expr/value/context.hh"
|
#include "nix/expr/value/context.hh"
|
||||||
#include "nix/util/source-path.hh"
|
#include "nix/util/source-path.hh"
|
||||||
#include "nix/expr/print-options.hh"
|
#include "nix/expr/print-options.hh"
|
||||||
@@ -193,91 +191,6 @@ public:
|
|||||||
friend struct Value;
|
friend struct Value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StringData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using size_type = std::size_t;
|
|
||||||
|
|
||||||
size_type size_;
|
|
||||||
char data_[];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This in particular ensures that we cannot have a `StringData`
|
|
||||||
* that we use by value, which is just what we want!
|
|
||||||
*
|
|
||||||
* Dynamically sized types aren't a thing in C++ and even flexible array
|
|
||||||
* members are a language extension and beyond the realm of standard C++.
|
|
||||||
* Technically, sizeof data_ member is 0 and the intended way to use flexible
|
|
||||||
* array members is to allocate sizeof(StrindData) + count * sizeof(char) bytes
|
|
||||||
* and the compiler will consider alignment restrictions for the FAM.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
StringData(StringData &&) = delete;
|
|
||||||
StringData & operator=(StringData &&) = delete;
|
|
||||||
StringData(const StringData &) = delete;
|
|
||||||
StringData & operator=(const StringData &) = delete;
|
|
||||||
~StringData() = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
StringData() = delete;
|
|
||||||
|
|
||||||
explicit StringData(size_type size)
|
|
||||||
: size_(size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Allocate StringData on the (possibly) GC-managed heap and copy
|
|
||||||
* the contents of s to it.
|
|
||||||
*/
|
|
||||||
static const StringData & make(std::string_view s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate StringData on the (possibly) GC-managed heap.
|
|
||||||
* @param size Length of the string (without the NUL terminator).
|
|
||||||
*/
|
|
||||||
static StringData & alloc(size_t size);
|
|
||||||
|
|
||||||
size_t size() const
|
|
||||||
{
|
|
||||||
return size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * data() noexcept
|
|
||||||
{
|
|
||||||
return data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * data() const noexcept
|
|
||||||
{
|
|
||||||
return data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * c_str() const noexcept
|
|
||||||
{
|
|
||||||
return data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr std::string_view view() const noexcept
|
|
||||||
{
|
|
||||||
return std::string_view(data_, size_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t N>
|
|
||||||
struct Static;
|
|
||||||
|
|
||||||
static StringData & make(std::pmr::memory_resource & resource, std::string_view s)
|
|
||||||
{
|
|
||||||
auto & res =
|
|
||||||
*new (resource.allocate(sizeof(StringData) + s.size() + 1, alignof(StringData))) StringData(s.size());
|
|
||||||
std::memcpy(res.data_, s.data(), s.size());
|
|
||||||
res.data_[s.size()] = '\0';
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
|||||||
#include "nix/expr/primops.hh"
|
#include "nix/expr/primops.hh"
|
||||||
#include "nix/expr/eval-inline.hh"
|
#include "nix/expr/eval-inline.hh"
|
||||||
|
#include "nix/expr/string-data-static.hh"
|
||||||
#include "nix/store/derivations.hh"
|
#include "nix/store/derivations.hh"
|
||||||
#include "nix/store/store-api.hh"
|
#include "nix/store/store-api.hh"
|
||||||
#include "nix/store/globals.hh"
|
#include "nix/store/globals.hh"
|
||||||
@@ -17,9 +18,9 @@ static void prim_unsafeDiscardStringContext(EvalState & state, const PosIdx pos,
|
|||||||
static RegisterPrimOp primop_unsafeDiscardStringContext({
|
static RegisterPrimOp primop_unsafeDiscardStringContext({
|
||||||
.name = "__unsafeDiscardStringContext",
|
.name = "__unsafeDiscardStringContext",
|
||||||
.args = {"s"},
|
.args = {"s"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Discard the [string context](@docroot@/language/string-context.md) from a value that can be coerced to a string.
|
Discard the [string context](@docroot@/language/string-context.md) from a value that can be coerced to a string.
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_unsafeDiscardStringContext,
|
.fun = prim_unsafeDiscardStringContext,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ static void prim_hasContext(EvalState & state, const PosIdx pos, Value ** args,
|
|||||||
static RegisterPrimOp primop_hasContext(
|
static RegisterPrimOp primop_hasContext(
|
||||||
{.name = "__hasContext",
|
{.name = "__hasContext",
|
||||||
.args = {"s"},
|
.args = {"s"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Return `true` if string *s* has a non-empty context.
|
Return `true` if string *s* has a non-empty context.
|
||||||
The context can be obtained with
|
The context can be obtained with
|
||||||
[`getContext`](#builtins-getContext).
|
[`getContext`](#builtins-getContext).
|
||||||
@@ -50,7 +51,7 @@ static RegisterPrimOp primop_hasContext(
|
|||||||
> then throw "package name cannot contain string context"
|
> then throw "package name cannot contain string context"
|
||||||
> else { ${name} = meta; }
|
> else { ${name} = meta; }
|
||||||
> ```
|
> ```
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_hasContext});
|
.fun = prim_hasContext});
|
||||||
|
|
||||||
static void prim_unsafeDiscardOutputDependency(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
static void prim_unsafeDiscardOutputDependency(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
||||||
@@ -75,7 +76,7 @@ static void prim_unsafeDiscardOutputDependency(EvalState & state, const PosIdx p
|
|||||||
static RegisterPrimOp primop_unsafeDiscardOutputDependency(
|
static RegisterPrimOp primop_unsafeDiscardOutputDependency(
|
||||||
{.name = "__unsafeDiscardOutputDependency",
|
{.name = "__unsafeDiscardOutputDependency",
|
||||||
.args = {"s"},
|
.args = {"s"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Create a copy of the given string where every
|
Create a copy of the given string where every
|
||||||
[derivation deep](@docroot@/language/string-context.md#string-context-element-derivation-deep)
|
[derivation deep](@docroot@/language/string-context.md#string-context-element-derivation-deep)
|
||||||
string context element is turned into a
|
string context element is turned into a
|
||||||
@@ -91,7 +92,7 @@ static RegisterPrimOp primop_unsafeDiscardOutputDependency(
|
|||||||
Replacing a constant string context element with a "derivation deep" element is a safe operation that just enlargens the string context without forgetting anything.
|
Replacing a constant string context element with a "derivation deep" element is a safe operation that just enlargens the string context without forgetting anything.
|
||||||
|
|
||||||
[`builtins.addDrvOutputDependencies`]: #builtins-addDrvOutputDependencies
|
[`builtins.addDrvOutputDependencies`]: #builtins-addDrvOutputDependencies
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_unsafeDiscardOutputDependency});
|
.fun = prim_unsafeDiscardOutputDependency});
|
||||||
|
|
||||||
static void prim_addDrvOutputDependencies(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
static void prim_addDrvOutputDependencies(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
||||||
@@ -143,7 +144,7 @@ static void prim_addDrvOutputDependencies(EvalState & state, const PosIdx pos, V
|
|||||||
static RegisterPrimOp primop_addDrvOutputDependencies(
|
static RegisterPrimOp primop_addDrvOutputDependencies(
|
||||||
{.name = "__addDrvOutputDependencies",
|
{.name = "__addDrvOutputDependencies",
|
||||||
.args = {"s"},
|
.args = {"s"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Create a copy of the given string where a single
|
Create a copy of the given string where a single
|
||||||
[constant](@docroot@/language/string-context.md#string-context-constant)
|
[constant](@docroot@/language/string-context.md#string-context-constant)
|
||||||
string context element is turned into a
|
string context element is turned into a
|
||||||
@@ -156,7 +157,7 @@ static RegisterPrimOp primop_addDrvOutputDependencies(
|
|||||||
The latter is supported so this function is idempotent.
|
The latter is supported so this function is idempotent.
|
||||||
|
|
||||||
This is the opposite of [`builtins.unsafeDiscardOutputDependency`](#builtins-unsafeDiscardOutputDependency).
|
This is the opposite of [`builtins.unsafeDiscardOutputDependency`](#builtins-unsafeDiscardOutputDependency).
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_addDrvOutputDependencies});
|
.fun = prim_addDrvOutputDependencies});
|
||||||
|
|
||||||
/* Extract the context of a string as a structured Nix value.
|
/* Extract the context of a string as a structured Nix value.
|
||||||
@@ -230,7 +231,7 @@ static void prim_getContext(EvalState & state, const PosIdx pos, Value ** args,
|
|||||||
static RegisterPrimOp primop_getContext(
|
static RegisterPrimOp primop_getContext(
|
||||||
{.name = "__getContext",
|
{.name = "__getContext",
|
||||||
.args = {"s"},
|
.args = {"s"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Return the string context of *s*.
|
Return the string context of *s*.
|
||||||
|
|
||||||
The string context tracks references to derivations within a string.
|
The string context tracks references to derivations within a string.
|
||||||
@@ -248,7 +249,7 @@ static RegisterPrimOp primop_getContext(
|
|||||||
```
|
```
|
||||||
{ "/nix/store/arhvjaf6zmlyn8vh8fgn55rpwnxq0n7l-a.drv" = { outputs = [ "out" ]; }; }
|
{ "/nix/store/arhvjaf6zmlyn8vh8fgn55rpwnxq0n7l-a.drv" = { outputs = [ "out" ]; }; }
|
||||||
```
|
```
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_getContext});
|
.fun = prim_getContext});
|
||||||
|
|
||||||
/* Append the given context to a given string.
|
/* Append the given context to a given string.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "nix/expr/primops.hh"
|
#include "nix/expr/primops.hh"
|
||||||
|
#include "nix/expr/string-data-static.hh"
|
||||||
#include "nix/store/store-open.hh"
|
#include "nix/store/store-open.hh"
|
||||||
#include "nix/store/realisation.hh"
|
#include "nix/store/realisation.hh"
|
||||||
#include "nix/store/make-content-addressed.hh"
|
#include "nix/store/make-content-addressed.hh"
|
||||||
@@ -216,7 +217,7 @@ static void prim_fetchClosure(EvalState & state, const PosIdx pos, Value ** args
|
|||||||
static RegisterPrimOp primop_fetchClosure({
|
static RegisterPrimOp primop_fetchClosure({
|
||||||
.name = "__fetchClosure",
|
.name = "__fetchClosure",
|
||||||
.args = {"args"},
|
.args = {"args"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Fetch a store path [closure](@docroot@/glossary.md#gloss-closure) from a binary cache, and return the store path as a string with context.
|
Fetch a store path [closure](@docroot@/glossary.md#gloss-closure) from a binary cache, and return the store path as a string with context.
|
||||||
|
|
||||||
This function can be invoked in three ways that we will discuss in order of preference.
|
This function can be invoked in three ways that we will discuss in order of preference.
|
||||||
@@ -284,7 +285,7 @@ static RegisterPrimOp primop_fetchClosure({
|
|||||||
`fetchClosure` is similar to [`builtins.storePath`](#builtins-storePath) in that it allows you to use a previously built store path in a Nix expression.
|
`fetchClosure` is similar to [`builtins.storePath`](#builtins-storePath) in that it allows you to use a previously built store path in a Nix expression.
|
||||||
However, `fetchClosure` is more reproducible because it specifies a binary cache from which the path can be fetched.
|
However, `fetchClosure` is more reproducible because it specifies a binary cache from which the path can be fetched.
|
||||||
Also, using content-addressed store paths does not require users to configure [`trusted-public-keys`](@docroot@/command-ref/conf-file.md#conf-trusted-public-keys) to ensure their authenticity.
|
Also, using content-addressed store paths does not require users to configure [`trusted-public-keys`](@docroot@/command-ref/conf-file.md#conf-trusted-public-keys) to ensure their authenticity.
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_fetchClosure,
|
.fun = prim_fetchClosure,
|
||||||
.experimentalFeature = Xp::FetchClosure,
|
.experimentalFeature = Xp::FetchClosure,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "nix/expr/primops.hh"
|
#include "nix/expr/primops.hh"
|
||||||
#include "nix/expr/eval-inline.hh"
|
#include "nix/expr/eval-inline.hh"
|
||||||
#include "nix/expr/eval-settings.hh"
|
#include "nix/expr/eval-settings.hh"
|
||||||
|
#include "nix/expr/string-data-static.hh"
|
||||||
#include "nix/store/store-api.hh"
|
#include "nix/store/store-api.hh"
|
||||||
#include "nix/fetchers/fetchers.hh"
|
#include "nix/fetchers/fetchers.hh"
|
||||||
#include "nix/store/filetransfer.hh"
|
#include "nix/store/filetransfer.hh"
|
||||||
@@ -235,7 +236,7 @@ static void prim_fetchTree(EvalState & state, const PosIdx pos, Value ** args, V
|
|||||||
static RegisterPrimOp primop_fetchTree({
|
static RegisterPrimOp primop_fetchTree({
|
||||||
.name = "fetchTree",
|
.name = "fetchTree",
|
||||||
.args = {"input"},
|
.args = {"input"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Fetch a file system tree or a plain file using one of the supported backends and return an attribute set with:
|
Fetch a file system tree or a plain file using one of the supported backends and return an attribute set with:
|
||||||
|
|
||||||
- the resulting fixed-output [store path](@docroot@/store/store-path.md)
|
- the resulting fixed-output [store path](@docroot@/store/store-path.md)
|
||||||
@@ -457,7 +458,7 @@ static RegisterPrimOp primop_fetchTree({
|
|||||||
> ```nix
|
> ```nix
|
||||||
> builtins.fetchTree "github:NixOS/nixpkgs/ae2e6b3958682513d28f7d633734571fb18285dd"
|
> builtins.fetchTree "github:NixOS/nixpkgs/ae2e6b3958682513d28f7d633734571fb18285dd"
|
||||||
> ```
|
> ```
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_fetchTree,
|
.fun = prim_fetchTree,
|
||||||
.experimentalFeature = Xp::FetchTree,
|
.experimentalFeature = Xp::FetchTree,
|
||||||
});
|
});
|
||||||
@@ -617,7 +618,7 @@ static void prim_fetchurl(EvalState & state, const PosIdx pos, Value ** args, Va
|
|||||||
static RegisterPrimOp primop_fetchurl({
|
static RegisterPrimOp primop_fetchurl({
|
||||||
.name = "__fetchurl",
|
.name = "__fetchurl",
|
||||||
.args = {"arg"},
|
.args = {"arg"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Download the specified URL and return the path of the downloaded file.
|
Download the specified URL and return the path of the downloaded file.
|
||||||
`arg` can be either a string denoting the URL, or an attribute set with the following attributes:
|
`arg` can be either a string denoting the URL, or an attribute set with the following attributes:
|
||||||
|
|
||||||
@@ -631,7 +632,7 @@ static RegisterPrimOp primop_fetchurl({
|
|||||||
characters that are invalid for the store.
|
characters that are invalid for the store.
|
||||||
|
|
||||||
Not available in [restricted evaluation mode](@docroot@/command-ref/conf-file.md#conf-restrict-eval).
|
Not available in [restricted evaluation mode](@docroot@/command-ref/conf-file.md#conf-restrict-eval).
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_fetchurl,
|
.fun = prim_fetchurl,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -643,7 +644,7 @@ static void prim_fetchTarball(EvalState & state, const PosIdx pos, Value ** args
|
|||||||
static RegisterPrimOp primop_fetchTarball({
|
static RegisterPrimOp primop_fetchTarball({
|
||||||
.name = "fetchTarball",
|
.name = "fetchTarball",
|
||||||
.args = {"args"},
|
.args = {"args"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Download the specified URL, unpack it and return the path of the
|
Download the specified URL, unpack it and return the path of the
|
||||||
unpacked tree. The file must be a tape archive (`.tar`) compressed
|
unpacked tree. The file must be a tape archive (`.tar`) compressed
|
||||||
with `gzip`, `bzip2` or `xz`. If the tarball consists of a
|
with `gzip`, `bzip2` or `xz`. If the tarball consists of a
|
||||||
@@ -681,7 +682,7 @@ static RegisterPrimOp primop_fetchTarball({
|
|||||||
```
|
```
|
||||||
|
|
||||||
Not available in [restricted evaluation mode](@docroot@/command-ref/conf-file.md#conf-restrict-eval).
|
Not available in [restricted evaluation mode](@docroot@/command-ref/conf-file.md#conf-restrict-eval).
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_fetchTarball,
|
.fun = prim_fetchTarball,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -694,7 +695,7 @@ static void prim_fetchGit(EvalState & state, const PosIdx pos, Value ** args, Va
|
|||||||
static RegisterPrimOp primop_fetchGit({
|
static RegisterPrimOp primop_fetchGit({
|
||||||
.name = "fetchGit",
|
.name = "fetchGit",
|
||||||
.args = {"args"},
|
.args = {"args"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Fetch a path from git. *args* can be a URL, in which case the HEAD
|
Fetch a path from git. *args* can be a URL, in which case the HEAD
|
||||||
of the repo at that URL is fetched. Otherwise, it can be an
|
of the repo at that URL is fetched. Otherwise, it can be an
|
||||||
attribute with the following attributes (all except `url` optional):
|
attribute with the following attributes (all except `url` optional):
|
||||||
@@ -897,7 +898,7 @@ static RegisterPrimOp primop_fetchGit({
|
|||||||
given, `fetchGit` uses the current content of the checked-out
|
given, `fetchGit` uses the current content of the checked-out
|
||||||
files, even if they are not committed or added to Git's index. It
|
files, even if they are not committed or added to Git's index. It
|
||||||
only considers files added to the Git repository, as listed by `git ls-files`.
|
only considers files added to the Git repository, as listed by `git ls-files`.
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_fetchGit,
|
.fun = prim_fetchGit,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "nix/expr/primops.hh"
|
#include "nix/expr/primops.hh"
|
||||||
#include "nix/expr/eval-inline.hh"
|
#include "nix/expr/eval-inline.hh"
|
||||||
#include "nix/expr/static-string-data.hh"
|
#include "nix/expr/string-data-static.hh"
|
||||||
|
|
||||||
#include "expr-config-private.hh"
|
#include "expr-config-private.hh"
|
||||||
|
|
||||||
@@ -170,10 +170,10 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_fromTOML(
|
static RegisterPrimOp primop_fromTOML({
|
||||||
{.name = "fromTOML",
|
.name = "fromTOML",
|
||||||
.args = {"e"},
|
.args = {"e"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Convert a TOML string to a Nix value. For example,
|
Convert a TOML string to a Nix value. For example,
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
@@ -186,7 +186,8 @@ static RegisterPrimOp primop_fromTOML(
|
|||||||
```
|
```
|
||||||
|
|
||||||
returns the value `{ s = "a"; table = { y = 2; }; x = 1; }`.
|
returns the value `{ s = "a"; table = { y = 2; }; x = 1; }`.
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_fromTOML});
|
.fun = prim_fromTOML,
|
||||||
|
});
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "nix/expr/eval-settings.hh"
|
#include "nix/expr/eval-settings.hh"
|
||||||
#include "nix/expr/symbol-table.hh"
|
#include "nix/expr/symbol-table.hh"
|
||||||
#include "nix/expr/value.hh"
|
#include "nix/expr/value.hh"
|
||||||
|
#include "nix/expr/string-data-static.hh"
|
||||||
#include "nix/fetchers/attrs.hh"
|
#include "nix/fetchers/attrs.hh"
|
||||||
#include "nix/fetchers/fetchers.hh"
|
#include "nix/fetchers/fetchers.hh"
|
||||||
#include "nix/util/configuration.hh"
|
#include "nix/util/configuration.hh"
|
||||||
@@ -62,7 +63,7 @@ PrimOp getFlake(const Settings & settings)
|
|||||||
return PrimOp{
|
return PrimOp{
|
||||||
.name = "__getFlake",
|
.name = "__getFlake",
|
||||||
.args = {"args"},
|
.args = {"args"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Fetch a flake from a flake reference, and return its output attributes and some metadata. For example:
|
Fetch a flake from a flake reference, and return its output attributes and some metadata. For example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
@@ -76,7 +77,7 @@ PrimOp getFlake(const Settings & settings)
|
|||||||
```nix
|
```nix
|
||||||
(builtins.getFlake "github:edolstra/dwarffs").rev
|
(builtins.getFlake "github:edolstra/dwarffs").rev
|
||||||
```
|
```
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_getFlake,
|
.fun = prim_getFlake,
|
||||||
.experimentalFeature = Xp::Flakes,
|
.experimentalFeature = Xp::Flakes,
|
||||||
};
|
};
|
||||||
@@ -104,7 +105,7 @@ static void prim_parseFlakeRef(EvalState & state, const PosIdx pos, Value ** arg
|
|||||||
nix::PrimOp parseFlakeRef({
|
nix::PrimOp parseFlakeRef({
|
||||||
.name = "__parseFlakeRef",
|
.name = "__parseFlakeRef",
|
||||||
.args = {"flake-ref"},
|
.args = {"flake-ref"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Parse a flake reference, and return its exploded form.
|
Parse a flake reference, and return its exploded form.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
@@ -118,7 +119,7 @@ nix::PrimOp parseFlakeRef({
|
|||||||
```nix
|
```nix
|
||||||
{ dir = "lib"; owner = "NixOS"; ref = "23.05"; repo = "nixpkgs"; type = "github"; }
|
{ dir = "lib"; owner = "NixOS"; ref = "23.05"; repo = "nixpkgs"; type = "github"; }
|
||||||
```
|
```
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_parseFlakeRef,
|
.fun = prim_parseFlakeRef,
|
||||||
.experimentalFeature = Xp::Flakes,
|
.experimentalFeature = Xp::Flakes,
|
||||||
});
|
});
|
||||||
@@ -162,7 +163,7 @@ static void prim_flakeRefToString(EvalState & state, const PosIdx pos, Value **
|
|||||||
nix::PrimOp flakeRefToString({
|
nix::PrimOp flakeRefToString({
|
||||||
.name = "__flakeRefToString",
|
.name = "__flakeRefToString",
|
||||||
.args = {"attrs"},
|
.args = {"attrs"},
|
||||||
.doc = R"(
|
.doc = &R"(
|
||||||
Convert a flake reference from attribute set format to URL format.
|
Convert a flake reference from attribute set format to URL format.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
@@ -178,7 +179,7 @@ nix::PrimOp flakeRefToString({
|
|||||||
```nix
|
```nix
|
||||||
"github:NixOS/nixpkgs/23.05?dir=lib"
|
"github:NixOS/nixpkgs/23.05?dir=lib"
|
||||||
```
|
```
|
||||||
)",
|
)"_sds,
|
||||||
.fun = prim_flakeRefToString,
|
.fun = prim_flakeRefToString,
|
||||||
.experimentalFeature = Xp::Flakes,
|
.experimentalFeature = Xp::Flakes,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ void mainWrapped(int argc, char ** argv)
|
|||||||
if (!primOp->doc)
|
if (!primOp->doc)
|
||||||
continue;
|
continue;
|
||||||
b["args"] = primOp->args;
|
b["args"] = primOp->args;
|
||||||
b["doc"] = trim(stripIndentation(primOp->doc));
|
b["doc"] = trim(stripIndentation(primOp->doc->view()));
|
||||||
if (primOp->experimentalFeature)
|
if (primOp->experimentalFeature)
|
||||||
b["experimental-feature"] = primOp->experimentalFeature;
|
b["experimental-feature"] = primOp->experimentalFeature;
|
||||||
builtinsJson.emplace(state.symbols[builtin.name], std::move(b));
|
builtinsJson.emplace(state.symbols[builtin.name], std::move(b));
|
||||||
@@ -449,7 +449,7 @@ void mainWrapped(int argc, char ** argv)
|
|||||||
auto b = nlohmann::json::object();
|
auto b = nlohmann::json::object();
|
||||||
if (!info.doc)
|
if (!info.doc)
|
||||||
continue;
|
continue;
|
||||||
b["doc"] = trim(stripIndentation(info.doc));
|
b["doc"] = trim(stripIndentation(info.doc->view()));
|
||||||
b["type"] = showType(info.type, false);
|
b["type"] = showType(info.type, false);
|
||||||
if (info.impureOnly)
|
if (info.impureOnly)
|
||||||
b["impure-only"] = true;
|
b["impure-only"] = true;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "nix/expr/eval-inline.hh"
|
#include "nix/expr/eval-inline.hh"
|
||||||
#include "nix/store/profiles.hh"
|
#include "nix/store/profiles.hh"
|
||||||
#include "nix/expr/print-ambiguous.hh"
|
#include "nix/expr/print-ambiguous.hh"
|
||||||
#include "nix/expr/static-string-data.hh"
|
#include "nix/expr/string-data-static.hh"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|||||||
Reference in New Issue
Block a user