C API: Consolidate initializers

This commit is contained in:
José Luis Lafuente 2024-02-22 00:09:15 +01:00 committed by José Luis Lafuente
parent 51ff547d9a
commit dfdb90dc8e
No known key found for this signature in database
GPG key ID: 8A3455EBE455489A
3 changed files with 183 additions and 62 deletions

View file

@ -17,6 +17,32 @@
#include "gc_cpp.h" #include "gc_cpp.h"
#endif #endif
class ListBuilder
{
private:
std::vector<nix::Value *> values;
public:
ListBuilder(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;
}
};
// Helper function to throw an exception if value is null // Helper function to throw an exception if value is null
static const nix::Value & check_value_not_null(const Value * value) static const nix::Value & check_value_not_null(const Value * value)
{ {
@ -334,7 +360,7 @@ const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * valu
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL
} }
nix_err nix_set_bool(nix_c_context * context, Value * value, bool b) nix_err nix_init_bool(nix_c_context * context, Value * value, bool b)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -346,7 +372,7 @@ nix_err nix_set_bool(nix_c_context * context, Value * value, bool b)
} }
// todo string context // todo string context
nix_err nix_set_string(nix_c_context * context, Value * value, const char * str) nix_err nix_init_string(nix_c_context * context, Value * value, const char * str)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -357,7 +383,7 @@ nix_err nix_set_string(nix_c_context * context, Value * value, const char * str)
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
nix_err nix_set_path_string(nix_c_context * context, Value * value, const char * str) nix_err nix_init_path_string(nix_c_context * context, Value * value, const char * str)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -368,7 +394,7 @@ nix_err nix_set_path_string(nix_c_context * context, Value * value, const char *
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
nix_err nix_set_float(nix_c_context * context, Value * value, double d) nix_err nix_init_float(nix_c_context * context, Value * value, double d)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -379,7 +405,7 @@ nix_err nix_set_float(nix_c_context * context, Value * value, double d)
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
nix_err nix_set_int(nix_c_context * context, Value * value, int64_t i) nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -390,7 +416,7 @@ nix_err nix_set_int(nix_c_context * context, Value * value, int64_t i)
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
nix_err nix_set_null(nix_c_context * context, Value * value) nix_err nix_init_null(nix_c_context * context, Value * value)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -401,7 +427,7 @@ nix_err nix_set_null(nix_c_context * context, Value * value)
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
nix_err nix_set_external(nix_c_context * context, Value * value, ExternalValue * val) nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue * val)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -413,31 +439,52 @@ nix_err nix_set_external(nix_c_context * context, Value * value, ExternalValue *
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
nix_err nix_make_list(nix_c_context * context, EvalState * s, Value * value, unsigned int size) ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state, size_t capacity)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto builder = ListBuilder(capacity);
return new
#if HAVE_BOEHMGC
(NoGC)
#endif
ListBuilder{std::move(builder)};
}
NIXC_CATCH_ERRS_NULL
}
nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * builder, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
builder->push_back((nix::Value *) value);
}
NIXC_CATCH_ERRS
}
void nix_list_builder_free(ListBuilder * bb)
{
#if HAVE_BOEHMGC
GC_FREE(bb);
#else
delete bb;
#endif
}
nix_err nix_make_list(nix_c_context * context, EvalState * s, Value * value, ListBuilder * b)
{ {
if (context) if (context)
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);
s->state.mkList(v, size); b->finish(&(s->state), &v);
} }
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
nix_err nix_set_list_byidx(nix_c_context * context, Value * value, unsigned int ix, Value * elem) nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * p)
{
if (context)
context->last_err_code = NIX_OK;
try {
// todo: assert that this is a list
auto & v = check_value_not_null(value);
auto & e = check_value_not_null(elem);
v.listElems()[ix] = &e;
}
NIXC_CATCH_ERRS
}
nix_err nix_set_primop(nix_c_context * context, Value * value, PrimOp * p)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -486,14 +533,14 @@ BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState *
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL
} }
nix_err nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * b, const char * name, Value * value) nix_err nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * bb, const char * name, Value * value)
{ {
if (context) if (context)
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);
nix::Symbol s = b->builder.state.symbols.create(name); nix::Symbol s = bb->builder.state.symbols.create(name);
b->builder.insert(s, &v); bb->builder.insert(s, &v);
} }
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }

