From 535694122e4cbbffa04fec903002ba08cf9deb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Lafuente?= Date: Wed, 10 Jan 2024 11:58:35 +0100 Subject: [PATCH] C API: rename State to EvalState --- doc/external-api/README.md | 49 +++++++++++++++++---------- src/libexpr/c/nix_api_expr.cc | 16 ++++----- src/libexpr/c/nix_api_expr.h | 24 ++++++------- src/libexpr/c/nix_api_expr_internal.h | 2 +- src/libexpr/c/nix_api_external.cc | 5 +-- src/libexpr/c/nix_api_external.h | 11 ++++-- src/libexpr/c/nix_api_value.cc | 18 +++++----- src/libexpr/c/nix_api_value.h | 22 ++++++------ tests/unit/libexpr/nix_api_expr.cc | 2 +- 9 files changed, 85 insertions(+), 64 deletions(-) diff --git a/doc/external-api/README.md b/doc/external-api/README.md index 3fa1c55f9..e9ca25ab6 100644 --- a/doc/external-api/README.md +++ b/doc/external-api/README.md @@ -1,30 +1,40 @@ # Getting started -> **Warning** -> These bindings are **experimental**, which means they can change at any time or be removed outright; nevertheless the plan is to provide a stable external C API to the Nix language and the Nix store. +> **Warning** These bindings are **experimental**, which means they can change +> at any time or be removed outright; nevertheless the plan is to provide a +> stable external C API to the Nix language and the Nix store. -The language library allows evaluating Nix expressions and interacting with Nix language values. -The Nix store API is still rudimentary, and only allows initialising and connecting to a store for the Nix language evaluator to interact with. +The language library allows evaluating Nix expressions and interacting with Nix +language values. The Nix store API is still rudimentary, and only allows +initialising and connecting to a store for the Nix language evaluator to +interact with. + +Currently there are two ways to interface with the Nix language evaluator +programmatically: -Currently there are two ways to interface with the Nix language evaluator programmatically: 1. Embedding the evaluator 2. Writing language plug-ins -Embedding means you link the Nix C libraries in your program and use them from there. -Adding a plug-in means you make a library that gets loaded by the Nix language evaluator, specified through a configuration option. +Embedding means you link the Nix C libraries in your program and use them from +there. Adding a plug-in means you make a library that gets loaded by the Nix +language evaluator, specified through a configuration option. -Many of the components and mechanisms involved are not yet documented, therefore please refer to the [Nix source code](https://github.com/NixOS/nix/) for details. -Additions to in-code documentation and the reference manual are highly appreciated. +Many of the components and mechanisms involved are not yet documented, therefore +please refer to the [Nix source code](https://github.com/NixOS/nix/) for +details. Additions to in-code documentation and the reference manual are highly +appreciated. - -The following examples, for simplicity, don't include error handling. -See the [Handling errors](@ref errors) section for more information. +The following examples, for simplicity, don't include error handling. See the +[Handling errors](@ref errors) section for more information. # Embedding the Nix Evaluator -In this example we programmatically start the Nix language evaluator with a dummy store (that has no store paths and cannot be written to), and evaluate the Nix expression `builtins.nixVersion`. +In this example we programmatically start the Nix language evaluator with a +dummy store (that has no store paths and cannot be written to), and evaluate the +Nix expression `builtins.nixVersion`. **main.c:** + ```C #include #include @@ -35,7 +45,7 @@ int main() { nix_libexpr_init(NULL); Store* store = nix_store_open(NULL, "dummy://", NULL); - State* state = nix_state_create(NULL, NULL, store); // empty search path (NIX_PATH) + EvalState* state = nix_state_create(NULL, NULL, store); // empty search path (NIX_PATH) Value *value = nix_alloc_value(NULL, state); nix_expr_eval_from_string(NULL, state, "builtins.nixVersion", ".", value); @@ -50,24 +60,26 @@ int main() { ``` **Usage:** + ```ShellSession $ gcc main.c $(pkg-config nix-expr-c --libs --cflags) -o main $ ./main Nix version: 2.17 ``` - # Writing a Nix language plug-in -In this example we add a custom primitive operation (*primop*) to `builtins`. -It will increment the argument if it is an integer and throw an error otherwise. + +In this example we add a custom primitive operation (_primop_) to `builtins`. It +will increment the argument if it is an integer and throw an error otherwise. **plugin.c:** + ```C #include #include #include -void increment(void* user_data, nix_c_context* ctx, State* state, Value** args, Value* v) { +void increment(void* user_data, nix_c_context* ctx, EvalState* state, Value** args, Value* v) { nix_value_force(NULL, state, args[0]); if (nix_get_type(NULL, args[0]) == NIX_TYPE_INT) { nix_set_int(NULL, v, nix_get_int(NULL, args[0]) + 1); @@ -85,6 +97,7 @@ void nix_plugin_entry() { ``` **Usage:** + ```ShellSession $ gcc plugin.c $(pkg-config nix-expr-c --libs --cflags) -shared -o plugin.so $ nix --plugin-files ./plugin.so repl diff --git a/src/libexpr/c/nix_api_expr.cc b/src/libexpr/c/nix_api_expr.cc index dc114c777..f18ef399b 100644 --- a/src/libexpr/c/nix_api_expr.cc +++ b/src/libexpr/c/nix_api_expr.cc @@ -41,8 +41,8 @@ nix_err nix_libexpr_init(nix_c_context * context) NIXC_CATCH_ERRS } -nix_err -nix_expr_eval_from_string(nix_c_context * context, State * state, const char * expr, const char * path, Value * value) +nix_err nix_expr_eval_from_string( + nix_c_context * context, EvalState * state, const char * expr, const char * path, Value * value) { if (context) context->last_err_code = NIX_OK; @@ -54,7 +54,7 @@ nix_expr_eval_from_string(nix_c_context * context, State * state, const char * e NIXC_CATCH_ERRS } -nix_err nix_value_call(nix_c_context * context, State * state, Value * fn, Value * arg, Value * value) +nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, Value * arg, Value * value) { if (context) context->last_err_code = NIX_OK; @@ -65,7 +65,7 @@ nix_err nix_value_call(nix_c_context * context, State * state, Value * fn, Value NIXC_CATCH_ERRS } -nix_err nix_value_force(nix_c_context * context, State * state, Value * value) +nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * value) { if (context) context->last_err_code = NIX_OK; @@ -75,7 +75,7 @@ nix_err nix_value_force(nix_c_context * context, State * state, Value * value) NIXC_CATCH_ERRS } -nix_err nix_value_force_deep(nix_c_context * context, State * state, Value * value) +nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value * value) { if (context) context->last_err_code = NIX_OK; @@ -85,7 +85,7 @@ nix_err nix_value_force_deep(nix_c_context * context, State * state, Value * val NIXC_CATCH_ERRS } -State * nix_state_create(nix_c_context * context, const char ** searchPath_c, Store * store) +EvalState * nix_state_create(nix_c_context * context, const char ** searchPath_c, Store * store) { if (context) context->last_err_code = NIX_OK; @@ -95,12 +95,12 @@ State * nix_state_create(nix_c_context * context, const char ** searchPath_c, St for (size_t i = 0; searchPath_c[i] != nullptr; i++) searchPath.push_back(searchPath_c[i]); - return new State{nix::EvalState(nix::SearchPath::parse(searchPath), store->ptr)}; + return new EvalState{nix::EvalState(nix::SearchPath::parse(searchPath), store->ptr)}; } NIXC_CATCH_ERRS_NULL } -void nix_state_free(State * state) +void nix_state_free(EvalState * state) { delete state; } diff --git a/src/libexpr/c/nix_api_expr.h b/src/libexpr/c/nix_api_expr.h index 8cc6c916c..7f32140a0 100644 --- a/src/libexpr/c/nix_api_expr.h +++ b/src/libexpr/c/nix_api_expr.h @@ -9,7 +9,7 @@ * nix_libexpr_init(NULL); * * Store* store = nix_store_open(NULL, "dummy", NULL); - * State* state = nix_state_create(NULL, NULL, store); // empty nix path + * EvalState* state = nix_state_create(NULL, NULL, store); // empty nix path * Value *value = nix_alloc_value(NULL, state); * * nix_expr_eval_from_string(NULL, state, "builtins.nixVersion", ".", value); @@ -42,10 +42,10 @@ extern "C" { * * Multiple states can be created for multi-threaded * operation. - * @struct State + * @struct EvalState * @see nix_state_create */ -typedef struct State State; // nix::EvalState +typedef struct EvalState EvalState; // nix::EvalState /** * @brief Represents a value in the Nix language. * @@ -60,7 +60,7 @@ typedef void Value; // nix::Value * @brief Initialize the Nix language evaluator. * * This function must be called at least once, - * at some point before constructing a State for the first time. + * at some point before constructing a EvalState for the first time. * This function can be called multiple times, and is idempotent. * * @param[out] context Optional, stores error information @@ -77,12 +77,12 @@ nix_err nix_libexpr_init(nix_c_context * context); * @param[in] path The file path to associate with the expression. * This is required for expressions that contain relative paths (such as `./.`) that are resolved relative to the given * directory. - * @param[out] value The result of the evaluation. You should allocate this + * @param[out] value The result of the evaluation. You must allocate this * yourself. * @return NIX_OK if the evaluation was successful, an error code otherwise. */ -nix_err -nix_expr_eval_from_string(nix_c_context * context, State * state, const char * expr, const char * path, Value * value); +nix_err nix_expr_eval_from_string( + nix_c_context * context, EvalState * state, const char * expr, const char * path, Value * value); /** * @brief Calls a Nix function with an argument. @@ -94,7 +94,7 @@ nix_expr_eval_from_string(nix_c_context * context, State * state, const char * e * @param[out] value The result of the function call. * @return NIX_OK if the function call was successful, an error code otherwise. */ -nix_err nix_value_call(nix_c_context * context, State * state, Value * fn, Value * arg, Value * value); +nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, Value * arg, Value * value); /** * @brief Forces the evaluation of a Nix value. @@ -116,7 +116,7 @@ nix_err nix_value_call(nix_c_context * context, State * state, Value * fn, Value * @return NIX_OK if the force operation was successful, an error code * otherwise. */ -nix_err nix_value_force(nix_c_context * context, State * state, Value * value); +nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * value); /** * @brief Forces the deep evaluation of a Nix value. @@ -132,7 +132,7 @@ nix_err nix_value_force(nix_c_context * context, State * state, Value * value); * @return NIX_OK if the deep force operation was successful, an error code * otherwise. */ -nix_err nix_value_force_deep(nix_c_context * context, State * state, Value * value); +nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value * value); /** * @brief Create a new Nix language evaluator state. @@ -142,7 +142,7 @@ nix_err nix_value_force_deep(nix_c_context * context, State * state, Value * val * @param[in] store The Nix store to use. * @return A new Nix state or NULL on failure. */ -State * nix_state_create(nix_c_context * context, const char ** searchPath, Store * store); +EvalState * nix_state_create(nix_c_context * context, const char ** searchPath, Store * store); /** * @brief Frees a Nix state. @@ -151,7 +151,7 @@ State * nix_state_create(nix_c_context * context, const char ** searchPath, Stor * * @param[in] state The state to free. */ -void nix_state_free(State * state); +void nix_state_free(EvalState * state); /** @addtogroup GC * @brief Reference counting and garbage collector operations diff --git a/src/libexpr/c/nix_api_expr_internal.h b/src/libexpr/c/nix_api_expr_internal.h index c9906dd3a..e116af165 100644 --- a/src/libexpr/c/nix_api_expr_internal.h +++ b/src/libexpr/c/nix_api_expr_internal.h @@ -4,7 +4,7 @@ #include "eval.hh" #include "attr-set.hh" -struct State +struct EvalState { nix::EvalState state; }; diff --git a/src/libexpr/c/nix_api_external.cc b/src/libexpr/c/nix_api_external.cc index a2d776a47..2e8a98567 100644 --- a/src/libexpr/c/nix_api_external.cc +++ b/src/libexpr/c/nix_api_external.cc @@ -148,7 +148,7 @@ public: } nix_string_context ctx{context}; nix_string_return res{""}; - desc.printValueAsJSON(v, (State *) &state, strict, &ctx, copyToStore, &res); + desc.printValueAsJSON(v, (EvalState *) &state, strict, &ctx, copyToStore, &res); if (res.str.empty()) { return nix::ExternalValueBase::printValueAsJSON(state, strict, context, copyToStore); } @@ -172,7 +172,8 @@ public: } nix_string_context ctx{context}; desc.printValueAsXML( - v, (State *) &state, strict, location, &doc, &ctx, &drvsSeen, *reinterpret_cast(&pos)); + v, (EvalState *) &state, strict, location, &doc, &ctx, &drvsSeen, + *reinterpret_cast(&pos)); } virtual ~NixCExternalValue() override{}; diff --git a/src/libexpr/c/nix_api_external.h b/src/libexpr/c/nix_api_external.h index 00eaa4460..daa74c5a8 100644 --- a/src/libexpr/c/nix_api_external.h +++ b/src/libexpr/c/nix_api_external.h @@ -136,7 +136,7 @@ typedef struct NixCExternalValueDesc * or setting it to the empty string, will make the conversion throw an error. */ void (*printValueAsJSON)( - void * self, State *, int strict, nix_string_context * c, bool copyToStore, nix_string_return * res); + void * self, EvalState *, int strict, nix_string_context * c, bool copyToStore, nix_string_return * res); /** * @brief Convert the external value to XML * @@ -154,7 +154,14 @@ typedef struct NixCExternalValueDesc * @param[in] pos The position of the call. */ void (*printValueAsXML)( - void * self, State *, int strict, int location, void * doc, nix_string_context * c, void * drvsSeen, int pos); + void * self, + EvalState *, + int strict, + int location, + void * doc, + nix_string_context * c, + void * drvsSeen, + int pos); } NixCExternalValueDesc; /** diff --git a/src/libexpr/c/nix_api_value.cc b/src/libexpr/c/nix_api_value.cc index b0fb960c6..ffa3aa5f7 100644 --- a/src/libexpr/c/nix_api_value.cc +++ b/src/libexpr/c/nix_api_value.cc @@ -43,7 +43,7 @@ static void nix_c_primop_wrapper( PrimOpFun f, void * userdata, nix::EvalState & state, const nix::PosIdx pos, nix::Value ** args, nix::Value & v) { nix_c_context ctx; - f(userdata, &ctx, (State *) &state, (Value **) args, (Value *) &v); + f(userdata, &ctx, (EvalState *) &state, (Value **) args, (Value *) &v); /* TODO: In the future, this should throw different errors depending on the error code */ if (ctx.last_err_code != NIX_OK) state.debugThrowLastTrace(nix::Error( @@ -92,7 +92,7 @@ nix_err nix_register_primop(nix_c_context * context, PrimOp * primOp) NIXC_CATCH_ERRS } -Value * nix_alloc_value(nix_c_context * context, State * state) +Value * nix_alloc_value(nix_c_context * context, EvalState * state) { if (context) context->last_err_code = NIX_OK; @@ -255,7 +255,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, State * state, unsigned int ix) +Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int ix) { if (context) context->last_err_code = NIX_OK; @@ -270,7 +270,7 @@ Value * nix_get_list_byidx(nix_c_context * context, const Value * value, State * NIXC_CATCH_ERRS_NULL } -Value * nix_get_attr_byname(nix_c_context * context, const Value * value, State * state, const char * name) +Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name) { if (context) context->last_err_code = NIX_OK; @@ -290,7 +290,7 @@ Value * nix_get_attr_byname(nix_c_context * context, const Value * value, State NIXC_CATCH_ERRS_NULL } -bool nix_has_attr_byname(nix_c_context * context, const Value * value, State * state, const char * name) +bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name) { if (context) context->last_err_code = NIX_OK; @@ -307,7 +307,7 @@ bool nix_has_attr_byname(nix_c_context * context, const Value * value, State * s } Value * -nix_get_attr_byidx(nix_c_context * context, const Value * value, State * state, unsigned int i, const char ** name) +nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i, const char ** name) { if (context) context->last_err_code = NIX_OK; @@ -322,7 +322,7 @@ nix_get_attr_byidx(nix_c_context * context, const Value * value, State * state, NIXC_CATCH_ERRS_NULL } -const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * value, State * state, unsigned int i) +const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i) { if (context) context->last_err_code = NIX_OK; @@ -413,7 +413,7 @@ nix_err nix_set_external(nix_c_context * context, Value * value, ExternalValue * NIXC_CATCH_ERRS } -nix_err nix_make_list(nix_c_context * context, State * s, Value * value, unsigned int size) +nix_err nix_make_list(nix_c_context * context, EvalState * s, Value * value, unsigned int size) { if (context) context->last_err_code = NIX_OK; @@ -471,7 +471,7 @@ nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder * NIXC_CATCH_ERRS } -BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, State * state, size_t capacity) +BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState * state, size_t capacity) { 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 ca4e83cf4..de6dbc9ff 100644 --- a/src/libexpr/c/nix_api_value.h +++ b/src/libexpr/c/nix_api_value.h @@ -35,7 +35,7 @@ typedef enum { // forward declarations typedef void Value; -typedef struct State State; +typedef struct EvalState EvalState; // type defs /** @brief Stores an under-construction set of bindings * @ingroup value_manip @@ -75,7 +75,7 @@ typedef struct ExternalValue ExternalValue; * @param[out] ret return value * @see nix_alloc_primop, nix_set_primop */ -typedef void (*PrimOpFun)(void * user_data, nix_c_context * context, State * state, Value ** args, Value * ret); +typedef void (*PrimOpFun)(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret); /** @brief Allocate a PrimOp * @@ -127,7 +127,7 @@ 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, State * state); +Value * nix_alloc_value(nix_c_context * context, EvalState * state); /** @addtogroup value_manip Manipulating values * @brief Functions to inspect and change Nix language values, represented by Value. * @{ @@ -209,7 +209,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, State * 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 * * Owned by the GC. Use nix_gc_decref when you're done with the pointer @@ -219,7 +219,7 @@ Value * nix_get_list_byidx(nix_c_context * context, const Value * value, State * * @param[in] name attribute name * @return value, NULL in case of errors */ -Value * nix_get_attr_byname(nix_c_context * context, const Value * value, State * state, const char * name); +Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name); /** @brief Check if an attribute name exists on a value * @param[out] context Optional, stores error information @@ -228,7 +228,7 @@ Value * nix_get_attr_byname(nix_c_context * context, const Value * value, State * @param[in] name attribute name * @return value, error info via context */ -bool nix_has_attr_byname(nix_c_context * context, const Value * value, State * state, const char * name); +bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name); /** @brief Get an attribute by index in the sorted bindings * @@ -243,20 +243,20 @@ bool nix_has_attr_byname(nix_c_context * context, const Value * value, State * s * @return value, NULL in case of errors */ Value * -nix_get_attr_byidx(nix_c_context * context, const Value * value, State * state, unsigned int i, const char ** name); +nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i, const char ** name); /** @brief Get an attribute name by index in the sorted bindings * * Useful when you want the name but want to avoid evaluation. * - * Owned by the nix State + * Owned by the nix EvalState * @param[out] context Optional, stores error information * @param[in] value Nix value to inspect * @param[in] state nix evaluator state * @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, State * 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 */ @@ -315,7 +315,7 @@ nix_err nix_set_external(nix_c_context * context, Value * value, ExternalValue * * @param[in] size size of list * @return error code, NIX_OK on success. */ -nix_err nix_make_list(nix_c_context * context, State * s, Value * value, unsigned int size); +nix_err nix_make_list(nix_c_context * context, EvalState * s, Value * value, unsigned int size); /** @brief Manipulate a list by index * * Don't do this mid-computation. @@ -359,7 +359,7 @@ nix_err nix_copy_value(nix_c_context * context, Value * value, Value * source); * @return owned reference to a bindings builder. Make sure to unref when you're done. */ -BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, State * state, size_t capacity); +BindingsBuilder * nix_make_bindings_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 BindingsBuilder to insert into diff --git a/tests/unit/libexpr/nix_api_expr.cc b/tests/unit/libexpr/nix_api_expr.cc index 03de4547a..60a33a5cf 100644 --- a/tests/unit/libexpr/nix_api_expr.cc +++ b/tests/unit/libexpr/nix_api_expr.cc @@ -25,7 +25,7 @@ public: nix_state_free(state); } - State * state; + EvalState * state; Value * value; };