nix_api_external: own return strings on the nix side

Change from nix_returned_string that passes ownership, into a
nix_string_return parameter that can be set using nix_set_string_return.
This commit is contained in:
Yorick van Pelt 2023-07-28 10:03:08 +02:00 committed by José Luis Lafuente
parent 022b918db1
commit bebee700ea
No known key found for this signature in database
GPG key ID: 8A3455EBE455489A
2 changed files with 37 additions and 45 deletions

View file

@ -20,7 +20,7 @@
#include "gc_cpp.h" #include "gc_cpp.h"
#endif #endif
struct nix_returned_string { struct nix_string_return {
std::string str; std::string str;
}; };
@ -32,10 +32,9 @@ struct nix_string_context {
nix::NixStringContext &ctx; nix::NixStringContext &ctx;
}; };
nix_returned_string *nix_external_alloc_string(const char *c) { void nix_set_string_return(nix_string_return *str, const char *c) {
return new nix_returned_string{c}; str->str = c;
} }
void nix_external_dealloc_string(nix_returned_string *str) { delete str; }
nix_err nix_external_print(nix_c_context *context, nix_printer *printer, nix_err nix_external_print(nix_c_context *context, nix_printer *printer,
const char *c) { const char *c) {
@ -79,16 +78,18 @@ public:
* Return a simple string describing the type * Return a simple string describing the type
*/ */
virtual std::string showType() const override { virtual std::string showType() const override {
std::unique_ptr<nix_returned_string> r(desc.showType(v)); nix_string_return res;
return std::move(r->str); desc.showType(v, &res);
return std::move(res.str);
} }
/** /**
* Return a string to be used in builtins.typeOf * Return a string to be used in builtins.typeOf
*/ */
virtual std::string typeOf() const override { virtual std::string typeOf() const override {
std::unique_ptr<nix_returned_string> r(desc.typeOf(v)); nix_string_return res;
return std::move(r->str); desc.typeOf(v, &res);
return std::move(res.str);
} }
/** /**
@ -103,14 +104,14 @@ public:
copyToStore); copyToStore);
} }
nix_string_context ctx{context}; nix_string_context ctx{context};
nix_string_return res{""};
// todo: pos, errors // todo: pos, errors
std::unique_ptr<nix_returned_string> r( desc.coerceToString(v, &ctx, copyMore, copyToStore, &res);
desc.coerceToString(v, &ctx, copyMore, copyToStore)); if (res.str.empty()) {
if (!r) {
return nix::ExternalValueBase::coerceToString(pos, context, copyMore, return nix::ExternalValueBase::coerceToString(pos, context, copyMore,
copyToStore); copyToStore);
} }
return std::move(r->str); return std::move(res.str);
} }
/** /**
@ -138,13 +139,13 @@ public:
copyToStore); copyToStore);
} }
nix_string_context ctx{context}; nix_string_context ctx{context};
std::unique_ptr<nix_returned_string> r( nix_string_return res{""};
desc.printValueAsJSON(v, (State *)&state, strict, &ctx, copyToStore)); desc.printValueAsJSON(v, (State *)&state, strict, &ctx, copyToStore, &res);
if (!r) { if (res.str.empty()) {
return nix::ExternalValueBase::printValueAsJSON(state, strict, context, return nix::ExternalValueBase::printValueAsJSON(state, strict, context,
copyToStore); copyToStore);
} }
return nlohmann::json::parse(r->str); return nlohmann::json::parse(res.str);
} }
/** /**

View file

@ -17,9 +17,10 @@ extern "C" {
// cffi start // cffi start
/** /**
* @brief Represents a string meant for consumption by nix. * @brief Represents a string owned by nix.
* @see nix_set_owned_string
*/ */
typedef struct nix_returned_string nix_returned_string; typedef struct nix_string_return nix_string_return;
/** /**
* @brief Wraps a stream that can output multiple string pieces. * @brief Wraps a stream that can output multiple string pieces.
*/ */
@ -30,23 +31,13 @@ typedef struct nix_printer nix_printer;
typedef struct nix_string_context nix_string_context; typedef struct nix_string_context nix_string_context;
/** /**
* @brief Allocate a nix_returned_string from a const char*. * @brief Sets the contents of a nix_string_return
* *
* Copies the passed string. * Copies the passed string.
* @param[in] c The string to copy * @param[out] str the nix_string_return to write to
* @returns A nix_returned_string* * @param[in] c The string to copy
*/ */
nix_returned_string *nix_external_alloc_string(const char *c); void nix_set_string_return(nix_string_return *str, const char *c);
/**
* @brief Deallocate a nix_returned_string
*
* There's generally no need to call this, since
* returning the string will pass ownership to nix,
* but you can use it in case of errors.
* @param[in] str The string to deallocate
*/
void nix_external_dealloc_string(nix_returned_string *str);
/** /**
* Print to the nix_printer * Print to the nix_printer
@ -91,15 +82,15 @@ typedef struct NixCExternalValueDesc {
/** /**
* @brief Called on :t * @brief Called on :t
* @param[in] self the void* passed to nix_create_external_value * @param[in] self the void* passed to nix_create_external_value
* @returns a nix_returned_string, ownership passed to nix * @param[out] res the return value
*/ */
nix_returned_string *(*showType)(void *self); // std::string void (*showType)(void *self, nix_string_return *res);
/** /**
* @brief Called on `builtins.typeOf` * @brief Called on `builtins.typeOf`
* @param self the void* passed to nix_create_external_value * @param self the void* passed to nix_create_external_value
* @returns a nix_returned_string, ownership passed to nix * @param[out] res the return value
*/ */
nix_returned_string *(*typeOf)(void *self); // std::string void (*typeOf)(void *self, nix_string_return *res);
/** /**
* @brief Called on "${str}" and builtins.toString. * @brief Called on "${str}" and builtins.toString.
* *
@ -111,11 +102,11 @@ typedef struct NixCExternalValueDesc {
* instead of throwing an error * instead of throwing an error
* @param[in] copyToStore boolean, whether to copy referenced paths to store * @param[in] copyToStore boolean, whether to copy referenced paths to store
* or keep them as-is * or keep them as-is
* @returns a nix_returned_string, ownership passed to nix. Optional, * @param[out] res the return value. Not touching this, or setting it to the
* returning NULL will make the conversion throw an error. * empty string, will make the conversion throw an error.
*/ */
nix_returned_string *(*coerceToString)(void *self, nix_string_context *c, void (*coerceToString)(void *self, nix_string_context *c, int coerceMore,
int coerceMore, int copyToStore); int copyToStore, nix_string_return *res);
/** /**
* @brief Try to compare two external values * @brief Try to compare two external values
* *
@ -138,12 +129,12 @@ typedef struct NixCExternalValueDesc {
* @param[out] c writable string context for the resulting string * @param[out] c writable string context for the resulting string
* @param[in] copyToStore whether to copy referenced paths to store or keep * @param[in] copyToStore whether to copy referenced paths to store or keep
* them as-is * them as-is
* @returns string that gets parsed as json. Optional, returning NULL will * @param[out] res the return value. Gets parsed as JSON. Not touching this,
* make the conversion throw an error. * or setting it to the empty string, will make the conversion throw an error.
*/ */
nix_returned_string *(*printValueAsJSON)(void *self, State *, int strict, void (*printValueAsJSON)(void *self, State *, int strict,
nix_string_context *c, nix_string_context *c, bool copyToStore,
bool copyToStore); nix_string_return *res);
/** /**
* @brief Convert the external value to XML * @brief Convert the external value to XML
* *