View file

@ -46,6 +46,8 @@ typedef struct EvalState EvalState;
*/ */
typedef struct BindingsBuilder BindingsBuilder; typedef struct BindingsBuilder BindingsBuilder;
typedef class ListBuilder ListBuilder;
/** @brief PrimOp function /** @brief PrimOp function
* @ingroup primops * @ingroup primops
* *
@ -73,7 +75,7 @@ typedef struct ExternalValue ExternalValue;
* @param[in] args list of arguments. Note that these can be thunks and should be forced using nix_value_force before * @param[in] args list of arguments. Note that these can be thunks and should be forced using nix_value_force before
* use. * use.
* @param[out] ret return value * @param[out] ret return value
* @see nix_alloc_primop, nix_set_primop * @see nix_alloc_primop, nix_init_primop
*/ */
typedef void (*PrimOpFun)(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret); typedef void (*PrimOpFun)(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret);
@ -90,7 +92,7 @@ typedef void (*PrimOpFun)(void * user_data, nix_c_context * context, EvalState *
* @param[in] doc optional, documentation for this primop * @param[in] doc optional, documentation for this primop
* @param[in] user_data optional, arbitrary data, passed to the callback when it's called * @param[in] user_data optional, arbitrary data, passed to the callback when it's called
* @return primop, or null in case of errors * @return primop, or null in case of errors
* @see nix_set_primop * @see nix_init_primop
*/ */
PrimOp * nix_alloc_primop( PrimOp * nix_alloc_primop(
nix_c_context * context, nix_c_context * context,
@ -162,6 +164,7 @@ bool nix_get_bool(nix_c_context * context, const Value * value);
* @return NULL in case of error. * @return NULL in case of error.
*/ */
const char * nix_get_string(nix_c_context * context, const Value * value); const char * nix_get_string(nix_c_context * context, const Value * value);
/** @brief Get path as string /** @brief Get path as string
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect * @param[in] value Nix value to inspect
@ -169,30 +172,35 @@ const char * nix_get_string(nix_c_context * context, const Value * value);
* @return NULL in case of error. * @return NULL in case of error.
*/ */
const char * nix_get_path_string(nix_c_context * context, const Value * value); const char * nix_get_path_string(nix_c_context * context, const Value * value);
/** @brief Get the length of a list /** @brief Get the length of a list
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect * @param[in] value Nix value to inspect
* @return length of list, error info via context * @return length of list, error info via context
*/ */
unsigned int nix_get_list_size(nix_c_context * context, const Value * value); unsigned int nix_get_list_size(nix_c_context * context, const Value * value);
/** @brief Get the element count of an attrset /** @brief Get the element count of an attrset
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect * @param[in] value Nix value to inspect
* @return attrset element count, error info via context * @return attrset element count, error info via context
*/ */
unsigned int nix_get_attrs_size(nix_c_context * context, const Value * value); unsigned int nix_get_attrs_size(nix_c_context * context, const Value * value);
/** @brief Get float value in 64 bits /** @brief Get float value in 64 bits
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect * @param[in] value Nix value to inspect
* @return float contents, error info via context * @return float contents, error info via context
*/ */
double nix_get_float(nix_c_context * context, const Value * value); double nix_get_float(nix_c_context * context, const Value * value);
/** @brief Get int value /** @brief Get int value
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect * @param[in] value Nix value to inspect
* @return int contents, error info via context * @return int contents, error info via context
*/ */
int64_t nix_get_int(nix_c_context * context, const Value * value); int64_t nix_get_int(nix_c_context * context, const Value * value);
/** @brief Get external reference /** @brief Get external reference
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect * @param[in] value Nix value to inspect
@ -210,6 +218,7 @@ ExternalValue * nix_get_external(nix_c_context * context, Value *);
* @return value, NULL in case of errors * @return value, NULL in case of errors
*/ */
Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int ix); Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int ix);
/** @brief Get an attr by name /** @brief Get an attr by name
* *
* Owned by the GC. Use nix_gc_decref when you're done with the pointer * Owned by the GC. Use nix_gc_decref when you're done with the pointer
@ -257,8 +266,9 @@ nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * sta
* @return name, NULL in case of errors * @return name, NULL in case of errors
*/ */
const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i); const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i);
/**@}*/ /**@}*/
/** @name Setters /** @name Initializers
*/ */
/**@{*/ /**@{*/
/** @brief Set boolean value /** @brief Set boolean value
@ -267,66 +277,82 @@ const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * valu
* @param[in] b the boolean value * @param[in] b the boolean value
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_set_bool(nix_c_context * context, Value * value, bool b); nix_err nix_init_bool(nix_c_context * context, Value * value, bool b);
/** @brief Set a string /** @brief Set a string
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
* @param[in] str the string, copied * @param[in] str the string, copied
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_set_string(nix_c_context * context, Value * value, const char * str); nix_err nix_init_string(nix_c_context * context, Value * value, const char * str);
/** @brief Set a path /** @brief Set a path
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
* @param[in] str the path string, copied * @param[in] str the path string, copied
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_set_path_string(nix_c_context * context, Value * value, const char * str); nix_err nix_init_path_string(nix_c_context * context, Value * value, const char * str);
/** @brief Set a float /** @brief Set a float
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
* @param[in] d the float, 64-bits * @param[in] d the float, 64-bits
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_set_float(nix_c_context * context, Value * value, double d); nix_err nix_init_float(nix_c_context * context, Value * value, double d);
/** @brief Set an int /** @brief Set an int
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
* @param[in] i the int * @param[in] i the int
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_set_int(nix_c_context * context, Value * value, int64_t i);
nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i);
/** @brief Set null /** @brief Set null
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_set_null(nix_c_context * context, Value * value);
nix_err nix_init_null(nix_c_context * context, Value * value);
/** @brief Set an external value /** @brief Set an external value
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
* @param[in] val the external value to set. Will be GC-referenced by the value. * @param[in] val the external value to set. Will be GC-referenced by the value.
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_set_external(nix_c_context * context, Value * value, ExternalValue * val); nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue * val);
/** @brief Allocate a list
/** @brief Create a list from a list builder
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
* @param[in] size size of list * @param[in] b list builder to use. Make sure to unref this afterwards.
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_make_list(nix_c_context * context, EvalState * s, Value * value, unsigned int size); nix_err nix_make_list(nix_c_context * context, EvalState * s, Value * value, ListBuilder * b);
/** @brief Manipulate a list by index
/** @brief Create a list builder
* @param[out] context Optional, stores error information
* @param[in] state nix evaluator state
* @param[in] capacity how many bindings you'll add. Don't exceed.
* @return owned reference to a list builder. Make sure to unref when you're done.
*/
ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state, size_t capacity);
/** @brief Insert bindings into a builder
* @param[out] context Optional, stores error information
* @param[in] builder ListBuilder to insert into
* @param[in] value value to insert
* @return error code, NIX_OK on success.
*/
nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * builder, Value * value);
/** @brief Free a list builder
* *
* Don't do this mid-computation. * Does not fail.
* @pre your list should be at least 'ix+1' items long * @param[in] builder the builder to free
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] ix index to manipulate
* @param[in] elem the value to set, will be gc-referenced by the value
* @return error code, NIX_OK on success.
*/ */
nix_err nix_set_list_byidx(nix_c_context * context, Value * value, unsigned int ix, Value * elem); void nix_list_builder_free(ListBuilder * 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
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
@ -334,6 +360,7 @@ nix_err nix_set_list_byidx(nix_c_context * context, Value * value, unsigned int
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder * b); nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder * b);
/** @brief Set primop /** @brief Set primop
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
@ -341,7 +368,7 @@ nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder *
* @see nix_alloc_primop * @see nix_alloc_primop
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_set_primop(nix_c_context * context, Value * value, PrimOp * op); nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * op);
/** @brief Copy from another value /** @brief Copy from another value
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[out] value Nix value to modify * @param[out] value Nix value to modify
@ -352,7 +379,6 @@ nix_err nix_copy_value(nix_c_context * context, Value * value, Value * source);
/**@}*/ /**@}*/
/** @brief Create a bindings builder /** @brief Create a bindings builder
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[in] state nix evaluator state * @param[in] state nix evaluator state
* @param[in] capacity how many bindings you'll add. Don't exceed. * @param[in] capacity how many bindings you'll add. Don't exceed.
@ -360,6 +386,7 @@ nix_err nix_copy_value(nix_c_context * context, Value * value, Value * source);
done. done.
*/ */
BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState * state, size_t capacity); BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState * state, size_t capacity);
/** @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] builder BindingsBuilder to insert into * @param[in] builder BindingsBuilder to insert into
@ -369,6 +396,7 @@ BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState *
*/ */
nix_err nix_err
nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * builder, const char * name, Value * value); nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * builder, const char * name, Value * value);
/** @brief Free a bindings builder /** @brief Free a bindings builder
* *
* Does not fail. * Does not fail.

View file

@ -7,6 +7,7 @@
#include "tests/nix_api_store.hh" #include "tests/nix_api_store.hh"
#include <cstdlib>
#include <gtest/gtest.h> #include <gtest/gtest.h>
namespace nixC { namespace nixC {
@ -32,30 +33,75 @@ public:
TEST_F(nix_api_value_test, nix_value_set_get_int) TEST_F(nix_api_value_test, nix_value_set_get_int)
{ {
int myInt = 1; int myInt = 1;
nix_set_int(nullptr, value, myInt); nix_init_int(nullptr, value, myInt);
ASSERT_EQ(myInt, nix_get_int(nullptr, value)); ASSERT_EQ(myInt, nix_get_int(nullptr, value));
} }
TEST_F(nix_api_value_test, nix_value_make_list) TEST_F(nix_api_value_test, nix_make_and_set_list)
{ {
int size = 10; int size = 10;
nix_make_list(nullptr, state, value, size); ListBuilder * builder = nix_make_list_builder(nullptr, state, size);
ASSERT_EQ(size, nix_get_list_size(nullptr, value));
}
TEST_F(nix_api_value_test, nix_value_set_get_list)
{
int size = 10;
nix_make_list(nullptr, state, value, size);
Value * intValue = nix_alloc_value(nullptr, state); Value * intValue = nix_alloc_value(nullptr, state);
nix_set_int(nullptr, intValue, 42); nix_init_int(nullptr, intValue, 42);
nix_set_list_byidx(nullptr, value, 0, intValue); nix_list_builder_insert(nullptr, builder, intValue);
nix_make_list(nullptr, state, value, 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));
// Clean up // Clean up
nix_gc_decref(nullptr, intValue); nix_gc_decref(nullptr, intValue);
} }
TEST_F(nix_api_value_test, nix_make_attrs_t)
{
int size = 10;
const char ** out_name = (const char **) malloc(sizeof(char *));
BindingsBuilder * builder = nix_make_bindings_builder(nullptr, state, size);
Value * intValue = nix_alloc_value(nullptr, state);
nix_init_int(nullptr, intValue, 42);
Value * stringValue = nix_alloc_value(nullptr, state);
nix_init_string(nullptr, stringValue, "foo");
nix_bindings_builder_insert(nullptr, builder, "a", intValue);
nix_bindings_builder_insert(nullptr, builder, "b", stringValue);
nix_make_attrs(nullptr, value, builder);
nix_bindings_builder_free(builder);
ASSERT_EQ(2, nix_get_attrs_size(nullptr, value));
Value * out_value = nix_get_attr_byname(nullptr, value, state, "a");
ASSERT_EQ(42, nix_get_int(nullptr, out_value));
nix_gc_decref(nullptr, out_value);
out_value = nix_get_attr_byidx(nullptr, value, state, 0, out_name);
ASSERT_EQ(42, nix_get_int(nullptr, out_value));
ASSERT_STREQ("a", *out_name);
nix_gc_decref(nullptr, out_value);
ASSERT_STREQ("a", nix_get_attr_name_byidx(nullptr, value, state, 0));
out_value = nix_get_attr_byname(nullptr, value, state, "b");
ASSERT_STREQ("foo", nix_get_string(nullptr, out_value));
nix_gc_decref(nullptr, out_value);
out_value = nix_get_attr_byidx(nullptr, value, state, 1, out_name);
ASSERT_STREQ("foo", nix_get_string(nullptr, out_value));
ASSERT_STREQ("b", *out_name);
nix_gc_decref(nullptr, out_value);
ASSERT_STREQ("b", nix_get_attr_name_byidx(nullptr, value, state, 1));
// Clean up
nix_gc_decref(nullptr, intValue);
nix_gc_decref(nullptr, stringValue);
free(out_name);
}
} }