Merge pull request #10486 from tweag/jl/c-api_function-pointer

C API: Safer function pointer casting
This commit is contained in:
Eelco Dolstra 2024-04-16 18:56:08 +02:00 committed by GitHub
commit 74e4bc9b1d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 35 additions and 28 deletions

View file

@ -537,7 +537,7 @@ nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * st
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::NixStringContext stringContext; nix::NixStringContext stringContext;
auto rawStr = state->state.coerceToString(nix::noPos, v, stringContext, "while realising a string").toOwned(); auto rawStr = state->state.coerceToString(nix::noPos, v, stringContext, "while realising a string").toOwned();
nix::StorePathSet storePaths; nix::StorePathSet storePaths;
@ -547,14 +547,11 @@ nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * st
// Convert to the C API StorePath type and convert to vector for index-based access // Convert to the C API StorePath type and convert to vector for index-based access
std::vector<StorePath> vec; std::vector<StorePath> vec;
for (auto &sp : storePaths) { for (auto & sp : storePaths) {
vec.push_back(StorePath{sp}); vec.push_back(StorePath{sp});
} }
return new nix_realised_string { return new nix_realised_string{.str = s, .storePaths = vec};
.str = s,
.storePaths = vec
};
} }
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL
} }

View file

@ -56,7 +56,7 @@ void nix_store_free(Store * store)
delete store; delete store;
} }
nix_err nix_store_get_uri(nix_c_context * context, Store * store, void * callback, void * user_data) nix_err nix_store_get_uri(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -67,7 +67,8 @@ nix_err nix_store_get_uri(nix_c_context * context, Store * store, void * callbac
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
nix_err nix_store_get_version(nix_c_context * context, Store * store, void * callback, void * user_data) nix_err
nix_store_get_version(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -128,13 +129,12 @@ nix_err nix_store_realise(
NIXC_CATCH_ERRS NIXC_CATCH_ERRS
} }
void nix_store_path_name(const StorePath *store_path, void * callback, void * user_data) void nix_store_path_name(const StorePath * store_path, nix_get_string_callback callback, void * user_data)
{ {
std::string_view name = store_path->path.name(); std::string_view name = store_path->path.name();
((nix_get_string_callback) callback)(name.data(), name.size(), user_data); callback(name.data(), name.size(), user_data);
} }
void nix_store_path_free(StorePath * sp) void nix_store_path_free(StorePath * sp)
{ {
delete sp; delete sp;

View file

@ -76,7 +76,7 @@ void nix_store_free(Store * store);
* @see nix_get_string_callback * @see nix_get_string_callback
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_store_get_uri(nix_c_context * context, Store * store, void * callback, void * user_data); nix_err nix_store_get_uri(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data);
// returns: owned StorePath* // returns: owned StorePath*
/** /**
@ -97,7 +97,7 @@ StorePath * nix_store_parse_path(nix_c_context * context, Store * store, const c
* @param[in] callback called with the name * @param[in] callback called with the name
* @param[in] user_data arbitrary data, passed to the callback when it's called. * @param[in] user_data arbitrary data, passed to the callback when it's called.
*/ */
void nix_store_path_name(const StorePath *store_path, void * callback, void * user_data); void nix_store_path_name(const StorePath * store_path, nix_get_string_callback callback, void * user_data);
/** /**
* @brief Copy a StorePath * @brief Copy a StorePath
@ -130,7 +130,8 @@ bool nix_store_is_valid_path(nix_c_context * context, Store * store, StorePath *
* *
* Blocking, calls callback once for each realised output. * Blocking, calls callback once for each realised output.
* *
* @note When working with expressions, consider using e.g. nix_string_realise to get the output. `.drvPath` may not be accurate or available in the future. See https://github.com/NixOS/nix/issues/6507 * @note When working with expressions, consider using e.g. nix_string_realise to get the output. `.drvPath` may not be
* accurate or available in the future. See https://github.com/NixOS/nix/issues/6507
* *
* @param[out] context Optional, stores error information * @param[out] context Optional, stores error information
* @param[in] store Nix Store reference * @param[in] store Nix Store reference
@ -155,7 +156,8 @@ nix_err nix_store_realise(
* @see nix_get_string_callback * @see nix_get_string_callback
* @return error code, NIX_OK on success. * @return error code, NIX_OK on success.
*/ */
nix_err nix_store_get_version(nix_c_context * context, Store * store, void * callback, void * user_data); nix_err
nix_store_get_version(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data);
// cffi end // cffi end
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -64,7 +64,7 @@ const char * nix_version_get()
// Implementations // Implementations
nix_err nix_setting_get(nix_c_context * context, const char * key, void * callback, void * user_data) nix_err nix_setting_get(nix_c_context * context, const char * key, nix_get_string_callback callback, void * user_data)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -115,7 +115,8 @@ const char * nix_err_msg(nix_c_context * context, const nix_c_context * read_con
return nullptr; return nullptr;
} }
nix_err nix_err_name(nix_c_context * context, const nix_c_context * read_context, void * callback, void * user_data) nix_err nix_err_name(
nix_c_context * context, const nix_c_context * read_context, nix_get_string_callback callback, void * user_data)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -125,7 +126,8 @@ nix_err nix_err_name(nix_c_context * context, const nix_c_context * read_context
return call_nix_get_string_callback(read_context->name, callback, user_data); return call_nix_get_string_callback(read_context->name, callback, user_data);
} }
nix_err nix_err_info_msg(nix_c_context * context, const nix_c_context * read_context, void * callback, void * user_data) nix_err nix_err_info_msg(
nix_c_context * context, const nix_c_context * read_context, nix_get_string_callback callback, void * user_data)
{ {
if (context) if (context)
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
@ -141,8 +143,8 @@ nix_err nix_err_code(const nix_c_context * read_context)
} }
// internal // internal
nix_err call_nix_get_string_callback(const std::string str, void * callback, void * user_data) nix_err call_nix_get_string_callback(const std::string str, nix_get_string_callback callback, void * user_data)
{ {
((nix_get_string_callback) callback)(str.c_str(), str.size(), user_data); callback(str.c_str(), str.size(), user_data);
return NIX_OK; return NIX_OK;
} }

View file

@ -175,7 +175,7 @@ nix_err nix_libutil_init(nix_c_context * context);
* @return NIX_ERR_KEY if the setting is unknown, or NIX_OK if the setting was retrieved * @return NIX_ERR_KEY if the setting is unknown, or NIX_OK if the setting was retrieved
* successfully. * successfully.
*/ */
nix_err nix_setting_get(nix_c_context * context, const char * key, void * callback, void * user_data); nix_err nix_setting_get(nix_c_context * context, const char * key, nix_get_string_callback callback, void * user_data);
/** /**
* @brief Sets a setting in the nix global configuration. * @brief Sets a setting in the nix global configuration.
@ -241,8 +241,8 @@ const char * nix_err_msg(nix_c_context * context, const nix_c_context * ctx, uns
* @see nix_get_string_callback * @see nix_get_string_callback
* @return NIX_OK if there were no errors, an error code otherwise. * @return NIX_OK if there were no errors, an error code otherwise.
*/ */
nix_err nix_err nix_err_info_msg(
nix_err_info_msg(nix_c_context * context, const nix_c_context * read_context, void * callback, void * user_data); nix_c_context * context, const nix_c_context * read_context, nix_get_string_callback callback, void * user_data);
/** /**
* @brief Retrieves the error name from a context. * @brief Retrieves the error name from a context.
@ -260,7 +260,8 @@ nix_err_info_msg(nix_c_context * context, const nix_c_context * read_context, vo
* @see nix_get_string_callback * @see nix_get_string_callback
* @return NIX_OK if there were no errors, an error code otherwise. * @return NIX_OK if there were no errors, an error code otherwise.
*/ */
nix_err nix_err_name(nix_c_context * context, const nix_c_context * read_context, void * callback, void * user_data); nix_err nix_err_name(
nix_c_context * context, const nix_c_context * read_context, nix_get_string_callback callback, void * user_data);
/** /**
* @brief Retrieves the most recent error code from a nix_c_context * @brief Retrieves the most recent error code from a nix_c_context

View file

@ -29,7 +29,7 @@ nix_err nix_context_error(nix_c_context * context);
* @return NIX_OK if there were no errors. * @return NIX_OK if there were no errors.
* @see nix_get_string_callback * @see nix_get_string_callback
*/ */
nix_err call_nix_get_string_callback(const std::string str, void * callback, void * user_data); nix_err call_nix_get_string_callback(const std::string str, nix_get_string_callback callback, void * user_data);
#define NIXC_CATCH_ERRS \ #define NIXC_CATCH_ERRS \
catch (...) \ catch (...) \

View file

@ -2,7 +2,8 @@
namespace nix::testing { namespace nix::testing {
void observe_string_cb(const char * start, unsigned int n, std::string * user_data) { void observe_string_cb(const char * start, unsigned int n, std::string * user_data)
{
*user_data = std::string(start); *user_data = std::string(start);
} }

View file

@ -4,9 +4,13 @@
namespace nix::testing { namespace nix::testing {
void observe_string_cb(const char * start, unsigned int n, std::string * user_data); void observe_string_cb(const char * start, unsigned int n, std::string * user_data);
inline void * observe_string_cb_data(std::string & out) {
inline void * observe_string_cb_data(std::string & out)
{
return (void *) &out; return (void *) &out;
}; };
#define OBSERVE_STRING(str) (void *)nix::testing::observe_string_cb, nix::testing::observe_string_cb_data(str)
#define OBSERVE_STRING(str) \
(nix_get_string_callback) nix::testing::observe_string_cb, nix::testing::observe_string_cb_data(str)
} }