Skip to content

Commit 78a0c48

Browse files
committed
Support to build with Ruby 4.1
* Handle RB_OBJ_INFECT * Use TypedData instead of Data_Wrap_Struct
1 parent 1e5f537 commit 78a0c48

2 files changed

Lines changed: 27 additions & 10 deletions

File tree

ext/iconv/extconf.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
raise "vasprintf is required for Ruby 1.8"
1010
end
1111
have_func("rb_sys_fail_str", "ruby.h")
12+
# Check if OBJ_INFECT macro is available (removed in Ruby 3.0+)
13+
if try_compile(<<SRC, opt: "-Werror")
14+
#include "ruby.h"
15+
int main(void) { VALUE v = Qnil; OBJ_INFECT(v, v); return 0; }
16+
SRC
17+
$defs.push("-DHAVE_OBJ_INFECT")
18+
end
1219
if have_func("iconv", "iconv.h") or
1320
have_library("iconv", "iconv", "iconv.h")
1421
check_signedness("size_t") rescue nil

ext/iconv/iconv.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ static VALUE iconv_try _((iconv_t cd, const char **inptr, size_t *inlen, char **
185185
static VALUE rb_str_derive _((VALUE str, const char* ptr, long len));
186186
static VALUE iconv_convert _((iconv_t cd, VALUE str, long start, long length, int toidx,
187187
struct iconv_env_t* env));
188+
static const rb_data_type_t iconv_type;
188189
static VALUE iconv_s_allocate _((VALUE klass));
189190
static VALUE iconv_initialize _((int argc, VALUE *argv, VALUE self));
190191
static VALUE iconv_s_open _((int argc, VALUE *argv, VALUE self));
@@ -368,6 +369,13 @@ iconv_dfree(void *cd)
368369

369370
#define ICONV_FREE iconv_dfree
370371

372+
static const rb_data_type_t iconv_type = {
373+
"iconv",
374+
{NULL, iconv_dfree, NULL},
375+
NULL, NULL,
376+
RUBY_TYPED_FREE_IMMEDIATELY
377+
};
378+
371379
static VALUE
372380
iconv_free(VALUE cd)
373381
{
@@ -379,11 +387,10 @@ iconv_free(VALUE cd)
379387
static VALUE
380388
check_iconv(VALUE obj)
381389
{
382-
Check_Type(obj, T_DATA);
383-
if (RDATA(obj)->dfree != ICONV_FREE) {
390+
if (!rb_typeddata_is_kind_of(obj, &iconv_type)) {
384391
rb_raise(rb_eArgError, "Iconv expected (%s)", rb_class2name(CLASS_OF(obj)));
385392
}
386-
return (VALUE)DATA_PTR(obj);
393+
return (VALUE)RTYPEDDATA_DATA(obj);
387394
}
388395

389396
static VALUE
@@ -483,7 +490,9 @@ rb_str_derive(VALUE str, const char* ptr, long len)
483490
ret = rb_str_subseq(str, ptr - RSTRING_PTR(str), len);
484491
else
485492
ret = rb_str_new(ptr, len);
493+
#ifdef HAVE_OBJ_INFECT
486494
OBJ_INFECT(ret, str);
495+
#endif
487496
return ret;
488497
}
489498

@@ -576,7 +585,9 @@ iconv_convert(iconv_t cd, VALUE str, long start, long length, int toidx, struct
576585
#ifdef HAVE_RUBY_ENCODING_H
577586
if (toidx >= 0) rb_enc_associate_index(ret, toidx);
578587
#endif
588+
#ifdef HAVE_OBJ_INFECT
579589
OBJ_INFECT(ret, str);
590+
#endif
580591
}
581592
ret = rb_str_buf_cat(ret, buffer, outlen);
582593
instart = inptr;
@@ -638,7 +649,7 @@ iconv_convert(iconv_t cd, VALUE str, long start, long length, int toidx, struct
638649
static VALUE
639650
iconv_s_allocate(VALUE klass)
640651
{
641-
return Data_Wrap_Struct(klass, 0, ICONV_FREE, 0);
652+
return TypedData_Wrap_Struct(klass, &iconv_type, 0);
642653
}
643654

644655
static VALUE
@@ -743,8 +754,8 @@ iconv_initialize(int argc, VALUE *argv, VALUE self)
743754
rb_scan_args(argc, argv, "21", &to, &from, &options);
744755
get_iconv_opt(&opt, options);
745756
iconv_free(check_iconv(self));
746-
DATA_PTR(self) = NULL;
747-
DATA_PTR(self) = (void *)ICONV2VALUE(iconv_create(to, from, &opt, &idx));
757+
RTYPEDDATA_DATA(self) = NULL;
758+
RTYPEDDATA_DATA(self) = (void *)ICONV2VALUE(iconv_create(to, from, &opt, &idx));
748759
#ifdef HAVE_RUBY_ENCODING_H
749760
ICONV_ENCODING_SET(self, idx);
750761
#endif
@@ -770,7 +781,7 @@ iconv_s_open(int argc, VALUE *argv, VALUE self)
770781
get_iconv_opt(&opt, options);
771782
cd = ICONV2VALUE(iconv_create(to, from, &opt, &idx));
772783

773-
self = Data_Wrap_Struct(self, NULL, ICONV_FREE, (void *)cd);
784+
self = TypedData_Wrap_Struct(self, &iconv_type, (void *)cd);
774785
#ifdef HAVE_RUBY_ENCODING_H
775786
if (idx >= 0) ICONV_ENCODING_SET(self, idx);
776787
#endif
@@ -957,8 +968,8 @@ iconv_s_list(VALUE klass)
957968
static VALUE
958969
iconv_init_state(VALUE self)
959970
{
960-
iconv_t cd = VALUE2ICONV((VALUE)DATA_PTR(self));
961-
DATA_PTR(self) = NULL;
971+
iconv_t cd = VALUE2ICONV((VALUE)RTYPEDDATA_DATA(self));
972+
RTYPEDDATA_DATA(self) = NULL;
962973
return iconv_convert(cd, Qnil, 0, 0, ICONV_ENCODING_GET(self), NULL);
963974
}
964975

@@ -1330,4 +1341,3 @@ Init_iconv(void)
13301341
charset_map = rb_hash_new();
13311342
rb_define_singleton_method(rb_cIconv, "charset_map", charset_map_get, 0);
13321343
}
1333-

0 commit comments

Comments
 (0)