diff --git a/src/libexpr-c/nix_api_expr.cc b/src/libexpr-c/nix_api_expr.cc index b86d745db..bdf7a1e63 100644 --- a/src/libexpr-c/nix_api_expr.cc +++ b/src/libexpr-c/nix_api_expr.cc @@ -42,56 +42,56 @@ nix_err nix_libexpr_init(nix_c_context * context) } nix_err nix_expr_eval_from_string( - nix_c_context * context, EvalState * state, const char * expr, const char * path, Value * value) + nix_c_context * context, EvalState * state, const char * expr, const char * path, nix_value * value) { if (context) context->last_err_code = NIX_OK; try { nix::Expr * parsedExpr = state->state.parseExprFromString(expr, state->state.rootPath(nix::CanonPath(path))); - state->state.eval(parsedExpr, *(nix::Value *) value); - state->state.forceValue(*(nix::Value *) value, nix::noPos); + state->state.eval(parsedExpr, value->value); + state->state.forceValue(value->value, nix::noPos); } NIXC_CATCH_ERRS } -nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, Value * arg, Value * value) +nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, nix_value * arg, nix_value * value) { if (context) context->last_err_code = NIX_OK; try { - state->state.callFunction(*(nix::Value *) fn, *(nix::Value *) arg, *(nix::Value *) value, nix::noPos); - state->state.forceValue(*(nix::Value *) value, nix::noPos); + state->state.callFunction(fn->value, arg->value, value->value, nix::noPos); + state->state.forceValue(value->value, nix::noPos); } NIXC_CATCH_ERRS } -nix_err nix_value_call_multi(nix_c_context * context, EvalState * state, Value * fn, size_t nargs, Value ** args, Value * value) +nix_err nix_value_call_multi(nix_c_context * context, EvalState * state, nix_value * fn, size_t nargs, nix_value ** args, nix_value * value) { if (context) context->last_err_code = NIX_OK; try { - state->state.callFunction(*(nix::Value *) fn, nargs, (nix::Value * *)args, *(nix::Value *) value, nix::noPos); - state->state.forceValue(*(nix::Value *) value, nix::noPos); + state->state.callFunction(fn->value, nargs, (nix::Value * *)args, value->value, nix::noPos); + state->state.forceValue(value->value, nix::noPos); } NIXC_CATCH_ERRS } -nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * value) +nix_err nix_value_force(nix_c_context * context, EvalState * state, nix_value * value) { if (context) context->last_err_code = NIX_OK; try { - state->state.forceValue(*(nix::Value *) value, nix::noPos); + state->state.forceValue(value->value, nix::noPos); } NIXC_CATCH_ERRS } -nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value * value) +nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_value * value) { if (context) context->last_err_code = NIX_OK; try { - state->state.forceValueDeep(*(nix::Value *) value); + state->state.forceValueDeep(value->value); } NIXC_CATCH_ERRS } @@ -181,6 +181,15 @@ nix_err nix_gc_decref(nix_c_context * context, const void *) void nix_gc_now() {} #endif +nix_err nix_value_incref(nix_c_context * context, nix_value *x) +{ + return nix_gc_incref(context, (const void *) x); +} +nix_err nix_value_decref(nix_c_context * context, nix_value *x) +{ + return nix_gc_decref(context, (const void *) x); +} + void nix_gc_register_finalizer(void * obj, void * cd, void (*finalizer)(void * obj, void * cd)) { #ifdef HAVE_BOEHMGC diff --git a/src/libexpr-c/nix_api_expr.h b/src/libexpr-c/nix_api_expr.h index cb6c00385..adf8b65b1 100644 --- a/src/libexpr-c/nix_api_expr.h +++ b/src/libexpr-c/nix_api_expr.h @@ -29,14 +29,23 @@ extern "C" { * @see nix_state_create */ typedef struct EvalState EvalState; // nix::EvalState -/** - * @brief Represents a value in the Nix language. + +/** @brief A Nix language value, or thunk that may evaluate to a value. + * + * Values are the primary objects manipulated in the Nix language. + * They are considered to be immutable from a user's perspective, but the process of evaluating a value changes its + * ValueType if it was a thunk. After a value has been evaluated, its ValueType does not change. + * + * Evaluation in this context refers to the process of evaluating a single value object, also called "forcing" the + * value; see `nix_value_force`. + * + * The evaluator manages its own memory, but your use of the C API must follow the reference counting rules. * - * Owned by the garbage collector. - * @struct Value * @see value_manip + * @see nix_value_incref, nix_value_decref */ -typedef void Value; // nix::Value +typedef struct nix_value nix_value; +[[deprecated("use nix_value instead")]] typedef nix_value Value; // Function prototypes /** @@ -65,7 +74,7 @@ nix_err nix_libexpr_init(nix_c_context * context); * @return NIX_OK if the evaluation was successful, an error code otherwise. */ nix_err nix_expr_eval_from_string( - nix_c_context * context, EvalState * state, const char * expr, const char * path, Value * value); + nix_c_context * context, EvalState * state, const char * expr, const char * path, nix_value * value); /** * @brief Calls a Nix function with an argument. @@ -79,7 +88,7 @@ nix_err nix_expr_eval_from_string( * @see nix_init_apply() for a similar function that does not performs the call immediately, but stores it as a thunk. * Note the different argument order. */ -nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, Value * arg, Value * value); +nix_err nix_value_call(nix_c_context * context, EvalState * state, nix_value * fn, nix_value * arg, nix_value * value); /** * @brief Calls a Nix function with multiple arguments. @@ -98,7 +107,7 @@ nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, V * @see NIX_VALUE_CALL For a macro that wraps this function for convenience. */ nix_err nix_value_call_multi( - nix_c_context * context, EvalState * state, Value * fn, size_t nargs, Value ** args, Value * value); + nix_c_context * context, EvalState * state, nix_value * fn, size_t nargs, nix_value ** args, nix_value * value); /** * @brief Calls a Nix function with multiple arguments. @@ -116,7 +125,7 @@ nix_err nix_value_call_multi( */ #define NIX_VALUE_CALL(context, state, value, fn, ...) \ do { \ - Value * args_array[] = {__VA_ARGS__}; \ + nix_value * args_array[] = {__VA_ARGS__}; \ size_t nargs = sizeof(args_array) / sizeof(args_array[0]); \ nix_value_call_multi(context, state, fn, nargs, args_array, value); \ } while (0) @@ -124,12 +133,10 @@ nix_err nix_value_call_multi( /** * @brief Forces the evaluation of a Nix value. * - * The Nix interpreter is lazy, and not-yet-evaluated Values can be + * The Nix interpreter is lazy, and not-yet-evaluated values can be * of type NIX_TYPE_THUNK instead of their actual value. * - * This function converts these Values into their final type. - * - * @note This function is mainly needed before calling @ref getters, but not for API calls that return a `Value`. + * This function mutates such a `nix_value`, so that, if successful, it has its final type. * * @param[out] context Optional, stores error information * @param[in] state The state of the evaluation. @@ -138,7 +145,7 @@ nix_err nix_value_call_multi( * @return NIX_OK if the force operation was successful, an error code * otherwise. */ -nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * value); +nix_err nix_value_force(nix_c_context * context, EvalState * state, nix_value * value); /** * @brief Forces the deep evaluation of a Nix value. @@ -154,7 +161,7 @@ nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * valu * @return NIX_OK if the deep force operation was successful, an error code * otherwise. */ -nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value * value); +nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_value * value); /** * @brief Create a new Nix language evaluator state. @@ -188,6 +195,11 @@ void nix_state_free(EvalState * state); * you're done with a value returned by the evaluator. * @{ */ + +// TODO: Deprecate nix_gc_incref in favor of the type-specific reference counting functions? +// e.g. nix_value_incref. +// It gives implementors more flexibility, and adds safety, so that generated +// bindings can be used without fighting the host type system (where applicable). /** * @brief Increment the garbage collector reference counter for the given object. * diff --git a/src/libexpr-c/nix_api_expr_internal.h b/src/libexpr-c/nix_api_expr_internal.h index 7743849fd..5a875ef39 100644 --- a/src/libexpr-c/nix_api_expr_internal.h +++ b/src/libexpr-c/nix_api_expr_internal.h @@ -20,6 +20,11 @@ struct ListBuilder nix::ListBuilder builder; }; +struct nix_value +{ + nix::Value value; +}; + struct nix_string_return { std::string str; diff --git a/src/libexpr-c/nix_api_value.cc b/src/libexpr-c/nix_api_value.cc index 978cf7f43..2f2f99617 100644 --- a/src/libexpr-c/nix_api_value.cc +++ b/src/libexpr-c/nix_api_value.cc @@ -21,49 +21,54 @@ #endif // Internal helper functions to check [in] and [out] `Value *` parameters -static const nix::Value & check_value_not_null(const Value * value) +static const nix::Value & check_value_not_null(const nix_value * value) { if (!value) { - throw std::runtime_error("Value is null"); + throw std::runtime_error("nix_value is null"); } return *((const nix::Value *) value); } -static nix::Value & check_value_not_null(Value * value) +static nix::Value & check_value_not_null(nix_value * value) { if (!value) { - throw std::runtime_error("Value is null"); + throw std::runtime_error("nix_value is null"); } - return *((nix::Value *) value); + return value->value; } -static const nix::Value & check_value_in(const Value * value) +static const nix::Value & check_value_in(const nix_value * value) { auto & v = check_value_not_null(value); if (!v.isValid()) { - throw std::runtime_error("Uninitialized Value"); + throw std::runtime_error("Uninitialized nix_value"); } return v; } -static nix::Value & check_value_in(Value * value) +static nix::Value & check_value_in(nix_value * value) { auto & v = check_value_not_null(value); if (!v.isValid()) { - throw std::runtime_error("Uninitialized Value"); + throw std::runtime_error("Uninitialized nix_value"); } return v; } -static nix::Value & check_value_out(Value * value) +static nix::Value & check_value_out(nix_value * value) { auto & v = check_value_not_null(value); if (v.isValid()) { - throw std::runtime_error("Value already initialized. Variables are immutable"); + throw std::runtime_error("nix_value already initialized. Variables are immutable"); } return v; } +static inline nix_value * as_nix_value_ptr(nix::Value * v) +{ + return reinterpret_cast(v); +} + /** * Helper function to convert calls from nix into C API. * @@ -87,7 +92,7 @@ static void nix_c_primop_wrapper( // or maybe something to make blackholes work better; we don't know). nix::Value vTmp; - f(userdata, &ctx, (EvalState *) &state, (Value **) args, (Value *) &vTmp); + f(userdata, &ctx, (EvalState *) &state, (nix_value **) args, (nix_value *) &vTmp); if (ctx.last_err_code != NIX_OK) { /* TODO: Throw different errors depending on the error code */ @@ -154,19 +159,19 @@ nix_err nix_register_primop(nix_c_context * context, PrimOp * primOp) NIXC_CATCH_ERRS } -Value * nix_alloc_value(nix_c_context * context, EvalState * state) +nix_value * nix_alloc_value(nix_c_context * context, EvalState * state) { if (context) context->last_err_code = NIX_OK; try { - Value * res = state->state.allocValue(); + nix_value * res = as_nix_value_ptr(state->state.allocValue()); nix_gc_incref(nullptr, res); return res; } NIXC_CATCH_ERRS_NULL } -ValueType nix_get_type(nix_c_context * context, const Value * value) +ValueType nix_get_type(nix_c_context * context, const nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -202,7 +207,7 @@ ValueType nix_get_type(nix_c_context * context, const Value * value) NIXC_CATCH_ERRS_RES(NIX_TYPE_NULL); } -const char * nix_get_typename(nix_c_context * context, const Value * value) +const char * nix_get_typename(nix_c_context * context, const nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -214,7 +219,7 @@ const char * nix_get_typename(nix_c_context * context, const Value * value) NIXC_CATCH_ERRS_NULL } -bool nix_get_bool(nix_c_context * context, const Value * value) +bool nix_get_bool(nix_c_context * context, const nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -226,7 +231,8 @@ bool nix_get_bool(nix_c_context * context, const Value * value) NIXC_CATCH_ERRS_RES(false); } -nix_err nix_get_string(nix_c_context * context, const Value * value, nix_get_string_callback callback, void * user_data) +nix_err +nix_get_string(nix_c_context * context, const nix_value * value, nix_get_string_callback callback, void * user_data) { if (context) context->last_err_code = NIX_OK; @@ -238,7 +244,7 @@ nix_err nix_get_string(nix_c_context * context, const Value * value, nix_get_str NIXC_CATCH_ERRS } -const char * nix_get_path_string(nix_c_context * context, const Value * value) +const char * nix_get_path_string(nix_c_context * context, const nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -257,7 +263,7 @@ const char * nix_get_path_string(nix_c_context * context, const Value * value) NIXC_CATCH_ERRS_NULL } -unsigned int nix_get_list_size(nix_c_context * context, const Value * value) +unsigned int nix_get_list_size(nix_c_context * context, const nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -269,7 +275,7 @@ unsigned int nix_get_list_size(nix_c_context * context, const Value * value) NIXC_CATCH_ERRS_RES(0); } -unsigned int nix_get_attrs_size(nix_c_context * context, const Value * value) +unsigned int nix_get_attrs_size(nix_c_context * context, const nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -281,7 +287,7 @@ unsigned int nix_get_attrs_size(nix_c_context * context, const Value * value) NIXC_CATCH_ERRS_RES(0); } -double nix_get_float(nix_c_context * context, const Value * value) +double nix_get_float(nix_c_context * context, const nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -293,7 +299,7 @@ double nix_get_float(nix_c_context * context, const Value * value) NIXC_CATCH_ERRS_RES(0.0); } -int64_t nix_get_int(nix_c_context * context, const Value * value) +int64_t nix_get_int(nix_c_context * context, const nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -305,7 +311,7 @@ int64_t nix_get_int(nix_c_context * context, const Value * value) NIXC_CATCH_ERRS_RES(0); } -ExternalValue * nix_get_external(nix_c_context * context, Value * value) +ExternalValue * nix_get_external(nix_c_context * context, nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -317,7 +323,7 @@ ExternalValue * nix_get_external(nix_c_context * context, Value * value) NIXC_CATCH_ERRS_NULL; } -Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int ix) +nix_value * nix_get_list_byidx(nix_c_context * context, const nix_value * value, EvalState * state, unsigned int ix) { if (context) context->last_err_code = NIX_OK; @@ -328,12 +334,12 @@ Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalSta nix_gc_incref(nullptr, p); if (p != nullptr) state->state.forceValue(*p, nix::noPos); - return (Value *) p; + return as_nix_value_ptr(p); } NIXC_CATCH_ERRS_NULL } -Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name) +nix_value * nix_get_attr_byname(nix_c_context * context, const nix_value * value, EvalState * state, const char * name) { if (context) context->last_err_code = NIX_OK; @@ -345,7 +351,7 @@ Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalSt if (attr) { nix_gc_incref(nullptr, attr->value); state->state.forceValue(*attr->value, nix::noPos); - return attr->value; + return as_nix_value_ptr(attr->value); } nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute"); return nullptr; @@ -353,7 +359,7 @@ Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalSt NIXC_CATCH_ERRS_NULL } -bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name) +bool nix_has_attr_byname(nix_c_context * context, const nix_value * value, EvalState * state, const char * name) { if (context) context->last_err_code = NIX_OK; @@ -369,8 +375,8 @@ bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState NIXC_CATCH_ERRS_RES(false); } -Value * -nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i, const char ** name) +nix_value * nix_get_attr_byidx( + nix_c_context * context, const nix_value * value, EvalState * state, unsigned int i, const char ** name) { if (context) context->last_err_code = NIX_OK; @@ -380,12 +386,13 @@ nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * sta *name = ((const std::string &) (state->state.symbols[a.name])).c_str(); nix_gc_incref(nullptr, a.value); state->state.forceValue(*a.value, nix::noPos); - return a.value; + return as_nix_value_ptr(a.value); } NIXC_CATCH_ERRS_NULL } -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 nix_value * value, EvalState * state, unsigned int i) { if (context) context->last_err_code = NIX_OK; @@ -397,7 +404,7 @@ const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * valu NIXC_CATCH_ERRS_NULL } -nix_err nix_init_bool(nix_c_context * context, Value * value, bool b) +nix_err nix_init_bool(nix_c_context * context, nix_value * value, bool b) { if (context) context->last_err_code = NIX_OK; @@ -409,7 +416,7 @@ nix_err nix_init_bool(nix_c_context * context, Value * value, bool b) } // todo string context -nix_err nix_init_string(nix_c_context * context, Value * value, const char * str) +nix_err nix_init_string(nix_c_context * context, nix_value * value, const char * str) { if (context) context->last_err_code = NIX_OK; @@ -420,7 +427,7 @@ nix_err nix_init_string(nix_c_context * context, Value * value, const char * str NIXC_CATCH_ERRS } -nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * value, const char * str) +nix_err nix_init_path_string(nix_c_context * context, EvalState * s, nix_value * value, const char * str) { if (context) context->last_err_code = NIX_OK; @@ -431,7 +438,7 @@ nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * val NIXC_CATCH_ERRS } -nix_err nix_init_float(nix_c_context * context, Value * value, double d) +nix_err nix_init_float(nix_c_context * context, nix_value * value, double d) { if (context) context->last_err_code = NIX_OK; @@ -442,7 +449,7 @@ nix_err nix_init_float(nix_c_context * context, Value * value, double d) NIXC_CATCH_ERRS } -nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i) +nix_err nix_init_int(nix_c_context * context, nix_value * value, int64_t i) { if (context) context->last_err_code = NIX_OK; @@ -453,7 +460,7 @@ nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i) NIXC_CATCH_ERRS } -nix_err nix_init_null(nix_c_context * context, Value * value) +nix_err nix_init_null(nix_c_context * context, nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -464,7 +471,7 @@ nix_err nix_init_null(nix_c_context * context, Value * value) NIXC_CATCH_ERRS } -nix_err nix_init_apply(nix_c_context * context, Value * value, Value * fn, Value * arg) +nix_err nix_init_apply(nix_c_context * context, nix_value * value, nix_value * fn, nix_value * arg) { if (context) context->last_err_code = NIX_OK; @@ -477,7 +484,7 @@ nix_err nix_init_apply(nix_c_context * context, Value * value, Value * fn, Value NIXC_CATCH_ERRS } -nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue * val) +nix_err nix_init_external(nix_c_context * context, nix_value * value, ExternalValue * val) { if (context) context->last_err_code = NIX_OK; @@ -504,7 +511,8 @@ ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state, NIXC_CATCH_ERRS_NULL } -nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, Value * value) +nix_err +nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -524,7 +532,7 @@ void nix_list_builder_free(ListBuilder * list_builder) #endif } -nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, Value * value) +nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -535,7 +543,7 @@ nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, Value NIXC_CATCH_ERRS } -nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * p) +nix_err nix_init_primop(nix_c_context * context, nix_value * value, PrimOp * p) { if (context) context->last_err_code = NIX_OK; @@ -546,7 +554,7 @@ nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * p) NIXC_CATCH_ERRS } -nix_err nix_copy_value(nix_c_context * context, Value * value, const Value * source) +nix_err nix_copy_value(nix_c_context * context, nix_value * value, const nix_value * source) { if (context) context->last_err_code = NIX_OK; @@ -558,7 +566,7 @@ nix_err nix_copy_value(nix_c_context * context, Value * value, const Value * sou NIXC_CATCH_ERRS } -nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder * b) +nix_err nix_make_attrs(nix_c_context * context, nix_value * value, BindingsBuilder * b) { if (context) context->last_err_code = NIX_OK; @@ -584,7 +592,7 @@ BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState * NIXC_CATCH_ERRS_NULL } -nix_err nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * bb, const char * name, Value * value) +nix_err nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * bb, const char * name, nix_value * value) { if (context) context->last_err_code = NIX_OK; @@ -605,7 +613,7 @@ void nix_bindings_builder_free(BindingsBuilder * bb) #endif } -nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * state, Value * value, bool isIFD) +nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * state, nix_value * value, bool isIFD) { if (context) context->last_err_code = NIX_OK; diff --git a/src/libexpr-c/nix_api_value.h b/src/libexpr-c/nix_api_value.h index 244860707..044f68c9e 100644 --- a/src/libexpr-c/nix_api_value.h +++ b/src/libexpr-c/nix_api_value.h @@ -35,8 +35,11 @@ typedef enum { } ValueType; // forward declarations -typedef void Value; +typedef struct nix_value nix_value; typedef struct EvalState EvalState; + +[[deprecated("use nix_value instead")]] typedef nix_value Value; + // type defs /** @brief Stores an under-construction set of bindings * @ingroup value_manip @@ -90,7 +93,8 @@ typedef struct nix_realised_string nix_realised_string; * @param[out] ret return value * @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, nix_value ** args, nix_value * ret); /** @brief Allocate a PrimOp * @@ -142,10 +146,29 @@ nix_err nix_register_primop(nix_c_context * context, PrimOp * primOp); * @return value, or null in case of errors * */ -Value * nix_alloc_value(nix_c_context * context, EvalState * state); +nix_value * nix_alloc_value(nix_c_context * context, EvalState * state); + +/** + * @brief Increment the garbage collector reference counter for the given `nix_value`. + * + * The Nix language evaluator C API keeps track of alive objects by reference counting. + * When you're done with a refcounted pointer, call nix_value_decref(). + * + * @param[out] context Optional, stores error information + * @param[in] value The object to keep alive + */ +nix_err nix_value_incref(nix_c_context * context, nix_value * value); + +/** + * @brief Decrement the garbage collector reference counter for the given object + * + * @param[out] context Optional, stores error information + * @param[in] value The object to stop referencing + */ +nix_err nix_value_decref(nix_c_context * context, nix_value * value); /** @addtogroup value_manip Manipulating values - * @brief Functions to inspect and change Nix language values, represented by Value. + * @brief Functions to inspect and change Nix language values, represented by nix_value. * @{ */ /** @anchor getters @@ -157,7 +180,7 @@ Value * nix_alloc_value(nix_c_context * context, EvalState * state); * @param[in] value Nix value to inspect * @return type of nix value */ -ValueType nix_get_type(nix_c_context * context, const Value * value); +ValueType nix_get_type(nix_c_context * context, const nix_value * value); /** @brief Get type name of value as defined in the evaluator * @param[out] context Optional, stores error information @@ -165,14 +188,14 @@ ValueType nix_get_type(nix_c_context * context, const Value * value); * @return type name, owned string * @todo way to free the result */ -const char * nix_get_typename(nix_c_context * context, const Value * value); +const char * nix_get_typename(nix_c_context * context, const nix_value * value); /** @brief Get boolean value * @param[out] context Optional, stores error information * @param[in] value Nix value to inspect * @return true or false, error info via context */ -bool nix_get_bool(nix_c_context * context, const Value * value); +bool nix_get_bool(nix_c_context * context, const nix_value * value); /** @brief Get the raw string * @@ -186,7 +209,7 @@ bool nix_get_bool(nix_c_context * context, const Value * value); * @return error code, NIX_OK on success. */ nix_err -nix_get_string(nix_c_context * context, const Value * value, nix_get_string_callback callback, void * user_data); +nix_get_string(nix_c_context * context, const nix_value * value, nix_get_string_callback callback, void * user_data); /** @brief Get path as string * @param[out] context Optional, stores error information @@ -194,42 +217,42 @@ nix_get_string(nix_c_context * context, const Value * value, nix_get_string_call * @return string * @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 nix_value * value); /** @brief Get the length of a list * @param[out] context Optional, stores error information * @param[in] value Nix value to inspect * @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 nix_value * value); /** @brief Get the element count of an attrset * @param[out] context Optional, stores error information * @param[in] value Nix value to inspect * @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 nix_value * value); /** @brief Get float value in 64 bits * @param[out] context Optional, stores error information * @param[in] value Nix value to inspect * @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 nix_value * value); /** @brief Get int value * @param[out] context Optional, stores error information * @param[in] value Nix value to inspect * @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 nix_value * value); /** @brief Get external reference * @param[out] context Optional, stores error information * @param[in] value Nix value to inspect * @return reference to external, NULL in case of error */ -ExternalValue * nix_get_external(nix_c_context * context, Value *); +ExternalValue * nix_get_external(nix_c_context * context, nix_value *); /** @brief Get the ix'th element of a list * @@ -240,7 +263,7 @@ ExternalValue * nix_get_external(nix_c_context * context, Value *); * @param[in] ix list element to get * @return value, NULL in case of errors */ -Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int ix); +nix_value * nix_get_list_byidx(nix_c_context * context, const nix_value * value, EvalState * state, unsigned int ix); /** @brief Get an attr by name * @@ -251,7 +274,7 @@ Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalSta * @param[in] name attribute name * @return value, NULL in case of errors */ -Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name); +nix_value * nix_get_attr_byname(nix_c_context * context, const nix_value * value, EvalState * state, const char * name); /** @brief Check if an attribute name exists on a value * @param[out] context Optional, stores error information @@ -260,7 +283,7 @@ Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalSt * @param[in] name attribute name * @return value, error info via context */ -bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name); +bool nix_has_attr_byname(nix_c_context * context, const nix_value * value, EvalState * state, const char * name); /** @brief Get an attribute by index in the sorted bindings * @@ -274,8 +297,8 @@ bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState * @param[out] name will store a pointer to the attribute name * @return value, NULL in case of errors */ -Value * -nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i, const char ** name); +nix_value * nix_get_attr_byidx( + nix_c_context * context, const nix_value * value, EvalState * state, unsigned int i, const char ** name); /** @brief Get an attribute name by index in the sorted bindings * @@ -288,7 +311,8 @@ nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * sta * @param[in] i attribute index * @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 nix_value * value, EvalState * state, unsigned int i); /**@}*/ /** @name Initializers @@ -305,7 +329,7 @@ const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * valu * @param[in] b the boolean value * @return error code, NIX_OK on success. */ -nix_err nix_init_bool(nix_c_context * context, Value * value, bool b); +nix_err nix_init_bool(nix_c_context * context, nix_value * value, bool b); /** @brief Set a string * @param[out] context Optional, stores error information @@ -313,7 +337,7 @@ nix_err nix_init_bool(nix_c_context * context, Value * value, bool b); * @param[in] str the string, copied * @return error code, NIX_OK on success. */ -nix_err nix_init_string(nix_c_context * context, Value * value, const char * str); +nix_err nix_init_string(nix_c_context * context, nix_value * value, const char * str); /** @brief Set a path * @param[out] context Optional, stores error information @@ -321,7 +345,7 @@ nix_err nix_init_string(nix_c_context * context, Value * value, const char * str * @param[in] str the path string, copied * @return error code, NIX_OK on success. */ -nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * value, const char * str); +nix_err nix_init_path_string(nix_c_context * context, EvalState * s, nix_value * value, const char * str); /** @brief Set a float * @param[out] context Optional, stores error information @@ -329,7 +353,7 @@ nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * val * @param[in] d the float, 64-bits * @return error code, NIX_OK on success. */ -nix_err nix_init_float(nix_c_context * context, Value * value, double d); +nix_err nix_init_float(nix_c_context * context, nix_value * value, double d); /** @brief Set an int * @param[out] context Optional, stores error information @@ -338,13 +362,13 @@ nix_err nix_init_float(nix_c_context * context, Value * value, double d); * @return error code, NIX_OK on success. */ -nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i); +nix_err nix_init_int(nix_c_context * context, nix_value * value, int64_t i); /** @brief Set null * @param[out] context Optional, stores error information * @param[out] value Nix value to modify * @return error code, NIX_OK on success. */ -nix_err nix_init_null(nix_c_context * context, Value * value); +nix_err nix_init_null(nix_c_context * context, nix_value * value); /** @brief Set the value to a thunk that will perform a function application when needed. * @@ -360,7 +384,7 @@ nix_err nix_init_null(nix_c_context * context, Value * value); * @see nix_value_call() for a similar function that performs the call immediately and only stores the return value. * Note the different argument order. */ -nix_err nix_init_apply(nix_c_context * context, Value * value, Value * fn, Value * arg); +nix_err nix_init_apply(nix_c_context * context, nix_value * value, nix_value * fn, nix_value * arg); /** @brief Set an external value * @param[out] context Optional, stores error information @@ -368,7 +392,7 @@ nix_err nix_init_apply(nix_c_context * context, Value * value, Value * fn, Value * @param[in] val the external value to set. Will be GC-referenced by the value. * @return error code, NIX_OK on success. */ -nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue * val); +nix_err nix_init_external(nix_c_context * context, nix_value * value, ExternalValue * val); /** @brief Create a list from a list builder * @param[out] context Optional, stores error information @@ -376,7 +400,7 @@ nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue * @param[out] value Nix value to modify * @return error code, NIX_OK on success. */ -nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, Value * value); +nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, nix_value * value); /** @brief Create a list builder * @param[out] context Optional, stores error information @@ -393,7 +417,8 @@ ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state, * @param[in] value value to insert * @return error code, NIX_OK on success. */ -nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, Value * value); +nix_err +nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, nix_value * value); /** @brief Free a list builder * @@ -408,7 +433,7 @@ void nix_list_builder_free(ListBuilder * list_builder); * @param[in] b bindings builder to use. Make sure to unref this afterwards. * @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, nix_value * value, BindingsBuilder * b); /** @brief Set primop * @param[out] context Optional, stores error information @@ -417,14 +442,14 @@ nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder * * @see nix_alloc_primop * @return error code, NIX_OK on success. */ -nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * op); +nix_err nix_init_primop(nix_c_context * context, nix_value * value, PrimOp * op); /** @brief Copy from another value * @param[out] context Optional, stores error information * @param[out] value Nix value to modify * @param[in] source value to copy from * @return error code, NIX_OK on success. */ -nix_err nix_copy_value(nix_c_context * context, Value * value, const Value * source); +nix_err nix_copy_value(nix_c_context * context, nix_value * value, const nix_value * source); /**@}*/ /** @brief Create a bindings builder @@ -444,7 +469,7 @@ BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState * * @return error code, NIX_OK on success. */ 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, nix_value * value); /** @brief Free a bindings builder * @@ -471,7 +496,7 @@ void nix_bindings_builder_free(BindingsBuilder * builder); You should set this to false when building for your application's purpose. * @return NULL if failed, are a new nix_realised_string, which must be freed with nix_realised_string_free */ -nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * state, Value * value, bool isIFD); +nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * state, nix_value * value, bool isIFD); /** @brief Start of the string * @param[in] realised_string diff --git a/tests/unit/libexpr-support/tests/nix_api_expr.hh b/tests/unit/libexpr-support/tests/nix_api_expr.hh index d1840d034..6ddca0d14 100644 --- a/tests/unit/libexpr-support/tests/nix_api_expr.hh +++ b/tests/unit/libexpr-support/tests/nix_api_expr.hh @@ -25,7 +25,7 @@ protected: } EvalState * state; - Value * value; + nix_value * value; }; } diff --git a/tests/unit/libexpr/nix_api_expr.cc b/tests/unit/libexpr/nix_api_expr.cc index 92a6a1175..8b97d6923 100644 --- a/tests/unit/libexpr/nix_api_expr.cc +++ b/tests/unit/libexpr/nix_api_expr.cc @@ -39,12 +39,12 @@ TEST_F(nix_api_expr_test, nix_expr_eval_drv) ASSERT_EQ(NIX_TYPE_ATTRS, nix_get_type(nullptr, value)); EvalState * stateFn = nix_state_create(nullptr, nullptr, store); - Value * valueFn = nix_alloc_value(nullptr, state); + nix_value * valueFn = nix_alloc_value(nullptr, state); nix_expr_eval_from_string(nullptr, stateFn, "builtins.toString", ".", valueFn); ASSERT_EQ(NIX_TYPE_FUNCTION, nix_get_type(nullptr, valueFn)); EvalState * stateResult = nix_state_create(nullptr, nullptr, store); - Value * valueResult = nix_alloc_value(nullptr, stateResult); + nix_value * valueResult = nix_alloc_value(nullptr, stateResult); nix_value_call(ctx, stateResult, valueFn, value, valueResult); ASSERT_EQ(NIX_TYPE_STRING, nix_get_type(nullptr, valueResult)); @@ -70,7 +70,7 @@ TEST_F(nix_api_expr_test, nix_build_drv) })"; nix_expr_eval_from_string(nullptr, state, expr, ".", value); - Value * drvPathValue = nix_get_attr_byname(nullptr, value, state, "drvPath"); + nix_value * drvPathValue = nix_get_attr_byname(nullptr, value, state, "drvPath"); std::string drvPath; nix_get_string(nullptr, drvPathValue, OBSERVE_STRING(drvPath)); @@ -84,7 +84,7 @@ TEST_F(nix_api_expr_test, nix_build_drv) StorePath * drvStorePath = nix_store_parse_path(ctx, store, drvPath.c_str()); ASSERT_EQ(true, nix_store_is_valid_path(ctx, store, drvStorePath)); - Value * outPathValue = nix_get_attr_byname(ctx, value, state, "outPath"); + nix_value * outPathValue = nix_get_attr_byname(ctx, value, state, "outPath"); std::string outPath; nix_get_string(ctx, outPathValue, OBSERVE_STRING(outPath)); @@ -193,7 +193,8 @@ TEST_F(nix_api_expr_test, nix_expr_realise_context) const char * SAMPLE_USER_DATA = "whatever"; -static void primop_square(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret) +static void +primop_square(void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret) { assert(context); assert(state); @@ -207,17 +208,17 @@ TEST_F(nix_api_expr_test, nix_expr_primop) PrimOp * primop = nix_alloc_primop(ctx, primop_square, 1, "square", nullptr, "square an integer", (void *) SAMPLE_USER_DATA); assert_ctx_ok(); - Value * primopValue = nix_alloc_value(ctx, state); + nix_value * primopValue = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_primop(ctx, primopValue, primop); assert_ctx_ok(); - Value * three = nix_alloc_value(ctx, state); + nix_value * three = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_int(ctx, three, 3); assert_ctx_ok(); - Value * result = nix_alloc_value(ctx, state); + nix_value * result = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_value_call(ctx, state, primopValue, three, result); assert_ctx_ok(); @@ -226,7 +227,8 @@ TEST_F(nix_api_expr_test, nix_expr_primop) ASSERT_EQ(9, r); } -static void primop_repeat(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret) +static void +primop_repeat(void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret) { assert(context); assert(state); @@ -255,27 +257,27 @@ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_multiple_calls) PrimOp * primop = nix_alloc_primop(ctx, primop_repeat, 2, "repeat", nullptr, "repeat a string", (void *) SAMPLE_USER_DATA); assert_ctx_ok(); - Value * primopValue = nix_alloc_value(ctx, state); + nix_value * primopValue = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_primop(ctx, primopValue, primop); assert_ctx_ok(); - Value * hello = nix_alloc_value(ctx, state); + nix_value * hello = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_string(ctx, hello, "hello"); assert_ctx_ok(); - Value * three = nix_alloc_value(ctx, state); + nix_value * three = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_int(ctx, three, 3); assert_ctx_ok(); - Value * partial = nix_alloc_value(ctx, state); + nix_value * partial = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_value_call(ctx, state, primopValue, hello, partial); assert_ctx_ok(); - Value * result = nix_alloc_value(ctx, state); + nix_value * result = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_value_call(ctx, state, partial, three, result); assert_ctx_ok(); @@ -290,22 +292,22 @@ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_single_call) PrimOp * primop = nix_alloc_primop(ctx, primop_repeat, 2, "repeat", nullptr, "repeat a string", (void *) SAMPLE_USER_DATA); assert_ctx_ok(); - Value * primopValue = nix_alloc_value(ctx, state); + nix_value * primopValue = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_primop(ctx, primopValue, primop); assert_ctx_ok(); - Value * hello = nix_alloc_value(ctx, state); + nix_value * hello = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_string(ctx, hello, "hello"); assert_ctx_ok(); - Value * three = nix_alloc_value(ctx, state); + nix_value * three = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_int(ctx, three, 3); assert_ctx_ok(); - Value * result = nix_alloc_value(ctx, state); + nix_value * result = nix_alloc_value(ctx, state); assert_ctx_ok(); NIX_VALUE_CALL(ctx, state, result, primopValue, hello, three); assert_ctx_ok(); @@ -318,7 +320,7 @@ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_single_call) } static void -primop_bad_no_return(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret) +primop_bad_no_return(void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret) { } @@ -327,17 +329,17 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_no_return) PrimOp * primop = nix_alloc_primop(ctx, primop_bad_no_return, 1, "badNoReturn", nullptr, "a broken primop", nullptr); assert_ctx_ok(); - Value * primopValue = nix_alloc_value(ctx, state); + nix_value * primopValue = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_primop(ctx, primopValue, primop); assert_ctx_ok(); - Value * three = nix_alloc_value(ctx, state); + nix_value * three = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_int(ctx, three, 3); assert_ctx_ok(); - Value * result = nix_alloc_value(ctx, state); + nix_value * result = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_value_call(ctx, state, primopValue, three, result); ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR); @@ -348,8 +350,8 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_no_return) ASSERT_THAT(ctx->last_err, testing::Optional(testing::HasSubstr("badNoReturn"))); } -static void -primop_bad_return_thunk(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret) +static void primop_bad_return_thunk( + void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret) { nix_init_apply(context, ret, args[0], args[1]); } @@ -358,22 +360,22 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_return_thunk) PrimOp * primop = nix_alloc_primop(ctx, primop_bad_return_thunk, 2, "badReturnThunk", nullptr, "a broken primop", nullptr); assert_ctx_ok(); - Value * primopValue = nix_alloc_value(ctx, state); + nix_value * primopValue = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_primop(ctx, primopValue, primop); assert_ctx_ok(); - Value * toString = nix_alloc_value(ctx, state); + nix_value * toString = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_expr_eval_from_string(ctx, state, "builtins.toString", ".", toString); assert_ctx_ok(); - Value * four = nix_alloc_value(ctx, state); + nix_value * four = nix_alloc_value(ctx, state); assert_ctx_ok(); nix_init_int(ctx, four, 4); assert_ctx_ok(); - Value * result = nix_alloc_value(ctx, state); + nix_value * result = nix_alloc_value(ctx, state); assert_ctx_ok(); NIX_VALUE_CALL(ctx, state, result, primopValue, toString, four); @@ -387,11 +389,11 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_return_thunk) TEST_F(nix_api_expr_test, nix_value_call_multi_no_args) { - Value * n = nix_alloc_value(ctx, state); + nix_value * n = nix_alloc_value(ctx, state); nix_init_int(ctx, n, 3); assert_ctx_ok(); - Value * r = nix_alloc_value(ctx, state); + nix_value * r = nix_alloc_value(ctx, state); nix_value_call_multi(ctx, state, n, 0, nullptr, r); assert_ctx_ok(); diff --git a/tests/unit/libexpr/nix_api_external.cc b/tests/unit/libexpr/nix_api_external.cc index 2391f8317..81ff285a4 100644 --- a/tests/unit/libexpr/nix_api_external.cc +++ b/tests/unit/libexpr/nix_api_external.cc @@ -49,10 +49,10 @@ TEST_F(nix_api_expr_test, nix_expr_eval_external) nix_init_external(ctx, value, val); EvalState * stateResult = nix_state_create(nullptr, nullptr, store); - Value * valueResult = nix_alloc_value(nullptr, stateResult); + nix_value * valueResult = nix_alloc_value(nullptr, stateResult); EvalState * stateFn = nix_state_create(nullptr, nullptr, store); - Value * valueFn = nix_alloc_value(nullptr, stateFn); + nix_value * valueFn = nix_alloc_value(nullptr, stateFn); nix_expr_eval_from_string(nullptr, state, "builtins.typeOf", ".", valueFn); diff --git a/tests/unit/libexpr/nix_api_value.cc b/tests/unit/libexpr/nix_api_value.cc index c71593c85..7fc8b4f64 100644 --- a/tests/unit/libexpr/nix_api_value.cc +++ b/tests/unit/libexpr/nix_api_value.cc @@ -4,16 +4,26 @@ #include "nix_api_util_internal.h" #include "nix_api_expr.h" #include "nix_api_value.h" +#include "nix_api_expr_internal.h" #include "tests/nix_api_expr.hh" #include "tests/string_callback.hh" #include "gmock/gmock.h" +#include #include #include namespace nixC { +TEST_F(nix_api_expr_test, as_nix_value_ptr) +{ + // nix_alloc_value casts nix::Value to nix_value + // It should be obvious from the decl that that works, but if it doesn't, + // the whole implementation would be utterly broken. + ASSERT_EQ(sizeof(nix::Value), sizeof(nix_value)); +} + TEST_F(nix_api_expr_test, nix_value_get_int_invalid) { ASSERT_EQ(0, nix_get_int(ctx, nullptr)); @@ -138,8 +148,8 @@ TEST_F(nix_api_expr_test, nix_build_and_init_list) int size = 10; ListBuilder * builder = nix_make_list_builder(ctx, state, size); - Value * intValue = nix_alloc_value(ctx, state); - Value * intValue2 = nix_alloc_value(ctx, state); + nix_value * intValue = nix_alloc_value(ctx, state); + nix_value * intValue2 = nix_alloc_value(ctx, state); // `init` and `insert` can be called in any order nix_init_int(ctx, intValue, 42); @@ -194,10 +204,10 @@ TEST_F(nix_api_expr_test, nix_build_and_init_attr) BindingsBuilder * builder = nix_make_bindings_builder(ctx, state, size); - Value * intValue = nix_alloc_value(ctx, state); + nix_value * intValue = nix_alloc_value(ctx, state); nix_init_int(ctx, intValue, 42); - Value * stringValue = nix_alloc_value(ctx, state); + nix_value * stringValue = nix_alloc_value(ctx, state); nix_init_string(ctx, stringValue, "foo"); nix_bindings_builder_insert(ctx, builder, "a", intValue); @@ -207,7 +217,7 @@ TEST_F(nix_api_expr_test, nix_build_and_init_attr) ASSERT_EQ(2, nix_get_attrs_size(ctx, value)); - Value * out_value = nix_get_attr_byname(ctx, value, state, "a"); + nix_value * out_value = nix_get_attr_byname(ctx, value, state, "a"); ASSERT_EQ(42, nix_get_int(ctx, out_value)); nix_gc_decref(ctx, out_value); @@ -251,10 +261,10 @@ TEST_F(nix_api_expr_test, nix_value_init) // two = 2; // f = a: a * a; - Value * two = nix_alloc_value(ctx, state); + nix_value * two = nix_alloc_value(ctx, state); nix_init_int(ctx, two, 2); - Value * f = nix_alloc_value(ctx, state); + nix_value * f = nix_alloc_value(ctx, state); nix_expr_eval_from_string( ctx, state, @@ -268,7 +278,7 @@ TEST_F(nix_api_expr_test, nix_value_init) // r = f two; - Value * r = nix_alloc_value(ctx, state); + nix_value * r = nix_alloc_value(ctx, state); nix_init_apply(ctx, r, f, two); assert_ctx_ok(); @@ -297,11 +307,11 @@ TEST_F(nix_api_expr_test, nix_value_init) TEST_F(nix_api_expr_test, nix_value_init_apply_error) { - Value * some_string = nix_alloc_value(ctx, state); + nix_value * some_string = nix_alloc_value(ctx, state); nix_init_string(ctx, some_string, "some string"); assert_ctx_ok(); - Value * v = nix_alloc_value(ctx, state); + nix_value * v = nix_alloc_value(ctx, state); nix_init_apply(ctx, v, some_string, some_string); assert_ctx_ok(); @@ -326,7 +336,7 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg) // r = f e // r should not throw an exception, because e is not evaluated - Value * f = nix_alloc_value(ctx, state); + nix_value * f = nix_alloc_value(ctx, state); nix_expr_eval_from_string( ctx, state, @@ -337,9 +347,9 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg) f); assert_ctx_ok(); - Value * e = nix_alloc_value(ctx, state); + nix_value * e = nix_alloc_value(ctx, state); { - Value * g = nix_alloc_value(ctx, state); + nix_value * g = nix_alloc_value(ctx, state); nix_expr_eval_from_string( ctx, state, @@ -355,7 +365,7 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg) nix_gc_decref(ctx, g); } - Value * r = nix_alloc_value(ctx, state); + nix_value * r = nix_alloc_value(ctx, state); nix_init_apply(ctx, r, f, e); assert_ctx_ok(); @@ -367,7 +377,7 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg) ASSERT_EQ(1, n); // nix_get_attr_byname isn't lazy (it could have been) so it will throw the exception - Value * foo = nix_get_attr_byname(ctx, r, state, "foo"); + nix_value * foo = nix_get_attr_byname(ctx, r, state, "foo"); ASSERT_EQ(nullptr, foo); ASSERT_THAT(ctx->last_err.value(), testing::HasSubstr("error message for test case nix_value_init_apply_lazy_arg")); @@ -378,7 +388,7 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg) TEST_F(nix_api_expr_test, nix_copy_value) { - Value * source = nix_alloc_value(ctx, state); + nix_value * source = nix_alloc_value(ctx, state); nix_init_int(ctx, source, 42); nix_copy_value(ctx, value, source);