summaryrefslogtreecommitdiff
path: root/spec/ruby/optional
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2020-02-28 19:07:17 +0100
committerBenoit Daloze <eregontp@gmail.com>2020-02-28 19:07:17 +0100
commita0f5ff4c3cd05f8717be2bf1d79f0817f288d398 (patch)
tree441f409cf816cf8a61dacdbaf204ae9f5cbe2f18 /spec/ruby/optional
parent5d210501825e1682e68cbfc2be424fc339f382fa (diff)
Update to ruby/spec@41bf282
Diffstat (limited to 'spec/ruby/optional')
-rw-r--r--spec/ruby/optional/capi/README9
-rw-r--r--spec/ruby/optional/capi/array_spec.rb10
-rw-r--r--spec/ruby/optional/capi/ext/array_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/bignum_spec.c4
-rw-r--r--spec/ruby/optional/capi/ext/boolean_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/class_id_under_autoload_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/class_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/class_under_autoload_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/data_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/globals_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/integer_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/io_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/kernel_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/language_spec.c34
-rw-r--r--spec/ruby/optional/capi/ext/module_under_autoload_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/numeric_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/object_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/proc_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/rubyspec.h26
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c26
-rw-r--r--spec/ruby/optional/capi/ext/symbol_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/thread_spec.c4
-rw-r--r--spec/ruby/optional/capi/ext/typed_data_spec.c51
-rw-r--r--spec/ruby/optional/capi/ext/util_spec.c4
-rw-r--r--spec/ruby/optional/capi/kernel_spec.rb48
-rw-r--r--spec/ruby/optional/capi/language_spec.rb31
-rw-r--r--spec/ruby/optional/capi/numeric_spec.rb28
-rw-r--r--spec/ruby/optional/capi/proc_spec.rb19
-rw-r--r--spec/ruby/optional/capi/spec_helper.rb25
-rw-r--r--spec/ruby/optional/capi/string_spec.rb18
-rw-r--r--spec/ruby/optional/capi/symbol_spec.rb10
32 files changed, 349 insertions, 85 deletions
diff --git a/spec/ruby/optional/capi/README b/spec/ruby/optional/capi/README
index 57b0c51f01..069ca3c106 100644
--- a/spec/ruby/optional/capi/README
+++ b/spec/ruby/optional/capi/README
@@ -8,9 +8,6 @@ specs:
optional/capi/array_spec.rb
2. Put the C file containing the C functions for array_spec.rb in
optional/capi/ext/array_spec.c
-3. Add a '#define HAVE_RB_ARY_NEW 1' to rubyspec.h
-4. Name the C extension class 'CApiArraySpecs'.
-5. Name the C functions 'array_spec_rb_ary_new'.
-6. Wrap the code in the optional/capi/ext/array_spec.c in
- '#ifdef HAVE_RB_ARY_NEW'
-7. Attach the C function to the class using the name 'rb_ary_new'
+3. Name the C extension class 'CApiArraySpecs'.
+4. Name the C functions 'array_spec_rb_ary_new'.
+5. Attach the C function to the class using the name 'rb_ary_new'
diff --git a/spec/ruby/optional/capi/array_spec.rb b/spec/ruby/optional/capi/array_spec.rb
index cf65bc19b6..6bb20e5921 100644
--- a/spec/ruby/optional/capi/array_spec.rb
+++ b/spec/ruby/optional/capi/array_spec.rb
@@ -272,6 +272,16 @@ describe "C-API Array function" do
end
end
+ describe "RARRAY_ASET" do
+ # This macro does NOT do any bounds checking!
+ it "writes an element in the array" do
+ ary = [1, 2, 3]
+ @s.RARRAY_ASET(ary, 0, 0)
+ @s.RARRAY_ASET(ary, 2, 42)
+ ary.should == [0, 2, 42]
+ end
+ end
+
describe "rb_assoc_new" do
it "returns an array containing the two elements" do
@s.rb_assoc_new(1, 2).should == [1, 2]
diff --git a/spec/ruby/optional/capi/ext/array_spec.c b/spec/ruby/optional/capi/ext/array_spec.c
index 454cf03303..afd6aeef15 100644
--- a/spec/ruby/optional/capi/ext/array_spec.c
+++ b/spec/ruby/optional/capi/ext/array_spec.c
@@ -54,6 +54,11 @@ static VALUE array_spec_RARRAY_AREF(VALUE self, VALUE array, VALUE index) {
return RARRAY_AREF(array, FIX2INT(index));
}
+static VALUE array_spec_RARRAY_ASET(VALUE self, VALUE array, VALUE index, VALUE value) {
+ RARRAY_ASET(array, FIX2INT(index), value);
+ return value;
+}
+
static VALUE array_spec_rb_ary_aref(int argc, VALUE *argv, VALUE self) {
VALUE ary, args;
rb_scan_args(argc, argv, "1*", &ary, &args);
@@ -244,6 +249,7 @@ void Init_array_spec(void) {
rb_define_method(cls, "RARRAY_PTR_assign", array_spec_RARRAY_PTR_assign, 2);
rb_define_method(cls, "RARRAY_PTR_memcpy", array_spec_RARRAY_PTR_memcpy, 2);
rb_define_method(cls, "RARRAY_AREF", array_spec_RARRAY_AREF, 2);
+ rb_define_method(cls, "RARRAY_ASET", array_spec_RARRAY_ASET, 3);
rb_define_method(cls, "rb_ary_aref", array_spec_rb_ary_aref, -1);
rb_define_method(cls, "rb_ary_clear", array_spec_rb_ary_clear, 1);
rb_define_method(cls, "rb_ary_delete", array_spec_rb_ary_delete, 2);
diff --git a/spec/ruby/optional/capi/ext/bignum_spec.c b/spec/ruby/optional/capi/ext/bignum_spec.c
index 14a51f5099..a950d8b16f 100644
--- a/spec/ruby/optional/capi/ext/bignum_spec.c
+++ b/spec/ruby/optional/capi/ext/bignum_spec.c
@@ -65,7 +65,7 @@ static VALUE bignum_spec_rb_big_pack_array(VALUE self, VALUE val, VALUE len) {
long long_len = NUM2LONG(len);
VALUE ary = rb_ary_new_capa(long_len);
- unsigned long *buf = malloc(long_len * SIZEOF_LONG);
+ unsigned long *buf = (unsigned long*) malloc(long_len * SIZEOF_LONG);
/* The array should be filled with recognisable junk so we can check
it is all cleared properly. */
@@ -102,5 +102,5 @@ void Init_bignum_spec(void) {
}
#ifdef __cplusplus
-extern "C" {
+}
#endif
diff --git a/spec/ruby/optional/capi/ext/boolean_spec.c b/spec/ruby/optional/capi/ext/boolean_spec.c
index 7bb6fe569d..081cffa103 100644
--- a/spec/ruby/optional/capi/ext/boolean_spec.c
+++ b/spec/ruby/optional/capi/ext/boolean_spec.c
@@ -29,5 +29,5 @@ void Init_boolean_spec(void) {
}
#ifdef __cplusplus
-extern "C" {
+}
#endif
diff --git a/spec/ruby/optional/capi/ext/class_id_under_autoload_spec.c b/spec/ruby/optional/capi/ext/class_id_under_autoload_spec.c
index 64393a9397..cc5550f041 100644
--- a/spec/ruby/optional/capi/ext/class_id_under_autoload_spec.c
+++ b/spec/ruby/optional/capi/ext/class_id_under_autoload_spec.c
@@ -1,5 +1,13 @@
#include "ruby.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void Init_class_id_under_autoload_spec(void) {
rb_define_class_id_under(rb_cObject, rb_intern("ClassIdUnderAutoload"), rb_cObject);
}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/spec/ruby/optional/capi/ext/class_spec.c b/spec/ruby/optional/capi/ext/class_spec.c
index 6e5c02e657..e62b9efe2e 100644
--- a/spec/ruby/optional/capi/ext/class_spec.c
+++ b/spec/ruby/optional/capi/ext/class_spec.c
@@ -45,7 +45,7 @@ static VALUE class_spec_rb_class_new_instance(VALUE self,
VALUE nargs, VALUE args,
VALUE klass) {
int c_nargs = FIX2INT(nargs);
- VALUE *c_args = alloca(sizeof(VALUE) * c_nargs);
+ VALUE *c_args = (VALUE*)alloca(sizeof(VALUE) * c_nargs);
int i;
for (i = 0; i < c_nargs; i++)
diff --git a/spec/ruby/optional/capi/ext/class_under_autoload_spec.c b/spec/ruby/optional/capi/ext/class_under_autoload_spec.c
index 120dec7327..e0b1f249c0 100644
--- a/spec/ruby/optional/capi/ext/class_under_autoload_spec.c
+++ b/spec/ruby/optional/capi/ext/class_under_autoload_spec.c
@@ -1,5 +1,13 @@
#include "ruby.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void Init_class_under_autoload_spec(void) {
rb_define_class_under(rb_cObject, "ClassUnderAutoload", rb_cObject);
}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/spec/ruby/optional/capi/ext/data_spec.c b/spec/ruby/optional/capi/ext/data_spec.c
index a41666f655..109bded1d1 100644
--- a/spec/ruby/optional/capi/ext/data_spec.c
+++ b/spec/ruby/optional/capi/ext/data_spec.c
@@ -19,7 +19,7 @@ void sample_wrapped_struct_mark(void* st) {
}
VALUE sdaf_alloc_func(VALUE klass) {
- struct sample_wrapped_struct* bar = malloc(sizeof(struct sample_wrapped_struct));
+ struct sample_wrapped_struct* bar = (struct sample_wrapped_struct*) malloc(sizeof(struct sample_wrapped_struct));
bar->foo = 42;
return Data_Wrap_Struct(klass, &sample_wrapped_struct_mark, &sample_wrapped_struct_free, bar);
}
@@ -32,7 +32,7 @@ VALUE sdaf_get_struct(VALUE self) {
}
VALUE sws_wrap_struct(VALUE self, VALUE val) {
- struct sample_wrapped_struct* bar = malloc(sizeof(struct sample_wrapped_struct));
+ struct sample_wrapped_struct* bar = (struct sample_wrapped_struct*) malloc(sizeof(struct sample_wrapped_struct));
bar->foo = FIX2INT(val);
return Data_Wrap_Struct(rb_cObject, &sample_wrapped_struct_mark, &sample_wrapped_struct_free, bar);
}
@@ -58,9 +58,9 @@ VALUE sws_get_struct_data_ptr(VALUE self, VALUE obj) {
VALUE sws_change_struct(VALUE self, VALUE obj, VALUE new_val) {
struct sample_wrapped_struct *old_struct, *new_struct;
- new_struct = malloc(sizeof(struct sample_wrapped_struct));
+ new_struct = (struct sample_wrapped_struct*) malloc(sizeof(struct sample_wrapped_struct));
new_struct->foo = FIX2INT(new_val);
- old_struct = RDATA(obj)->data;
+ old_struct = (struct sample_wrapped_struct*) RDATA(obj)->data;
free(old_struct);
RDATA(obj)->data = new_struct;
return Qnil;
diff --git a/spec/ruby/optional/capi/ext/gc_spec.c b/spec/ruby/optional/capi/ext/gc_spec.c
index 983b021df9..4611617c18 100644
--- a/spec/ruby/optional/capi/ext/gc_spec.c
+++ b/spec/ruby/optional/capi/ext/gc_spec.c
@@ -16,15 +16,15 @@ static VALUE registered_reference_address(VALUE self) {
return registered_reference_value;
}
-static VALUE gc_spec_rb_gc_enable() {
+static VALUE gc_spec_rb_gc_enable(VALUE self) {
return rb_gc_enable();
}
-static VALUE gc_spec_rb_gc_disable() {
+static VALUE gc_spec_rb_gc_disable(VALUE self) {
return rb_gc_disable();
}
-static VALUE gc_spec_rb_gc() {
+static VALUE gc_spec_rb_gc(VALUE self) {
rb_gc();
return Qnil;
}
diff --git a/spec/ruby/optional/capi/ext/globals_spec.c b/spec/ruby/optional/capi/ext/globals_spec.c
index f70622f66c..75860d3774 100644
--- a/spec/ruby/optional/capi/ext/globals_spec.c
+++ b/spec/ruby/optional/capi/ext/globals_spec.c
@@ -7,12 +7,16 @@ extern "C" {
VALUE g_hooked_var;
+VALUE var_2x_getter(ID id, VALUE *data) {
+ return *data;
+}
+
void var_2x_setter(VALUE val, ID id, VALUE *var) {
- *var = INT2NUM(NUM2INT(val) * 2);
+ *var = INT2NUM(NUM2INT(val) * 2);
}
static VALUE sb_define_hooked_variable(VALUE self, VALUE var_name) {
- rb_define_hooked_variable(StringValuePtr(var_name), &g_hooked_var, 0, var_2x_setter);
+ rb_define_hooked_variable(StringValuePtr(var_name), &g_hooked_var, var_2x_getter, var_2x_setter);
return Qnil;
}
diff --git a/spec/ruby/optional/capi/ext/integer_spec.c b/spec/ruby/optional/capi/ext/integer_spec.c
index 7e9e8b26bd..124591e231 100644
--- a/spec/ruby/optional/capi/ext/integer_spec.c
+++ b/spec/ruby/optional/capi/ext/integer_spec.c
@@ -30,5 +30,5 @@ void Init_integer_spec(void) {
}
#ifdef __cplusplus
-extern "C" {
+}
#endif
diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c
index 45f57810db..59613c110f 100644
--- a/spec/ruby/optional/capi/ext/io_spec.c
+++ b/spec/ruby/optional/capi/ext/io_spec.c
@@ -43,7 +43,7 @@ VALUE io_spec_rb_io_addstr(VALUE self, VALUE io, VALUE str) {
VALUE io_spec_rb_io_printf(VALUE self, VALUE io, VALUE ary) {
long argc = RARRAY_LEN(ary);
- VALUE *argv = alloca(sizeof(VALUE) * argc);
+ VALUE *argv = (VALUE*) alloca(sizeof(VALUE) * argc);
int i;
for (i = 0; i < argc; i++) {
@@ -55,7 +55,7 @@ VALUE io_spec_rb_io_printf(VALUE self, VALUE io, VALUE ary) {
VALUE io_spec_rb_io_print(VALUE self, VALUE io, VALUE ary) {
long argc = RARRAY_LEN(ary);
- VALUE *argv = alloca(sizeof(VALUE) * argc);
+ VALUE *argv = (VALUE*) alloca(sizeof(VALUE) * argc);
int i;
for (i = 0; i < argc; i++) {
@@ -67,7 +67,7 @@ VALUE io_spec_rb_io_print(VALUE self, VALUE io, VALUE ary) {
VALUE io_spec_rb_io_puts(VALUE self, VALUE io, VALUE ary) {
long argc = RARRAY_LEN(ary);
- VALUE *argv = alloca(sizeof(VALUE) * argc);
+ VALUE *argv = (VALUE*) alloca(sizeof(VALUE) * argc);
int i;
for (i = 0; i < argc; i++) {
diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c
index c5bb4a1d9a..13d9598125 100644
--- a/spec/ruby/optional/capi/ext/kernel_spec.c
+++ b/spec/ruby/optional/capi/ext/kernel_spec.c
@@ -68,7 +68,7 @@ VALUE rb_block_call_extra_data(VALUE self, VALUE object) {
}
VALUE kernel_spec_rb_block_call_no_func(VALUE self, VALUE ary) {
- return rb_block_call(ary, rb_intern("map"), 0, NULL, NULL, Qnil);
+ return rb_block_call(ary, rb_intern("map"), 0, NULL, (rb_block_call_func_t)NULL, Qnil);
}
@@ -153,6 +153,10 @@ VALUE kernel_spec_rb_rescue(VALUE self, VALUE main_proc, VALUE arg,
rb_ary_push(main_array, main_proc);
rb_ary_push(main_array, arg);
+ if (raise_proc == Qnil) {
+ return rb_rescue(kernel_spec_call_proc, main_array, NULL, arg2);
+ }
+
raise_array = rb_ary_new();
rb_ary_push(raise_array, raise_proc);
rb_ary_push(raise_array, arg2);
diff --git a/spec/ruby/optional/capi/ext/language_spec.c b/spec/ruby/optional/capi/ext/language_spec.c
new file mode 100644
index 0000000000..5aeac63f53
--- /dev/null
+++ b/spec/ruby/optional/capi/ext/language_spec.c
@@ -0,0 +1,34 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static VALUE language_spec_switch(VALUE self, VALUE value) {
+ if (value == ID2SYM(rb_intern("undef"))) {
+ value = Qundef;
+ }
+
+ switch (value) {
+ case Qtrue:
+ return ID2SYM(rb_intern("true"));
+ case Qfalse:
+ return ID2SYM(rb_intern("false"));
+ case Qnil:
+ return ID2SYM(rb_intern("nil"));
+ case Qundef:
+ return ID2SYM(rb_intern("undef"));
+ default:
+ return ID2SYM(rb_intern("default"));
+ }
+}
+
+void Init_language_spec(void) {
+ VALUE cls = rb_define_class("CApiLanguageSpecs", rb_cObject);
+ rb_define_method(cls, "switch", language_spec_switch, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/spec/ruby/optional/capi/ext/module_under_autoload_spec.c b/spec/ruby/optional/capi/ext/module_under_autoload_spec.c
index c8f19a287b..b19466e555 100644
--- a/spec/ruby/optional/capi/ext/module_under_autoload_spec.c
+++ b/spec/ruby/optional/capi/ext/module_under_autoload_spec.c
@@ -1,7 +1,15 @@
#include "ruby.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void Init_module_under_autoload_spec(void) {
VALUE specs = rb_const_get(rb_cObject, rb_intern("CApiModuleSpecs"));
rb_define_module_under(specs, "ModuleUnderAutoload");
rb_define_module_under(specs, "RubyUnderAutoload");
}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/spec/ruby/optional/capi/ext/numeric_spec.c b/spec/ruby/optional/capi/ext/numeric_spec.c
index 556c71a587..33f3a18c00 100644
--- a/spec/ruby/optional/capi/ext/numeric_spec.c
+++ b/spec/ruby/optional/capi/ext/numeric_spec.c
@@ -61,6 +61,10 @@ static VALUE numeric_spec_NUM2LONG(VALUE self, VALUE num) {
return LONG2NUM(NUM2LONG(num));
}
+static VALUE numeric_spec_NUM2SHORT(VALUE self, VALUE num) {
+ return LONG2NUM(NUM2SHORT(num));
+}
+
static VALUE numeric_spec_NUM2UINT(VALUE self, VALUE num) {
return ULONG2NUM(NUM2UINT(num));
}
@@ -109,6 +113,7 @@ void Init_numeric_spec(void) {
rb_define_method(cls, "NUM2DBL", numeric_spec_NUM2DBL, 1);
rb_define_method(cls, "NUM2INT", numeric_spec_NUM2INT, 1);
rb_define_method(cls, "NUM2LONG", numeric_spec_NUM2LONG, 1);
+ rb_define_method(cls, "NUM2SHORT", numeric_spec_NUM2SHORT, 1);
rb_define_method(cls, "INT2NUM", numeric_spec_INT2NUM, 1);
rb_define_method(cls, "NUM2UINT", numeric_spec_NUM2UINT, 1);
rb_define_method(cls, "NUM2ULONG", numeric_spec_NUM2ULONG, 1);
diff --git a/spec/ruby/optional/capi/ext/object_spec.c b/spec/ruby/optional/capi/ext/object_spec.c
index 2151e37e5c..c95e1b553f 100644
--- a/spec/ruby/optional/capi/ext/object_spec.c
+++ b/spec/ruby/optional/capi/ext/object_spec.c
@@ -102,7 +102,7 @@ static VALUE so_rb_obj_dup(VALUE self, VALUE klass) {
static VALUE so_rb_obj_call_init(VALUE self, VALUE object,
VALUE nargs, VALUE args) {
int c_nargs = FIX2INT(nargs);
- VALUE *c_args = alloca(sizeof(VALUE) * c_nargs);
+ VALUE *c_args = (VALUE*) alloca(sizeof(VALUE) * c_nargs);
int i;
for (i = 0; i < c_nargs; i++)
diff --git a/spec/ruby/optional/capi/ext/proc_spec.c b/spec/ruby/optional/capi/ext/proc_spec.c
index 18fd1997ee..e0bd8b1bbc 100644
--- a/spec/ruby/optional/capi/ext/proc_spec.c
+++ b/spec/ruby/optional/capi/ext/proc_spec.c
@@ -23,6 +23,10 @@ VALUE proc_spec_rb_proc_call(VALUE self, VALUE prc, VALUE args) {
return rb_proc_call(prc, args);
}
+VALUE proc_spec_rb_obj_is_proc(VALUE self, VALUE prc) {
+ return rb_obj_is_proc(prc);
+}
+
/* This helper is not strictly necessary but reflects the code in wxRuby that
* originally exposed issues with this Proc.new behavior.
*/
@@ -61,6 +65,7 @@ void Init_proc_spec(void) {
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_new", proc_spec_rb_Proc_new, 1);
+ rb_define_method(cls, "rb_obj_is_proc", proc_spec_rb_obj_is_proc, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/rubyspec.h b/spec/ruby/optional/capi/ext/rubyspec.h
index 78e298fddb..cce3af22f2 100644
--- a/spec/ruby/optional/capi/ext/rubyspec.h
+++ b/spec/ruby/optional/capi/ext/rubyspec.h
@@ -23,6 +23,10 @@
(RUBY_VERSION_MAJOR == (major) && RUBY_VERSION_MINOR < (minor)) || \
(RUBY_VERSION_MAJOR == (major) && RUBY_VERSION_MINOR == (minor) && RUBY_VERSION_TEENY < (teeny)))
+#if RUBY_VERSION_MAJOR > 2 || (RUBY_VERSION_MAJOR == 2 && RUBY_VERSION_MINOR >= 7)
+#define RUBY_VERSION_IS_2_7
+#endif
+
#if RUBY_VERSION_MAJOR > 2 || (RUBY_VERSION_MAJOR == 2 && RUBY_VERSION_MINOR >= 6)
#define RUBY_VERSION_IS_2_6
#endif
@@ -31,4 +35,26 @@
#define RUBY_VERSION_IS_2_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_iterate(function, arg1, block, arg2) rb_iterate(function, arg1, RUBY_METHOD_FUNC(block), arg2)
+#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_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)
+#endif
+
#endif
diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c
index a44e437bba..97f6b031ef 100644
--- a/spec/ruby/optional/capi/ext/string_spec.c
+++ b/spec/ruby/optional/capi/ext/string_spec.c
@@ -284,6 +284,26 @@ VALUE string_spec_RSTRING_PTR_iterate(VALUE self, VALUE str) {
return Qnil;
}
+VALUE string_spec_RSTRING_PTR_iterate_uint32(VALUE self, VALUE str) {
+ int i;
+ uint32_t* ptr;
+ int l = RSTRING_LEN(str) / sizeof(uint32_t);
+
+ ptr = (uint32_t *)RSTRING_PTR(str);
+ for(i = 0; i < l; i++) {
+ rb_yield(UINT2NUM(ptr[i]));
+ }
+ return Qnil;
+}
+
+VALUE string_spec_RSTRING_PTR_short_memcpy(VALUE self, VALUE str) {
+ // Short memcpy operations may be optimised by the compiler to a single write.
+ if (RSTRING_LEN(str) >= 8) {
+ memcpy(RSTRING_PTR(str), "Infinity", 8);
+ }
+ return str;
+}
+
VALUE string_spec_RSTRING_PTR_assign(VALUE self, VALUE str, VALUE chr) {
int i;
char c;
@@ -362,11 +382,11 @@ static VALUE string_spec_rb_sprintf2(VALUE self, VALUE str, VALUE repl1, VALUE r
}
static VALUE string_spec_rb_sprintf3(VALUE self, VALUE str) {
- return rb_sprintf("Result: %"PRIsVALUE".", str);
+ return rb_sprintf("Result: %" PRIsVALUE ".", str);
}
static VALUE string_spec_rb_sprintf4(VALUE self, VALUE str) {
- return rb_sprintf("Result: %+"PRIsVALUE".", str);
+ return rb_sprintf("Result: %+" PRIsVALUE ".", str);
}
static VALUE string_spec_rb_vsprintf_worker(char* fmt, ...) {
@@ -477,6 +497,8 @@ void Init_string_spec(void) {
rb_define_method(cls, "RSTRING_LEN", string_spec_RSTRING_LEN, 1);
rb_define_method(cls, "RSTRING_LENINT", string_spec_RSTRING_LENINT, 1);
rb_define_method(cls, "RSTRING_PTR_iterate", string_spec_RSTRING_PTR_iterate, 1);
+ rb_define_method(cls, "RSTRING_PTR_iterate_uint32", string_spec_RSTRING_PTR_iterate_uint32, 1);
+ rb_define_method(cls, "RSTRING_PTR_short_memcpy", string_spec_RSTRING_PTR_short_memcpy, 1);
rb_define_method(cls, "RSTRING_PTR_assign", string_spec_RSTRING_PTR_assign, 2);
rb_define_method(cls, "RSTRING_PTR_set", string_spec_RSTRING_PTR_set, 3);
rb_define_method(cls, "RSTRING_PTR_after_funcall", string_spec_RSTRING_PTR_after_funcall, 2);
diff --git a/spec/ruby/optional/capi/ext/symbol_spec.c b/spec/ruby/optional/capi/ext/symbol_spec.c
index 27732ae58f..d2ca62d81e 100644
--- a/spec/ruby/optional/capi/ext/symbol_spec.c
+++ b/spec/ruby/optional/capi/ext/symbol_spec.c
@@ -7,6 +7,10 @@
extern "C" {
#endif
+VALUE symbol_spec_SYMBOL_P(VALUE self, VALUE obj) {
+ return SYMBOL_P(obj) ? Qtrue : Qfalse;
+}
+
VALUE symbol_spec_rb_intern(VALUE self, VALUE string) {
return ID2SYM(rb_intern(RSTRING_PTR(string)));
}
@@ -73,6 +77,7 @@ VALUE symbol_spec_rb_sym2str(VALUE self, VALUE sym) {
void Init_symbol_spec(void) {
VALUE cls = rb_define_class("CApiSymbolSpecs", rb_cObject);
+ rb_define_method(cls, "SYMBOL_P", symbol_spec_SYMBOL_P, 1);
rb_define_method(cls, "rb_intern", symbol_spec_rb_intern, 1);
rb_define_method(cls, "rb_intern2", symbol_spec_rb_intern2, 2);
rb_define_method(cls, "rb_intern_const", symbol_spec_rb_intern_const, 1);
diff --git a/spec/ruby/optional/capi/ext/thread_spec.c b/spec/ruby/optional/capi/ext/thread_spec.c
index 139652e326..743828b523 100644
--- a/spec/ruby/optional/capi/ext/thread_spec.c
+++ b/spec/ruby/optional/capi/ext/thread_spec.c
@@ -15,7 +15,7 @@
extern "C" {
#endif
-static VALUE thread_spec_rb_thread_alone() {
+static VALUE thread_spec_rb_thread_alone(VALUE self) {
return rb_thread_alone() ? Qtrue : Qfalse;
}
@@ -89,7 +89,7 @@ static VALUE thread_spec_rb_thread_call_without_gvl_with_ubf_io(VALUE self) {
return (VALUE)ret;
}
-static VALUE thread_spec_rb_thread_current() {
+static VALUE thread_spec_rb_thread_current(VALUE self) {
return rb_thread_current();
}
diff --git a/spec/ruby/optional/capi/ext/typed_data_spec.c b/spec/ruby/optional/capi/ext/typed_data_spec.c
index a2cc53f54d..6eb91b76bf 100644
--- a/spec/ruby/optional/capi/ext/typed_data_spec.c
+++ b/spec/ruby/optional/capi/ext/typed_data_spec.c
@@ -8,7 +8,7 @@ extern "C" {
#endif
struct sample_typed_wrapped_struct_parent {
- int foo;
+ int foo;
};
void sample_typed_wrapped_struct_parent_free(void* st) {
@@ -32,7 +32,7 @@ static const rb_data_type_t sample_typed_wrapped_struct_parent_data_type = {
};
struct sample_typed_wrapped_struct {
- int foo;
+ int foo;
};
void sample_typed_wrapped_struct_free(void* st) {
@@ -61,7 +61,7 @@ static const rb_data_type_t sample_typed_wrapped_struct_data_type = {
};
struct sample_typed_wrapped_struct_other {
- int foo;
+ int foo;
};
void sample_typed_wrapped_struct_other_free(void* st) {
@@ -86,43 +86,45 @@ static const rb_data_type_t sample_typed_wrapped_struct_other_data_type = {
VALUE sdaf_alloc_typed_func(VALUE klass) {
- struct sample_typed_wrapped_struct* bar = (struct sample_typed_wrapped_struct *)malloc(sizeof(struct sample_typed_wrapped_struct));
- bar->foo = 42;
- return TypedData_Wrap_Struct(klass, &sample_typed_wrapped_struct_data_type, bar);
+ struct sample_typed_wrapped_struct* bar;
+ bar = (struct sample_typed_wrapped_struct *) malloc(sizeof(struct sample_typed_wrapped_struct));
+ bar->foo = 42;
+ return TypedData_Wrap_Struct(klass, &sample_typed_wrapped_struct_data_type, bar);
}
VALUE sdaf_typed_get_struct(VALUE self) {
- struct sample_typed_wrapped_struct* bar;
- TypedData_Get_Struct(self, struct sample_typed_wrapped_struct, &sample_typed_wrapped_struct_data_type, bar);
+ struct sample_typed_wrapped_struct* bar;
+ TypedData_Get_Struct(self, struct sample_typed_wrapped_struct, &sample_typed_wrapped_struct_data_type, bar);
- return INT2FIX((*bar).foo);
+ return INT2FIX((*bar).foo);
}
VALUE sws_typed_wrap_struct(VALUE self, VALUE val) {
- struct sample_typed_wrapped_struct* bar = (struct sample_typed_wrapped_struct *)malloc(sizeof(struct sample_typed_wrapped_struct));
- bar->foo = FIX2INT(val);
- return TypedData_Wrap_Struct(rb_cObject, &sample_typed_wrapped_struct_data_type, bar);
+ struct sample_typed_wrapped_struct* bar;
+ bar = (struct sample_typed_wrapped_struct *) malloc(sizeof(struct sample_typed_wrapped_struct));
+ bar->foo = FIX2INT(val);
+ return TypedData_Wrap_Struct(rb_cObject, &sample_typed_wrapped_struct_data_type, bar);
}
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);
+ struct sample_typed_wrapped_struct* bar;
+ TypedData_Get_Struct(obj, struct sample_typed_wrapped_struct, &sample_typed_wrapped_struct_data_type, bar);
- return INT2FIX((*bar).foo);
+ return INT2FIX((*bar).foo);
}
VALUE sws_typed_get_struct_different_type(VALUE self, VALUE obj) {
- struct sample_typed_wrapped_struct_other* bar;
- TypedData_Get_Struct(obj, struct sample_typed_wrapped_struct_other, &sample_typed_wrapped_struct_other_data_type, bar);
+ struct sample_typed_wrapped_struct_other* bar;
+ TypedData_Get_Struct(obj, struct sample_typed_wrapped_struct_other, &sample_typed_wrapped_struct_other_data_type, bar);
- return INT2FIX((*bar).foo);
+ return INT2FIX((*bar).foo);
}
VALUE sws_typed_get_struct_parent_type(VALUE self, VALUE obj) {
- struct sample_typed_wrapped_struct_parent* bar;
- TypedData_Get_Struct(obj, struct sample_typed_wrapped_struct_parent, &sample_typed_wrapped_struct_parent_data_type, bar);
+ struct sample_typed_wrapped_struct_parent* bar;
+ TypedData_Get_Struct(obj, struct sample_typed_wrapped_struct_parent, &sample_typed_wrapped_struct_parent_data_type, bar);
- return INT2FIX((*bar).foo);
+ return INT2FIX((*bar).foo);
}
VALUE sws_typed_get_struct_rdata(VALUE self, VALUE obj) {
@@ -138,11 +140,10 @@ VALUE sws_typed_get_struct_data_ptr(VALUE self, VALUE obj) {
}
VALUE sws_typed_change_struct(VALUE self, VALUE obj, VALUE new_val) {
- struct sample_typed_wrapped_struct *old_struct, *new_struct;
- new_struct = (struct sample_typed_wrapped_struct *)malloc(sizeof(struct sample_typed_wrapped_struct));
+ struct sample_typed_wrapped_struct *new_struct;
+ new_struct = (struct sample_typed_wrapped_struct *) malloc(sizeof(struct sample_typed_wrapped_struct));
new_struct->foo = FIX2INT(new_val);
- old_struct = RTYPEDDATA(obj)->data;
- free(old_struct);
+ free(RTYPEDDATA(obj)->data);
RTYPEDDATA(obj)->data = new_struct;
return Qnil;
}
diff --git a/spec/ruby/optional/capi/ext/util_spec.c b/spec/ruby/optional/capi/ext/util_spec.c
index f3c6a1ba58..f7b45de6b6 100644
--- a/spec/ruby/optional/capi/ext/util_spec.c
+++ b/spec/ruby/optional/capi/ext/util_spec.c
@@ -60,8 +60,8 @@ static VALUE util_spec_rb_get_kwargs(VALUE self, VALUE keyword_hash, VALUE keys,
int values_len = req + (opt < 0 ? -1 - opt : opt);
int i = 0;
- ID *ids = malloc(sizeof(VALUE) * len);
- VALUE *results = malloc(sizeof(VALUE) * values_len);
+ ID *ids = (ID*) malloc(sizeof(VALUE) * len);
+ VALUE *results = (VALUE*) malloc(sizeof(VALUE) * values_len);
int extracted = 0;
VALUE ary = Qundef;
diff --git a/spec/ruby/optional/capi/kernel_spec.rb b/spec/ruby/optional/capi/kernel_spec.rb
index c6fddc3f64..5c272947ab 100644
--- a/spec/ruby/optional/capi/kernel_spec.rb
+++ b/spec/ruby/optional/capi/kernel_spec.rb
@@ -261,28 +261,28 @@ describe "C-API Kernel function" do
describe "rb_protect" do
it "will run a function with an argument" do
proof = [] # Hold proof of work performed after the yield.
- res = @s.rb_protect_yield(7, proof) { |x| x + 1 }
- res.should == 8
+ res = @s.rb_protect_yield(77, proof) { |x| x + 1 }
+ res.should == 78
proof[0].should == 23
end
it "will allow cleanup code to run after break" do
proof = [] # Hold proof of work performed after the yield.
- @s.rb_protect_yield(7, proof) { |x| break }
+ @s.rb_protect_yield(77, proof) { |x| break }
proof[0].should == 23
end
it "will allow cleanup code to run after break with value" do
proof = [] # Hold proof of work performed after the yield.
- res = @s.rb_protect_yield(7, proof) { |x| break x + 1 }
- res.should == 8
+ res = @s.rb_protect_yield(77, proof) { |x| break x + 1 }
+ res.should == 78
proof[0].should == 23
end
it "will allow cleanup code to run after a raise" do
proof = [] # Hold proof of work performed after the yield.
-> do
- @s.rb_protect_yield(7, proof) { |x| raise NameError}
+ @s.rb_protect_yield(77, proof) { |x| raise NameError}
end.should raise_error(NameError)
proof[0].should == 23
end
@@ -290,7 +290,7 @@ describe "C-API Kernel function" do
it "will return nil if an error was raised" do
proof = [] # Hold proof of work performed after the yield.
-> do
- @s.rb_protect_yield(7, proof) { |x| raise NameError}
+ @s.rb_protect_yield(77, proof) { |x| raise NameError}
end.should raise_error(NameError)
proof[0].should == 23
proof[1].should == nil
@@ -316,47 +316,47 @@ describe "C-API Kernel function" do
describe "rb_rescue" do
before :each do
@proc = -> x { x }
- @raise_proc_returns_sentinel = -> *_ { :raise_proc_executed }
- @raise_proc_returns_arg = -> *a { a }
+ @rescue_proc_returns_sentinel = -> *_ { :rescue_proc_executed }
+ @rescue_proc_returns_arg = -> *a { a }
@arg_error_proc = -> *_ { raise ArgumentError, '' }
@std_error_proc = -> *_ { raise StandardError, '' }
@exc_error_proc = -> *_ { raise Exception, '' }
end
it "executes passed function" do
- @s.rb_rescue(@proc, :no_exc, @raise_proc_returns_arg, :exc).should == :no_exc
+ @s.rb_rescue(@proc, :no_exc, @rescue_proc_returns_arg, :exc).should == :no_exc
end
- it "executes passed 'raise function' if a StandardError exception is raised" do
- @s.rb_rescue(@arg_error_proc, nil, @raise_proc_returns_sentinel, :exc).should == :raise_proc_executed
- @s.rb_rescue(@std_error_proc, nil, @raise_proc_returns_sentinel, :exc).should == :raise_proc_executed
+ it "executes the passed 'rescue function' if a StandardError exception is raised" do
+ @s.rb_rescue(@arg_error_proc, nil, @rescue_proc_returns_sentinel, :exc).should == :rescue_proc_executed
+ @s.rb_rescue(@std_error_proc, nil, @rescue_proc_returns_sentinel, :exc).should == :rescue_proc_executed
end
- it "passes the user supplied argument to the 'raise function' if a StandardError exception is raised" do
- arg1, _ = @s.rb_rescue(@arg_error_proc, nil, @raise_proc_returns_arg, :exc1)
+ it "passes the user supplied argument to the 'rescue function' if a StandardError exception is raised" do
+ arg1, _ = @s.rb_rescue(@arg_error_proc, nil, @rescue_proc_returns_arg, :exc1)
arg1.should == :exc1
- arg2, _ = @s.rb_rescue(@std_error_proc, nil, @raise_proc_returns_arg, :exc2)
+ arg2, _ = @s.rb_rescue(@std_error_proc, nil, @rescue_proc_returns_arg, :exc2)
arg2.should == :exc2
end
- it "passes the raised exception to the 'raise function' if a StandardError exception is raised" do
- _, exc1 = @s.rb_rescue(@arg_error_proc, nil, @raise_proc_returns_arg, :exc)
+ it "passes the raised exception to the 'rescue function' if a StandardError exception is raised" do
+ _, exc1 = @s.rb_rescue(@arg_error_proc, nil, @rescue_proc_returns_arg, :exc)
exc1.class.should == ArgumentError
- _, exc2 = @s.rb_rescue(@std_error_proc, nil, @raise_proc_returns_arg, :exc)
+ _, exc2 = @s.rb_rescue(@std_error_proc, nil, @rescue_proc_returns_arg, :exc)
exc2.class.should == StandardError
end
it "raises an exception if passed function raises an exception other than StandardError" do
- -> { @s.rb_rescue(@exc_error_proc, nil, @raise_proc_returns_arg, nil) }.should raise_error(Exception)
+ -> { @s.rb_rescue(@exc_error_proc, nil, @rescue_proc_returns_arg, nil) }.should raise_error(Exception)
end
- it "raises an exception if any exception is raised inside 'raise function'" do
+ it "raises an exception if any exception is raised inside the 'rescue function'" do
-> { @s.rb_rescue(@std_error_proc, nil, @std_error_proc, nil) }.should raise_error(StandardError)
end
- it "makes $! available only during 'raise function' execution" do
+ it "makes $! available only during the 'rescue function' execution" do
@s.rb_rescue(@std_error_proc, nil, -> *_ { $! }, nil).class.should == StandardError
$!.should == nil
end
@@ -368,6 +368,10 @@ describe "C-API Kernel function" do
proc_caller { break :value }.should == :value
end
+
+ it "returns nil if the 'rescue function' is null" do
+ @s.rb_rescue(@std_error_proc, nil, nil, nil).should == nil
+ end
end
describe "rb_rescue2" do
diff --git a/spec/ruby/optional/capi/language_spec.rb b/spec/ruby/optional/capi/language_spec.rb
new file mode 100644
index 0000000000..7605332fbd
--- /dev/null
+++ b/spec/ruby/optional/capi/language_spec.rb
@@ -0,0 +1,31 @@
+require_relative 'spec_helper'
+
+load_extension("language")
+
+describe "C language construct" do
+ before :each do
+ @s = CApiLanguageSpecs.new
+ end
+
+ describe "switch (VALUE)" do
+ it "works for Qtrue" do
+ @s.switch(true).should == :true
+ end
+
+ it "works for Qfalse" do
+ @s.switch(false).should == :false
+ end
+
+ it "works for Qnil" do
+ @s.switch(nil).should == :nil
+ end
+
+ it "works for Qundef" do
+ @s.switch(:undef).should == :undef
+ end
+
+ it "works for the default case" do
+ @s.switch(Object.new).should == :default
+ end
+ end
+end
diff --git a/spec/ruby/optional/capi/numeric_spec.rb b/spec/ruby/optional/capi/numeric_spec.rb
index d76f353850..de7e180414 100644
--- a/spec/ruby/optional/capi/numeric_spec.rb
+++ b/spec/ruby/optional/capi/numeric_spec.rb
@@ -143,6 +143,34 @@ describe "CApiNumericSpecs" do
end
end
+ describe "NUM2SHORT" do
+ it "raises a TypeError if passed nil" do
+ -> { @s.NUM2SHORT(nil) }.should raise_error(TypeError)
+ end
+
+ it "converts a Float" do
+ @s.NUM2SHORT(4.2).should == 4
+ end
+
+ it "converts a Fixnum" do
+ @s.NUM2SHORT(5).should == 5
+ end
+
+ it "converts -1 to an signed number" do
+ @s.NUM2SHORT(-1).should == -1
+ end
+
+ it "raises a RangeError if the value is more than 32bits" do
+ -> { @s.NUM2SHORT(0xffff_ffff+1) }.should raise_error(RangeError)
+ end
+
+ it "calls #to_int to coerce the value" do
+ obj = mock("number")
+ obj.should_receive(:to_int).and_return(2)
+ @s.NUM2SHORT(obj).should == 2
+ end
+ end
+
describe "INT2NUM" do
it "raises a TypeError if passed nil" do
-> { @s.INT2NUM(nil) }.should raise_error(TypeError)
diff --git a/spec/ruby/optional/capi/proc_spec.rb b/spec/ruby/optional/capi/proc_spec.rb
index 9f9a37cc98..ff119416f6 100644
--- a/spec/ruby/optional/capi/proc_spec.rb
+++ b/spec/ruby/optional/capi/proc_spec.rb
@@ -54,6 +54,25 @@ describe "C-API Proc function" do
@p.rb_proc_call(prc, [6, 7]).should == 42
end
end
+
+ describe "rb_obj_is_proc" do
+ it "returns true for Proc" do
+ prc = Proc.new {|a,b| a * b }
+ @p.rb_obj_is_proc(prc).should be_true
+ end
+
+ it "returns true for subclass of Proc" do
+ prc = Class.new(Proc).new {}
+ @p.rb_obj_is_proc(prc).should be_true
+ end
+
+ it "returns false for non Proc instances" do
+ @p.rb_obj_is_proc("aoeui").should be_false
+ @p.rb_obj_is_proc(123).should be_false
+ @p.rb_obj_is_proc(true).should be_false
+ @p.rb_obj_is_proc([]).should be_false
+ end
+ end
end
describe "C-API when calling Proc.new from a C function" do
diff --git a/spec/ruby/optional/capi/spec_helper.rb b/spec/ruby/optional/capi/spec_helper.rb
index eda4964b69..30e6196d05 100644
--- a/spec/ruby/optional/capi/spec_helper.rb
+++ b/spec/ruby/optional/capi/spec_helper.rb
@@ -8,12 +8,17 @@ require 'rbconfig'
OBJDIR ||= File.expand_path("../../../ext/#{RUBY_ENGINE}/#{RUBY_VERSION}", __FILE__)
def object_path
- mkdir_p(OBJDIR)
- OBJDIR
+ path = OBJDIR
+ if ENV['SPEC_CAPI_CXX'] == 'true'
+ path = "#{path}/cxx"
+ end
+ mkdir_p(path)
+ path
end
def compile_extension(name)
debug = false
+ cxx = ENV['SPEC_CAPI_CXX'] == 'true'
run_mkmf_in_process = RUBY_ENGINE == 'truffleruby'
core_ext_dir = File.expand_path("../ext", __FILE__)
@@ -54,7 +59,11 @@ def compile_extension(name)
Dir.mkdir(tmpdir)
begin
["#{core_ext_dir}/rubyspec.h", "#{spec_ext_dir}/#{ext}.c"].each do |file|
- cp file, "#{tmpdir}/#{File.basename(file)}"
+ if cxx and file.end_with?('.c')
+ cp file, "#{tmpdir}/#{File.basename(file, '.c')}.cpp"
+ else
+ cp file, "#{tmpdir}/#{File.basename(file)}"
+ end
end
Dir.chdir(tmpdir) do
@@ -64,11 +73,13 @@ def compile_extension(name)
init_mkmf unless required
create_makefile(ext, tmpdir)
else
- File.write("extconf.rb", "require 'mkmf'\n" +
- "$ruby = ENV.values_at('RUBY_EXE', 'RUBY_FLAGS').join(' ')\n" +
+ File.write("extconf.rb", <<-RUBY)
+ require 'mkmf'
+ $ruby = ENV.values_at('RUBY_EXE', 'RUBY_FLAGS').join(' ')
# MRI magic to consider building non-bundled extensions
- "$extout = nil\n" +
- "create_makefile(#{ext.inspect})\n")
+ $extout = nil
+ create_makefile(#{ext.inspect})
+ RUBY
output = ruby_exe("extconf.rb")
raise "extconf failed:\n#{output}" unless $?.success?
$stderr.puts output if debug
diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb
index 1ad35b9e8a..243765cdbe 100644
--- a/spec/ruby/optional/capi/string_spec.rb
+++ b/spec/ruby/optional/capi/string_spec.rb
@@ -513,6 +513,24 @@ describe "C-API String function" do
end
chars.should == [55, 48, 227, 131, 145, 227, 130, 175]
end
+
+ it "returns a pointer which can be cast and used as another type" do
+ s = "70パク".
+ encode(Encoding::UTF_16LE).
+ force_encoding(Encoding::UTF_16LE).
+ encode(Encoding::UTF_8)
+
+ ints = []
+ @s.RSTRING_PTR_iterate_uint32(s) do |i|
+ ints << i
+ end
+ ints.should == s.unpack('LL')
+ end
+
+ it "allows a short memcpy to the string which may be converted to a single write operation by the compiler" do
+ str = " "
+ @s.RSTRING_PTR_short_memcpy(str).should == "Infinity"
+ end
end
describe "RSTRING_LEN" do
diff --git a/spec/ruby/optional/capi/symbol_spec.rb b/spec/ruby/optional/capi/symbol_spec.rb
index 7f345f879f..0d71c1c711 100644
--- a/spec/ruby/optional/capi/symbol_spec.rb
+++ b/spec/ruby/optional/capi/symbol_spec.rb
@@ -8,6 +8,16 @@ describe "C-API Symbol function" do
@s = CApiSymbolSpecs.new
end
+ describe "SYMBOL_P" do
+ it "returns true for a Symbol" do
+ @s.SYMBOL_P(:foo).should == true
+ end
+
+ it "returns false for non-Symbols" do
+ @s.SYMBOL_P('bar').should == false
+ end
+ end
+
describe "rb_intern" do
it "converts a string to a symbol, uniquely" do
@s.rb_intern("test_symbol").should == :test_symbol