diff --git a/ext/rubydex/declaration.c b/ext/rubydex/declaration.c index 3f8366fe..e36e70c1 100644 --- a/ext/rubydex/declaration.c +++ b/ext/rubydex/declaration.c @@ -59,20 +59,10 @@ VALUE rdxi_declaration_class_for_kind(CDeclarationKind kind) { */ static VALUE rdxr_declaration_name(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const char *name = rdx_declaration_name(graph, data->id); - if (name == NULL) { - return Qnil; - } - - VALUE str = rb_utf8_str_new_cstr(name); - free_c_string(name); - - return str; + return rdxi_owned_c_string_to_ruby(name); } /* @@ -83,20 +73,10 @@ static VALUE rdxr_declaration_name(VALUE self) { */ static VALUE rdxr_declaration_unqualified_name(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const char *name = rdx_declaration_unqualified_name(graph, data->id); - if (name == NULL) { - return Qnil; - } - - VALUE str = rb_utf8_str_new_cstr(name); - free_c_string(name); - - return str; + return rdxi_owned_c_string_to_ruby(name); } // Body function for rb_ensure in Declaration#definitions @@ -130,10 +110,7 @@ static VALUE declaration_definitions_ensure(VALUE args) { // Size function for the Declaration#definitions enumerator static VALUE declaration_definitions_size(VALUE self, VALUE _args, VALUE _eobj) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); struct DefinitionsIter *iter = rdx_declaration_definitions_iter_new(graph, data->id); size_t len = rdx_definitions_iter_len(iter); rdx_definitions_iter_free(iter); @@ -153,10 +130,7 @@ static VALUE rdxr_declaration_definitions(VALUE self) { } HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); void *iter = rdx_declaration_definitions_iter_new(graph, data->id); VALUE args = rb_ary_new_from_args(2, self, ULL2NUM((uintptr_t)iter)); @@ -173,10 +147,7 @@ static VALUE rdxr_declaration_definitions(VALUE self) { */ static VALUE rdxr_declaration_member(VALUE self, VALUE name) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); if (TYPE(name) != T_STRING) { rb_raise(rb_eTypeError, "expected String"); @@ -217,10 +188,7 @@ static VALUE rdxr_declaration_find_member(int argc, VALUE *argv, VALUE self) { } HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const CDeclaration *decl = rdx_declaration_find_member(graph, data->id, StringValueCStr(member), only_inherited); if (decl == NULL) { @@ -242,10 +210,7 @@ static VALUE rdxr_declaration_find_member(int argc, VALUE *argv, VALUE self) { */ static VALUE rdxr_declaration_singleton_class(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const CDeclaration *decl = rdx_declaration_singleton_class(graph, data->id); if (decl == NULL) { @@ -267,10 +232,7 @@ static VALUE rdxr_declaration_singleton_class(VALUE self) { */ static VALUE rdxr_declaration_owner(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const CDeclaration *decl = rdx_declaration_owner(graph, data->id); if (decl == NULL) { @@ -296,10 +258,7 @@ static VALUE rdxr_declaration_ancestors(VALUE self) { } HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); void *iter = rdx_declaration_ancestors(graph, data->id); if (iter == NULL) { @@ -324,10 +283,7 @@ static VALUE rdxr_declaration_descendants(VALUE self) { } HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); void *iter = rdx_declaration_descendants(graph, data->id); if (iter == NULL) { @@ -352,10 +308,7 @@ static VALUE rdxr_declaration_members(VALUE self) { } HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); void *iter = rdx_declaration_members(graph, data->id); if (iter == NULL) { @@ -371,10 +324,7 @@ static VALUE rdxr_declaration_members(VALUE self) { // Size function for constant declaration references enumerator static VALUE constant_declaration_references_size(VALUE self, VALUE _args, VALUE _eobj) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); struct ConstantReferencesIter *iter = rdx_declaration_constant_references_iter_new(graph, data->id); if (iter == NULL) { @@ -399,10 +349,7 @@ static VALUE rdxr_constant_declaration_references(VALUE self) { } HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); void *iter = rdx_declaration_constant_references_iter_new(graph, data->id); if (iter == NULL) { @@ -418,10 +365,7 @@ static VALUE rdxr_constant_declaration_references(VALUE self) { // Size function for method declaration references enumerator static VALUE method_declaration_references_size(VALUE self, VALUE _args, VALUE _eobj) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); struct MethodReferencesIter *iter = rdx_declaration_method_references_iter_new(graph, data->id); if (iter == NULL) { @@ -446,10 +390,7 @@ static VALUE rdxr_method_declaration_references(VALUE self) { } HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); void *iter = rdx_declaration_method_references_iter_new(graph, data->id); if (iter == NULL) { @@ -493,10 +434,7 @@ static VALUE rdxi_visibility_to_symbol(CVisibility visibility) { */ static VALUE rdxr_declaration_visibility(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const CVisibility *visibility = rdx_graph_visibility(graph, data->id); if (visibility == NULL) { @@ -518,10 +456,7 @@ static VALUE rdxr_declaration_visibility(VALUE self) { */ static VALUE rdxr_constant_alias_target(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const CDeclaration *decl = rdx_constant_alias_target(graph, data->id); if (decl == NULL) { diff --git a/ext/rubydex/definition.c b/ext/rubydex/definition.c index 58bd4ac7..a302083c 100644 --- a/ext/rubydex/definition.c +++ b/ext/rubydex/definition.c @@ -7,6 +7,7 @@ #include "signature.h" #include "ruby/internal/scan_args.h" #include "rustbindings.h" +#include "utils.h" /* * RDoc parser workaround for https://github.com/ruby/rdoc/issues/1744: @@ -84,10 +85,7 @@ VALUE rdxi_definition_class_for_kind(DefinitionKind kind) { */ static VALUE rdxr_definition_location(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); Location *loc = rdx_definition_location(graph, data->id); VALUE location = rdxi_build_location_value(loc); @@ -104,10 +102,7 @@ static VALUE rdxr_definition_location(VALUE self) { */ static VALUE rdxr_definition_comments(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); CommentArray *arr = rdx_definition_comments(graph, data->id); if (arr == NULL || arr->len == 0) { @@ -147,18 +142,10 @@ static VALUE rdxr_definition_comments(VALUE self) { */ static VALUE rdxr_definition_name(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const char *name = rdx_definition_name(graph, data->id); - if (name == NULL) { - return Qnil; - } - VALUE str = rb_utf8_str_new_cstr(name); - free_c_string(name); - return str; + return rdxi_owned_c_string_to_ruby(name); } /* @@ -169,10 +156,7 @@ static VALUE rdxr_definition_name(VALUE self) { */ static VALUE rdxr_definition_deprecated(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); bool deprecated = rdx_definition_is_deprecated(graph, data->id); return deprecated ? Qtrue : Qfalse; @@ -187,10 +171,7 @@ static VALUE rdxr_definition_deprecated(VALUE self) { */ static VALUE rdxr_definition_name_location(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); Location *loc = rdx_definition_name_location(graph, data->id); if (loc == NULL) { @@ -210,10 +191,7 @@ static VALUE rdxr_definition_name_location(VALUE self) { */ static VALUE rdxr_definition_declaration(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const struct CDeclaration *decl = rdx_definition_declaration(graph, data->id); if (decl == NULL) { @@ -243,10 +221,7 @@ static VALUE rdxi_build_definition(VALUE graph_obj, void *graph, uint64_t defini */ static VALUE rdxr_definition_lexical_owner(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const uint64_t *owner_id = rdx_definition_lexical_nesting_id(graph, data->id); if (owner_id == NULL) { @@ -267,10 +242,7 @@ static VALUE rdxr_definition_lexical_owner(VALUE self) { */ static VALUE rdxr_definition_lexical_nesting(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); VALUE nesting = rb_ary_new(); uint64_t definition_id = data->id; @@ -306,10 +278,7 @@ static VALUE rdxi_build_constant_reference(VALUE graph_obj, const CConstantRefer */ static VALUE rdxr_class_definition_superclass(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const CConstantReference *ref = rdx_class_definition_superclass(graph, data->id); if (ref == NULL) { @@ -342,10 +311,7 @@ static VALUE rdxi_mixin_class_for_kind(MixinKind kind) { */ static VALUE rdxr_definition_mixins(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); MixinsIter *iter = rdx_definition_mixins(graph, data->id); if (iter == NULL) { @@ -375,10 +341,7 @@ static VALUE rdxr_definition_mixins(VALUE self) { */ static VALUE rdxr_method_definition_signatures(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); SignatureArray *arr = rdx_definition_signatures(graph, data->id); return rdxi_signatures_to_ruby(arr); @@ -392,10 +355,7 @@ static VALUE rdxr_method_definition_signatures(VALUE self) { */ static VALUE rdxr_method_alias_definition_signatures(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); SignatureArray *arr = rdx_method_alias_definition_signatures(graph, data->id); return rdxi_signatures_to_ruby(arr); @@ -410,10 +370,7 @@ static VALUE rdxr_method_alias_definition_signatures(VALUE self) { */ static VALUE rdxr_method_alias_definition_target(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); CMethodAliasTargetResult result = rdx_method_alias_definition_target(graph, data->id); diff --git a/ext/rubydex/document.c b/ext/rubydex/document.c index 615463c1..8a7e5c93 100644 --- a/ext/rubydex/document.c +++ b/ext/rubydex/document.c @@ -20,20 +20,10 @@ VALUE cDocument; */ static VALUE rdxr_document_uri(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const char *uri = rdx_document_uri(graph, data->id); - if (uri == NULL) { - return Qnil; - } - - VALUE str = rb_utf8_str_new_cstr(uri); - free_c_string(uri); - - return str; + return rdxi_owned_c_string_to_ruby(uri); } // Body function for rb_ensure in Document#definitions @@ -66,10 +56,7 @@ static VALUE document_definitions_ensure(VALUE args) { // Size function for the Document#definitions enumerator static VALUE document_definitions_size(VALUE self, VALUE _args, VALUE _eobj) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); struct DefinitionsIter *iter = rdx_document_definitions_iter_new(graph, data->id); size_t len = rdx_definitions_iter_len(iter); rdx_definitions_iter_free(iter); @@ -89,10 +76,7 @@ static VALUE rdxr_document_definitions(VALUE self) { } HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); void *iter = rdx_document_definitions_iter_new(graph, data->id); VALUE args = rb_ary_new_from_args(2, self, ULL2NUM((uintptr_t)iter)); rb_ensure(document_definitions_yield, args, document_definitions_ensure, args); @@ -103,10 +87,7 @@ static VALUE rdxr_document_definitions(VALUE self) { // Size function for the Document#method_references enumerator static VALUE document_method_references_size(VALUE self, VALUE _args, VALUE _eobj) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); struct MethodReferencesIter *iter = rdx_document_method_references_iter_new(graph, data->id); size_t len = rdx_method_references_iter_len(iter); rdx_method_references_iter_free(iter); @@ -123,10 +104,7 @@ static VALUE rdxr_document_method_references(VALUE self) { } HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); void *iter = rdx_document_method_references_iter_new(graph, data->id); VALUE args = rb_ary_new_from_args(2, data->graph_obj, ULL2NUM((uintptr_t)iter)); rb_ensure(rdxi_method_references_yield, args, rdxi_method_references_ensure, args); diff --git a/ext/rubydex/graph.c b/ext/rubydex/graph.c index 4eb79eae..96174f5b 100644 --- a/ext/rubydex/graph.c +++ b/ext/rubydex/graph.c @@ -843,8 +843,7 @@ static VALUE rdxr_graph_workspace_path(VALUE self) { rb_raise(rb_eRuntimeError, "Converting workspace path to Ruby string failed"); } - VALUE path = rb_utf8_str_new_cstr(result); - free_c_string(result); + VALUE path = rdxi_owned_c_string_to_ruby(result); return path; } diff --git a/ext/rubydex/handle.h b/ext/rubydex/handle.h index dba57acd..cfd82c19 100644 --- a/ext/rubydex/handle.h +++ b/ext/rubydex/handle.h @@ -1,6 +1,7 @@ #ifndef RUBYDEX_HANDLE_H #define RUBYDEX_HANDLE_H +#include "graph.h" #include "ruby.h" typedef struct { @@ -34,6 +35,18 @@ static const rb_data_type_t handle_type = { .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; +static inline void *rdxi_graph_from_handle(VALUE self, HandleData **out_data) { + HandleData *data; + TypedData_Get_Struct(self, HandleData, &handle_type, data); + + void *graph; + TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + + *out_data = data; + + return graph; +} + static VALUE rdxr_handle_alloc(VALUE klass) { HandleData *data = ALLOC(HandleData); diff --git a/ext/rubydex/reference.c b/ext/rubydex/reference.c index bf0a656a..8d7e6c67 100644 --- a/ext/rubydex/reference.c +++ b/ext/rubydex/reference.c @@ -4,6 +4,7 @@ #include "handle.h" #include "location.h" #include "rustbindings.h" +#include "utils.h" /* * RDoc parser workaround for https://github.com/ruby/rdoc/issues/1744: @@ -24,19 +25,10 @@ VALUE cMethodReference; */ static VALUE rdxr_constant_reference_name(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const char *name = rdx_constant_reference_name(graph, data->id); - if (name == NULL) { - return Qnil; - } - - VALUE str = rb_utf8_str_new_cstr(name); - free_c_string(name); - return str; + return rdxi_owned_c_string_to_ruby(name); } /* @@ -47,10 +39,7 @@ static VALUE rdxr_constant_reference_name(VALUE self) { */ static VALUE rdxr_constant_reference_location(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); Location *loc = rdx_constant_reference_location(graph, data->id); VALUE location = rdxi_build_location_value(loc); @@ -66,19 +55,10 @@ static VALUE rdxr_constant_reference_location(VALUE self) { */ static VALUE rdxr_method_reference_name(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const char *name = rdx_method_reference_name(graph, data->id); - if (name == NULL) { - return Qnil; - } - - VALUE str = rb_utf8_str_new_cstr(name); - free_c_string(name); - return str; + return rdxi_owned_c_string_to_ruby(name); } /* @@ -89,10 +69,7 @@ static VALUE rdxr_method_reference_name(VALUE self) { */ static VALUE rdxr_method_reference_location(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); Location *loc = rdx_method_reference_location(graph, data->id); VALUE location = rdxi_build_location_value(loc); @@ -109,10 +86,7 @@ static VALUE rdxr_method_reference_location(VALUE self) { */ static VALUE rdxr_method_reference_receiver(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const struct CDeclaration *decl = rdx_method_reference_receiver_declaration(graph, data->id); if (decl == NULL) { @@ -134,10 +108,7 @@ static VALUE rdxr_method_reference_receiver(VALUE self) { */ static VALUE rdxr_resolved_constant_reference_declaration(VALUE self) { HandleData *data; - TypedData_Get_Struct(self, HandleData, &handle_type, data); - - void *graph; - TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph); + void *graph = rdxi_graph_from_handle(self, &data); const struct CDeclaration *decl = rdx_resolved_constant_reference_declaration(graph, data->id); if (decl == NULL) { diff --git a/ext/rubydex/utils.c b/ext/rubydex/utils.c index 5860a8dd..bf046e86 100644 --- a/ext/rubydex/utils.c +++ b/ext/rubydex/utils.c @@ -39,6 +39,19 @@ void rdxi_check_array_of_strings(VALUE array) { } } +// Convert a Rust-owned C string to a Ruby string and release it with free_c_string. +// Returns nil when the Rust side returned NULL. +VALUE rdxi_owned_c_string_to_ruby(const char *string) { + if (string == NULL) { + return Qnil; + } + + VALUE value = rb_utf8_str_new_cstr(string); + free_c_string(string); + + return value; +} + // Yield body for iterating over declarations VALUE rdxi_declarations_yield(VALUE args) { VALUE self = rb_ary_entry(args, 0); diff --git a/ext/rubydex/utils.h b/ext/rubydex/utils.h index 627ce477..9a72646c 100644 --- a/ext/rubydex/utils.h +++ b/ext/rubydex/utils.h @@ -13,6 +13,10 @@ void rdxi_free_str_array(char **array, size_t length); // Verify that the Ruby object is an array of strings or raise `TypeError` void rdxi_check_array_of_strings(VALUE array); +// Convert a Rust-owned C string to a Ruby string and release it with free_c_string. +// Returns nil when the Rust side returned NULL. +VALUE rdxi_owned_c_string_to_ruby(const char *string); + // Yield body for iterating over declarations VALUE rdxi_declarations_yield(VALUE args);