C API: Use new ListBuilder helper

See https://github.com/NixOS/nix/pull/10251
This commit is contained in:
José Luis Lafuente 2024-03-28 19:02:01 +01:00
parent c57de60522
commit 925a8fda6e
No known key found for this signature in database
GPG Key ID: 8A3455EBE455489A
4 changed files with 16 additions and 38 deletions

View File

@ -5,32 +5,6 @@
#include "attr-set.hh" #include "attr-set.hh"
#include "nix_api_value.h" #include "nix_api_value.h"
class CListBuilder
{
private:
std::vector<nix::Value *> values;
public:
CListBuilder(size_t capacity)
{
values.reserve(capacity);
}
void push_back(nix::Value * value)
{
values.push_back(value);
}
Value * finish(nix::EvalState * state, nix::Value * list)
{
state->mkList(*list, values.size());
for (size_t n = 0; n < list->listSize(); ++n) {
list->listElems()[n] = values[n];
}
return list;
}
};
struct EvalState struct EvalState
{ {
nix::EvalState state; nix::EvalState state;
@ -43,7 +17,7 @@ struct BindingsBuilder
struct ListBuilder struct ListBuilder
{ {
CListBuilder builder; nix::ListBuilder builder;
}; };
struct nix_string_return struct nix_string_return

View File

@ -263,7 +263,8 @@ Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalSta
assert(v.type() == nix::nList); assert(v.type() == nix::nList);
auto * p = v.listElems()[ix]; auto * p = v.listElems()[ix];
nix_gc_incref(nullptr, p); nix_gc_incref(nullptr, p);
state->state.forceValue(*p, nix::noPos); if (p != nullptr)
state->state.forceValue(*p, nix::noPos);
return (Value *) p; return (Value *) p;
} }
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL
@ -417,7 +418,7 @@ ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state,
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
try { try {
auto builder = CListBuilder(capacity); auto builder = state->state.buildList(capacity);
return new return new
#if HAVE_BOEHMGC #if HAVE_BOEHMGC
(NoGC) (NoGC)
@ -427,20 +428,21 @@ ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state,
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL
} }
nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, Value * value) nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, Value * value)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
try { try {
list_builder->builder.push_back((nix::Value *) value); auto & e = check_value_not_null(value);
list_builder->builder[index] = &e;
} }
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
void nix_list_builder_free(ListBuilder * bb) void nix_list_builder_free(ListBuilder * list_builder)
{ {
#if HAVE_BOEHMGC #if HAVE_BOEHMGC
GC_FREE(bb); GC_FREE(list_builder);
#else #else
delete bb; delete bb;
#endif #endif
@ -452,7 +454,7 @@ nix_err nix_make_list(nix_c_context * context, EvalState * s, ListBuilder * list
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
try { try {
auto & v = check_value_not_null(value); auto & v = check_value_not_null(value);
list_builder->builder.finish(&(s->state), &v); v.mkList(list_builder->builder);
} }
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }

View File

@ -360,17 +360,18 @@ ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state,
/** @brief Insert bindings into a builder /** @brief Insert bindings into a builder
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[in] list_builder ListBuilder to insert into * @param[in] list_builder ListBuilder to insert into
* @param[in] index index to manipulate
* @param[in] value value to insert * @param[in] value value to insert
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, Value * value); nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, Value * value);
/** @brief Free a list builder /** @brief Free a list builder
* *
* Does not fail. * Does not fail.
* @param[in] builder the builder to free * @param[in] builder the builder to free
*/ */
void nix_list_builder_free(ListBuilder * builder); void nix_list_builder_free(ListBuilder * list_builder);
/** @brief Create an attribute set from a bindings builder /** @brief Create an attribute set from a bindings builder
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information

View File

@ -77,12 +77,13 @@ TEST_F(nix_api_expr_test, nix_build_and_init_list)
Value * intValue = nix_alloc_value(nullptr, state); Value * intValue = nix_alloc_value(nullptr, state);
nix_init_int(nullptr, intValue, 42); nix_init_int(nullptr, intValue, 42);
nix_list_builder_insert(nullptr, builder, intValue); nix_list_builder_insert(nullptr, builder, 0, intValue);
nix_make_list(nullptr, state, builder, value); nix_make_list(nullptr, state, builder, value);
nix_list_builder_free(builder); nix_list_builder_free(builder);
ASSERT_EQ(42, nix_get_int(nullptr, nix_get_list_byidx(nullptr, value, state, 0))); ASSERT_EQ(42, nix_get_int(nullptr, nix_get_list_byidx(nullptr, value, state, 0)));
ASSERT_EQ(1, nix_get_list_size(nullptr, value)); ASSERT_EQ(nullptr, nix_get_list_byidx(nullptr, value, state, 1));
ASSERT_EQ(10, nix_get_list_size(nullptr, value));
ASSERT_STREQ("a list", nix_get_typename(nullptr, value)); ASSERT_STREQ("a list", nix_get_typename(nullptr, value));
ASSERT_EQ(NIX_TYPE_LIST, nix_get_type(nullptr, value)); ASSERT_EQ(NIX_TYPE_LIST, nix_get_type(nullptr, value));