summaryrefslogtreecommitdiff
path: root/spec/ruby/optional/capi/ext
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/optional/capi/ext')
-rw-r--r--spec/ruby/optional/capi/ext/array_spec.c36
-rw-r--r--spec/ruby/optional/capi/ext/class_spec.c46
-rw-r--r--spec/ruby/optional/capi/ext/constants_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/data_spec.c4
-rw-r--r--spec/ruby/optional/capi/ext/debug_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/digest_spec.c168
-rw-r--r--spec/ruby/optional/capi/ext/encoding_spec.c61
-rw-r--r--spec/ruby/optional/capi/ext/exception_spec.c27
-rw-r--r--spec/ruby/optional/capi/ext/fiber_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/finalizer_spec.c25
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c89
-rw-r--r--spec/ruby/optional/capi/ext/globals_spec.c34
-rw-r--r--spec/ruby/optional/capi/ext/hash_spec.c20
-rw-r--r--spec/ruby/optional/capi/ext/integer_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/io_spec.c173
-rw-r--r--spec/ruby/optional/capi/ext/kernel_spec.c115
-rw-r--r--spec/ruby/optional/capi/ext/module_spec.c56
-rw-r--r--spec/ruby/optional/capi/ext/mutex_spec.c23
-rw-r--r--spec/ruby/optional/capi/ext/object_spec.c158
-rw-r--r--spec/ruby/optional/capi/ext/proc_spec.c74
-rw-r--r--spec/ruby/optional/capi/ext/range_spec.c50
-rw-r--r--spec/ruby/optional/capi/ext/rbasic_spec.c72
-rw-r--r--spec/ruby/optional/capi/ext/regexp_spec.c7
-rw-r--r--spec/ruby/optional/capi/ext/rubyspec.h73
-rw-r--r--spec/ruby/optional/capi/ext/set_spec.c65
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c127
-rw-r--r--spec/ruby/optional/capi/ext/struct_spec.c46
-rw-r--r--spec/ruby/optional/capi/ext/symbol_spec.c11
-rw-r--r--spec/ruby/optional/capi/ext/thread_spec.c61
-rw-r--r--spec/ruby/optional/capi/ext/tracepoint_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/typed_data_spec.c14
-rw-r--r--spec/ruby/optional/capi/ext/util_spec.c34
32 files changed, 1299 insertions, 391 deletions
diff --git a/spec/ruby/optional/capi/ext/array_spec.c b/spec/ruby/optional/capi/ext/array_spec.c
index 9386239813..628c4df9d7 100644
--- a/spec/ruby/optional/capi/ext/array_spec.c
+++ b/spec/ruby/optional/capi/ext/array_spec.c
@@ -196,6 +196,16 @@ static VALUE copy_ary(RB_BLOCK_CALL_FUNC_ARGLIST(el, new_ary)) {
return rb_ary_push(new_ary, el);
}
+#ifndef RUBY_VERSION_IS_4_0
+static VALUE array_spec_rb_iterate(VALUE self, VALUE ary) {
+ VALUE new_ary = rb_ary_new();
+
+ rb_iterate(rb_each, ary, copy_ary, new_ary);
+
+ return new_ary;
+}
+#endif
+
static VALUE array_spec_rb_block_call(VALUE self, VALUE ary) {
VALUE new_ary = rb_ary_new();
@@ -208,6 +218,20 @@ static VALUE sub_pair(RB_BLOCK_CALL_FUNC_ARGLIST(el, holder)) {
return rb_ary_push(holder, rb_ary_entry(el, 1));
}
+#ifndef RUBY_VERSION_IS_4_0
+static VALUE each_pair(VALUE obj) {
+ return rb_funcall(obj, rb_intern("each_pair"), 0);
+}
+
+static VALUE array_spec_rb_iterate_each_pair(VALUE self, VALUE obj) {
+ VALUE new_ary = rb_ary_new();
+
+ rb_iterate(each_pair, obj, sub_pair, new_ary);
+
+ return new_ary;
+}
+#endif
+
static VALUE array_spec_rb_block_call_each_pair(VALUE self, VALUE obj) {
VALUE new_ary = rb_ary_new();
@@ -221,6 +245,13 @@ static VALUE iter_yield(RB_BLOCK_CALL_FUNC_ARGLIST(el, ary)) {
return Qnil;
}
+#ifndef RUBY_VERSION_IS_4_0
+static VALUE array_spec_rb_iterate_then_yield(VALUE self, VALUE obj) {
+ rb_iterate(rb_each, obj, iter_yield, obj);
+ return Qnil;
+}
+#endif
+
static VALUE array_spec_rb_block_call_then_yield(VALUE self, VALUE obj) {
rb_block_call(obj, rb_intern("each"), 0, 0, iter_yield, obj);
return Qnil;
@@ -283,6 +314,11 @@ void Init_array_spec(void) {
rb_define_method(cls, "rb_ary_plus", array_spec_rb_ary_plus, 2);
rb_define_method(cls, "rb_ary_unshift", array_spec_rb_ary_unshift, 2);
rb_define_method(cls, "rb_assoc_new", array_spec_rb_assoc_new, 2);
+#ifndef RUBY_VERSION_IS_4_0
+ rb_define_method(cls, "rb_iterate", array_spec_rb_iterate, 1);
+ rb_define_method(cls, "rb_iterate_each_pair", array_spec_rb_iterate_each_pair, 1);
+ rb_define_method(cls, "rb_iterate_then_yield", array_spec_rb_iterate_then_yield, 1);
+#endif
rb_define_method(cls, "rb_block_call", array_spec_rb_block_call, 1);
rb_define_method(cls, "rb_block_call_each_pair", array_spec_rb_block_call_each_pair, 1);
rb_define_method(cls, "rb_block_call_then_yield", array_spec_rb_block_call_then_yield, 1);
diff --git a/spec/ruby/optional/capi/ext/class_spec.c b/spec/ruby/optional/capi/ext/class_spec.c
index 36b8c8f2f3..8ac0e7a93f 100644
--- a/spec/ruby/optional/capi/ext/class_spec.c
+++ b/spec/ruby/optional/capi/ext/class_spec.c
@@ -61,27 +61,26 @@ static VALUE class_spec_rb_class_new(VALUE self, VALUE super) {
return rb_class_new(super);
}
-static VALUE class_spec_rb_class_new_instance(VALUE self,
- VALUE nargs, VALUE args,
- VALUE klass) {
- int c_nargs = FIX2INT(nargs);
- VALUE *c_args = (VALUE*)alloca(sizeof(VALUE) * c_nargs);
- int i;
-
- for (i = 0; i < c_nargs; i++)
- c_args[i] = rb_ary_entry(args, i);
+static VALUE class_spec_rb_class_new_instance(VALUE self, VALUE args, VALUE klass) {
+ return rb_class_new_instance(RARRAY_LENINT(args), RARRAY_PTR(args), klass);
+}
- return rb_class_new_instance(c_nargs, c_args, klass);
+static VALUE class_spec_rb_class_new_instance_kw(VALUE self, VALUE args, VALUE klass) {
+ return rb_class_new_instance_kw(RARRAY_LENINT(args), RARRAY_PTR(args), klass, RB_PASS_KEYWORDS);
}
static VALUE class_spec_rb_class_real(VALUE self, VALUE object) {
- if(rb_type_p(object, T_FIXNUM)) {
+ if (rb_type_p(object, T_FIXNUM)) {
return INT2FIX(rb_class_real(FIX2INT(object)));
} else {
return rb_class_real(CLASS_OF(object));
}
}
+static VALUE class_spec_rb_class_get_superclass(VALUE self, VALUE klass) {
+ return rb_class_get_superclass(klass);
+}
+
static VALUE class_spec_rb_class_superclass(VALUE self, VALUE klass) {
return rb_class_superclass(klass);
}
@@ -119,19 +118,19 @@ VALUE class_spec_define_attr(VALUE self, VALUE klass, VALUE sym, VALUE read, VAL
}
static VALUE class_spec_rb_define_class(VALUE self, VALUE name, VALUE super) {
- if(NIL_P(super)) super = 0;
+ if (NIL_P(super)) super = 0;
return rb_define_class(RSTRING_PTR(name), super);
}
static VALUE class_spec_rb_define_class_under(VALUE self, VALUE outer,
VALUE name, VALUE super) {
- if(NIL_P(super)) super = 0;
+ if (NIL_P(super)) super = 0;
return rb_define_class_under(outer, RSTRING_PTR(name), super);
}
static VALUE class_spec_rb_define_class_id_under(VALUE self, VALUE outer,
VALUE name, VALUE super) {
- if(NIL_P(super)) super = 0;
+ if (NIL_P(super)) super = 0;
return rb_define_class_id_under(outer, SYM2ID(name), super);
}
@@ -145,19 +144,6 @@ static VALUE class_spec_include_module(VALUE self, VALUE klass, VALUE module) {
return klass;
}
-static VALUE class_spec_method_var_args_1(int argc, VALUE *argv, VALUE self) {
- VALUE ary = rb_ary_new();
- int i;
- for (i = 0; i < argc; i++) {
- rb_ary_push(ary, argv[i]);
- }
- return ary;
-}
-
-static VALUE class_spec_method_var_args_2(VALUE self, VALUE argv) {
- return argv;
-}
-
void Init_class_spec(void) {
VALUE cls = rb_define_class("CApiClassSpecs", rb_cObject);
rb_define_method(cls, "define_call_super_method", class_spec_define_call_super_method, 2);
@@ -171,8 +157,10 @@ void Init_class_spec(void) {
rb_define_method(cls, "rb_class_protected_instance_methods", class_spec_rb_class_protected_instance_methods, -1);
rb_define_method(cls, "rb_class_private_instance_methods", class_spec_rb_class_private_instance_methods, -1);
rb_define_method(cls, "rb_class_new", class_spec_rb_class_new, 1);
- rb_define_method(cls, "rb_class_new_instance", class_spec_rb_class_new_instance, 3);
+ rb_define_method(cls, "rb_class_new_instance", class_spec_rb_class_new_instance, 2);
+ rb_define_method(cls, "rb_class_new_instance_kw", class_spec_rb_class_new_instance_kw, 2);
rb_define_method(cls, "rb_class_real", class_spec_rb_class_real, 1);
+ rb_define_method(cls, "rb_class_get_superclass", class_spec_rb_class_get_superclass, 1);
rb_define_method(cls, "rb_class_superclass", class_spec_rb_class_superclass, 1);
rb_define_method(cls, "rb_cvar_defined", class_spec_cvar_defined, 2);
rb_define_method(cls, "rb_cvar_get", class_spec_cvar_get, 2);
@@ -185,8 +173,6 @@ void Init_class_spec(void) {
rb_define_method(cls, "rb_define_class_id_under", class_spec_rb_define_class_id_under, 3);
rb_define_method(cls, "rb_define_class_variable", class_spec_define_class_variable, 3);
rb_define_method(cls, "rb_include_module", class_spec_include_module, 2);
- rb_define_method(cls, "rb_method_varargs_1", class_spec_method_var_args_1, -1);
- rb_define_method(cls, "rb_method_varargs_2", class_spec_method_var_args_2, -2);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/constants_spec.c b/spec/ruby/optional/capi/ext/constants_spec.c
index 9aee8db37f..05819ea476 100644
--- a/spec/ruby/optional/capi/ext/constants_spec.c
+++ b/spec/ruby/optional/capi/ext/constants_spec.c
@@ -14,9 +14,6 @@ defconstfunc(rb_cBinding)
defconstfunc(rb_cClass)
defconstfunc(rb_cComplex)
defconstfunc(rb_mComparable)
-#ifndef RUBY_VERSION_IS_3_0
-defconstfunc(rb_cData)
-#endif
defconstfunc(rb_cDir)
defconstfunc(rb_cEncoding)
defconstfunc(rb_mEnumerable)
@@ -97,9 +94,6 @@ void Init_constants_spec(void) {
rb_define_method(cls, "rb_cClass", constants_spec_rb_cClass, 0);
rb_define_method(cls, "rb_cComplex", constants_spec_rb_cComplex, 0);
rb_define_method(cls, "rb_mComparable", constants_spec_rb_mComparable, 0);
- #ifndef RUBY_VERSION_IS_3_0
- rb_define_method(cls, "rb_cData", constants_spec_rb_cData, 0);
- #endif
rb_define_method(cls, "rb_cDir", constants_spec_rb_cDir, 0);
rb_define_method(cls, "rb_cEncoding", constants_spec_rb_cEncoding, 0);
rb_define_method(cls, "rb_mEnumerable", constants_spec_rb_mEnumerable, 0);
diff --git a/spec/ruby/optional/capi/ext/data_spec.c b/spec/ruby/optional/capi/ext/data_spec.c
index ef069ef0ba..efefe37c3a 100644
--- a/spec/ruby/optional/capi/ext/data_spec.c
+++ b/spec/ruby/optional/capi/ext/data_spec.c
@@ -3,6 +3,7 @@
#include <string.h>
+#ifndef RUBY_VERSION_IS_3_4
#ifdef __cplusplus
extern "C" {
#endif
@@ -70,8 +71,10 @@ VALUE sws_rb_check_type(VALUE self, VALUE obj, VALUE other) {
rb_check_type(obj, TYPE(other));
return Qtrue;
}
+#endif
void Init_data_spec(void) {
+#ifndef RUBY_VERSION_IS_3_4
VALUE cls = rb_define_class("CApiAllocSpecs", rb_cObject);
rb_define_alloc_func(cls, sdaf_alloc_func);
rb_define_method(cls, "wrapped_data", sdaf_get_struct, 0);
@@ -82,6 +85,7 @@ void Init_data_spec(void) {
rb_define_method(cls, "get_struct_data_ptr", sws_get_struct_data_ptr, 1);
rb_define_method(cls, "change_struct", sws_change_struct, 2);
rb_define_method(cls, "rb_check_type", sws_rb_check_type, 2);
+#endif
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/debug_spec.c b/spec/ruby/optional/capi/ext/debug_spec.c
index 344dfc33fa..9131eda78b 100644
--- a/spec/ruby/optional/capi/ext/debug_spec.c
+++ b/spec/ruby/optional/capi/ext/debug_spec.c
@@ -45,7 +45,7 @@ static VALUE rb_debug_inspector_frame_iseq_get_callback(const rb_debug_inspector
return rb_debug_inspector_frame_iseq_get(dc, NUM2LONG((VALUE) ptr));
}
-static VALUE debug_spec_callback_data(VALUE self){
+static VALUE debug_spec_callback_data(VALUE self) {
return callback_data;
}
diff --git a/spec/ruby/optional/capi/ext/digest_spec.c b/spec/ruby/optional/capi/ext/digest_spec.c
new file mode 100644
index 0000000000..65c8defa20
--- /dev/null
+++ b/spec/ruby/optional/capi/ext/digest_spec.c
@@ -0,0 +1,168 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#include "ruby/digest.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DIGEST_LENGTH 20
+#define BLOCK_LENGTH 40
+
+const char *init_string = "Initialized\n";
+const char *update_string = "Updated: ";
+const char *finish_string = "Finished\n";
+
+#define PAYLOAD_SIZE 128
+
+typedef struct CTX {
+ uint8_t pos;
+ char payload[PAYLOAD_SIZE];
+} CTX;
+
+void* context = NULL;
+
+int digest_spec_plugin_init(void *raw_ctx) {
+ // Make the context accessible to tests. This isn't safe, but there's no way to access the context otherwise.
+ context = raw_ctx;
+
+ struct CTX *ctx = (struct CTX *)raw_ctx;
+ size_t len = strlen(init_string);
+
+ // Clear the payload since this init function will be invoked as part of the `reset` operation.
+ memset(ctx->payload, 0, PAYLOAD_SIZE);
+
+ // Write a simple value we can verify in tests.
+ // This is not what a real digest would do, but we're using a dummy digest plugin to test interactions.
+ memcpy(ctx->payload, init_string, len);
+ ctx->pos = (uint8_t) len;
+
+ return 1;
+}
+
+void digest_spec_plugin_update(void *raw_ctx, unsigned char *ptr, size_t size) {
+ struct CTX *ctx = (struct CTX *)raw_ctx;
+ size_t update_str_len = strlen(update_string);
+
+ if (ctx->pos + update_str_len + size >= PAYLOAD_SIZE) {
+ rb_raise(rb_eRuntimeError, "update size too large; reset the digest and write fewer updates");
+ }
+
+ // Write the supplied value to the payload so it can be easily verified in test.
+ // This is not what a real digest would do, but we're using a dummy digest plugin to test interactions.
+ memcpy(ctx->payload + ctx->pos, update_string, update_str_len);
+ ctx->pos += update_str_len;
+
+ memcpy(ctx->payload + ctx->pos, ptr, size);
+ ctx->pos += size;
+
+ return;
+}
+
+int digest_spec_plugin_finish(void *raw_ctx, unsigned char *ptr) {
+ struct CTX *ctx = (struct CTX *)raw_ctx;
+ size_t finish_string_len = strlen(finish_string);
+
+ // We're always going to write DIGEST_LENGTH bytes. In a real plugin, this would be the digest value. Here we
+ // write out a text string in order to make validation in tests easier.
+ //
+ // In order to delineate the output more clearly from an `Digest#update` call, we always write out the
+ // `finish_string` message. That leaves `DIGEST_LENGTH - finish_string_len` bytes to read out of the context.
+ size_t context_bytes = DIGEST_LENGTH - finish_string_len;
+
+ memcpy(ptr, ctx->payload + (ctx->pos - context_bytes), context_bytes);
+ memcpy(ptr + context_bytes, finish_string, finish_string_len);
+
+ return 1;
+}
+
+static const rb_digest_metadata_t metadata = {
+ // The RUBY_DIGEST_API_VERSION value comes from ruby/digest.h and may vary based on the Ruby being tested. Since
+ // it isn't publicly exposed in the digest gem, we ignore for these tests. Either the test hard-codes an expected
+ // value and is subject to breaking depending on the Ruby being run or we publicly expose `RUBY_DIGEST_API_VERSION`,
+ // in which case the test would pass trivially.
+ RUBY_DIGEST_API_VERSION,
+ DIGEST_LENGTH,
+ BLOCK_LENGTH,
+ sizeof(CTX),
+ (rb_digest_hash_init_func_t) digest_spec_plugin_init,
+ (rb_digest_hash_update_func_t) digest_spec_plugin_update,
+ (rb_digest_hash_finish_func_t) digest_spec_plugin_finish,
+};
+
+// The `get_metadata_ptr` function is not publicly available in the digest gem. However, we need to use
+// to extract the `rb_digest_metadata_t*` value set up by the plugin so we reproduce and adjust the
+// definition here.
+//
+// Taken and adapted from https://github.com/ruby/digest/blob/v3.2.0/ext/digest/digest.c#L558-L568
+static rb_digest_metadata_t * get_metadata_ptr(VALUE obj) {
+ rb_digest_metadata_t *algo;
+
+#ifdef DIGEST_USE_RB_EXT_RESOLVE_SYMBOL
+ // In the digest gem there is an additional data type check performed before reading the value out.
+ // Since the type definition isn't public, we can't use it as part of a type check here so we omit it.
+ // This is safe to do because this code is intended to only load digest plugins written as part of this test suite.
+ algo = (rb_digest_metadata_t *) RTYPEDDATA_DATA(obj);
+#else
+# undef RUBY_UNTYPED_DATA_WARNING
+# define RUBY_UNTYPED_DATA_WARNING 0
+ Data_Get_Struct(obj, rb_digest_metadata_t, algo);
+#endif
+
+ return algo;
+}
+
+VALUE digest_spec_rb_digest_make_metadata(VALUE self) {
+ return rb_digest_make_metadata(&metadata);
+}
+
+VALUE digest_spec_block_length(VALUE self, VALUE meta) {
+ rb_digest_metadata_t* algo = get_metadata_ptr(meta);
+
+ return SIZET2NUM(algo->block_len);
+}
+
+VALUE digest_spec_digest_length(VALUE self, VALUE meta) {
+ rb_digest_metadata_t* algo = get_metadata_ptr(meta);
+
+ return SIZET2NUM(algo->digest_len);
+}
+
+VALUE digest_spec_context_size(VALUE self, VALUE meta) {
+ rb_digest_metadata_t* algo = get_metadata_ptr(meta);
+
+ return SIZET2NUM(algo->ctx_size);
+}
+
+#ifndef PTR2NUM
+#define PTR2NUM(x) (rb_int2inum((intptr_t)(void *)(x)))
+#endif
+
+VALUE digest_spec_context(VALUE self, VALUE digest) {
+ return PTR2NUM(context);
+}
+
+void Init_digest_spec(void) {
+ VALUE cls;
+
+ cls = rb_define_class("CApiDigestSpecs", rb_cObject);
+ rb_define_method(cls, "rb_digest_make_metadata", digest_spec_rb_digest_make_metadata, 0);
+ rb_define_method(cls, "block_length", digest_spec_block_length, 1);
+ rb_define_method(cls, "digest_length", digest_spec_digest_length, 1);
+ rb_define_method(cls, "context_size", digest_spec_context_size, 1);
+ rb_define_method(cls, "context", digest_spec_context, 1);
+
+ VALUE mDigest, cDigest_Base, cDigest;
+
+ mDigest = rb_define_module("Digest");
+ mDigest = rb_digest_namespace();
+ cDigest_Base = rb_const_get(mDigest, rb_intern_const("Base"));
+
+ cDigest = rb_define_class_under(mDigest, "TestDigest", cDigest_Base);
+ rb_iv_set(cDigest, "metadata", rb_digest_make_metadata(&metadata));
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/spec/ruby/optional/capi/ext/encoding_spec.c b/spec/ruby/optional/capi/ext/encoding_spec.c
index cde4d0c351..aa8662cfbd 100644
--- a/spec/ruby/optional/capi/ext/encoding_spec.c
+++ b/spec/ruby/optional/capi/ext/encoding_spec.c
@@ -12,7 +12,7 @@ static VALUE encoding_spec_MBCLEN_CHARFOUND_P(VALUE self, VALUE obj) {
}
static VALUE encoding_spec_ENC_CODERANGE_ASCIIONLY(VALUE self, VALUE obj) {
- if(ENC_CODERANGE_ASCIIONLY(obj)) {
+ if (ENC_CODERANGE_ASCIIONLY(obj)) {
return Qtrue;
} else {
return Qfalse;
@@ -61,21 +61,19 @@ static VALUE encoding_spec_rb_filesystem_encindex(VALUE self) {
static VALUE encoding_spec_rb_default_internal_encoding(VALUE self) {
rb_encoding* enc = rb_default_internal_encoding();
- if(enc == 0) return Qnil;
+ if (enc == 0) return Qnil;
return rb_str_new2(enc->name);
}
static VALUE encoding_spec_rb_default_external_encoding(VALUE self) {
rb_encoding* enc = rb_default_external_encoding();
- if(enc == 0) return Qnil;
+ if (enc == 0) return Qnil;
return rb_str_new2(enc->name);
}
-#ifdef RUBY_VERSION_IS_2_6
static VALUE encoding_spec_rb_enc_alias(VALUE self, VALUE alias, VALUE orig) {
return INT2NUM(rb_enc_alias(RSTRING_PTR(alias), RSTRING_PTR(orig)));
}
-#endif
static VALUE encoding_spec_rb_enc_associate(VALUE self, VALUE obj, VALUE enc) {
return rb_enc_associate(obj, NIL_P(enc) ? NULL : rb_enc_find(RSTRING_PTR(enc)));
@@ -88,7 +86,7 @@ static VALUE encoding_spec_rb_enc_associate_index(VALUE self, VALUE obj, VALUE i
static VALUE encoding_spec_rb_enc_compatible(VALUE self, VALUE a, VALUE b) {
rb_encoding* enc = rb_enc_compatible(a, b);
- if(!enc) return INT2FIX(0);
+ if (!enc) return INT2FIX(0);
return rb_enc_from_encoding(enc);
}
@@ -120,10 +118,9 @@ static VALUE encoding_spec_rb_enc_from_index(VALUE self, VALUE index) {
return rb_str_new2(rb_enc_from_index(NUM2INT(index))->name);
}
-static VALUE encoding_spec_rb_enc_mbc_to_codepoint(VALUE self, VALUE str, VALUE offset) {
- int o = FIX2INT(offset);
+static VALUE encoding_spec_rb_enc_mbc_to_codepoint(VALUE self, VALUE str) {
char *p = RSTRING_PTR(str);
- char *e = p + o;
+ char *e = RSTRING_END(str);
return INT2FIX(rb_enc_mbc_to_codepoint(p, e, rb_enc_get(str)));
}
@@ -274,8 +271,17 @@ static VALUE encoding_spec_rb_enc_str_asciionly_p(VALUE self, VALUE str) {
}
}
+static VALUE encoding_spec_rb_enc_raise(VALUE self, VALUE encoding, VALUE exception_class, VALUE format) {
+ rb_encoding *e = rb_to_encoding(encoding);
+ const char *f = RSTRING_PTR(format);
+
+ rb_enc_raise(e, exception_class, "%s", f);
+}
+
static VALUE encoding_spec_rb_uv_to_utf8(VALUE self, VALUE buf, VALUE num) {
- return INT2NUM(rb_uv_to_utf8(RSTRING_PTR(buf), NUM2INT(num)));
+ int len = rb_uv_to_utf8(RSTRING_PTR(buf), NUM2INT(num));
+ RB_ENC_CODERANGE_CLEAR(buf);
+ return INT2NUM(len);
}
static VALUE encoding_spec_ONIGENC_MBC_CASE_FOLD(VALUE self, VALUE str) {
@@ -300,6 +306,24 @@ static VALUE encoding_spec_rb_enc_codelen(VALUE self, VALUE code, VALUE encoding
return INT2FIX(rb_enc_codelen(c, enc));
}
+static VALUE encoding_spec_rb_enc_strlen(VALUE self, VALUE str, VALUE length, VALUE encoding) {
+ int l = FIX2INT(length);
+ char *p = RSTRING_PTR(str);
+ char *e = p + l;
+
+ return LONG2FIX(rb_enc_strlen(p, e, rb_to_encoding(encoding)));
+}
+
+static VALUE encoding_spec_rb_enc_left_char_head(VALUE self, VALUE str, VALUE offset) {
+ char *ptr = RSTRING_PTR(str);
+ char *result = rb_enc_left_char_head(ptr, ptr + NUM2INT(offset), RSTRING_END(str), rb_enc_get(str));
+ return LONG2NUM(result - ptr);
+}
+
+static VALUE encoding_spec_rb_define_dummy_encoding(VALUE self, VALUE name) {
+ return INT2NUM(rb_define_dummy_encoding(RSTRING_PTR(name)));
+}
+
void Init_encoding_spec(void) {
VALUE cls;
native_rb_encoding_pointer = (rb_encoding**) malloc(sizeof(rb_encoding*));
@@ -318,28 +342,22 @@ void Init_encoding_spec(void) {
rb_define_method(cls, "rb_locale_encindex", encoding_spec_rb_locale_encindex, 0);
rb_define_method(cls, "rb_filesystem_encoding", encoding_spec_rb_filesystem_encoding, 0);
rb_define_method(cls, "rb_filesystem_encindex", encoding_spec_rb_filesystem_encindex, 0);
- rb_define_method(cls, "rb_default_internal_encoding",
- encoding_spec_rb_default_internal_encoding, 0);
-
- rb_define_method(cls, "rb_default_external_encoding",
- encoding_spec_rb_default_external_encoding, 0);
-
-#ifdef RUBY_VERSION_IS_2_6
+ rb_define_method(cls, "rb_default_internal_encoding", encoding_spec_rb_default_internal_encoding, 0);
+ rb_define_method(cls, "rb_default_external_encoding", encoding_spec_rb_default_external_encoding, 0);
rb_define_method(cls, "rb_enc_alias", encoding_spec_rb_enc_alias, 2);
-#endif
-
rb_define_method(cls, "MBCLEN_CHARFOUND_P", encoding_spec_MBCLEN_CHARFOUND_P, 1);
rb_define_method(cls, "rb_enc_associate", encoding_spec_rb_enc_associate, 2);
rb_define_method(cls, "rb_enc_associate_index", encoding_spec_rb_enc_associate_index, 2);
rb_define_method(cls, "rb_enc_compatible", encoding_spec_rb_enc_compatible, 2);
rb_define_method(cls, "rb_enc_copy", encoding_spec_rb_enc_copy, 2);
rb_define_method(cls, "rb_enc_codelen", encoding_spec_rb_enc_codelen, 2);
+ rb_define_method(cls, "rb_enc_strlen", encoding_spec_rb_enc_strlen, 3);
rb_define_method(cls, "rb_enc_find", encoding_spec_rb_enc_find, 1);
rb_define_method(cls, "rb_enc_find_index", encoding_spec_rb_enc_find_index, 1);
rb_define_method(cls, "rb_enc_isalnum", encoding_spec_rb_enc_isalnum, 2);
rb_define_method(cls, "rb_enc_isspace", encoding_spec_rb_enc_isspace, 2);
rb_define_method(cls, "rb_enc_from_index", encoding_spec_rb_enc_from_index, 1);
- rb_define_method(cls, "rb_enc_mbc_to_codepoint", encoding_spec_rb_enc_mbc_to_codepoint, 2);
+ rb_define_method(cls, "rb_enc_mbc_to_codepoint", encoding_spec_rb_enc_mbc_to_codepoint, 1);
rb_define_method(cls, "rb_enc_mbcput", encoding_spec_rb_enc_mbcput, 2);
rb_define_method(cls, "rb_enc_from_encoding", encoding_spec_rb_enc_from_encoding, 1);
rb_define_method(cls, "rb_enc_get", encoding_spec_rb_enc_get, 1);
@@ -361,8 +379,11 @@ void Init_encoding_spec(void) {
rb_define_method(cls, "rb_enc_nth", encoding_spec_rb_enc_nth, 2);
rb_define_method(cls, "rb_enc_codepoint_len", encoding_spec_rb_enc_codepoint_len, 1);
rb_define_method(cls, "rb_enc_str_asciionly_p", encoding_spec_rb_enc_str_asciionly_p, 1);
+ rb_define_method(cls, "rb_enc_raise", encoding_spec_rb_enc_raise, 3);
rb_define_method(cls, "rb_uv_to_utf8", encoding_spec_rb_uv_to_utf8, 2);
rb_define_method(cls, "ONIGENC_MBC_CASE_FOLD", encoding_spec_ONIGENC_MBC_CASE_FOLD, 1);
+ rb_define_method(cls, "rb_enc_left_char_head", encoding_spec_rb_enc_left_char_head, 2);
+ rb_define_method(cls, "rb_define_dummy_encoding", encoding_spec_rb_define_dummy_encoding, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/exception_spec.c b/spec/ruby/optional/capi/ext/exception_spec.c
index e1114aabb8..c3b94d7bcd 100644
--- a/spec/ruby/optional/capi/ext/exception_spec.c
+++ b/spec/ruby/optional/capi/ext/exception_spec.c
@@ -27,7 +27,7 @@ VALUE exception_spec_rb_exc_new3(VALUE self, VALUE str) {
}
VALUE exception_spec_rb_exc_raise(VALUE self, VALUE exc) {
- if (self != Qundef) rb_exc_raise(exc);
+ if (self != Qundef) rb_exc_raise(exc);
return Qnil;
}
@@ -36,6 +36,28 @@ VALUE exception_spec_rb_set_errinfo(VALUE self, VALUE exc) {
return Qnil;
}
+NORETURN(VALUE exception_spec_rb_error_frozen_object(VALUE self, VALUE object));
+
+VALUE exception_spec_rb_error_frozen_object(VALUE self, VALUE object) {
+ rb_error_frozen_object(object);
+ UNREACHABLE_RETURN(Qnil);
+}
+
+VALUE exception_spec_rb_syserr_new(VALUE self, VALUE num, VALUE msg) {
+ int n = NUM2INT(num);
+ char *cstr = NULL;
+
+ if (msg != Qnil) {
+ cstr = StringValuePtr(msg);
+ }
+
+ return rb_syserr_new(n, cstr);
+}
+
+VALUE exception_spec_rb_syserr_new_str(VALUE self, VALUE num, VALUE msg) {
+ int n = NUM2INT(num);
+ return rb_syserr_new_str(n, msg);
+}
VALUE exception_spec_rb_make_exception(VALUE self, VALUE ary) {
int argc = RARRAY_LENINT(ary);
@@ -51,6 +73,9 @@ void Init_exception_spec(void) {
rb_define_method(cls, "rb_exc_new3", exception_spec_rb_exc_new3, 1);
rb_define_method(cls, "rb_exc_raise", exception_spec_rb_exc_raise, 1);
rb_define_method(cls, "rb_set_errinfo", exception_spec_rb_set_errinfo, 1);
+ rb_define_method(cls, "rb_error_frozen_object", exception_spec_rb_error_frozen_object, 1);
+ rb_define_method(cls, "rb_syserr_new", exception_spec_rb_syserr_new, 2);
+ rb_define_method(cls, "rb_syserr_new_str", exception_spec_rb_syserr_new_str, 2);
rb_define_method(cls, "rb_make_exception", exception_spec_rb_make_exception, 1);
}
diff --git a/spec/ruby/optional/capi/ext/fiber_spec.c b/spec/ruby/optional/capi/ext/fiber_spec.c
index 7912e878f3..db54f7ad8c 100644
--- a/spec/ruby/optional/capi/ext/fiber_spec.c
+++ b/spec/ruby/optional/capi/ext/fiber_spec.c
@@ -44,6 +44,11 @@ VALUE fiber_spec_rb_fiber_new(VALUE self) {
return rb_fiber_new(fiber_spec_rb_fiber_new_function, Qnil);
}
+VALUE fiber_spec_rb_fiber_raise(int argc, VALUE *argv, VALUE self) {
+ VALUE fiber = argv[0];
+ return rb_fiber_raise(fiber, argc-1, argv+1);
+}
+
void Init_fiber_spec(void) {
VALUE cls = rb_define_class("CApiFiberSpecs", rb_cObject);
rb_define_method(cls, "rb_fiber_current", fiber_spec_rb_fiber_current, 0);
@@ -51,6 +56,7 @@ void Init_fiber_spec(void) {
rb_define_method(cls, "rb_fiber_resume", fiber_spec_rb_fiber_resume, 2);
rb_define_method(cls, "rb_fiber_yield", fiber_spec_rb_fiber_yield, 1);
rb_define_method(cls, "rb_fiber_new", fiber_spec_rb_fiber_new, 0);
+ rb_define_method(cls, "rb_fiber_raise", fiber_spec_rb_fiber_raise, -1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/finalizer_spec.c b/spec/ruby/optional/capi/ext/finalizer_spec.c
new file mode 100644
index 0000000000..83347da912
--- /dev/null
+++ b/spec/ruby/optional/capi/ext/finalizer_spec.c
@@ -0,0 +1,25 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static VALUE define_finalizer(VALUE self, VALUE obj, VALUE finalizer) {
+ return rb_define_finalizer(obj, finalizer);
+}
+
+static VALUE undefine_finalizer(VALUE self, VALUE obj) {
+ return rb_undefine_finalizer(obj);
+}
+
+void Init_finalizer_spec(void) {
+ VALUE cls = rb_define_class("CApiFinalizerSpecs", rb_cObject);
+
+ rb_define_method(cls, "rb_define_finalizer", define_finalizer, 2);
+ rb_define_method(cls, "rb_undefine_finalizer", undefine_finalizer, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/spec/ruby/optional/capi/ext/gc_spec.c b/spec/ruby/optional/capi/ext/gc_spec.c
index 7dc9c347c7..2637ad27ac 100644
--- a/spec/ruby/optional/capi/ext/gc_spec.c
+++ b/spec/ruby/optional/capi/ext/gc_spec.c
@@ -7,6 +7,16 @@ extern "C" {
VALUE registered_tagged_value;
VALUE registered_reference_value;
+VALUE registered_before_rb_gc_register_address;
+VALUE registered_before_rb_global_variable_string;
+VALUE registered_before_rb_global_variable_bignum;
+VALUE registered_before_rb_global_variable_float;
+VALUE registered_after_rb_global_variable_string;
+VALUE registered_after_rb_global_variable_bignum;
+VALUE registered_after_rb_global_variable_float;
+VALUE rb_gc_register_address_outside_init;
+
+VALUE rb_gc_register_mark_object_not_referenced_float;
static VALUE registered_tagged_address(VALUE self) {
return registered_tagged_value;
@@ -16,6 +26,45 @@ static VALUE registered_reference_address(VALUE self) {
return registered_reference_value;
}
+static VALUE get_registered_before_rb_gc_register_address(VALUE self) {
+ return registered_before_rb_gc_register_address;
+}
+
+static VALUE get_registered_before_rb_global_variable_string(VALUE self) {
+ return registered_before_rb_global_variable_string;
+}
+
+static VALUE get_registered_before_rb_global_variable_bignum(VALUE self) {
+ return registered_before_rb_global_variable_bignum;
+}
+
+static VALUE get_registered_before_rb_global_variable_float(VALUE self) {
+ return registered_before_rb_global_variable_float;
+}
+
+static VALUE get_registered_after_rb_global_variable_string(VALUE self) {
+ return registered_after_rb_global_variable_string;
+}
+
+static VALUE get_registered_after_rb_global_variable_bignum(VALUE self) {
+ return registered_after_rb_global_variable_bignum;
+}
+
+static VALUE get_registered_after_rb_global_variable_float(VALUE self) {
+ return registered_after_rb_global_variable_float;
+}
+
+static VALUE gc_spec_rb_gc_register_address(VALUE self) {
+ rb_gc_register_address(&rb_gc_register_address_outside_init);
+ rb_gc_register_address_outside_init = rb_str_new_cstr("rb_gc_register_address() outside Init_");
+ return rb_gc_register_address_outside_init;
+}
+
+static VALUE gc_spec_rb_gc_unregister_address(VALUE self) {
+ rb_gc_unregister_address(&rb_gc_register_address_outside_init);
+ return Qnil;
+}
+
static VALUE gc_spec_rb_gc_enable(VALUE self) {
return rb_gc_enable();
}
@@ -29,7 +78,7 @@ static VALUE gc_spec_rb_gc(VALUE self) {
return Qnil;
}
-static VALUE gc_spec_rb_gc_latest_gc_info(VALUE self, VALUE hash_or_key){
+static VALUE gc_spec_rb_gc_latest_gc_info(VALUE self, VALUE hash_or_key) {
return rb_gc_latest_gc_info(hash_or_key);
}
@@ -43,21 +92,55 @@ static VALUE gc_spec_rb_gc_register_mark_object(VALUE self, VALUE obj) {
return Qnil;
}
+static VALUE gc_spec_rb_gc_register_mark_object_not_referenced_float(VALUE self) {
+ return rb_gc_register_mark_object_not_referenced_float;
+}
+
void Init_gc_spec(void) {
VALUE cls = rb_define_class("CApiGCSpecs", rb_cObject);
- registered_tagged_value = INT2NUM(10);
- registered_reference_value = rb_str_new2("Globally registered data");
rb_gc_register_address(&registered_tagged_value);
rb_gc_register_address(&registered_reference_value);
+ rb_gc_register_address(&registered_before_rb_gc_register_address);
+ rb_global_variable(&registered_before_rb_global_variable_string);
+ rb_global_variable(&registered_before_rb_global_variable_bignum);
+ rb_global_variable(&registered_before_rb_global_variable_float);
+
+ registered_tagged_value = INT2NUM(10);
+ registered_reference_value = rb_str_new2("Globally registered data");
+ registered_before_rb_gc_register_address = rb_str_new_cstr("registered before rb_gc_register_address()");
+
+ registered_before_rb_global_variable_string = rb_str_new_cstr("registered before rb_global_variable()");
+ registered_before_rb_global_variable_bignum = LL2NUM(INT64_MAX);
+ registered_before_rb_global_variable_float = DBL2NUM(3.14);
+
+ registered_after_rb_global_variable_string = rb_str_new_cstr("registered after rb_global_variable()");
+ rb_global_variable(&registered_after_rb_global_variable_string);
+ registered_after_rb_global_variable_bignum = LL2NUM(INT64_MAX);
+ rb_global_variable(&registered_after_rb_global_variable_bignum);
+ registered_after_rb_global_variable_float = DBL2NUM(6.28);
+ rb_global_variable(&registered_after_rb_global_variable_float);
+
+ rb_gc_register_mark_object_not_referenced_float = DBL2NUM(1.61);
+ rb_gc_register_mark_object(rb_gc_register_mark_object_not_referenced_float);
rb_define_method(cls, "registered_tagged_address", registered_tagged_address, 0);
rb_define_method(cls, "registered_reference_address", registered_reference_address, 0);
+ rb_define_method(cls, "registered_before_rb_gc_register_address", get_registered_before_rb_gc_register_address, 0);
+ rb_define_method(cls, "registered_before_rb_global_variable_string", get_registered_before_rb_global_variable_string, 0);
+ rb_define_method(cls, "registered_before_rb_global_variable_bignum", get_registered_before_rb_global_variable_bignum, 0);
+ rb_define_method(cls, "registered_before_rb_global_variable_float", get_registered_before_rb_global_variable_float, 0);
+ rb_define_method(cls, "registered_after_rb_global_variable_string", get_registered_after_rb_global_variable_string, 0);
+ rb_define_method(cls, "registered_after_rb_global_variable_bignum", get_registered_after_rb_global_variable_bignum, 0);
+ rb_define_method(cls, "registered_after_rb_global_variable_float", get_registered_after_rb_global_variable_float, 0);
+ rb_define_method(cls, "rb_gc_register_address", gc_spec_rb_gc_register_address, 0);
+ rb_define_method(cls, "rb_gc_unregister_address", gc_spec_rb_gc_unregister_address, 0);
rb_define_method(cls, "rb_gc_enable", gc_spec_rb_gc_enable, 0);
rb_define_method(cls, "rb_gc_disable", gc_spec_rb_gc_disable, 0);
rb_define_method(cls, "rb_gc", gc_spec_rb_gc, 0);
rb_define_method(cls, "rb_gc_adjust_memory_usage", gc_spec_rb_gc_adjust_memory_usage, 1);
rb_define_method(cls, "rb_gc_register_mark_object", gc_spec_rb_gc_register_mark_object, 1);
+ rb_define_method(cls, "rb_gc_register_mark_object_not_referenced_float", gc_spec_rb_gc_register_mark_object_not_referenced_float, 0);
rb_define_method(cls, "rb_gc_latest_gc_info", gc_spec_rb_gc_latest_gc_info, 1);
}
diff --git a/spec/ruby/optional/capi/ext/globals_spec.c b/spec/ruby/optional/capi/ext/globals_spec.c
index 28a9633f98..20dea1a05a 100644
--- a/spec/ruby/optional/capi/ext/globals_spec.c
+++ b/spec/ruby/optional/capi/ext/globals_spec.c
@@ -20,6 +20,16 @@ static VALUE sb_define_hooked_variable(VALUE self, VALUE var_name) {
return Qnil;
}
+static VALUE sb_define_hooked_variable_default_accessors(VALUE self, VALUE var_name) {
+ rb_define_hooked_variable(StringValuePtr(var_name), &g_hooked_var, (rb_gvar_getter_t*) NULL, (rb_gvar_setter_t*) NULL);
+ return Qnil;
+}
+
+static VALUE sb_define_hooked_variable_null_var(VALUE self, VALUE var_name) {
+ rb_define_hooked_variable(StringValuePtr(var_name), NULL, (rb_gvar_getter_t*) NULL, (rb_gvar_setter_t*) NULL);
+ return Qnil;
+}
+
VALUE g_ro_var;
static VALUE sb_define_readonly_variable(VALUE self, VALUE var_name, VALUE val) {
@@ -40,6 +50,26 @@ static VALUE sb_define_variable(VALUE self, VALUE var_name, VALUE val) {
return Qnil;
}
+long virtual_var_storage;
+
+VALUE incrementing_getter(ID id, VALUE *data) {
+ return LONG2FIX(virtual_var_storage++);
+}
+
+void incrementing_setter(VALUE val, ID id, VALUE *data) {
+ virtual_var_storage = FIX2LONG(val);
+}
+
+static VALUE sb_define_virtual_variable_default_accessors(VALUE self, VALUE name) {
+ rb_define_virtual_variable(StringValuePtr(name), (rb_gvar_getter_t*) NULL, (rb_gvar_setter_t*) NULL);
+ return Qnil;
+}
+
+static VALUE sb_define_virtual_variable_incrementing_accessors(VALUE self, VALUE name) {
+ rb_define_virtual_variable(StringValuePtr(name), incrementing_getter, incrementing_setter);
+ return Qnil;
+}
+
static VALUE sb_f_global_variables(VALUE self) {
return rb_f_global_variables();
}
@@ -101,10 +131,14 @@ void Init_globals_spec(void) {
VALUE cls = rb_define_class("CApiGlobalSpecs", rb_cObject);
g_hooked_var = Qnil;
rb_define_method(cls, "rb_define_hooked_variable_2x", sb_define_hooked_variable, 1);
+ rb_define_method(cls, "rb_define_hooked_variable_default_accessors", sb_define_hooked_variable_default_accessors, 1);
+ rb_define_method(cls, "rb_define_hooked_variable_null_var", sb_define_hooked_variable_null_var, 1);
g_ro_var = Qnil;
rb_define_method(cls, "rb_define_readonly_variable", sb_define_readonly_variable, 2);
g_var = Qnil;
rb_define_method(cls, "rb_define_variable", sb_define_variable, 2);
+ rb_define_method(cls, "rb_define_virtual_variable_default_accessors", sb_define_virtual_variable_default_accessors, 1);
+ rb_define_method(cls, "rb_define_virtual_variable_incrementing_accessors", sb_define_virtual_variable_incrementing_accessors, 1);
rb_define_method(cls, "sb_get_global_value", sb_get_global_value, 0);
rb_define_method(cls, "rb_f_global_variables", sb_f_global_variables, 0);
rb_define_method(cls, "sb_gv_get", sb_gv_get, 1);
diff --git a/spec/ruby/optional/capi/ext/hash_spec.c b/spec/ruby/optional/capi/ext/hash_spec.c
index 7f38708915..653917f2c4 100644
--- a/spec/ruby/optional/capi/ext/hash_spec.c
+++ b/spec/ruby/optional/capi/ext/hash_spec.c
@@ -105,6 +105,10 @@ VALUE hash_spec_rb_hash_new(VALUE self) {
return rb_hash_new();
}
+VALUE hash_spec_rb_hash_new_capa(VALUE self, VALUE capacity) {
+ return rb_hash_new_capa(NUM2LONG(capacity));
+}
+
VALUE rb_ident_hash_new(void); /* internal.h, used in ripper */
VALUE hash_spec_rb_ident_hash_new(VALUE self) {
@@ -128,6 +132,20 @@ VALUE hash_spec_compute_a_hash_code(VALUE self, VALUE seed) {
return ULONG2NUM(h);
}
+VALUE hash_spec_rb_hash_bulk_insert(VALUE self, VALUE array_len, VALUE array, VALUE hash) {
+ VALUE* ptr;
+
+ if (array == Qnil) {
+ ptr = NULL;
+ } else {
+ ptr = RARRAY_PTR(array);
+ }
+
+ long len = FIX2LONG(array_len);
+ rb_hash_bulk_insert(len, ptr, hash);
+ return Qnil;
+}
+
void Init_hash_spec(void) {
VALUE cls = rb_define_class("CApiHashSpecs", rb_cObject);
rb_define_method(cls, "rb_hash", hash_spec_rb_hash, 1);
@@ -149,10 +167,12 @@ void Init_hash_spec(void) {
rb_define_method(cls, "rb_hash_lookup2", hash_spec_rb_hash_lookup2, 3);
rb_define_method(cls, "rb_hash_lookup2_default_undef", hash_spec_rb_hash_lookup2_default_undef, 2);
rb_define_method(cls, "rb_hash_new", hash_spec_rb_hash_new, 0);
+ rb_define_method(cls, "rb_hash_new_capa", hash_spec_rb_hash_new_capa, 1);
rb_define_method(cls, "rb_ident_hash_new", hash_spec_rb_ident_hash_new, 0);
rb_define_method(cls, "rb_hash_size", hash_spec_rb_hash_size, 1);
rb_define_method(cls, "rb_hash_set_ifnone", hash_spec_rb_hash_set_ifnone, 2);
rb_define_method(cls, "compute_a_hash_code", hash_spec_compute_a_hash_code, 1);
+ rb_define_method(cls, "rb_hash_bulk_insert", hash_spec_rb_hash_bulk_insert, 3);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/integer_spec.c b/spec/ruby/optional/capi/ext/integer_spec.c
index 16cd95f111..792fc0652a 100644
--- a/spec/ruby/optional/capi/ext/integer_spec.c
+++ b/spec/ruby/optional/capi/ext/integer_spec.c
@@ -6,8 +6,7 @@ extern "C" {
#endif
static VALUE integer_spec_rb_integer_pack(VALUE self, VALUE value,
- VALUE words, VALUE numwords, VALUE wordsize, VALUE nails, VALUE flags)
-{
+ VALUE words, VALUE numwords, VALUE wordsize, VALUE nails, VALUE flags) {
int result = rb_integer_pack(value, (void*)RSTRING_PTR(words), FIX2INT(numwords),
FIX2INT(wordsize), FIX2INT(nails), FIX2INT(flags));
return INT2FIX(result);
@@ -15,7 +14,7 @@ static VALUE integer_spec_rb_integer_pack(VALUE self, VALUE value,
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y); /* internal.h, used in ripper */
-static VALUE integer_spec_rb_int_positive_pow(VALUE self, VALUE a, VALUE b){
+static VALUE integer_spec_rb_int_positive_pow(VALUE self, VALUE a, VALUE b) {
return rb_int_positive_pow(FIX2INT(a), FIX2INT(b));
}
diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c
index b4ffe9207a..f3ede15729 100644
--- a/spec/ruby/optional/capi/ext/io_spec.c
+++ b/spec/ruby/optional/capi/ext/io_spec.c
@@ -28,9 +28,7 @@ static int set_non_blocking(int fd) {
}
static int io_spec_get_fd(VALUE io) {
- rb_io_t* fp;
- GetOpenFile(io, fp);
- return fp->fd;
+ return rb_io_descriptor(io);
}
VALUE io_spec_GetOpenFile_fd(VALUE self, VALUE io) {
@@ -130,7 +128,7 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) {
rb_sys_fail("set_non_blocking failed");
#ifndef SET_NON_BLOCKING_FAILS_ALWAYS
- if(RTEST(read_p)) {
+ if (RTEST(read_p)) {
if (read(fd, buf, RB_IO_WAIT_READABLE_BUF) != -1) {
return Qnil;
}
@@ -139,9 +137,9 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) {
errno = saved_errno;
}
- ret = rb_io_wait_readable(fd);
+ ret = rb_io_maybe_wait_readable(errno, io, Qnil);
- if(RTEST(read_p)) {
+ if (RTEST(read_p)) {
ssize_t r = read(fd, buf, RB_IO_WAIT_READABLE_BUF);
if (r != RB_IO_WAIT_READABLE_BUF) {
perror("read");
@@ -153,28 +151,80 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) {
return ret ? Qtrue : Qfalse;
#else
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
#endif
}
VALUE io_spec_rb_io_wait_writable(VALUE self, VALUE io) {
- int ret = rb_io_wait_writable(io_spec_get_fd(io));
+ int ret = rb_io_maybe_wait_writable(errno, io, Qnil);
return ret ? Qtrue : Qfalse;
}
+VALUE io_spec_rb_io_maybe_wait_writable(VALUE self, VALUE error, VALUE io, VALUE timeout) {
+ int ret = rb_io_maybe_wait_writable(NUM2INT(error), io, timeout);
+ return INT2NUM(ret);
+}
+
+#ifdef SET_NON_BLOCKING_FAILS_ALWAYS
+NORETURN(VALUE io_spec_rb_io_maybe_wait_readable(VALUE self, VALUE error, VALUE io, VALUE timeout, VALUE read_p));
+#endif
+
+VALUE io_spec_rb_io_maybe_wait_readable(VALUE self, VALUE error, VALUE io, VALUE timeout, VALUE read_p) {
+ int fd = io_spec_get_fd(io);
+#ifndef SET_NON_BLOCKING_FAILS_ALWAYS
+ char buf[RB_IO_WAIT_READABLE_BUF];
+ int ret, saved_errno;
+#endif
+
+ if (set_non_blocking(fd) == -1)
+ rb_sys_fail("set_non_blocking failed");
+
+#ifndef SET_NON_BLOCKING_FAILS_ALWAYS
+ if (RTEST(read_p)) {
+ if (read(fd, buf, RB_IO_WAIT_READABLE_BUF) != -1) {
+ return Qnil;
+ }
+ saved_errno = errno;
+ rb_ivar_set(self, rb_intern("@write_data"), Qtrue);
+ errno = saved_errno;
+ }
+
+ // main part
+ ret = rb_io_maybe_wait_readable(NUM2INT(error), io, timeout);
+
+ if (RTEST(read_p)) {
+ ssize_t r = read(fd, buf, RB_IO_WAIT_READABLE_BUF);
+ if (r != RB_IO_WAIT_READABLE_BUF) {
+ perror("read");
+ return SSIZET2NUM(r);
+ }
+ rb_ivar_set(self, rb_intern("@read_data"),
+ rb_str_new(buf, RB_IO_WAIT_READABLE_BUF));
+ }
+
+ return INT2NUM(ret);
+#else
+ UNREACHABLE_RETURN(Qnil);
+#endif
+}
+
+VALUE io_spec_rb_io_maybe_wait(VALUE self, VALUE error, VALUE io, VALUE events, VALUE timeout) {
+ return rb_io_maybe_wait(NUM2INT(error), io, events, timeout);
+}
+
VALUE io_spec_rb_thread_wait_fd(VALUE self, VALUE io) {
rb_thread_wait_fd(io_spec_get_fd(io));
return Qnil;
}
VALUE io_spec_rb_wait_for_single_fd(VALUE self, VALUE io, VALUE events, VALUE secs, VALUE usecs) {
- int fd = io_spec_get_fd(io);
- struct timeval tv;
+ VALUE timeout = Qnil;
if (!NIL_P(secs)) {
- tv.tv_sec = FIX2INT(secs);
- tv.tv_usec = FIX2INT(usecs);
+ timeout = rb_float_new((double)FIX2INT(secs) + (0.000001 * FIX2INT(usecs)));
}
- return INT2FIX(rb_wait_for_single_fd(fd, FIX2INT(events), NIL_P(secs) ? NULL : &tv));
+ VALUE result = rb_io_wait(io, events, timeout);
+ if (result == Qfalse) return INT2FIX(0);
+ else return result;
}
VALUE io_spec_rb_thread_fd_writable(VALUE self, VALUE io) {
@@ -182,6 +232,46 @@ VALUE io_spec_rb_thread_fd_writable(VALUE self, VALUE io) {
return Qnil;
}
+VALUE io_spec_rb_thread_fd_select_read(VALUE self, VALUE io) {
+ int fd = io_spec_get_fd(io);
+
+ rb_fdset_t fds;
+ rb_fd_init(&fds);
+ rb_fd_set(fd, &fds);
+
+ int r = rb_thread_fd_select(fd + 1, &fds, NULL, NULL, NULL);
+ rb_fd_term(&fds);
+ return INT2FIX(r);
+}
+
+VALUE io_spec_rb_thread_fd_select_write(VALUE self, VALUE io) {
+ int fd = io_spec_get_fd(io);
+
+ rb_fdset_t fds;
+ rb_fd_init(&fds);
+ rb_fd_set(fd, &fds);
+
+ int r = rb_thread_fd_select(fd + 1, NULL, &fds, NULL, NULL);
+ rb_fd_term(&fds);
+ return INT2FIX(r);
+}
+
+VALUE io_spec_rb_thread_fd_select_timeout(VALUE self, VALUE io) {
+ int fd = io_spec_get_fd(io);
+
+ struct timeval timeout;
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 20;
+
+ rb_fdset_t fds;
+ rb_fd_init(&fds);
+ rb_fd_set(fd, &fds);
+
+ int r = rb_thread_fd_select(fd + 1, NULL, &fds, NULL, &timeout);
+ rb_fd_term(&fds);
+ return INT2FIX(r);
+}
+
VALUE io_spec_rb_io_binmode(VALUE self, VALUE io) {
return rb_io_binmode(io);
}
@@ -209,7 +299,7 @@ VALUE io_spec_rb_io_set_nonblock(VALUE self, VALUE io) {
GetOpenFile(io, fp);
rb_io_set_nonblock(fp);
#ifdef F_GETFL
- flags = fcntl(fp->fd, F_GETFL, 0);
+ flags = fcntl(io_spec_get_fd(io), F_GETFL, 0);
return flags & O_NONBLOCK ? Qtrue : Qfalse;
#else
return Qfalse;
@@ -228,15 +318,50 @@ static VALUE io_spec_errno_set(VALUE self, VALUE val) {
}
VALUE io_spec_mode_sync_flag(VALUE self, VALUE io) {
+ int mode;
+#ifdef RUBY_VERSION_IS_3_3
+ mode = rb_io_mode(io);
+#else
rb_io_t *fp;
GetOpenFile(io, fp);
- if (fp->mode & FMODE_SYNC) {
+ mode = fp->mode;
+#endif
+ if (mode & FMODE_SYNC) {
return Qtrue;
} else {
return Qfalse;
}
}
+#if defined(RUBY_VERSION_IS_3_3) || defined(TRUFFLERUBY)
+static VALUE io_spec_rb_io_mode(VALUE self, VALUE io) {
+ return INT2FIX(rb_io_mode(io));
+}
+
+static VALUE io_spec_rb_io_path(VALUE self, VALUE io) {
+ return rb_io_path(io);
+}
+
+static VALUE io_spec_rb_io_closed_p(VALUE self, VALUE io) {
+ return rb_io_closed_p(io);
+}
+
+static VALUE io_spec_rb_io_open_descriptor(VALUE self, VALUE klass, VALUE descriptor, VALUE mode, VALUE path, VALUE timeout, VALUE internal_encoding, VALUE external_encoding, VALUE ecflags, VALUE ecopts) {
+ struct rb_io_encoding io_encoding;
+
+ io_encoding.enc = rb_to_encoding(internal_encoding);
+ io_encoding.enc2 = rb_to_encoding(external_encoding);
+ io_encoding.ecflags = FIX2INT(ecflags);
+ io_encoding.ecopts = ecopts;
+
+ return rb_io_open_descriptor(klass, FIX2INT(descriptor), FIX2INT(mode), path, timeout, &io_encoding);
+}
+
+static VALUE io_spec_rb_io_open_descriptor_without_encoding(VALUE self, VALUE klass, VALUE descriptor, VALUE mode, VALUE path, VALUE timeout) {
+ return rb_io_open_descriptor(klass, FIX2INT(descriptor), FIX2INT(mode), path, timeout, NULL);
+}
+#endif
+
void Init_io_spec(void) {
VALUE cls = rb_define_class("CApiIOSpecs", rb_cObject);
rb_define_method(cls, "GetOpenFile_fd", io_spec_GetOpenFile_fd, 1);
@@ -254,14 +379,32 @@ void Init_io_spec(void) {
rb_define_method(cls, "rb_io_taint_check", io_spec_rb_io_taint_check, 1);
rb_define_method(cls, "rb_io_wait_readable", io_spec_rb_io_wait_readable, 2);
rb_define_method(cls, "rb_io_wait_writable", io_spec_rb_io_wait_writable, 1);
+ rb_define_method(cls, "rb_io_maybe_wait_writable", io_spec_rb_io_maybe_wait_writable, 3);
+ rb_define_method(cls, "rb_io_maybe_wait_readable", io_spec_rb_io_maybe_wait_readable, 4);
+ rb_define_method(cls, "rb_io_maybe_wait", io_spec_rb_io_maybe_wait, 4);
rb_define_method(cls, "rb_thread_wait_fd", io_spec_rb_thread_wait_fd, 1);
rb_define_method(cls, "rb_thread_fd_writable", io_spec_rb_thread_fd_writable, 1);
+ rb_define_method(cls, "rb_thread_fd_select_read", io_spec_rb_thread_fd_select_read, 1);
+ rb_define_method(cls, "rb_thread_fd_select_write", io_spec_rb_thread_fd_select_write, 1);
+ rb_define_method(cls, "rb_thread_fd_select_timeout", io_spec_rb_thread_fd_select_timeout, 1);
rb_define_method(cls, "rb_wait_for_single_fd", io_spec_rb_wait_for_single_fd, 4);
rb_define_method(cls, "rb_io_binmode", io_spec_rb_io_binmode, 1);
rb_define_method(cls, "rb_fd_fix_cloexec", io_spec_rb_fd_fix_cloexec, 1);
rb_define_method(cls, "rb_cloexec_open", io_spec_rb_cloexec_open, 3);
rb_define_method(cls, "errno=", io_spec_errno_set, 1);
rb_define_method(cls, "rb_io_mode_sync_flag", io_spec_mode_sync_flag, 1);
+#if defined(RUBY_VERSION_IS_3_3) || defined(TRUFFLERUBY)
+ rb_define_method(cls, "rb_io_mode", io_spec_rb_io_mode, 1);
+ rb_define_method(cls, "rb_io_path", io_spec_rb_io_path, 1);
+ rb_define_method(cls, "rb_io_closed_p", io_spec_rb_io_closed_p, 1);
+ rb_define_method(cls, "rb_io_open_descriptor", io_spec_rb_io_open_descriptor, 9);
+ rb_define_method(cls, "rb_io_open_descriptor_without_encoding", io_spec_rb_io_open_descriptor_without_encoding, 5);
+ rb_define_const(cls, "FMODE_READABLE", INT2FIX(FMODE_READABLE));
+ rb_define_const(cls, "FMODE_WRITABLE", INT2FIX(FMODE_WRITABLE));
+ rb_define_const(cls, "FMODE_BINMODE", INT2FIX(FMODE_BINMODE));
+ rb_define_const(cls, "FMODE_TEXTMODE", INT2FIX(FMODE_TEXTMODE));
+ rb_define_const(cls, "ECONV_UNIVERSAL_NEWLINE_DECORATOR", INT2FIX(ECONV_UNIVERSAL_NEWLINE_DECORATOR));
+#endif
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c
index bbfeb198b7..a8fed21b59 100644
--- a/spec/ruby/optional/capi/ext/kernel_spec.c
+++ b/spec/ruby/optional/capi/ext/kernel_spec.c
@@ -7,16 +7,12 @@
extern "C" {
#endif
-VALUE kernel_spec_call_proc(VALUE arg_array) {
+static VALUE kernel_spec_call_proc(VALUE arg_array) {
VALUE arg = rb_ary_pop(arg_array);
VALUE proc = rb_ary_pop(arg_array);
return rb_funcall(proc, rb_intern("call"), 1, arg);
}
-VALUE kernel_spec_call_proc_raise(VALUE arg_array, VALUE raised_exc) {
- return kernel_spec_call_proc(arg_array);
-}
-
static VALUE kernel_spec_rb_block_given_p(VALUE self) {
return rb_block_given_p() ? Qtrue : Qfalse;
}
@@ -71,11 +67,20 @@ VALUE kernel_spec_rb_block_call_no_func(VALUE self, VALUE ary) {
return rb_block_call(ary, rb_intern("map"), 0, NULL, (rb_block_call_func_t)NULL, Qnil);
}
-
VALUE kernel_spec_rb_frame_this_func(VALUE self) {
return ID2SYM(rb_frame_this_func());
}
+VALUE kernel_spec_rb_category_warn_deprecated(VALUE self) {
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "foo");
+ return Qnil;
+}
+
+VALUE kernel_spec_rb_category_warn_deprecated_with_integer_extra_value(VALUE self, VALUE value) {
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "foo %d", FIX2INT(value));
+ return Qnil;
+}
+
VALUE kernel_spec_rb_ensure(VALUE self, VALUE main_proc, VALUE arg,
VALUE ensure_proc, VALUE arg2) {
VALUE main_array, ensure_array;
@@ -112,6 +117,12 @@ VALUE kernel_spec_rb_eval_string(VALUE self, VALUE str) {
return rb_eval_string(RSTRING_PTR(str));
}
+#ifndef RUBY_VERSION_IS_4_0
+VALUE kernel_spec_rb_eval_cmd_kw(VALUE self, VALUE cmd, VALUE args, VALUE kw_splat) {
+ return rb_eval_cmd_kw(cmd, args, NUM2INT(kw_splat));
+}
+#endif
+
VALUE kernel_spec_rb_raise(VALUE self, VALUE hash) {
rb_hash_aset(hash, ID2SYM(rb_intern("stage")), ID2SYM(rb_intern("before")));
if (self != Qundef)
@@ -130,7 +141,16 @@ VALUE kernel_spec_rb_throw_obj(VALUE self, VALUE obj, VALUE result) {
return ID2SYM(rb_intern("rb_throw_failed"));
}
-VALUE kernel_spec_call_proc_with_raised_exc(VALUE arg_array, VALUE raised_exc) {
+VALUE kernel_spec_rb_errinfo(VALUE self) {
+ return rb_errinfo();
+}
+
+VALUE kernel_spec_rb_set_errinfo(VALUE self, VALUE exc) {
+ rb_set_errinfo(exc);
+ return Qnil;
+}
+
+static VALUE kernel_spec_call_proc_with_raised_exc(VALUE arg_array, VALUE raised_exc) {
VALUE argv[2];
int argc;
@@ -142,7 +162,7 @@ VALUE kernel_spec_call_proc_with_raised_exc(VALUE arg_array, VALUE raised_exc) {
argc = 2;
- return rb_funcall2(proc, rb_intern("call"), argc, argv);
+ return rb_funcallv(proc, rb_intern("call"), argc, argv);
}
VALUE kernel_spec_rb_rescue(VALUE self, VALUE main_proc, VALUE arg,
@@ -177,7 +197,7 @@ VALUE kernel_spec_rb_rescue2(int argc, VALUE *args, VALUE self) {
rb_ary_push(raise_array, args[3]);
return rb_rescue2(kernel_spec_call_proc, main_array,
- kernel_spec_call_proc_raise, raise_array, args[4], args[5], (VALUE)0);
+ kernel_spec_call_proc_with_raised_exc, raise_array, args[4], args[5], (VALUE)0);
}
static VALUE kernel_spec_rb_protect_yield(VALUE self, VALUE obj, VALUE ary) {
@@ -191,7 +211,7 @@ static VALUE kernel_spec_rb_protect_yield(VALUE self, VALUE obj, VALUE ary) {
return res;
}
-static VALUE kernel_spec_rb_protect_errinfo(VALUE self, VALUE obj, VALUE ary) {
+static VALUE kernel_spec_rb_protect_ignore_status(VALUE self, VALUE obj, VALUE ary) {
int status = 0;
VALUE res = rb_protect(rb_yield, obj, &status);
rb_ary_store(ary, 0, INT2NUM(23));
@@ -216,8 +236,8 @@ static VALUE kernel_spec_rb_eval_string_protect(VALUE self, VALUE str, VALUE ary
VALUE kernel_spec_rb_sys_fail(VALUE self, VALUE msg) {
errno = 1;
- if(msg == Qnil) {
- rb_sys_fail(0);
+ if (msg == Qnil) {
+ rb_sys_fail(NULL);
} else if (self != Qundef) {
rb_sys_fail(StringValuePtr(msg));
}
@@ -225,7 +245,7 @@ VALUE kernel_spec_rb_sys_fail(VALUE self, VALUE msg) {
}
VALUE kernel_spec_rb_syserr_fail(VALUE self, VALUE err, VALUE msg) {
- if(msg == Qnil) {
+ if (msg == Qnil) {
rb_syserr_fail(NUM2INT(err), NULL);
} else if (self != Qundef) {
rb_syserr_fail(NUM2INT(err), StringValuePtr(msg));
@@ -233,6 +253,13 @@ VALUE kernel_spec_rb_syserr_fail(VALUE self, VALUE err, VALUE msg) {
return Qnil;
}
+VALUE kernel_spec_rb_syserr_fail_str(VALUE self, VALUE err, VALUE msg) {
+ if (self != Qundef) {
+ rb_syserr_fail_str(NUM2INT(err), msg);
+ }
+ return Qnil;
+}
+
VALUE kernel_spec_rb_warn(VALUE self, VALUE msg) {
rb_warn("%s", StringValuePtr(msg));
return Qnil;
@@ -288,9 +315,9 @@ static VALUE kernel_spec_rb_yield_values2(VALUE self, VALUE ary) {
}
static VALUE do_rec(VALUE obj, VALUE arg, int is_rec) {
- if(is_rec) {
+ if (is_rec) {
return obj;
- } else if(arg == Qtrue) {
+ } else if (arg == Qtrue) {
return rb_exec_recursive(do_rec, obj, Qnil);
} else {
return Qnil;
@@ -314,16 +341,36 @@ static VALUE kernel_spec_rb_f_sprintf(VALUE self, VALUE ary) {
return rb_f_sprintf((int)RARRAY_LEN(ary), RARRAY_PTR(ary));
}
+static VALUE kernel_spec_rb_str_format(VALUE self, VALUE count, VALUE ary, VALUE format) {
+ return rb_str_format(FIX2INT(count), RARRAY_PTR(ary), format);
+}
+
static VALUE kernel_spec_rb_make_backtrace(VALUE self) {
return rb_make_backtrace();
}
-static VALUE kernel_spec_rb_funcall3(VALUE self, VALUE obj, VALUE method) {
- return rb_funcall3(obj, SYM2ID(method), 0, NULL);
+static VALUE kernel_spec_rb_funcallv(VALUE self, VALUE obj, VALUE method, VALUE args) {
+ return rb_funcallv(obj, SYM2ID(method), RARRAY_LENINT(args), RARRAY_PTR(args));
}
-static VALUE kernel_spec_rb_funcall_with_block(VALUE self, VALUE obj, VALUE method, VALUE block) {
- return rb_funcall_with_block(obj, SYM2ID(method), 0, NULL, block);
+static VALUE kernel_spec_rb_funcallv_kw(VALUE self, VALUE obj, VALUE method, VALUE args) {
+ return rb_funcallv_kw(obj, SYM2ID(method), RARRAY_LENINT(args), RARRAY_PTR(args), RB_PASS_KEYWORDS);
+}
+
+static VALUE kernel_spec_rb_keyword_given_p(int argc, VALUE *args, VALUE self) {
+ return rb_keyword_given_p() ? Qtrue : Qfalse;
+}
+
+static VALUE kernel_spec_rb_funcallv_public(VALUE self, VALUE obj, VALUE method) {
+ return rb_funcallv_public(obj, SYM2ID(method), 0, NULL);
+}
+
+static VALUE kernel_spec_rb_funcall_with_block(VALUE self, VALUE obj, VALUE method, VALUE args, VALUE block) {
+ return rb_funcall_with_block(obj, SYM2ID(method), RARRAY_LENINT(args), RARRAY_PTR(args), block);
+}
+
+static VALUE kernel_spec_rb_funcall_with_block_kw(VALUE self, VALUE obj, VALUE method, VALUE args, VALUE block) {
+ return rb_funcall_with_block_kw(obj, SYM2ID(method), RARRAY_LENINT(args), RARRAY_PTR(args), block, RB_PASS_KEYWORDS);
}
static VALUE kernel_spec_rb_funcall_many_args(VALUE self, VALUE obj, VALUE method) {
@@ -333,6 +380,15 @@ static VALUE kernel_spec_rb_funcall_many_args(VALUE self, VALUE obj, VALUE metho
INT2FIX(5), INT2FIX(4), INT2FIX(3), INT2FIX(2), INT2FIX(1));
}
+static VALUE kernel_spec_rb_check_funcall(VALUE self, VALUE receiver, VALUE method, VALUE args) {
+ VALUE ret = rb_check_funcall(receiver, SYM2ID(method), RARRAY_LENINT(args), RARRAY_PTR(args));
+ if (ret == Qundef) {
+ return ID2SYM(rb_intern("Qundef"));
+ } else {
+ return ret;
+ }
+}
+
void Init_kernel_spec(void) {
VALUE cls = rb_define_class("CApiKernelSpecs", rb_cObject);
rb_define_method(cls, "rb_block_given_p", kernel_spec_rb_block_given_p, 0);
@@ -345,21 +401,30 @@ void Init_kernel_spec(void) {
rb_define_method(cls, "rb_block_lambda", kernel_spec_rb_block_lambda, 0);
rb_define_method(cls, "rb_frame_this_func_test", kernel_spec_rb_frame_this_func, 0);
rb_define_method(cls, "rb_frame_this_func_test_again", kernel_spec_rb_frame_this_func, 0);
+ rb_define_method(cls, "rb_category_warn_deprecated", kernel_spec_rb_category_warn_deprecated, 0);
+ rb_define_method(cls, "rb_category_warn_deprecated_with_integer_extra_value", kernel_spec_rb_category_warn_deprecated_with_integer_extra_value, 1);
rb_define_method(cls, "rb_ensure", kernel_spec_rb_ensure, 4);
rb_define_method(cls, "rb_eval_string", kernel_spec_rb_eval_string, 1);
+#ifndef RUBY_VERSION_IS_4_0
+ rb_define_method(cls, "rb_eval_cmd_kw", kernel_spec_rb_eval_cmd_kw, 3);
+#endif
rb_define_method(cls, "rb_raise", kernel_spec_rb_raise, 1);
rb_define_method(cls, "rb_throw", kernel_spec_rb_throw, 1);
rb_define_method(cls, "rb_throw_obj", kernel_spec_rb_throw_obj, 2);
+ rb_define_method(cls, "rb_errinfo", kernel_spec_rb_errinfo, 0);
+ rb_define_method(cls, "rb_set_errinfo", kernel_spec_rb_set_errinfo, 1);
+ rb_define_method(cls, "rb_rescue", kernel_spec_rb_rescue, 4);
rb_define_method(cls, "rb_rescue", kernel_spec_rb_rescue, 4);
rb_define_method(cls, "rb_rescue2", kernel_spec_rb_rescue2, -1);
rb_define_method(cls, "rb_protect_yield", kernel_spec_rb_protect_yield, 2);
- rb_define_method(cls, "rb_protect_errinfo", kernel_spec_rb_protect_errinfo, 2);
+ rb_define_method(cls, "rb_protect_ignore_status", kernel_spec_rb_protect_ignore_status, 2);
rb_define_method(cls, "rb_protect_null_status", kernel_spec_rb_protect_null_status, 1);
rb_define_method(cls, "rb_eval_string_protect", kernel_spec_rb_eval_string_protect, 2);
rb_define_method(cls, "rb_catch", kernel_spec_rb_catch, 2);
rb_define_method(cls, "rb_catch_obj", kernel_spec_rb_catch_obj, 2);
rb_define_method(cls, "rb_sys_fail", kernel_spec_rb_sys_fail, 1);
rb_define_method(cls, "rb_syserr_fail", kernel_spec_rb_syserr_fail, 2);
+ rb_define_method(cls, "rb_syserr_fail_str", kernel_spec_rb_syserr_fail_str, 2);
rb_define_method(cls, "rb_warn", kernel_spec_rb_warn, 1);
rb_define_method(cls, "rb_yield", kernel_spec_rb_yield, 1);
rb_define_method(cls, "rb_yield_indirected", kernel_spec_rb_yield_indirected, 1);
@@ -370,10 +435,16 @@ void Init_kernel_spec(void) {
rb_define_method(cls, "rb_exec_recursive", kernel_spec_rb_exec_recursive, 1);
rb_define_method(cls, "rb_set_end_proc", kernel_spec_rb_set_end_proc, 1);
rb_define_method(cls, "rb_f_sprintf", kernel_spec_rb_f_sprintf, 1);
+ rb_define_method(cls, "rb_str_format", kernel_spec_rb_str_format, 3);
rb_define_method(cls, "rb_make_backtrace", kernel_spec_rb_make_backtrace, 0);
- rb_define_method(cls, "rb_funcall3", kernel_spec_rb_funcall3, 2);
+ rb_define_method(cls, "rb_funcallv", kernel_spec_rb_funcallv, 3);
+ rb_define_method(cls, "rb_funcallv_kw", kernel_spec_rb_funcallv_kw, 3);
+ rb_define_method(cls, "rb_keyword_given_p", kernel_spec_rb_keyword_given_p, -1);
+ rb_define_method(cls, "rb_funcallv_public", kernel_spec_rb_funcallv_public, 2);
rb_define_method(cls, "rb_funcall_many_args", kernel_spec_rb_funcall_many_args, 2);
- rb_define_method(cls, "rb_funcall_with_block", kernel_spec_rb_funcall_with_block, 3);
+ rb_define_method(cls, "rb_funcall_with_block", kernel_spec_rb_funcall_with_block, 4);
+ rb_define_method(cls, "rb_funcall_with_block_kw", kernel_spec_rb_funcall_with_block_kw, 4);
+ rb_define_method(cls, "rb_check_funcall", kernel_spec_rb_check_funcall, 3);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/module_spec.c b/spec/ruby/optional/capi/ext/module_spec.c
index 7475994fa1..12bcf99983 100644
--- a/spec/ruby/optional/capi/ext/module_spec.c
+++ b/spec/ruby/optional/capi/ext/module_spec.c
@@ -9,18 +9,6 @@ static VALUE module_specs_test_method(VALUE self) {
return ID2SYM(rb_intern("test_method"));
}
-static VALUE module_specs_test_method_2required(VALUE self, VALUE arg1, VALUE arg2) {
- return ID2SYM(rb_intern("test_method_2required"));
-}
-
-static VALUE module_specs_test_method_c_array(int argc, VALUE *argv, VALUE self) {
- return ID2SYM(rb_intern("test_method_c_array"));
-}
-
-static VALUE module_specs_test_method_ruby_array(VALUE self, VALUE args) {
- return ID2SYM(rb_intern("test_method_ruby_array"));
-}
-
static VALUE module_specs_const_defined(VALUE self, VALUE klass, VALUE id) {
return rb_const_defined(klass, SYM2ID(id)) ? Qtrue : Qfalse;
}
@@ -88,19 +76,25 @@ static VALUE module_specs_rb_define_method(VALUE self, VALUE cls, VALUE str_name
return Qnil;
}
-static VALUE module_specs_rb_define_method_2required(VALUE self, VALUE cls, VALUE str_name) {
- rb_define_method(cls, RSTRING_PTR(str_name), module_specs_test_method_2required, 2);
- return Qnil;
+static VALUE module_specs_method_var_args_1(int argc, VALUE *argv, VALUE self) {
+ VALUE ary = rb_ary_new();
+ int i;
+ for (i = 0; i < argc; i++) {
+ rb_ary_push(ary, argv[i]);
+ }
+ return ary;
}
-static VALUE module_specs_rb_define_method_c_array(VALUE self, VALUE cls, VALUE str_name) {
- rb_define_method(cls, RSTRING_PTR(str_name), module_specs_test_method_c_array, -1);
- return Qnil;
+static VALUE module_specs_method_var_args_2(VALUE self, VALUE argv) {
+ return argv;
}
-static VALUE module_specs_rb_define_method_ruby_array(VALUE self, VALUE cls, VALUE str_name) {
- rb_define_method(cls, RSTRING_PTR(str_name), module_specs_test_method_ruby_array, -2);
- return Qnil;
+static VALUE module_specs_rb_define_method_1required(VALUE self, VALUE arg1) {
+ return arg1;
+}
+
+static VALUE module_specs_rb_define_method_2required(VALUE self, VALUE arg1, VALUE arg2) {
+ return arg2;
}
static VALUE module_specs_rb_define_module_function(VALUE self, VALUE cls, VALUE str_name) {
@@ -155,25 +149,21 @@ void Init_module_spec(void) {
rb_define_method(cls, "rb_define_module_under", module_specs_rb_define_module_under, 2);
rb_define_method(cls, "rb_define_const", module_specs_define_const, 3);
rb_define_method(cls, "rb_define_global_const", module_specs_define_global_const, 2);
- rb_define_method(cls, "rb_define_global_function",
- module_specs_rb_define_global_function, 1);
+ rb_define_method(cls, "rb_define_global_function", module_specs_rb_define_global_function, 1);
rb_define_method(cls, "rb_define_method", module_specs_rb_define_method, 2);
+ rb_define_method(cls, "rb_define_method_varargs_1", module_specs_method_var_args_1, -1);
+ rb_define_method(cls, "rb_define_method_varargs_2", module_specs_method_var_args_2, -2);
+ rb_define_method(cls, "rb_define_method_1required", module_specs_rb_define_method_1required, 1);
rb_define_method(cls, "rb_define_method_2required", module_specs_rb_define_method_2required, 2);
- rb_define_method(cls, "rb_define_method_c_array", module_specs_rb_define_method_c_array, 2);
- rb_define_method(cls, "rb_define_method_ruby_array", module_specs_rb_define_method_ruby_array, 2);
- rb_define_method(cls, "rb_define_module_function",
- module_specs_rb_define_module_function, 2);
+ rb_define_method(cls, "rb_define_module_function", module_specs_rb_define_module_function, 2);
- rb_define_method(cls, "rb_define_private_method",
- module_specs_rb_define_private_method, 2);
+ rb_define_method(cls, "rb_define_private_method", module_specs_rb_define_private_method, 2);
- rb_define_method(cls, "rb_define_protected_method",
- module_specs_rb_define_protected_method, 2);
+ rb_define_method(cls, "rb_define_protected_method", module_specs_rb_define_protected_method, 2);
- rb_define_method(cls, "rb_define_singleton_method",
- module_specs_rb_define_singleton_method, 2);
+ rb_define_method(cls, "rb_define_singleton_method", module_specs_rb_define_singleton_method, 2);
rb_define_method(cls, "rb_undef_method", module_specs_rb_undef_method, 2);
rb_define_method(cls, "rb_undef", module_specs_rb_undef, 2);
diff --git a/spec/ruby/optional/capi/ext/mutex_spec.c b/spec/ruby/optional/capi/ext/mutex_spec.c
index c2fdf917ac..d2c8f98e89 100644
--- a/spec/ruby/optional/capi/ext/mutex_spec.c
+++ b/spec/ruby/optional/capi/ext/mutex_spec.c
@@ -29,15 +29,34 @@ VALUE mutex_spec_rb_mutex_sleep(VALUE self, VALUE mutex, VALUE timeout) {
return rb_mutex_sleep(mutex, timeout);
}
-
VALUE mutex_spec_rb_mutex_callback(VALUE arg) {
return rb_funcall(arg, rb_intern("call"), 0);
}
+VALUE mutex_spec_rb_mutex_naughty_callback(VALUE arg) {
+ int *result = (int *) arg;
+ return (VALUE) result;
+}
+
+VALUE mutex_spec_rb_mutex_callback_basic(VALUE arg) {
+ return arg;
+}
+
VALUE mutex_spec_rb_mutex_synchronize(VALUE self, VALUE mutex, VALUE value) {
return rb_mutex_synchronize(mutex, mutex_spec_rb_mutex_callback, value);
}
+VALUE mutex_spec_rb_mutex_synchronize_with_naughty_callback(VALUE self, VALUE mutex) {
+ // a naughty callback accepts or returns not a Ruby object but arbitrary value
+ int arg = 42;
+ VALUE result = rb_mutex_synchronize(mutex, mutex_spec_rb_mutex_naughty_callback, (VALUE) &arg);
+ return INT2NUM(*((int *) result));
+}
+
+VALUE mutex_spec_rb_mutex_synchronize_with_native_callback(VALUE self, VALUE mutex, VALUE value) {
+ return rb_mutex_synchronize(mutex, mutex_spec_rb_mutex_callback_basic, value);
+}
+
void Init_mutex_spec(void) {
VALUE cls = rb_define_class("CApiMutexSpecs", rb_cObject);
rb_define_method(cls, "rb_mutex_new", mutex_spec_rb_mutex_new, 0);
@@ -47,6 +66,8 @@ void Init_mutex_spec(void) {
rb_define_method(cls, "rb_mutex_unlock", mutex_spec_rb_mutex_unlock, 1);
rb_define_method(cls, "rb_mutex_sleep", mutex_spec_rb_mutex_sleep, 2);
rb_define_method(cls, "rb_mutex_synchronize", mutex_spec_rb_mutex_synchronize, 2);
+ rb_define_method(cls, "rb_mutex_synchronize_with_naughty_callback", mutex_spec_rb_mutex_synchronize_with_naughty_callback, 1);
+ rb_define_method(cls, "rb_mutex_synchronize_with_native_callback", mutex_spec_rb_mutex_synchronize_with_native_callback, 2);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/object_spec.c b/spec/ruby/optional/capi/ext/object_spec.c
index c1f3b09ff8..995bc38fcf 100644
--- a/spec/ruby/optional/capi/ext/object_spec.c
+++ b/spec/ruby/optional/capi/ext/object_spec.c
@@ -15,11 +15,6 @@ static VALUE object_spec_FL_ABLE(VALUE self, VALUE obj) {
static int object_spec_FL_TEST_flag(VALUE flag_string) {
char *flag_cstr = StringValueCStr(flag_string);
-#ifndef RUBY_VERSION_IS_3_1
- if (strcmp(flag_cstr, "FL_TAINT") == 0) {
- return FL_TAINT;
- }
-#endif
if (strcmp(flag_cstr, "FL_FREEZE") == 0) {
return FL_FREEZE;
}
@@ -30,22 +25,6 @@ static VALUE object_spec_FL_TEST(VALUE self, VALUE obj, VALUE flag) {
return INT2FIX(FL_TEST(obj, object_spec_FL_TEST_flag(flag)));
}
-#ifndef RUBY_VERSION_IS_3_1
-static VALUE object_spec_OBJ_TAINT(VALUE self, VALUE obj) {
- OBJ_TAINT(obj);
- return Qnil;
-}
-
-static VALUE object_spec_OBJ_TAINTED(VALUE self, VALUE obj) {
- return OBJ_TAINTED(obj) ? Qtrue : Qfalse;
-}
-
-static VALUE object_spec_OBJ_INFECT(VALUE self, VALUE host, VALUE source) {
- OBJ_INFECT(host, source);
- return Qnil;
-}
-#endif
-
static VALUE object_spec_rb_any_to_s(VALUE self, VALUE obj) {
return rb_any_to_s(obj);
}
@@ -118,11 +97,14 @@ static VALUE so_rb_obj_call_init(VALUE self, VALUE object,
return Qnil;
}
+static VALUE so_rb_obj_class(VALUE self, VALUE obj) {
+ return rb_obj_class(obj);
+}
+
static VALUE so_rbobjclassname(VALUE self, VALUE obj) {
return rb_str_new2(rb_obj_classname(obj));
}
-
static VALUE object_spec_rb_obj_freeze(VALUE self, VALUE obj) {
return rb_obj_freeze(obj);
}
@@ -151,28 +133,6 @@ static VALUE object_specs_rb_obj_method(VALUE self, VALUE obj, VALUE method) {
return rb_obj_method(obj, method);
}
-#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#elif defined(__clang__) && defined(__has_warning)
-# if __has_warning("-Wdeprecated-declarations")
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wdeprecated-declarations"
-# endif
-#endif
-
-static VALUE object_spec_rb_obj_taint(VALUE self, VALUE obj) {
- return rb_obj_taint(obj);
-}
-
-#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
-# pragma GCC diagnostic pop
-#elif defined(__clang__) && defined(__has_warning)
-# if __has_warning("-Wdeprecated-declarations")
-# pragma clang diagnostic pop
-# endif
-#endif
-
static VALUE so_require(VALUE self) {
rb_require("fixtures/foo");
return Qnil;
@@ -192,11 +152,7 @@ static VALUE object_spec_rb_method_boundp(VALUE self, VALUE obj, VALUE method, V
}
static VALUE object_spec_rb_special_const_p(VALUE self, VALUE value) {
- if (rb_special_const_p(value)) {
- return Qtrue;
- } else {
- return Qfalse;
- }
+ return rb_special_const_p(value);
}
static VALUE so_to_id(VALUE self, VALUE obj) {
@@ -213,119 +169,126 @@ static VALUE so_check_type(VALUE self, VALUE obj, VALUE other) {
}
static VALUE so_is_type_nil(VALUE self, VALUE obj) {
- if(TYPE(obj) == T_NIL) {
+ if (TYPE(obj) == T_NIL) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_object(VALUE self, VALUE obj) {
- if(TYPE(obj) == T_OBJECT) {
+ if (TYPE(obj) == T_OBJECT) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_array(VALUE self, VALUE obj) {
- if(TYPE(obj) == T_ARRAY) {
+ if (TYPE(obj) == T_ARRAY) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_module(VALUE self, VALUE obj) {
- if(TYPE(obj) == T_MODULE) {
+ if (TYPE(obj) == T_MODULE) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_class(VALUE self, VALUE obj) {
- if(TYPE(obj) == T_CLASS) {
+ if (TYPE(obj) == T_CLASS) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_data(VALUE self, VALUE obj) {
- if(TYPE(obj) == T_DATA) {
+ if (TYPE(obj) == T_DATA) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_nil(VALUE self, VALUE obj) {
- if(rb_type_p(obj, T_NIL)) {
+ if (rb_type_p(obj, T_NIL)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_object(VALUE self, VALUE obj) {
- if(rb_type_p(obj, T_OBJECT)) {
+ if (rb_type_p(obj, T_OBJECT)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_array(VALUE self, VALUE obj) {
- if(rb_type_p(obj, T_ARRAY)) {
+ if (rb_type_p(obj, T_ARRAY)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_module(VALUE self, VALUE obj) {
- if(rb_type_p(obj, T_MODULE)) {
+ if (rb_type_p(obj, T_MODULE)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_class(VALUE self, VALUE obj) {
- if(rb_type_p(obj, T_CLASS)) {
+ if (rb_type_p(obj, T_CLASS)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_data(VALUE self, VALUE obj) {
- if(rb_type_p(obj, T_DATA)) {
+ if (rb_type_p(obj, T_DATA)) {
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+static VALUE so_is_rb_type_p_file(VALUE self, VALUE obj) {
+ if (rb_type_p(obj, T_FILE)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_object(VALUE self, VALUE obj) {
- if(BUILTIN_TYPE(obj) == T_OBJECT) {
+ if (BUILTIN_TYPE(obj) == T_OBJECT) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_array(VALUE self, VALUE obj) {
- if(BUILTIN_TYPE(obj) == T_ARRAY) {
+ if (BUILTIN_TYPE(obj) == T_ARRAY) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_module(VALUE self, VALUE obj) {
- if(BUILTIN_TYPE(obj) == T_MODULE) {
+ if (BUILTIN_TYPE(obj) == T_MODULE) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_class(VALUE self, VALUE obj) {
- if(BUILTIN_TYPE(obj) == T_CLASS) {
+ if (BUILTIN_TYPE(obj) == T_CLASS) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_data(VALUE self, VALUE obj) {
- if(BUILTIN_TYPE(obj) == T_DATA) {
+ if (BUILTIN_TYPE(obj) == T_DATA) {
return Qtrue;
}
return Qfalse;
@@ -381,50 +344,59 @@ static VALUE object_spec_rb_class_inherited_p(VALUE self, VALUE mod, VALUE arg)
return rb_class_inherited_p(mod, arg);
}
+static int foreach_f(ID key, VALUE val, VALUE ary) {
+ rb_ary_push(ary, ID2SYM(key));
+ rb_ary_push(ary, val);
+ return ST_CONTINUE;
+}
+
+static VALUE object_spec_rb_ivar_foreach(VALUE self, VALUE obj) {
+ VALUE ary = rb_ary_new();
+ rb_ivar_foreach(obj, foreach_f, ary);
+ return ary;
+}
+
static VALUE speced_allocator(VALUE klass) {
- VALUE flags = 0;
- VALUE instance;
- if (RTEST(rb_class_inherited_p(klass, rb_cString))) {
- flags = T_STRING;
- } else if (RTEST(rb_class_inherited_p(klass, rb_cArray))) {
- flags = T_ARRAY;
- } else {
- flags = T_OBJECT;
- }
- instance = rb_newobj_of(klass, flags);
+ VALUE super = rb_class_get_superclass(klass);
+ VALUE instance = rb_get_alloc_func(super)(klass);
rb_iv_set(instance, "@from_custom_allocator", Qtrue);
return instance;
}
-static VALUE define_alloc_func(VALUE self, VALUE klass) {
+static VALUE object_spec_rb_define_alloc_func(VALUE self, VALUE klass) {
rb_define_alloc_func(klass, speced_allocator);
return Qnil;
}
-static VALUE undef_alloc_func(VALUE self, VALUE klass) {
+static VALUE object_spec_rb_undef_alloc_func(VALUE self, VALUE klass) {
rb_undef_alloc_func(klass);
return Qnil;
}
-static VALUE speced_allocator_p(VALUE self, VALUE klass) {
+static VALUE object_spec_speced_allocator_p(VALUE self, VALUE klass) {
rb_alloc_func_t allocator = rb_get_alloc_func(klass);
return (allocator == speced_allocator) ? Qtrue : Qfalse;
}
-static VALUE custom_alloc_func_p(VALUE self, VALUE klass) {
+static VALUE object_spec_custom_alloc_func_p(VALUE self, VALUE klass) {
rb_alloc_func_t allocator = rb_get_alloc_func(klass);
return allocator ? Qtrue : Qfalse;
}
+static VALUE object_spec_redefine_frozen(VALUE self) {
+ // The purpose of this spec is to verify that `frozen?`
+ // and `RB_OBJ_FROZEN` do not mutually recurse infinitely.
+ if (RB_OBJ_FROZEN(self)) {
+ return Qtrue;
+ }
+
+ return Qfalse;
+}
+
void Init_object_spec(void) {
VALUE cls = rb_define_class("CApiObjectSpecs", rb_cObject);
rb_define_method(cls, "FL_ABLE", object_spec_FL_ABLE, 1);
rb_define_method(cls, "FL_TEST", object_spec_FL_TEST, 2);
-#ifndef RUBY_VERSION_IS_3_1
- rb_define_method(cls, "OBJ_TAINT", object_spec_OBJ_TAINT, 1);
- rb_define_method(cls, "OBJ_TAINTED", object_spec_OBJ_TAINTED, 1);
- rb_define_method(cls, "OBJ_INFECT", object_spec_OBJ_INFECT, 2);
-#endif
rb_define_method(cls, "rb_any_to_s", object_spec_rb_any_to_s, 1);
rb_define_method(cls, "rb_attr_get", so_attr_get, 2);
rb_define_method(cls, "rb_obj_instance_variables", object_spec_rb_obj_instance_variables, 1);
@@ -440,6 +412,7 @@ void Init_object_spec(void) {
rb_define_method(cls, "rb_obj_alloc", so_rb_obj_alloc, 1);
rb_define_method(cls, "rb_obj_dup", so_rb_obj_dup, 1);
rb_define_method(cls, "rb_obj_call_init", so_rb_obj_call_init, 3);
+ rb_define_method(cls, "rb_obj_class", so_rb_obj_class, 1);
rb_define_method(cls, "rb_obj_classname", so_rbobjclassname, 1);
rb_define_method(cls, "rb_obj_freeze", object_spec_rb_obj_freeze, 1);
rb_define_method(cls, "rb_obj_frozen_p", object_spec_rb_obj_frozen_p, 1);
@@ -448,13 +421,11 @@ void Init_object_spec(void) {
rb_define_method(cls, "rb_obj_is_kind_of", so_kind_of, 2);
rb_define_method(cls, "rb_obj_method_arity", object_specs_rb_obj_method_arity, 2);
rb_define_method(cls, "rb_obj_method", object_specs_rb_obj_method, 2);
- rb_define_method(cls, "rb_obj_taint", object_spec_rb_obj_taint, 1);
rb_define_method(cls, "rb_require", so_require, 0);
rb_define_method(cls, "rb_respond_to", so_respond_to, 2);
rb_define_method(cls, "rb_method_boundp", object_spec_rb_method_boundp, 3);
rb_define_method(cls, "rb_obj_respond_to", so_obj_respond_to, 3);
rb_define_method(cls, "rb_special_const_p", object_spec_rb_special_const_p, 1);
-
rb_define_method(cls, "rb_to_id", so_to_id, 1);
rb_define_method(cls, "RTEST", object_spec_RTEST, 1);
rb_define_method(cls, "rb_check_type", so_check_type, 2);
@@ -470,6 +441,7 @@ void Init_object_spec(void) {
rb_define_method(cls, "rb_is_rb_type_p_module", so_is_rb_type_p_module, 1);
rb_define_method(cls, "rb_is_rb_type_p_class", so_is_rb_type_p_class, 1);
rb_define_method(cls, "rb_is_rb_type_p_data", so_is_rb_type_p_data, 1);
+ rb_define_method(cls, "rb_is_rb_type_p_file", so_is_rb_type_p_file, 1);
rb_define_method(cls, "rb_is_builtin_type_object", so_is_builtin_type_object, 1);
rb_define_method(cls, "rb_is_builtin_type_array", so_is_builtin_type_array, 1);
rb_define_method(cls, "rb_is_builtin_type_module", so_is_builtin_type_module, 1);
@@ -487,11 +459,15 @@ void Init_object_spec(void) {
rb_define_method(cls, "rb_ivar_defined", object_spec_rb_ivar_defined, 2);
rb_define_method(cls, "rb_copy_generic_ivar", object_spec_rb_copy_generic_ivar, 2);
rb_define_method(cls, "rb_free_generic_ivar", object_spec_rb_free_generic_ivar, 1);
- rb_define_method(cls, "rb_define_alloc_func", define_alloc_func, 1);
- rb_define_method(cls, "rb_undef_alloc_func", undef_alloc_func, 1);
- rb_define_method(cls, "speced_allocator?", speced_allocator_p, 1);
- rb_define_method(cls, "custom_alloc_func?", custom_alloc_func_p, 1);
+ rb_define_method(cls, "rb_define_alloc_func", object_spec_rb_define_alloc_func, 1);
+ rb_define_method(cls, "rb_undef_alloc_func", object_spec_rb_undef_alloc_func, 1);
+ rb_define_method(cls, "speced_allocator?", object_spec_speced_allocator_p, 1);
+ rb_define_method(cls, "custom_alloc_func?", object_spec_custom_alloc_func_p, 1);
rb_define_method(cls, "not_implemented_method", rb_f_notimplement, -1);
+ rb_define_method(cls, "rb_ivar_foreach", object_spec_rb_ivar_foreach, 1);
+
+ cls = rb_define_class("CApiObjectRedefinitionSpecs", rb_cObject);
+ rb_define_method(cls, "frozen?", object_spec_redefine_frozen, 0);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/proc_spec.c b/spec/ruby/optional/capi/ext/proc_spec.c
index e0bd8b1bbc..b7cd5d6262 100644
--- a/spec/ruby/optional/capi/ext/proc_spec.c
+++ b/spec/ruby/optional/capi/ext/proc_spec.c
@@ -11,10 +11,63 @@ VALUE proc_spec_rb_proc_new_function(RB_BLOCK_CALL_FUNC_ARGLIST(args, dummy)) {
return rb_funcall(args, rb_intern("inspect"), 0);
}
+VALUE proc_spec_rb_proc_new_function_arg(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return arg;
+}
+
+VALUE proc_spec_rb_proc_new_function_argc(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return INT2FIX(argc);
+}
+
+VALUE proc_spec_rb_proc_new_function_argv_n(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ int n = FIX2INT(arg);
+ if (n < argc) {
+ return argv[n];
+ } else {
+ rb_exc_raise(rb_exc_new2(rb_eArgError, "Arg index out of bounds."));
+ }
+}
+
+VALUE proc_spec_rb_proc_new_function_callback_arg(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return callback_arg;
+}
+
+VALUE proc_spec_rb_proc_new_function_blockarg(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return blockarg;
+}
+
+VALUE proc_spec_rb_proc_new_function_block_given_p(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return rb_block_given_p() ? Qtrue : Qfalse;
+}
+
VALUE proc_spec_rb_proc_new(VALUE self) {
return rb_proc_new(proc_spec_rb_proc_new_function, Qnil);
}
+VALUE proc_spec_rb_proc_new_arg(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_arg, Qnil);
+}
+
+VALUE proc_spec_rb_proc_new_argc(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_argc, Qnil);
+}
+
+VALUE proc_spec_rb_proc_new_argv_n(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_argv_n, Qnil);
+}
+
+VALUE proc_spec_rb_proc_new_callback_arg(VALUE self, VALUE arg) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_callback_arg, arg);
+}
+
+VALUE proc_spec_rb_proc_new_blockarg(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_blockarg, Qnil);
+}
+
+VALUE proc_spec_rb_proc_new_block_given_p(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_block_given_p, Qnil);
+}
+
VALUE proc_spec_rb_proc_arity(VALUE self, VALUE prc) {
return INT2FIX(rb_proc_arity(prc));
}
@@ -23,6 +76,18 @@ VALUE proc_spec_rb_proc_call(VALUE self, VALUE prc, VALUE args) {
return rb_proc_call(prc, args);
}
+VALUE proc_spec_rb_proc_call_kw(VALUE self, VALUE prc, VALUE args) {
+ return rb_proc_call_kw(prc, args, RB_PASS_KEYWORDS);
+}
+
+VALUE proc_spec_rb_proc_call_with_block(VALUE self, VALUE prc, VALUE args, VALUE block) {
+ return rb_proc_call_with_block(prc, RARRAY_LENINT(args), RARRAY_PTR(args), block);
+}
+
+static VALUE proc_spec_rb_proc_call_with_block_kw(VALUE self, VALUE prc, VALUE args, VALUE block) {
+ return rb_proc_call_with_block_kw(prc, RARRAY_LENINT(args), RARRAY_PTR(args), block, RB_PASS_KEYWORDS);
+}
+
VALUE proc_spec_rb_obj_is_proc(VALUE self, VALUE prc) {
return rb_obj_is_proc(prc);
}
@@ -62,8 +127,17 @@ VALUE proc_spec_rb_Proc_new(VALUE self, VALUE scenario) {
void Init_proc_spec(void) {
VALUE cls = rb_define_class("CApiProcSpecs", rb_cObject);
rb_define_method(cls, "rb_proc_new", proc_spec_rb_proc_new, 0);
+ rb_define_method(cls, "rb_proc_new_arg", proc_spec_rb_proc_new_arg, 0);
+ rb_define_method(cls, "rb_proc_new_argc", proc_spec_rb_proc_new_argc, 0);
+ rb_define_method(cls, "rb_proc_new_argv_n", proc_spec_rb_proc_new_argv_n, 0);
+ rb_define_method(cls, "rb_proc_new_callback_arg", proc_spec_rb_proc_new_callback_arg, 1);
+ rb_define_method(cls, "rb_proc_new_blockarg", proc_spec_rb_proc_new_blockarg, 0);
+ rb_define_method(cls, "rb_proc_new_block_given_p", proc_spec_rb_proc_new_block_given_p, 0);
rb_define_method(cls, "rb_proc_arity", proc_spec_rb_proc_arity, 1);
rb_define_method(cls, "rb_proc_call", proc_spec_rb_proc_call, 2);
+ rb_define_method(cls, "rb_proc_call_kw", proc_spec_rb_proc_call_kw, 2);
+ rb_define_method(cls, "rb_proc_call_with_block", proc_spec_rb_proc_call_with_block, 3);
+ rb_define_method(cls, "rb_proc_call_with_block_kw", proc_spec_rb_proc_call_with_block_kw, 3);
rb_define_method(cls, "rb_Proc_new", proc_spec_rb_Proc_new, 1);
rb_define_method(cls, "rb_obj_is_proc", proc_spec_rb_obj_is_proc, 1);
}
diff --git a/spec/ruby/optional/capi/ext/range_spec.c b/spec/ruby/optional/capi/ext/range_spec.c
index 7a475ec695..9faed3e5ee 100644
--- a/spec/ruby/optional/capi/ext/range_spec.c
+++ b/spec/ruby/optional/capi/ext/range_spec.c
@@ -7,7 +7,7 @@ extern "C" {
VALUE range_spec_rb_range_new(int argc, VALUE* argv, VALUE self) {
int exclude_end = 0;
- if(argc == 3) {
+ if (argc == 3) {
exclude_end = RTEST(argv[2]);
}
return rb_range_new(argv[0], argv[1], exclude_end);
@@ -25,9 +25,9 @@ VALUE range_spec_rb_range_values(VALUE self, VALUE range) {
return ary;
}
-VALUE range_spec_rb_range_beg_len(VALUE self, VALUE range, VALUE begpv, VALUE lenpv, VALUE lenv, VALUE errv) {
- long begp = FIX2LONG(begpv);
- long lenp = FIX2LONG(lenpv);
+VALUE range_spec_rb_range_beg_len(VALUE self, VALUE range, VALUE lenv, VALUE errv) {
+ long begp = 0;
+ long lenp = 0;
long len = FIX2LONG(lenv);
int err = FIX2INT(errv);
VALUE ary = rb_ary_new();
@@ -38,11 +38,51 @@ VALUE range_spec_rb_range_beg_len(VALUE self, VALUE range, VALUE begpv, VALUE le
return ary;
}
+VALUE range_spec_rb_arithmetic_sequence_extract(VALUE self, VALUE object) {
+ VALUE ary = rb_ary_new();
+ rb_arithmetic_sequence_components_t components;
+
+ int status = rb_arithmetic_sequence_extract(object, &components);
+
+ if (!status) {
+ rb_ary_store(ary, 0, LONG2FIX(status));
+ return ary;
+ }
+
+ rb_ary_store(ary, 0, LONG2FIX(status));
+ rb_ary_store(ary, 1, components.begin);
+ rb_ary_store(ary, 2, components.end);
+ rb_ary_store(ary, 3, components.step);
+ rb_ary_store(ary, 4, components.exclude_end ? Qtrue : Qfalse);
+ return ary;
+}
+
+VALUE range_spec_rb_arithmetic_sequence_beg_len_step(VALUE self, VALUE aseq, VALUE lenv, VALUE errv) {
+ long begp = 0;
+ long lenp = 0;
+ long stepp = 0;
+
+ long len = FIX2LONG(lenv);
+ int err = FIX2INT(errv);
+
+ VALUE success = rb_arithmetic_sequence_beg_len_step(aseq, &begp, &lenp, &stepp, len, err);
+
+ VALUE ary = rb_ary_new();
+ rb_ary_store(ary, 0, success);
+ rb_ary_store(ary, 1, LONG2FIX(begp));
+ rb_ary_store(ary, 2, LONG2FIX(lenp));
+ rb_ary_store(ary, 3, LONG2FIX(stepp));
+
+ return ary;
+}
+
void Init_range_spec(void) {
VALUE cls = rb_define_class("CApiRangeSpecs", rb_cObject);
rb_define_method(cls, "rb_range_new", range_spec_rb_range_new, -1);
rb_define_method(cls, "rb_range_values", range_spec_rb_range_values, 1);
- rb_define_method(cls, "rb_range_beg_len", range_spec_rb_range_beg_len, 5);
+ rb_define_method(cls, "rb_range_beg_len", range_spec_rb_range_beg_len, 3);
+ rb_define_method(cls, "rb_arithmetic_sequence_extract", range_spec_rb_arithmetic_sequence_extract, 1);
+ rb_define_method(cls, "rb_arithmetic_sequence_beg_len_step", range_spec_rb_arithmetic_sequence_beg_len_step, 3);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/rbasic_spec.c b/spec/ruby/optional/capi/ext/rbasic_spec.c
index 6cd6c236c4..5a95b92804 100644
--- a/spec/ruby/optional/capi/ext/rbasic_spec.c
+++ b/spec/ruby/optional/capi/ext/rbasic_spec.c
@@ -5,10 +5,20 @@
extern "C" {
#endif
+#ifndef RBASIC_FLAGS
+#define RBASIC_FLAGS(obj) (RBASIC(obj)->flags)
+#endif
+
+#ifndef RBASIC_SET_FLAGS
+#define RBASIC_SET_FLAGS(obj, flags_to_set) (RBASIC(obj)->flags = flags_to_set)
+#endif
+
#ifndef FL_SHAREABLE
-static const VALUE VISIBLE_BITS = FL_TAINT | FL_FREEZE | ~(FL_USER0 - 1);
+static const VALUE VISIBLE_BITS = FL_TAINT | FL_FREEZE;
+static const VALUE DATA_VISIBLE_BITS = FL_TAINT | FL_FREEZE | ~(FL_USER0 - 1);
#else
-static const VALUE VISIBLE_BITS = FL_FREEZE | ~(FL_USER0 - 1);
+static const VALUE VISIBLE_BITS = FL_FREEZE;
+static const VALUE DATA_VISIBLE_BITS = FL_FREEZE | ~(FL_USER0 - 1);
#endif
#if SIZEOF_VALUE == SIZEOF_LONG
@@ -21,65 +31,61 @@ static const VALUE VISIBLE_BITS = FL_FREEZE | ~(FL_USER0 - 1);
#error "unsupported"
#endif
-
-#ifndef RUBY_VERSION_IS_3_1
-VALUE rbasic_spec_taint_flag(VALUE self) {
- return VALUE2NUM(RUBY_FL_TAINT);
-}
-#endif
-
VALUE rbasic_spec_freeze_flag(VALUE self) {
return VALUE2NUM(RUBY_FL_FREEZE);
}
-static VALUE spec_get_flags(const struct RBasic *b) {
- VALUE flags = b->flags & VISIBLE_BITS;
+static VALUE spec_get_flags(VALUE obj, VALUE visible_bits) {
+ VALUE flags = RB_FL_TEST(obj, visible_bits);
return VALUE2NUM(flags);
}
-static VALUE spec_set_flags(struct RBasic *b, VALUE flags) {
- flags &= VISIBLE_BITS;
- b->flags = (b->flags & ~VISIBLE_BITS) | flags;
+static VALUE spec_set_flags(VALUE obj, VALUE flags, VALUE visible_bits) {
+ flags &= visible_bits;
+
+ // Could also be done like:
+ // RB_FL_UNSET(obj, visible_bits);
+ // RB_FL_SET(obj, flags);
+ // But that seems rather indirect
+ RBASIC_SET_FLAGS(obj, (RBASIC_FLAGS(obj) & ~visible_bits) | flags);
+
return VALUE2NUM(flags);
}
-VALUE rbasic_spec_get_flags(VALUE self, VALUE val) {
- return spec_get_flags(RBASIC(val));
+static VALUE rbasic_spec_get_flags(VALUE self, VALUE obj) {
+ return spec_get_flags(obj, VISIBLE_BITS);
}
-VALUE rbasic_spec_set_flags(VALUE self, VALUE val, VALUE flags) {
- return spec_set_flags(RBASIC(val), NUM2VALUE(flags));
+static VALUE rbasic_spec_set_flags(VALUE self, VALUE obj, VALUE flags) {
+ return spec_set_flags(obj, NUM2VALUE(flags), VISIBLE_BITS);
}
-VALUE rbasic_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
- return spec_set_flags(RBASIC(to), RBASIC(from)->flags);
+static VALUE rbasic_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
+ return spec_set_flags(to, RBASIC_FLAGS(from), VISIBLE_BITS);
}
-VALUE rbasic_spec_get_klass(VALUE self, VALUE val) {
- return RBASIC(val)->klass;
+static VALUE rbasic_spec_get_klass(VALUE self, VALUE obj) {
+ return RBASIC_CLASS(obj);
}
-VALUE rbasic_rdata_spec_get_flags(VALUE self, VALUE structure) {
- return spec_get_flags(&RDATA(structure)->basic);
+static VALUE rbasic_rdata_spec_get_flags(VALUE self, VALUE structure) {
+ return spec_get_flags(structure, DATA_VISIBLE_BITS);
}
-VALUE rbasic_rdata_spec_set_flags(VALUE self, VALUE structure, VALUE flags) {
- return spec_set_flags(&RDATA(structure)->basic, NUM2VALUE(flags));
+static VALUE rbasic_rdata_spec_set_flags(VALUE self, VALUE structure, VALUE flags) {
+ return spec_set_flags(structure, NUM2VALUE(flags), DATA_VISIBLE_BITS);
}
-VALUE rbasic_rdata_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
- return spec_set_flags(&RDATA(to)->basic, RDATA(from)->basic.flags);
+static VALUE rbasic_rdata_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
+ return spec_set_flags(to, RBASIC_FLAGS(from), DATA_VISIBLE_BITS);
}
-VALUE rbasic_rdata_spec_get_klass(VALUE self, VALUE structure) {
- return RDATA(structure)->basic.klass;
+static VALUE rbasic_rdata_spec_get_klass(VALUE self, VALUE structure) {
+ return RBASIC_CLASS(structure);
}
void Init_rbasic_spec(void) {
VALUE cls = rb_define_class("CApiRBasicSpecs", rb_cObject);
-#ifndef RUBY_VERSION_IS_3_1
- rb_define_method(cls, "taint_flag", rbasic_spec_taint_flag, 0);
-#endif
rb_define_method(cls, "freeze_flag", rbasic_spec_freeze_flag, 0);
rb_define_method(cls, "get_flags", rbasic_spec_get_flags, 1);
rb_define_method(cls, "set_flags", rbasic_spec_set_flags, 2);
diff --git a/spec/ruby/optional/capi/ext/regexp_spec.c b/spec/ruby/optional/capi/ext/regexp_spec.c
index 0a62616f33..9de7982b50 100644
--- a/spec/ruby/optional/capi/ext/regexp_spec.c
+++ b/spec/ruby/optional/capi/ext/regexp_spec.c
@@ -49,6 +49,12 @@ VALUE regexp_spec_match(VALUE self, VALUE regexp, VALUE str) {
return rb_funcall(regexp, rb_intern("match"), 1, str);
}
+VALUE regexp_spec_memcicmp(VALUE self, VALUE str1, VALUE str2) {
+ long l1 = RSTRING_LEN(str1);
+ long l2 = RSTRING_LEN(str2);
+ return INT2FIX(rb_memcicmp(RSTRING_PTR(str1), RSTRING_PTR(str2), l1 < l2 ? l1 : l2));
+}
+
void Init_regexp_spec(void) {
VALUE cls = rb_define_class("CApiRegexpSpecs", rb_cObject);
rb_define_method(cls, "match", regexp_spec_match, 2);
@@ -60,6 +66,7 @@ void Init_regexp_spec(void) {
rb_define_method(cls, "rb_reg_match_backref_get", regexp_spec_reg_match_backref_get, 2);
rb_define_method(cls, "rb_reg_options", regexp_spec_rb_reg_options, 1);
rb_define_method(cls, "rb_reg_regcomp", regexp_spec_rb_reg_regcomp, 1);
+ rb_define_method(cls, "rb_memcicmp", regexp_spec_memcicmp, 2);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/rubyspec.h b/spec/ruby/optional/capi/ext/rubyspec.h
index 7e4a252b38..6c4bea5da0 100644
--- a/spec/ruby/optional/capi/ext/rubyspec.h
+++ b/spec/ruby/optional/capi/ext/rubyspec.h
@@ -5,59 +5,46 @@
* guards to assist with version incompatibilities. */
#include <ruby.h>
-#ifdef HAVE_RUBY_VERSION_H
-# include <ruby/version.h>
-#else
-# include <version.h>
-#endif
+#include <ruby/version.h>
-#ifndef RUBY_VERSION_MAJOR
-#define RUBY_VERSION_MAJOR RUBY_API_VERSION_MAJOR
-#define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
-#define RUBY_VERSION_TEENY RUBY_API_VERSION_TEENY
-#endif
+/* copied from ext/-test-/cxxanyargs/cxxanyargs.cpp */
+#if 0 /* Ignore deprecation warnings */
-#define RUBY_VERSION_BEFORE(major,minor,teeny) \
- ((RUBY_VERSION_MAJOR < (major)) || \
- (RUBY_VERSION_MAJOR == (major) && RUBY_VERSION_MINOR < (minor)) || \
- (RUBY_VERSION_MAJOR == (major) && RUBY_VERSION_MINOR == (minor) && RUBY_VERSION_TEENY < (teeny)))
+#elif defined(_MSC_VER)
+#pragma warning(disable : 4996)
-#if RUBY_VERSION_MAJOR > 3 || (RUBY_VERSION_MAJOR == 3 && RUBY_VERSION_MINOR >= 1)
-#define RUBY_VERSION_IS_3_1
-#endif
+#elif defined(__INTEL_COMPILER)
+#pragma warning(disable : 1786)
+
+#elif defined(__clang__)
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#elif defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+#elif defined(__SUNPRO_CC)
+#pragma error_messages (off,symdeprecated)
+
+#else
+// :FIXME: improve here for your compiler.
-#if RUBY_VERSION_MAJOR > 3 || (RUBY_VERSION_MAJOR == 3 && RUBY_VERSION_MINOR >= 0)
-#define RUBY_VERSION_IS_3_0
#endif
-#if RUBY_VERSION_MAJOR > 2 || (RUBY_VERSION_MAJOR == 2 && RUBY_VERSION_MINOR >= 7)
-#define RUBY_VERSION_IS_2_7
+#define RUBY_VERSION_BEFORE(major,minor) \
+ ((RUBY_API_VERSION_MAJOR < (major)) || \
+ (RUBY_API_VERSION_MAJOR == (major) && RUBY_API_VERSION_MINOR < (minor)))
+#define RUBY_VERSION_SINCE(major,minor) (!RUBY_VERSION_BEFORE(major, minor))
+
+#if RUBY_VERSION_SINCE(4, 0)
+#define RUBY_VERSION_IS_4_0
#endif
-#if RUBY_VERSION_MAJOR > 2 || (RUBY_VERSION_MAJOR == 2 && RUBY_VERSION_MINOR >= 6)
-#define RUBY_VERSION_IS_2_6
+#if RUBY_VERSION_SINCE(3, 4)
+#define RUBY_VERSION_IS_3_4
#endif
-#if defined(__cplusplus) && !defined(RUBY_VERSION_IS_2_7)
-/* Ruby < 2.7 needs this to let these function with callbacks and compile in C++ code */
-#define rb_define_method(mod, name, func, argc) rb_define_method(mod, name, RUBY_METHOD_FUNC(func), argc)
-#define rb_define_protected_method(mod, name, func, argc) rb_define_protected_method(mod, name, RUBY_METHOD_FUNC(func), argc)
-#define rb_define_private_method(mod, name, func, argc) rb_define_private_method(mod, name, RUBY_METHOD_FUNC(func), argc)
-#define rb_define_singleton_method(mod, name, func, argc) rb_define_singleton_method(mod, name, RUBY_METHOD_FUNC(func), argc)
-#define rb_define_module_function(mod, name, func, argc) rb_define_module_function(mod, name, RUBY_METHOD_FUNC(func), argc)
-#define rb_define_global_function(name, func, argc) rb_define_global_function(name, RUBY_METHOD_FUNC(func), argc)
-#define rb_hash_foreach(hash, func, farg) rb_hash_foreach(hash, (int (*)(...))func, farg)
-#define st_foreach(tab, func, arg) st_foreach(tab, (int (*)(...))func, arg)
-#define rb_block_call(object, name, args_count, args, block_call_func, data) rb_block_call(object, name, args_count, args, RUBY_METHOD_FUNC(block_call_func), data)
-#define rb_ensure(b_proc, data1, e_proc, data2) rb_ensure(RUBY_METHOD_FUNC(b_proc), data1, RUBY_METHOD_FUNC(e_proc), data2)
-#define rb_rescue(b_proc, data1, e_proc, data2) rb_rescue(RUBY_METHOD_FUNC(b_proc), data1, RUBY_METHOD_FUNC(e_proc), data2)
-#define rb_rescue2(b_proc, data1, e_proc, data2, ...) rb_rescue2(RUBY_METHOD_FUNC(b_proc), data1, RUBY_METHOD_FUNC(e_proc), data2, __VA_ARGS__)
-#define rb_catch(tag, func, data) rb_catch(tag, RUBY_METHOD_FUNC(func), data)
-#define rb_catch_obj(tag, func, data) rb_catch_obj(tag, RUBY_METHOD_FUNC(func), data)
-#define rb_proc_new(fn, arg) rb_proc_new(RUBY_METHOD_FUNC(fn), arg)
-#define rb_fiber_new(fn, arg) rb_fiber_new(RUBY_METHOD_FUNC(fn), arg)
-#define rb_thread_create(fn, arg) rb_thread_create(RUBY_METHOD_FUNC(fn), arg)
-#define rb_define_hooked_variable(name, var, getter, setter) rb_define_hooked_variable(name, var, RUBY_METHOD_FUNC(getter), (void (*)(...))setter)
+#if RUBY_VERSION_SINCE(3, 3)
+#define RUBY_VERSION_IS_3_3
#endif
#endif
diff --git a/spec/ruby/optional/capi/ext/set_spec.c b/spec/ruby/optional/capi/ext/set_spec.c
new file mode 100644
index 0000000000..11a271b361
--- /dev/null
+++ b/spec/ruby/optional/capi/ext/set_spec.c
@@ -0,0 +1,65 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef RUBY_VERSION_IS_4_0
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RBOOL(x) ((x) ? Qtrue : Qfalse)
+
+int yield_element_and_arg(VALUE element, VALUE arg) {
+ return RTEST(rb_yield_values(2, element, arg)) ? ST_CONTINUE : ST_STOP;
+}
+
+VALUE set_spec_rb_set_foreach(VALUE self, VALUE set, VALUE arg) {
+ rb_set_foreach(set, yield_element_and_arg, arg);
+ return Qnil;
+}
+
+VALUE set_spec_rb_set_new(VALUE self) {
+ return rb_set_new();
+}
+
+VALUE set_spec_rb_set_new_capa(VALUE self, VALUE capa) {
+ return rb_set_new_capa(NUM2INT(capa));
+}
+
+VALUE set_spec_rb_set_lookup(VALUE self, VALUE set, VALUE element) {
+ return RBOOL(rb_set_lookup(set, element));
+}
+
+VALUE set_spec_rb_set_add(VALUE self, VALUE set, VALUE element) {
+ return RBOOL(rb_set_add(set, element));
+}
+
+VALUE set_spec_rb_set_clear(VALUE self, VALUE set) {
+ return rb_set_clear(set);
+}
+
+VALUE set_spec_rb_set_delete(VALUE self, VALUE set, VALUE element) {
+ return RBOOL(rb_set_delete(set, element));
+}
+
+VALUE set_spec_rb_set_size(VALUE self, VALUE set) {
+ return SIZET2NUM(rb_set_size(set));
+}
+
+void Init_set_spec(void) {
+ VALUE cls = rb_define_class("CApiSetSpecs", rb_cObject);
+
+ rb_define_method(cls, "rb_set_foreach", set_spec_rb_set_foreach, 2);
+ rb_define_method(cls, "rb_set_new", set_spec_rb_set_new, 0);
+ rb_define_method(cls, "rb_set_new_capa", set_spec_rb_set_new_capa, 1);
+ rb_define_method(cls, "rb_set_lookup", set_spec_rb_set_lookup, 2);
+ rb_define_method(cls, "rb_set_add", set_spec_rb_set_add, 2);
+ rb_define_method(cls, "rb_set_clear", set_spec_rb_set_clear, 1);
+ rb_define_method(cls, "rb_set_delete", set_spec_rb_set_delete, 2);
+ rb_define_method(cls, "rb_set_size", set_spec_rb_set_size, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c
index c3fa53c5a7..094013e049 100644
--- a/spec/ruby/optional/capi/ext/string_spec.c
+++ b/spec/ruby/optional/capi/ext/string_spec.c
@@ -51,18 +51,12 @@ VALUE string_spec_rb_str_set_len_RSTRING_LEN(VALUE self, VALUE str, VALUE len) {
return INT2FIX(RSTRING_LEN(str));
}
-VALUE rb_fstring(VALUE str); /* internal.h, used in ripper */
-
-VALUE string_spec_rb_str_fstring(VALUE self, VALUE str) {
- return rb_fstring(str);
-}
-
VALUE string_spec_rb_str_buf_new(VALUE self, VALUE len, VALUE str) {
VALUE buf;
buf = rb_str_buf_new(NUM2LONG(len));
- if(RTEST(str)) {
+ if (RTEST(str)) {
snprintf(RSTRING_PTR(buf), NUM2LONG(len), "%s", RSTRING_PTR(str));
}
@@ -87,6 +81,10 @@ VALUE string_spec_rb_str_tmp_new_klass(VALUE self, VALUE len) {
return RBASIC_CLASS(rb_str_tmp_new(NUM2LONG(len)));
}
+VALUE string_spec_rb_str_buf_append(VALUE self, VALUE str, VALUE two) {
+ return rb_str_buf_append(str, two);
+}
+
VALUE string_spec_rb_str_buf_cat(VALUE self, VALUE str) {
const char *question_mark = "?";
rb_str_buf_cat(str, question_mark, strlen(question_mark));
@@ -119,13 +117,17 @@ VALUE string_spec_rb_str_cmp(VALUE self, VALUE str1, VALUE str2) {
return INT2NUM(rb_str_cmp(str1, str2));
}
+VALUE string_spec_rb_str_strlen(VALUE self, VALUE str) {
+ return LONG2NUM(rb_str_strlen(str));
+}
+
VALUE string_spec_rb_str_conv_enc(VALUE self, VALUE str, VALUE from, VALUE to) {
rb_encoding* from_enc;
rb_encoding* to_enc;
from_enc = rb_to_encoding(from);
- if(NIL_P(to)) {
+ if (NIL_P(to)) {
to_enc = 0;
} else {
to_enc = rb_to_encoding(to);
@@ -135,14 +137,13 @@ VALUE string_spec_rb_str_conv_enc(VALUE self, VALUE str, VALUE from, VALUE to) {
}
VALUE string_spec_rb_str_conv_enc_opts(VALUE self, VALUE str, VALUE from, VALUE to,
- VALUE ecflags, VALUE ecopts)
-{
+ VALUE ecflags, VALUE ecopts) {
rb_encoding* from_enc;
rb_encoding* to_enc;
from_enc = rb_to_encoding(from);
- if(NIL_P(to)) {
+ if (NIL_P(to)) {
to_enc = 0;
} else {
to_enc = rb_to_encoding(to);
@@ -196,7 +197,7 @@ VALUE string_spec_rb_str_new_offset(VALUE self, VALUE str, VALUE offset, VALUE l
}
VALUE string_spec_rb_str_new2(VALUE self, VALUE str) {
- if(NIL_P(str)) {
+ if (NIL_P(str)) {
return rb_str_new2("");
} else {
return rb_str_new2(RSTRING_PTR(str));
@@ -212,7 +213,7 @@ VALUE string_spec_rb_str_export_to_enc(VALUE self, VALUE str, VALUE enc) {
}
VALUE string_spec_rb_str_new_cstr(VALUE self, VALUE str) {
- if(NIL_P(str)) {
+ if (NIL_P(str)) {
return rb_str_new_cstr("");
} else {
return rb_str_new_cstr(RSTRING_PTR(str));
@@ -251,32 +252,6 @@ VALUE string_spec_rb_str_new5(VALUE self, VALUE str, VALUE ptr, VALUE len) {
return rb_str_new5(str, RSTRING_PTR(ptr), FIX2INT(len));
}
-#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#elif defined(__clang__) && defined(__has_warning)
-# if __has_warning("-Wdeprecated-declarations")
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wdeprecated-declarations"
-# endif
-#endif
-
-VALUE string_spec_rb_tainted_str_new(VALUE self, VALUE str, VALUE len) {
- return rb_tainted_str_new(RSTRING_PTR(str), FIX2INT(len));
-}
-
-VALUE string_spec_rb_tainted_str_new2(VALUE self, VALUE str) {
- return rb_tainted_str_new2(RSTRING_PTR(str));
-}
-
-#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
-# pragma GCC diagnostic pop
-#elif defined(__clang__) && defined(__has_warning)
-# if __has_warning("-Wdeprecated-declarations")
-# pragma clang diagnostic pop
-# endif
-#endif
-
VALUE string_spec_rb_str_plus(VALUE self, VALUE str1, VALUE str2) {
return rb_str_plus(str1, str2);
}
@@ -384,7 +359,7 @@ VALUE string_spec_RSTRING_PTR_set(VALUE self, VALUE str, VALUE i, VALUE chr) {
VALUE string_spec_RSTRING_PTR_after_funcall(VALUE self, VALUE str, VALUE cb) {
/* Silence gcc 4.3.2 warning about computed value not used */
- if(RSTRING_PTR(str)) { /* force it out */
+ if (RSTRING_PTR(str)) { /* force it out */
rb_funcall(cb, rb_intern("call"), 1, str);
}
@@ -431,6 +406,12 @@ VALUE string_spec_RSTRING_PTR_read(VALUE self, VALUE str, VALUE path) {
return capacities;
}
+VALUE string_spec_RSTRING_PTR_null_terminate(VALUE self, VALUE str, VALUE min_length) {
+ char* ptr = RSTRING_PTR(str);
+ char* end = ptr + RSTRING_LEN(str);
+ return rb_str_new(end, FIX2LONG(min_length));
+}
+
VALUE string_spec_StringValue(VALUE self, VALUE str) {
return StringValue(str);
}
@@ -459,6 +440,7 @@ static VALUE string_spec_rb_str_free(VALUE self, VALUE str) {
static VALUE string_spec_rb_sprintf1(VALUE self, VALUE str, VALUE repl) {
return rb_sprintf(RSTRING_PTR(str), RSTRING_PTR(repl));
}
+
static VALUE string_spec_rb_sprintf2(VALUE self, VALUE str, VALUE repl1, VALUE repl2) {
return rb_sprintf(RSTRING_PTR(str), RSTRING_PTR(repl1), RSTRING_PTR(repl2));
}
@@ -471,6 +453,32 @@ static VALUE string_spec_rb_sprintf4(VALUE self, VALUE str) {
return rb_sprintf("Result: %+" PRIsVALUE ".", str);
}
+static VALUE string_spec_rb_sprintf5(VALUE self, VALUE width, VALUE precision, VALUE str) {
+ return rb_sprintf("Result: %*.*s.", FIX2INT(width), FIX2INT(precision), RSTRING_PTR(str));
+}
+
+static VALUE string_spec_rb_sprintf6(VALUE self, VALUE width, VALUE precision, VALUE str) {
+ return rb_sprintf("Result: %*.*" PRIsVALUE ".", FIX2INT(width), FIX2INT(precision), str);
+}
+
+static VALUE string_spec_rb_sprintf7(VALUE self, VALUE str, VALUE obj) {
+ VALUE results = rb_ary_new();
+ rb_ary_push(results, rb_sprintf(RSTRING_PTR(str), obj));
+ char cstr[256];
+ int len = snprintf(cstr, 256, RSTRING_PTR(str), obj);
+ rb_ary_push(results, rb_str_new(cstr, len));
+ return results;
+}
+
+static VALUE string_spec_rb_sprintf8(VALUE self, VALUE str, VALUE num) {
+ VALUE results = rb_ary_new();
+ rb_ary_push(results, rb_sprintf(RSTRING_PTR(str), FIX2LONG(num)));
+ char cstr[256];
+ int len = snprintf(cstr, 256, RSTRING_PTR(str), FIX2LONG(num));
+ rb_ary_push(results, rb_str_new(cstr, len));
+ return results;
+}
+
PRINTF_ARGS(static VALUE string_spec_rb_vsprintf_worker(char* fmt, ...), 1, 2);
static VALUE string_spec_rb_vsprintf_worker(char* fmt, ...) {
va_list varargs;
@@ -535,7 +543,7 @@ static VALUE string_spec_rb_utf8_str_new_cstr(VALUE self) {
}
PRINTF_ARGS(static VALUE call_rb_str_vcatf(VALUE mesg, const char *fmt, ...), 2, 3);
-static VALUE call_rb_str_vcatf(VALUE mesg, const char *fmt, ...){
+static VALUE call_rb_str_vcatf(VALUE mesg, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
VALUE result = rb_str_vcatf(mesg, fmt, ap);
@@ -551,11 +559,32 @@ static VALUE string_spec_rb_str_catf(VALUE self, VALUE mesg) {
return rb_str_catf(mesg, "fmt %d %d number", 41, 6);
}
+static VALUE string_spec_rb_str_locktmp(VALUE self, VALUE str) {
+ return rb_str_locktmp(str);
+}
+
+static VALUE string_spec_rb_str_unlocktmp(VALUE self, VALUE str) {
+ return rb_str_unlocktmp(str);
+}
+
+static VALUE string_spec_rb_enc_interned_str_cstr(VALUE self, VALUE str, VALUE enc) {
+ rb_encoding *e = NIL_P(enc) ? 0 : rb_to_encoding(enc);
+ return rb_enc_interned_str_cstr(RSTRING_PTR(str), e);
+}
+
+static VALUE string_spec_rb_enc_interned_str(VALUE self, VALUE str, VALUE len, VALUE enc) {
+ rb_encoding *e = NIL_P(enc) ? 0 : rb_to_encoding(enc);
+ return rb_enc_interned_str(RSTRING_PTR(str), FIX2LONG(len), e);
+}
+
+static VALUE string_spec_rb_str_to_interned_str(VALUE self, VALUE str) {
+ return rb_str_to_interned_str(str);
+}
+
void Init_string_spec(void) {
VALUE cls = rb_define_class("CApiStringSpecs", rb_cObject);
rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2);
rb_define_method(cls, "rb_cstr_to_inum", string_spec_rb_cstr_to_inum, 3);
- rb_define_method(cls, "rb_fstring", string_spec_rb_str_fstring, 1);
rb_define_method(cls, "rb_str2inum", string_spec_rb_str2inum, 2);
rb_define_method(cls, "rb_str_append", string_spec_rb_str_append, 2);
rb_define_method(cls, "rb_str_buf_new", string_spec_rb_str_buf_new, 2);
@@ -563,6 +592,7 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_str_buf_new2", string_spec_rb_str_buf_new2, 0);
rb_define_method(cls, "rb_str_tmp_new", string_spec_rb_str_tmp_new, 1);
rb_define_method(cls, "rb_str_tmp_new_klass", string_spec_rb_str_tmp_new_klass, 1);
+ rb_define_method(cls, "rb_str_buf_append", string_spec_rb_str_buf_append, 2);
rb_define_method(cls, "rb_str_buf_cat", string_spec_rb_str_buf_cat, 1);
rb_define_method(cls, "rb_enc_str_buf_cat", string_spec_rb_enc_str_buf_cat, 3);
rb_define_method(cls, "rb_str_cat", string_spec_rb_str_cat, 1);
@@ -570,6 +600,7 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_str_cat_cstr", string_spec_rb_str_cat_cstr, 2);
rb_define_method(cls, "rb_str_cat_cstr_constant", string_spec_rb_str_cat_cstr_constant, 1);
rb_define_method(cls, "rb_str_cmp", string_spec_rb_str_cmp, 2);
+ rb_define_method(cls, "rb_str_strlen", string_spec_rb_str_strlen, 1);
rb_define_method(cls, "rb_str_conv_enc", string_spec_rb_str_conv_enc, 3);
rb_define_method(cls, "rb_str_conv_enc_opts", string_spec_rb_str_conv_enc_opts, 5);
rb_define_method(cls, "rb_str_drop_bytes", string_spec_rb_str_drop_bytes, 2);
@@ -595,8 +626,6 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_str_new3", string_spec_rb_str_new3, 1);
rb_define_method(cls, "rb_str_new4", string_spec_rb_str_new4, 1);
rb_define_method(cls, "rb_str_new5", string_spec_rb_str_new5, 3);
- rb_define_method(cls, "rb_tainted_str_new", string_spec_rb_tainted_str_new, 2);
- rb_define_method(cls, "rb_tainted_str_new2", string_spec_rb_tainted_str_new2, 1);
rb_define_method(cls, "rb_str_plus", string_spec_rb_str_plus, 2);
rb_define_method(cls, "rb_str_times", string_spec_rb_str_times, 2);
rb_define_method(cls, "rb_str_modify_expand", string_spec_rb_str_modify_expand, 2);
@@ -619,6 +648,7 @@ void Init_string_spec(void) {
rb_define_method(cls, "RSTRING_PTR_after_funcall", string_spec_RSTRING_PTR_after_funcall, 2);
rb_define_method(cls, "RSTRING_PTR_after_yield", string_spec_RSTRING_PTR_after_yield, 1);
rb_define_method(cls, "RSTRING_PTR_read", string_spec_RSTRING_PTR_read, 2);
+ rb_define_method(cls, "RSTRING_PTR_null_terminate", string_spec_RSTRING_PTR_null_terminate, 2);
rb_define_method(cls, "StringValue", string_spec_StringValue, 1);
rb_define_method(cls, "SafeStringValue", string_spec_SafeStringValue, 1);
rb_define_method(cls, "rb_str_hash", string_spec_rb_str_hash, 1);
@@ -628,6 +658,10 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_sprintf2", string_spec_rb_sprintf2, 3);
rb_define_method(cls, "rb_sprintf3", string_spec_rb_sprintf3, 1);
rb_define_method(cls, "rb_sprintf4", string_spec_rb_sprintf4, 1);
+ rb_define_method(cls, "rb_sprintf5", string_spec_rb_sprintf5, 3);
+ rb_define_method(cls, "rb_sprintf6", string_spec_rb_sprintf6, 3);
+ rb_define_method(cls, "rb_sprintf7", string_spec_rb_sprintf7, 2);
+ rb_define_method(cls, "rb_sprintf8", string_spec_rb_sprintf8, 2);
rb_define_method(cls, "rb_vsprintf", string_spec_rb_vsprintf, 4);
rb_define_method(cls, "rb_str_equal", string_spec_rb_str_equal, 2);
rb_define_method(cls, "rb_usascii_str_new", string_spec_rb_usascii_str_new, 2);
@@ -642,6 +676,11 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_utf8_str_new_cstr", string_spec_rb_utf8_str_new_cstr, 0);
rb_define_method(cls, "rb_str_vcatf", string_spec_rb_str_vcatf, 1);
rb_define_method(cls, "rb_str_catf", string_spec_rb_str_catf, 1);
+ rb_define_method(cls, "rb_str_locktmp", string_spec_rb_str_locktmp, 1);
+ rb_define_method(cls, "rb_str_unlocktmp", string_spec_rb_str_unlocktmp, 1);
+ rb_define_method(cls, "rb_enc_interned_str_cstr", string_spec_rb_enc_interned_str_cstr, 2);
+ rb_define_method(cls, "rb_enc_interned_str", string_spec_rb_enc_interned_str, 3);
+ rb_define_method(cls, "rb_str_to_interned_str", string_spec_rb_str_to_interned_str, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/struct_spec.c b/spec/ruby/optional/capi/ext/struct_spec.c
index 0393d6937d..756cfca8dd 100644
--- a/spec/ruby/optional/capi/ext/struct_spec.c
+++ b/spec/ruby/optional/capi/ext/struct_spec.c
@@ -15,13 +15,11 @@ static VALUE struct_spec_rb_struct_getmember(VALUE self, VALUE st, VALUE key) {
return rb_struct_getmember(st, SYM2ID(key));
}
-static VALUE struct_spec_rb_struct_s_members(VALUE self, VALUE klass)
-{
+static VALUE struct_spec_rb_struct_s_members(VALUE self, VALUE klass) {
return rb_ary_dup(rb_struct_s_members(klass));
}
-static VALUE struct_spec_rb_struct_members(VALUE self, VALUE st)
-{
+static VALUE struct_spec_rb_struct_members(VALUE self, VALUE st) {
return rb_ary_dup(rb_struct_members(st));
}
@@ -30,7 +28,7 @@ static VALUE struct_spec_rb_struct_aset(VALUE self, VALUE st, VALUE key, VALUE v
}
/* Only allow setting three attributes, should be sufficient for testing. */
-static VALUE struct_spec_struct_define(VALUE self, VALUE name,
+static VALUE struct_spec_rb_struct_define(VALUE self, VALUE name,
VALUE attr1, VALUE attr2, VALUE attr3) {
const char *a1 = StringValuePtr(attr1);
@@ -44,7 +42,7 @@ static VALUE struct_spec_struct_define(VALUE self, VALUE name,
}
/* Only allow setting three attributes, should be sufficient for testing. */
-static VALUE struct_spec_struct_define_under(VALUE self, VALUE outer,
+static VALUE struct_spec_rb_struct_define_under(VALUE self, VALUE outer,
VALUE name, VALUE attr1, VALUE attr2, VALUE attr3) {
const char *nm = StringValuePtr(name);
@@ -56,17 +54,35 @@ static VALUE struct_spec_struct_define_under(VALUE self, VALUE outer,
}
static VALUE struct_spec_rb_struct_new(VALUE self, VALUE klass,
- VALUE a, VALUE b, VALUE c)
-{
-
+ VALUE a, VALUE b, VALUE c) {
return rb_struct_new(klass, a, b, c);
}
-static VALUE struct_spec_rb_struct_size(VALUE self, VALUE st)
-{
+static VALUE struct_spec_rb_struct_size(VALUE self, VALUE st) {
return rb_struct_size(st);
}
+static VALUE struct_spec_rb_struct_initialize(VALUE self, VALUE st, VALUE values) {
+ return rb_struct_initialize(st, values);
+}
+
+#if defined(RUBY_VERSION_IS_3_3)
+/* Only allow setting three attributes, should be sufficient for testing. */
+static VALUE struct_spec_rb_data_define(VALUE self, VALUE superclass,
+ VALUE attr1, VALUE attr2, VALUE attr3) {
+
+ const char *a1 = StringValuePtr(attr1);
+ const char *a2 = StringValuePtr(attr2);
+ const char *a3 = StringValuePtr(attr3);
+
+ if (superclass == Qnil) {
+ superclass = 0;
+ }
+
+ return rb_data_define(superclass, a1, a2, a3, NULL);
+}
+#endif
+
void Init_struct_spec(void) {
VALUE cls = rb_define_class("CApiStructSpecs", rb_cObject);
rb_define_method(cls, "rb_struct_aref", struct_spec_rb_struct_aref, 2);
@@ -74,10 +90,14 @@ void Init_struct_spec(void) {
rb_define_method(cls, "rb_struct_s_members", struct_spec_rb_struct_s_members, 1);
rb_define_method(cls, "rb_struct_members", struct_spec_rb_struct_members, 1);
rb_define_method(cls, "rb_struct_aset", struct_spec_rb_struct_aset, 3);
- rb_define_method(cls, "rb_struct_define", struct_spec_struct_define, 4);
- rb_define_method(cls, "rb_struct_define_under", struct_spec_struct_define_under, 5);
+ rb_define_method(cls, "rb_struct_define", struct_spec_rb_struct_define, 4);
+ rb_define_method(cls, "rb_struct_define_under", struct_spec_rb_struct_define_under, 5);
rb_define_method(cls, "rb_struct_new", struct_spec_rb_struct_new, 4);
rb_define_method(cls, "rb_struct_size", struct_spec_rb_struct_size, 1);
+ rb_define_method(cls, "rb_struct_initialize", struct_spec_rb_struct_initialize, 2);
+#if defined(RUBY_VERSION_IS_3_3)
+ rb_define_method(cls, "rb_data_define", struct_spec_rb_data_define, 4);
+#endif
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/symbol_spec.c b/spec/ruby/optional/capi/ext/symbol_spec.c
index 7d9a7b4379..ba88635faa 100644
--- a/spec/ruby/optional/capi/ext/symbol_spec.c
+++ b/spec/ruby/optional/capi/ext/symbol_spec.c
@@ -47,10 +47,19 @@ VALUE symbol_spec_rb_id2name(VALUE self, VALUE symbol) {
return rb_str_new(c_str, strlen(c_str));
}
+VALUE symbol_spec_rb_id2name_id_zero(VALUE self) {
+ const char* c_str = rb_id2name((ID) 0);
+ return c_str ? rb_str_new(c_str, strlen(c_str)) : Qnil;
+}
+
VALUE symbol_spec_rb_id2str(VALUE self, VALUE symbol) {
return rb_id2str(SYM2ID(symbol));
}
+VALUE symbol_spec_rb_id2str_id_zero(VALUE self) {
+ return rb_id2str((ID) 0);
+}
+
VALUE symbol_spec_rb_intern_str(VALUE self, VALUE str) {
return ID2SYM(rb_intern_str(str));
}
@@ -90,7 +99,9 @@ void Init_symbol_spec(void) {
rb_define_method(cls, "rb_intern3", symbol_spec_rb_intern3, 3);
rb_define_method(cls, "rb_intern3_c_compare", symbol_spec_rb_intern3_c_compare, 4);
rb_define_method(cls, "rb_id2name", symbol_spec_rb_id2name, 1);
+ rb_define_method(cls, "rb_id2name_id_zero", symbol_spec_rb_id2name_id_zero, 0);
rb_define_method(cls, "rb_id2str", symbol_spec_rb_id2str, 1);
+ rb_define_method(cls, "rb_id2str_id_zero", symbol_spec_rb_id2str_id_zero, 0);
rb_define_method(cls, "rb_intern_str", symbol_spec_rb_intern_str, 1);
rb_define_method(cls, "rb_check_symbol_cstr", symbol_spec_rb_check_symbol_cstr, 1);
rb_define_method(cls, "rb_is_class_id", symbol_spec_rb_is_class_id, 1);
diff --git a/spec/ruby/optional/capi/ext/thread_spec.c b/spec/ruby/optional/capi/ext/thread_spec.c
index 21f98dec52..ac77e4e813 100644
--- a/spec/ruby/optional/capi/ext/thread_spec.c
+++ b/spec/ruby/optional/capi/ext/thread_spec.c
@@ -8,7 +8,14 @@
#include <unistd.h>
#endif
#if defined(_WIN32)
-#define pipe(p) rb_w32_pipe(p)
+#include "ruby/win32.h"
+#define read rb_w32_read
+#define write rb_w32_write
+#define pipe rb_w32_pipe
+#endif
+
+#ifndef _WIN32
+#include <pthread.h>
#endif
#ifdef __cplusplus
@@ -19,10 +26,6 @@ static VALUE thread_spec_rb_thread_alone(VALUE self) {
return rb_thread_alone() ? Qtrue : Qfalse;
}
-#if defined(__GNUC__)
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-
/* This is unblocked by unblock_func(). */
static void* blocking_gvl_func(void* data) {
int rfd = *(int *)data;
@@ -64,7 +67,7 @@ static VALUE thread_spec_rb_thread_call_without_gvl(VALUE self) {
}
/* This is unblocked by a signal. */
-static void* blocking_gvl_func_for_udf_io(void *data) {
+static void* blocking_gvl_func_for_ubf_io(void *data) {
int rfd = (int)(size_t)data;
char dummy;
@@ -84,7 +87,7 @@ static VALUE thread_spec_rb_thread_call_without_gvl_with_ubf_io(VALUE self) {
rb_raise(rb_eRuntimeError, "could not create pipe");
}
- ret = rb_thread_call_without_gvl(blocking_gvl_func_for_udf_io,
+ ret = rb_thread_call_without_gvl(blocking_gvl_func_for_ubf_io,
(void*)(size_t)fds[0], RUBY_UBF_IO, 0);
close(fds[0]);
close(fds[1]);
@@ -115,7 +118,6 @@ static VALUE thread_spec_rb_thread_wait_for(VALUE self, VALUE s, VALUE ms) {
return Qnil;
}
-
VALUE thread_spec_call_proc(void *arg_ptr) {
VALUE arg_array = (VALUE)arg_ptr;
VALUE arg = rb_ary_pop(arg_array);
@@ -131,6 +133,44 @@ static VALUE thread_spec_rb_thread_create(VALUE self, VALUE proc, VALUE arg) {
return rb_thread_create(thread_spec_call_proc, (void*)args);
}
+static VALUE thread_spec_ruby_native_thread_p(VALUE self) {
+ if (ruby_native_thread_p()) {
+ return Qtrue;
+ } else {
+ return Qfalse;
+ }
+}
+
+#ifndef _WIN32
+static VALUE false_result = Qfalse;
+static VALUE true_result = Qtrue;
+
+static void *new_thread_check(void *args) {
+ if (ruby_native_thread_p()) {
+ return &true_result;
+ } else {
+ return &false_result;
+ }
+}
+#endif
+
+static VALUE thread_spec_ruby_native_thread_p_new_thread(VALUE self) {
+#ifndef _WIN32
+ pthread_t t;
+ void *result = &true_result;
+ pthread_create(&t, NULL, new_thread_check, NULL);
+ pthread_join(t, &result);
+ return *(VALUE *)result;
+#else
+ return Qfalse;
+#endif
+}
+
+#ifdef RUBY_VERSION_IS_4_0
+static VALUE thread_spec_ruby_thread_has_gvl_p(VALUE self) {
+ return ruby_thread_has_gvl_p() ? Qtrue : Qfalse;
+}
+#endif
void Init_thread_spec(void) {
VALUE cls = rb_define_class("CApiThreadSpecs", rb_cObject);
@@ -143,6 +183,11 @@ void Init_thread_spec(void) {
rb_define_method(cls, "rb_thread_wakeup", thread_spec_rb_thread_wakeup, 1);
rb_define_method(cls, "rb_thread_wait_for", thread_spec_rb_thread_wait_for, 2);
rb_define_method(cls, "rb_thread_create", thread_spec_rb_thread_create, 2);
+ rb_define_method(cls, "ruby_native_thread_p", thread_spec_ruby_native_thread_p, 0);
+ rb_define_method(cls, "ruby_native_thread_p_new_thread", thread_spec_ruby_native_thread_p_new_thread, 0);
+#ifdef RUBY_VERSION_IS_4_0
+ rb_define_method(cls, "ruby_thread_has_gvl_p", thread_spec_ruby_thread_has_gvl_p, 0);
+#endif
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/tracepoint_spec.c b/spec/ruby/optional/capi/ext/tracepoint_spec.c
index 78c459d6cb..6666c8f85c 100644
--- a/spec/ruby/optional/capi/ext/tracepoint_spec.c
+++ b/spec/ruby/optional/capi/ext/tracepoint_spec.c
@@ -17,7 +17,7 @@ static VALUE tracepoint_spec_rb_tracepoint_new(VALUE self, VALUE data) {
return rb_tracepoint_new(Qnil, RUBY_EVENT_LINE, callback, (void*) data);
}
-static VALUE tracepoint_spec_callback_called(VALUE self){
+static VALUE tracepoint_spec_callback_called(VALUE self) {
return callback_called;
}
diff --git a/spec/ruby/optional/capi/ext/typed_data_spec.c b/spec/ruby/optional/capi/ext/typed_data_spec.c
index eca2b667cc..221f1c8ac4 100644
--- a/spec/ruby/optional/capi/ext/typed_data_spec.c
+++ b/spec/ruby/optional/capi/ext/typed_data_spec.c
@@ -106,6 +106,14 @@ VALUE sws_typed_wrap_struct(VALUE self, VALUE val) {
return TypedData_Wrap_Struct(rb_cObject, &sample_typed_wrapped_struct_data_type, bar);
}
+#undef RUBY_UNTYPED_DATA_WARNING
+#define RUBY_UNTYPED_DATA_WARNING 0
+VALUE sws_untyped_wrap_struct(VALUE self, VALUE val) {
+ int* data = (int*) malloc(sizeof(int));
+ *data = FIX2INT(val);
+ return Data_Wrap_Struct(rb_cObject, NULL, free, data);
+}
+
VALUE sws_typed_get_struct(VALUE self, VALUE obj) {
struct sample_typed_wrapped_struct* bar;
TypedData_Get_Struct(obj, struct sample_typed_wrapped_struct, &sample_typed_wrapped_struct_data_type, bar);
@@ -165,12 +173,17 @@ VALUE sws_typed_rb_check_typeddata_different_type(VALUE self, VALUE obj) {
return rb_check_typeddata(obj, &sample_typed_wrapped_struct_other_data_type) == DATA_PTR(obj) ? Qtrue : Qfalse;
}
+VALUE sws_typed_RTYPEDDATA_P(VALUE self, VALUE obj) {
+ return RTYPEDDATA_P(obj) ? Qtrue : Qfalse;
+}
+
void Init_typed_data_spec(void) {
VALUE cls = rb_define_class("CApiAllocTypedSpecs", rb_cObject);
rb_define_alloc_func(cls, sdaf_alloc_typed_func);
rb_define_method(cls, "typed_wrapped_data", sdaf_typed_get_struct, 0);
cls = rb_define_class("CApiWrappedTypedStructSpecs", rb_cObject);
rb_define_method(cls, "typed_wrap_struct", sws_typed_wrap_struct, 1);
+ rb_define_method(cls, "untyped_wrap_struct", sws_untyped_wrap_struct, 1);
rb_define_method(cls, "typed_get_struct", sws_typed_get_struct, 1);
rb_define_method(cls, "typed_get_struct_other", sws_typed_get_struct_different_type, 1);
rb_define_method(cls, "typed_get_struct_parent", sws_typed_get_struct_parent_type, 1);
@@ -181,6 +194,7 @@ void Init_typed_data_spec(void) {
rb_define_method(cls, "rb_check_typeddata_same_type", sws_typed_rb_check_typeddata_same_type, 1);
rb_define_method(cls, "rb_check_typeddata_same_type_parent", sws_typed_rb_check_typeddata_same_type_parent, 1);
rb_define_method(cls, "rb_check_typeddata_different_type", sws_typed_rb_check_typeddata_different_type, 1);
+ rb_define_method(cls, "RTYPEDDATA_P", sws_typed_RTYPEDDATA_P, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/util_spec.c b/spec/ruby/optional/capi/ext/util_spec.c
index a7269353c2..b5bde420d2 100644
--- a/spec/ruby/optional/capi/ext/util_spec.c
+++ b/spec/ruby/optional/capi/ext/util_spec.c
@@ -7,15 +7,18 @@ extern "C" {
#endif
VALUE util_spec_rb_scan_args(VALUE self, VALUE argv, VALUE fmt, VALUE expected, VALUE acc) {
- int i, result, argc = (int)RARRAY_LEN(argv);
- VALUE args[6], failed, a1, a2, a3, a4, a5, a6;
+ int result, argc;
+ VALUE a1, a2, a3, a4, a5, a6;
- failed = rb_intern("failed");
- a1 = a2 = a3 = a4 = a5 = a6 = failed;
+ argc = (int) RARRAY_LEN(argv);
+ VALUE* args = RARRAY_PTR(argv);
+ /* the line above can be replaced with this for Ruby implementations which do not support RARRAY_PTR() yet
+ VALUE args[6];
+ for(int i = 0; i < argc; i++) {
+ args[i] = rb_ary_entry(argv, i);
+ } */
- for(i = 0; i < argc; i++) {
- args[i] = rb_ary_entry(argv, i);
- }
+ a1 = a2 = a3 = a4 = a5 = a6 = INT2FIX(-1);
#ifdef RB_SCAN_ARGS_KEYWORDS
if (*RSTRING_PTR(fmt) == 'k') {
@@ -59,22 +62,17 @@ static VALUE util_spec_rb_get_kwargs(VALUE self, VALUE keyword_hash, VALUE keys,
int len = RARRAY_LENINT(keys);
int values_len = req + (opt < 0 ? -1 - opt : opt);
- int i = 0;
- ID *ids = (ID*) malloc(sizeof(VALUE) * len);
- VALUE *results = (VALUE*) malloc(sizeof(VALUE) * values_len);
- int extracted = 0;
- VALUE ary = Qundef;
+ ID *ids = (ID *)alloca(sizeof(VALUE) * len);
+ VALUE *results = (VALUE *)alloca(sizeof(VALUE) * values_len);
- for (i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++) {
ids[i] = SYM2ID(rb_ary_entry(keys, i));
}
- extracted = rb_get_kwargs(keyword_hash, ids, req, opt, results);
- ary = rb_ary_new_from_values(extracted, results);
- free(results);
- free(ids);
- return ary;
+ int extracted = rb_get_kwargs(keyword_hash, ids, req, opt, results);
+
+ return rb_ary_new_from_values(extracted, results);
}
static VALUE util_spec_rb_long2int(VALUE self, VALUE n) {