From 5d06ee3b4967295ca02b7144c2498b647b6a7afb Mon Sep 17 00:00:00 2001 From: Jitka Plesnikova Date: Thu, 23 Jan 2020 16:29:48 +0100 Subject: [PATCH] Add support for Ruby 2.7; Fix code generated for Ruby global variables --- swig-4.0.1-Add-support-for-Ruby-2.7.patch | 296 ++++++++++ ...-generated-for-Ruby-global-variables.patch | 534 ++++++++++++++++++ swig.spec | 25 +- swig308-Do-not-use-isystem.patch | 2 +- 4 files changed, 848 insertions(+), 9 deletions(-) create mode 100644 swig-4.0.1-Add-support-for-Ruby-2.7.patch create mode 100644 swig-4.0.1-Fix-code-generated-for-Ruby-global-variables.patch diff --git a/swig-4.0.1-Add-support-for-Ruby-2.7.patch b/swig-4.0.1-Add-support-for-Ruby-2.7.patch new file mode 100644 index 0000000..359422b --- /dev/null +++ b/swig-4.0.1-Add-support-for-Ruby-2.7.patch @@ -0,0 +1,296 @@ +From 00e291b319bd6b58bf061feee3721a58c9c6be32 Mon Sep 17 00:00:00 2001 +From: Thomas Reitmayr +Date: Mon, 30 Dec 2019 20:11:03 +0100 +Subject: [PATCH] Add support for Ruby 2.7 + +This commit fixes the signatures of various callback methods +and cleans up the macro definitions used for casting callbacks. + +Note that the transparent version of the macro RUBY_METHOD_FUNC +is currently masked behind RUBY_DEVEL, see commit +https://github.com/ruby/ruby/commit/1d91feaf13e0ffe04b2dabc6e77e4101b6d0bb07 +In order to still support strict signature checking and prevent +nasty deprecation warnings, the use of RUBY_METHOD_FUNC had to +be replaced with VALUEFUNC. +--- + Lib/ruby/rubyclasses.swg | 14 +++++++------- + Lib/ruby/rubyhead.swg | 26 +++++++++----------------- + Lib/ruby/rubyprimtypes.swg | 15 ++++++++------- + Lib/ruby/rubytracking.swg | 10 +++++----- + Source/Modules/ruby.cxx | 22 +++++++++------------- + 5 files changed, 38 insertions(+), 49 deletions(-) + +diff --git a/Lib/ruby/rubyclasses.swg b/Lib/ruby/rubyclasses.swg +index f7b51bdcc..b345fcebe 100644 +--- a/Lib/ruby/rubyclasses.swg ++++ b/Lib/ruby/rubyclasses.swg +@@ -174,7 +174,7 @@ namespace swig { + return rb_inspect(_obj); + } + +- static VALUE swig_rescue_swallow(VALUE) ++ static VALUE swig_rescue_swallow(VALUE, VALUE) + { + /* + VALUE errstr = rb_obj_as_string(rb_errinfo()); +@@ -203,8 +203,8 @@ namespace swig { + args.id = op_id; + args.nargs = 1; + args.target = VALUE(other); +- ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args), +- (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil); ++ ret = rb_rescue(VALUEFUNC(swig_rescue_funcall), VALUE(&args), ++ (VALUEFUNC(swig_rescue_swallow)), Qnil); + } + if (ret == Qnil) { + VALUE a = rb_funcall( _obj, hash_id, 0 ); +@@ -243,8 +243,8 @@ namespace swig { + args.id = op_id; + args.nargs = 0; + args.target = Qnil; +- ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args), +- (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil); ++ ret = rb_rescue(VALUEFUNC(swig_rescue_funcall), VALUE(&args), ++ (VALUEFUNC(swig_rescue_swallow)), Qnil); + SWIG_RUBY_THREAD_END_BLOCK; + return ret; + } +@@ -262,8 +262,8 @@ namespace swig { + args.id = op_id; + args.nargs = 1; + args.target = VALUE(other); +- ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args), +- (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil); ++ ret = rb_rescue(VALUEFUNC(swig_rescue_funcall), VALUE(&args), ++ (VALUEFUNC(swig_rescue_swallow)), Qnil); + SWIG_RUBY_THREAD_END_BLOCK; + return GC_VALUE(ret); + } +diff --git a/Lib/ruby/rubyhead.swg b/Lib/ruby/rubyhead.swg +index 90f07cf68..9a0400eea 100644 +--- a/Lib/ruby/rubyhead.swg ++++ b/Lib/ruby/rubyhead.swg +@@ -110,26 +110,18 @@ + * can be passed as an argument to API functions like Data_Wrap_Struct() + * and Data_Make_Struct(). + */ +- +-#ifdef __cplusplus +-# ifndef RUBY_METHOD_FUNC /* These definitions should work for Ruby 1.4.6 */ +-# define PROTECTFUNC(f) ((VALUE (*)()) f) +-# define VALUEFUNC(f) ((VALUE (*)()) f) +-# define VOIDFUNC(f) ((void (*)()) f) +-# else +-# ifndef ANYARGS /* These definitions should work for Ruby 1.6 */ +-# define PROTECTFUNC(f) ((VALUE (*)()) f) +-# define VALUEFUNC(f) ((VALUE (*)()) f) +-# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f) +-# else /* These definitions should work for Ruby 1.7+ */ +-# define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f) +-# define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f) +-# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f) +-# endif +-# endif ++#if defined(__cplusplus) && !defined(RB_METHOD_DEFINITION_DECL) ++# define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f) ++# define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f) ++# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f) ++# define VOID_ANYARGS_FUNC(f) ((void (*)(ANYARGS))(f)) ++# define INT_ANYARGS_FUNC(f) ((int (*)(ANYARGS))(f)) + #else ++# define PROTECTFUNC(f) (f) + # define VALUEFUNC(f) (f) + # define VOIDFUNC(f) (f) ++# define VOID_ANYARGS_FUNC(f) (f) ++# define INT_ANYARGS_FUNC(f) (f) + #endif + + /* Don't use for expressions have side effect */ +diff --git a/Lib/ruby/rubyprimtypes.swg b/Lib/ruby/rubyprimtypes.swg +index 3a848191c..4b078deea 100644 +--- a/Lib/ruby/rubyprimtypes.swg ++++ b/Lib/ruby/rubyprimtypes.swg +@@ -10,15 +10,16 @@ + %fragment("SWIG_ruby_failed","header") + { + SWIGINTERN VALUE +-SWIG_ruby_failed(void) ++SWIG_ruby_failed(VALUE SWIGUNUSEDPARM(arg1), VALUE SWIGUNUSEDPARM(arg2)) + { + return Qnil; + } + } + + %define %ruby_aux_method(Type, Method, Action) +-SWIGINTERN VALUE SWIG_AUX_##Method##(VALUE *args) ++SWIGINTERN VALUE SWIG_AUX_##Method##(VALUE arg) + { ++ VALUE *args = (VALUE *)arg; + VALUE obj = args[0]; + VALUE type = TYPE(obj); + Type *res = (Type *)(args[1]); +@@ -79,7 +80,7 @@ SWIG_AsVal_dec(long)(VALUE obj, long* val) + VALUE a[2]; + a[0] = obj; + a[1] = (VALUE)(&v); +- if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2LONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) { ++ if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2LONG), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) { + if (val) *val = v; + return SWIG_OK; + } +@@ -111,7 +112,7 @@ SWIG_AsVal_dec(unsigned long)(VALUE obj, unsigned long *val) + VALUE a[2]; + a[0] = obj; + a[1] = (VALUE)(&v); +- if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) { ++ if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2ULONG), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) { + if (val) *val = v; + return SWIG_OK; + } +@@ -149,7 +150,7 @@ SWIG_AsVal_dec(long long)(VALUE obj, long long *val) + VALUE a[2]; + a[0] = obj; + a[1] = (VALUE)(&v); +- if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2LL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) { ++ if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2LL), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) { + if (val) *val = v; + return SWIG_OK; + } +@@ -187,7 +188,7 @@ SWIG_AsVal_dec(unsigned long long)(VALUE obj, unsigned long long *val) + VALUE a[2]; + a[0] = obj; + a[1] = (VALUE)(&v); +- if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) { ++ if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2ULL), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) { + if (val) *val = v; + return SWIG_OK; + } +@@ -215,7 +216,7 @@ SWIG_AsVal_dec(double)(VALUE obj, double *val) + VALUE a[2]; + a[0] = obj; + a[1] = (VALUE)(&v); +- if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2DBL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) { ++ if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2DBL), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) { + if (val) *val = v; + return SWIG_OK; + } +diff --git a/Lib/ruby/rubytracking.swg b/Lib/ruby/rubytracking.swg +index b9fb249d8..221a68193 100644 +--- a/Lib/ruby/rubytracking.swg ++++ b/Lib/ruby/rubytracking.swg +@@ -32,7 +32,7 @@ extern "C" { + */ + static st_table* swig_ruby_trackings = NULL; + +-static VALUE swig_ruby_trackings_count(ANYARGS) { ++static VALUE swig_ruby_trackings_count(ID id, VALUE *var) { + return SWIG2NUM(swig_ruby_trackings->num_entries); + } + +@@ -69,7 +69,7 @@ SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) { + swig_ruby_trackings = (st_table*)NUM2SWIG(trackings_value); + } + +- rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", swig_ruby_trackings_count, NULL); ++ rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", VALUEFUNC(swig_ruby_trackings_count), VOID_ANYARGS_FUNC((rb_gvar_setter_t*)NULL)); + } + + /* Add a Tracking from a C/C++ struct to a Ruby object */ +@@ -118,13 +118,13 @@ SWIGRUNTIME void SWIG_RubyUnlinkObjects(void* ptr) { + to the passed callback function. */ + + /* Proxy method to abstract the internal trackings datatype */ +-static int swig_ruby_internal_iterate_callback(void* ptr, VALUE obj, void(*meth)(void* ptr, VALUE obj)) { +- (*meth)(ptr, obj); ++static int swig_ruby_internal_iterate_callback(st_data_t ptr, st_data_t obj, st_data_t meth) { ++ ((void (*) (void *, VALUE))meth)((void *)ptr, (VALUE)obj); + return ST_CONTINUE; + } + + SWIGRUNTIME void SWIG_RubyIterateTrackings( void(*meth)(void* ptr, VALUE obj) ) { +- st_foreach(swig_ruby_trackings, (int (*)(ANYARGS))&swig_ruby_internal_iterate_callback, (st_data_t)meth); ++ st_foreach(swig_ruby_trackings, INT_ANYARGS_FUNC(swig_ruby_internal_iterate_callback), (st_data_t)meth); + } + + #ifdef __cplusplus +diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx +index c8f582679..01b75befa 100644 +--- a/Source/Modules/ruby.cxx ++++ b/Source/Modules/ruby.cxx +@@ -2191,6 +2191,7 @@ public: + String *tm; + String *getfname, *setfname; + Wrapper *getf, *setf; ++ const int assignable = is_assignable(n); + + // Determine whether virtual global variables shall be used + // which have different getter and setter signatures, +@@ -2206,7 +2207,7 @@ public: + getfname = Swig_name_wrapper(getname); + Setattr(n, "wrap:name", getfname); + Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL); +- Printf(getf->def, (use_virtual_var) ? "ID id" : "VALUE self"); ++ Printf(getf->def, (use_virtual_var) ? "ID id, VALUE *data" : "VALUE self"); + Printf(getf->def, ") {"); + Wrapper_add_local(getf, "_val", "VALUE _val"); + +@@ -2229,8 +2230,8 @@ public: + + Wrapper_print(getf, f_wrappers); + +- if (!is_assignable(n)) { +- setfname = NewString("NULL"); ++ if (!assignable) { ++ setfname = NewString("(rb_gvar_setter_t *)NULL"); + } else { + /* create setter */ + String* docs = docstring(n, AUTODOC_SETTER); +@@ -2242,7 +2243,7 @@ public: + Setattr(n, "wrap:name", setfname); + Printf(setf->def, "SWIGINTERN "); + if (use_virtual_var) { +- Printv(setf->def, "void\n", setfname, "(VALUE _val, ID id) {", NIL); ++ Printv(setf->def, "void\n", setfname, "(VALUE _val, ID id, VALUE *data) {", NIL); + } else { + Printv(setf->def, "VALUE\n", setfname, "(VALUE self, VALUE _val) {", NIL); + } +@@ -2273,7 +2274,7 @@ public: + if (CPlusPlus) { + Insert(getfname, 0, "VALUEFUNC("); + Append(getfname, ")"); +- Insert(setfname, 0, (use_virtual_var) ? "(void (*)(ANYARGS))(" : "VALUEFUNC("); ++ Insert(setfname, 0, (use_virtual_var) ? "VOID_ANYARGS_FUNC(" : "VALUEFUNC("); + Append(setfname, ")"); + } + +@@ -2282,7 +2283,7 @@ public: + case STATIC_VAR: + /* C++ class variable */ + Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "\", ", getfname, ", 0);\n", NIL); +- if (!GetFlag(n, "feature:immutable")) { ++ if (assignable) { + Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "=\", ", setfname, ", 1);\n", NIL); + } + Printv(klass->init, s, NIL); +@@ -2293,16 +2294,11 @@ public: + assert(current == NO_CPP); + if (!useGlobalModule) { + Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "\", ", getfname, ", 0);\n", NIL); +- if (!GetFlag(n, "feature:immutable")) { ++ if (assignable) { + Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL); + } + } else { +- Printv(s, tab4, "rb_define_virtual_variable(\"$", iname, "\", ", getfname, ", ", NIL); +- if (GetFlag(n, "feature:immutable")) { +- Printv(s, tab4, "0);\n", NIL); +- } else { +- Printv(s, tab4, setfname, ");\n", NIL); +- } ++ Printv(s, tab4, "rb_define_virtual_variable(\"$", iname, "\", ", getfname, ", ", setfname, ");\n", NIL); + } + Printv(f_init, s, NIL); + Delete(s); +-- +2.21.1 + diff --git a/swig-4.0.1-Fix-code-generated-for-Ruby-global-variables.patch b/swig-4.0.1-Fix-code-generated-for-Ruby-global-variables.patch new file mode 100644 index 0000000..7e24cb8 --- /dev/null +++ b/swig-4.0.1-Fix-code-generated-for-Ruby-global-variables.patch @@ -0,0 +1,534 @@ +From 18a3ef391121d7c4d819448c929721fd1708b40b Mon Sep 17 00:00:00 2001 +From: Thomas Reitmayr +Date: Sun, 27 Oct 2019 21:41:03 +0100 +Subject: [PATCH] Fix code generated for Ruby global variables + +This commit fixes swig#1653 by creating a Ruby virtual variable +for a C/c++ global variable when SWIG is invoked with the +-globalmodule option. +--- + Doc/Manual/Ruby.html | 18 +++++++ + Examples/test-suite/common.mk | 2 + + Examples/test-suite/global_immutable_vars.i | 24 +++++++++ + .../test-suite/global_immutable_vars_cpp.i | 24 +++++++++ + Examples/test-suite/ruby/Makefile.in | 4 ++ + .../ruby/global_immutable_vars_cpp_runme.rb | 47 +++++++++++++++++ + .../ruby/global_immutable_vars_runme.rb | 51 +++++++++++++++++++ + .../ruby_global_immutable_vars_cpp_runme.rb | 47 +++++++++++++++++ + .../ruby/ruby_global_immutable_vars_runme.rb | 51 +++++++++++++++++++ + .../test-suite/ruby_global_immutable_vars.i | 25 +++++++++ + .../ruby_global_immutable_vars_cpp.i | 23 +++++++++ + Source/Modules/ruby.cxx | 36 +++++++++---- + 12 files changed, 342 insertions(+), 10 deletions(-) + create mode 100644 Examples/test-suite/global_immutable_vars.i + create mode 100644 Examples/test-suite/global_immutable_vars_cpp.i + create mode 100644 Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb + create mode 100644 Examples/test-suite/ruby/global_immutable_vars_runme.rb + create mode 100644 Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb + create mode 100644 Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb + create mode 100644 Examples/test-suite/ruby_global_immutable_vars.i + create mode 100644 Examples/test-suite/ruby_global_immutable_vars_cpp.i + +diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html +index 3cfd1292c..6939a8a18 100644 +--- a/Doc/Manual/Ruby.html ++++ b/Doc/Manual/Ruby.html +@@ -615,6 +615,24 @@ directive. For example:

+ effect until it is explicitly disabled using %mutable. +

+ ++

Note: When SWIG is invoked with the -globalmodule option in ++effect, the C/C++ global variables will be translated into Ruby global ++variables. Type-checking and the optional read-only characteristic are ++available in the same way as described above. However the example would ++then have to be modified and executed in the following way: ++ ++

++
$ irb
++irb(main):001:0> require 'Example'
++true
++irb(main):002:0> $variable1 = 2
++2
++irb(main):003:0> $Variable2 = 4 * 10.3
++41.2
++irb(main):004:0> $Variable2
++41.2
++
++ +

34.3.4 Constants

+ + +diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk +index 5f7792810..008916a56 100644 +--- a/Examples/test-suite/common.mk ++++ b/Examples/test-suite/common.mk +@@ -250,6 +250,7 @@ CPP_TEST_CASES += \ + funcptr_cpp \ + functors \ + fvirtual \ ++ global_immutable_vars_cpp \ + global_namespace \ + global_ns_arg \ + global_scope_types \ +@@ -689,6 +690,7 @@ C_TEST_CASES += \ + funcptr \ + function_typedef \ + global_functions \ ++ global_immutable_vars \ + immutable_values \ + inctest \ + infinity \ +diff --git a/Examples/test-suite/global_immutable_vars.i b/Examples/test-suite/global_immutable_vars.i +new file mode 100644 +index 000000000..cd8cb184b +--- /dev/null ++++ b/Examples/test-suite/global_immutable_vars.i +@@ -0,0 +1,24 @@ ++%module global_immutable_vars ++ ++// Test immutable and mutable global variables, ++// see http://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables ++ ++%inline %{ ++ int default_mutable_var = 40; ++%} ++ ++%immutable; ++%feature("immutable", "0") specific_mutable_var; ++ ++%inline %{ ++ int global_immutable_var = 41; ++ int specific_mutable_var = 42; ++%} ++ ++%mutable; ++%immutable specific_immutable_var; ++%inline %{ ++ int global_mutable_var = 43; ++ int specific_immutable_var = 44; ++%} ++ +diff --git a/Examples/test-suite/global_immutable_vars_cpp.i b/Examples/test-suite/global_immutable_vars_cpp.i +new file mode 100644 +index 000000000..66eb8545d +--- /dev/null ++++ b/Examples/test-suite/global_immutable_vars_cpp.i +@@ -0,0 +1,24 @@ ++%module global_immutable_vars_cpp ++ ++// Test immutable and mutable global variables, ++// see http://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables ++ ++%inline %{ ++ int default_mutable_var = 40; ++%} ++ ++%immutable; ++%feature("immutable", "0") specific_mutable_var; ++ ++%inline %{ ++ int global_immutable_var = 41; ++ int specific_mutable_var = 42; ++%} ++ ++%mutable; ++%immutable specific_immutable_var; ++%inline %{ ++ int global_mutable_var = 43; ++ int specific_immutable_var = 44; ++%} ++ +diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in +index d75cdb058..2c59029ec 100644 +--- a/Examples/test-suite/ruby/Makefile.in ++++ b/Examples/test-suite/ruby/Makefile.in +@@ -23,6 +23,7 @@ CPP_TEST_CASES = \ + li_std_wstring_inherit \ + primitive_types \ + ruby_alias_method \ ++ ruby_global_immutable_vars_cpp \ + ruby_keywords \ + ruby_minherit_shared_ptr \ + ruby_naming \ +@@ -48,6 +49,7 @@ C_TEST_CASES += \ + li_cstring \ + ruby_alias_global_function \ + ruby_alias_module_function \ ++ ruby_global_immutable_vars \ + ruby_manual_proxy \ + + include $(srcdir)/../common.mk +@@ -57,6 +59,8 @@ SWIGOPT += -w801 -noautorename -features autodoc=4 + + # Custom tests - tests with additional commandline options + ruby_alias_global_function.ctest: SWIGOPT += -globalmodule ++ruby_global_immutable_vars.ctest: SWIGOPT += -globalmodule ++ruby_global_immutable_vars_cpp.cpptest: SWIGOPT += -globalmodule + ruby_naming.cpptest: SWIGOPT += -autorename + + # Rules for the different types of tests +diff --git a/Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb b/Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb +new file mode 100644 +index 000000000..c40896a86 +--- /dev/null ++++ b/Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb +@@ -0,0 +1,47 @@ ++#!/usr/bin/env ruby ++# ++# C++ version of global_immutable_vars_runme.rb ++# ++ ++require 'swig_assert' ++ ++require 'global_immutable_vars_cpp' ++ ++# first check if all variables can be read ++swig_assert_each_line( < e ++ had_exception = true ++end ++swig_assert(had_exception, nil, ++ "Global_immutable_vars_cpp::global_immutable_var is writable (expected to be immutable)") ++ ++had_exception = false ++begin ++ Global_immutable_vars_cpp::specific_immutable_var = 81 ++rescue NoMethodError => e ++ had_exception = true ++end ++swig_assert(had_exception, nil, ++ "Global_immutable_vars_cpp::specific_immutable_var is writable (expected to be immutable)") ++ +diff --git a/Examples/test-suite/ruby/global_immutable_vars_runme.rb b/Examples/test-suite/ruby/global_immutable_vars_runme.rb +new file mode 100644 +index 000000000..af55cfeb3 +--- /dev/null ++++ b/Examples/test-suite/ruby/global_immutable_vars_runme.rb +@@ -0,0 +1,51 @@ ++#!/usr/bin/env ruby ++# ++# Here the proper generation of mutable and immutable variables is tested ++# in the target language. ++# Immutable variables do not have "=" methods generated by SWIG, ++# therefore trying to assign these variables shall throw a NoMethodError ++# exception. ++# ++ ++require 'swig_assert' ++ ++require 'global_immutable_vars' ++ ++# first check if all variables can be read ++swig_assert_each_line( < e ++ had_exception = true ++end ++swig_assert(had_exception, nil, ++ "Global_immutable_vars::global_immutable_var is writable (expected to be immutable)") ++ ++had_exception = false ++begin ++ Global_immutable_vars::specific_immutable_var = 81 ++rescue NoMethodError => e ++ had_exception = true ++end ++swig_assert(had_exception, nil, ++ "Global_immutable_vars::specific_immutable_var is writable (expected to be immutable)") ++ +diff --git a/Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb b/Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb +new file mode 100644 +index 000000000..8453254eb +--- /dev/null ++++ b/Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb +@@ -0,0 +1,47 @@ ++#!/usr/bin/env ruby ++# ++# C++ version of ruby_global_immutable_vars_runme.rb. ++# ++ ++require 'swig_assert' ++ ++require 'ruby_global_immutable_vars_cpp' ++ ++# first check if all variables can be read ++swig_assert_each_line( < e ++ had_exception = true ++end ++swig_assert(had_exception, nil, ++ "$global_immutable_var is writable (expected to be immutable)") ++ ++had_exception = false ++begin ++ $specific_immutable_var = 81 ++rescue NameError => e ++ had_exception = true ++end ++swig_assert(had_exception, nil, ++ "$specific_immutable_var is writable (expected to be immutable)") ++ +diff --git a/Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb b/Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb +new file mode 100644 +index 000000000..fda1ccf0f +--- /dev/null ++++ b/Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb +@@ -0,0 +1,51 @@ ++#!/usr/bin/env ruby ++# ++# This test program is similar to global_immutable_vars_runme.rb ++# with the difference that the global variables to check are also ++# Ruby global variables (SWIG Ruby option "-globalmodule"). ++# ++# Immutable global variables shall throw a NameError exception. ++# ++ ++require 'swig_assert' ++ ++require 'ruby_global_immutable_vars' ++ ++# first check if all variables can be read ++swig_assert_each_line( < e ++ had_exception = true ++end ++swig_assert(had_exception, nil, ++ "$global_immutable_var is writable (expected to be immutable)") ++ ++had_exception = false ++begin ++ $specific_immutable_var = 81 ++rescue NameError => e ++ had_exception = true ++end ++swig_assert(had_exception, nil, ++ "$specific_immutable_var is writable (expected to be immutable)") ++ +diff --git a/Examples/test-suite/ruby_global_immutable_vars.i b/Examples/test-suite/ruby_global_immutable_vars.i +new file mode 100644 +index 000000000..dc49cd946 +--- /dev/null ++++ b/Examples/test-suite/ruby_global_immutable_vars.i +@@ -0,0 +1,25 @@ ++%module ruby_global_immutable_vars ++ ++// This copy of global_immutable_vars.i shall be compiled with the ++// SWIG Ruby option "-globalmodule" in order to check the code path ++// for registering global methods (in contrast to module methods). ++ ++%inline %{ ++ int default_mutable_var = 40; ++%} ++ ++%immutable; ++%feature("immutable", "0") specific_mutable_var; ++ ++%inline %{ ++ int global_immutable_var = 41; ++ int specific_mutable_var = 42; ++%} ++ ++%mutable; ++%immutable specific_immutable_var; ++%inline %{ ++ int global_mutable_var = 43; ++ int specific_immutable_var = 44; ++%} ++ +diff --git a/Examples/test-suite/ruby_global_immutable_vars_cpp.i b/Examples/test-suite/ruby_global_immutable_vars_cpp.i +new file mode 100644 +index 000000000..cf3145e80 +--- /dev/null ++++ b/Examples/test-suite/ruby_global_immutable_vars_cpp.i +@@ -0,0 +1,23 @@ ++%module ruby_global_immutable_vars_cpp ++ ++// C++ version of ruby_global_immutable_vars.i ++ ++%inline %{ ++ int default_mutable_var = 40; ++%} ++ ++%immutable; ++%feature("immutable", "0") specific_mutable_var; ++ ++%inline %{ ++ int global_immutable_var = 41; ++ int specific_mutable_var = 42; ++%} ++ ++%mutable; ++%immutable specific_immutable_var; ++%inline %{ ++ int global_mutable_var = 43; ++ int specific_immutable_var = 44; ++%} ++ +diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx +index 6a1e16d5d..c8f582679 100644 +--- a/Source/Modules/ruby.cxx ++++ b/Source/Modules/ruby.cxx +@@ -2192,6 +2192,11 @@ public: + String *getfname, *setfname; + Wrapper *getf, *setf; + ++ // Determine whether virtual global variables shall be used ++ // which have different getter and setter signatures, ++ // see https://docs.ruby-lang.org/en/2.6.0/extension_rdoc.html#label-Global+Variables+Shared+Between+C+and+Ruby ++ const bool use_virtual_var = (current == NO_CPP && useGlobalModule); ++ + getf = NewWrapper(); + setf = NewWrapper(); + +@@ -2201,7 +2206,7 @@ public: + getfname = Swig_name_wrapper(getname); + Setattr(n, "wrap:name", getfname); + Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL); +- Printf(getf->def, "VALUE self"); ++ Printf(getf->def, (use_virtual_var) ? "ID id" : "VALUE self"); + Printf(getf->def, ") {"); + Wrapper_add_local(getf, "_val", "VALUE _val"); + +@@ -2235,8 +2240,12 @@ public: + String *setname = Swig_name_set(NSPACE_TODO, iname); + setfname = Swig_name_wrapper(setname); + Setattr(n, "wrap:name", setfname); +- Printv(setf->def, "SWIGINTERN VALUE\n", setfname, "(VALUE self, ", NIL); +- Printf(setf->def, "VALUE _val) {"); ++ Printf(setf->def, "SWIGINTERN "); ++ if (use_virtual_var) { ++ Printv(setf->def, "void\n", setfname, "(VALUE _val, ID id) {", NIL); ++ } else { ++ Printv(setf->def, "VALUE\n", setfname, "(VALUE self, VALUE _val) {", NIL); ++ } + tm = Swig_typemap_lookup("varin", n, name, 0); + if (tm) { + Replaceall(tm, "$input", "_val"); +@@ -2247,9 +2256,14 @@ public: + } else { + Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t, 0)); + } +- Printv(setf->code, tab4, "return _val;\n", NIL); +- Printf(setf->code, "fail:\n"); +- Printv(setf->code, tab4, "return Qnil;\n", NIL); ++ if (use_virtual_var) { ++ Printf(setf->code, "fail:\n"); ++ Printv(setf->code, tab4, "return;\n", NIL); ++ } else { ++ Printv(setf->code, tab4, "return _val;\n", NIL); ++ Printf(setf->code, "fail:\n"); ++ Printv(setf->code, tab4, "return Qnil;\n", NIL); ++ } + Printf(setf->code, "}\n"); + Wrapper_print(setf, f_wrappers); + Delete(setname); +@@ -2259,7 +2273,7 @@ public: + if (CPlusPlus) { + Insert(getfname, 0, "VALUEFUNC("); + Append(getfname, ")"); +- Insert(setfname, 0, "VALUEFUNC("); ++ Insert(setfname, 0, (use_virtual_var) ? "(void (*)(ANYARGS))(" : "VALUEFUNC("); + Append(setfname, ")"); + } + +@@ -2283,9 +2297,11 @@ public: + Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL); + } + } else { +- Printv(s, tab4, "rb_define_global_method(\"", iname, "\", ", getfname, ", 0);\n", NIL); +- if (!GetFlag(n, "feature:immutable")) { +- Printv(s, tab4, "rb_define_global_method(\"", iname, "=\", ", setfname, ", 1);\n", NIL); ++ Printv(s, tab4, "rb_define_virtual_variable(\"$", iname, "\", ", getfname, ", ", NIL); ++ if (GetFlag(n, "feature:immutable")) { ++ Printv(s, tab4, "0);\n", NIL); ++ } else { ++ Printv(s, tab4, setfname, ");\n", NIL); + } + } + Printv(f_init, s, NIL); +-- +2.21.1 + diff --git a/swig.spec b/swig.spec index 2ff9791..dc7930a 100644 --- a/swig.spec +++ b/swig.spec @@ -19,9 +19,11 @@ %{!?lualang:%global lualang 1} %{!?phplang:%global phplang 1} # Disable Ruby test failed with swig 4.0.0 on s390 -# Tests on x86_64 fails with Ruby 2.6.4 -# https://github.com/swig/swig/issues/1646 +%ifarch s390x %{!?rubylang:%global rubylang 0} +%else +%{!?rubylang:%global rubylang 1} +%endif %{!?python2lang:%global python2lang 1} %{!?python3lang:%global python3lang 1} @@ -51,7 +53,7 @@ Summary: Connects C/C++/Objective C to some high-level programming languages Name: swig Version: 4.0.1 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ and BSD URL: http://swig.sourceforge.net/ Source0: http://downloads.sourceforge.net/project/swig/swig/swig-%{version}/swig-%{version}.tar.gz @@ -64,10 +66,12 @@ Source4: ccache-swig.csh %endif Patch0: swig308-Do-not-use-isystem.patch -# https://github.com/swig/swig/issues/1689 -# https://github.com/swig/swig/pull/1692/commits/00e291b319bd6b58bf061feee3721a58c9c6be32 -# For now, modify as small as possible for ruby 2.7 build -Patch1: swig-4.0.1-ruby27-minimum.patch +# Fix code generated for Ruby global variables +# https://github.com/swig/swig/issues/1668 +Patch1: swig-4.0.1-Fix-code-generated-for-Ruby-global-variables.patch +# Add support for Ruby 2.7 +# https://github.com/swig/swig/pull/1692 +Patch2: swig-4.0.1-Add-support-for-Ruby-2.7.patch BuildRequires: perl-interpreter, pcre-devel %if %{python2lang} @@ -169,7 +173,8 @@ in gdb. %setup -q -n swig-%{version} %patch0 -p1 -b .isystem -%patch1 -p1 -b .ruby27 +%patch1 -p1 -b .global +%patch2 -p1 -b .ruby27 for all in CHANGES README; do iconv -f ISO88591 -t UTF8 < $all > $all.new @@ -342,6 +347,10 @@ install -pm 644 Tools/swig.gdb %{buildroot}%{_datadir}/%{name}/gdb %{_datadir}/%{name}/gdb %changelog +* Thu Jan 23 2020 Jitka Plesnikova - 4.0.1-5 +- Add support for Ruby 2.7 +- Fix code generated for Ruby global variables + * Sat Jan 18 2020 Mamoru TASAKA - 4.0.1-4 - Backport upstream fixes for ruby 2.7 (as small as possible for now) diff --git a/swig308-Do-not-use-isystem.patch b/swig308-Do-not-use-isystem.patch index 48f0105..efd0312 100644 --- a/swig308-Do-not-use-isystem.patch +++ b/swig308-Do-not-use-isystem.patch @@ -1,7 +1,7 @@ diff -up swig-3.0.8/configure.ac.orig swig-3.0.8/configure.ac --- swig-3.0.8/configure.ac.orig 2016-02-02 16:01:09.094852303 +0100 +++ swig-3.0.8/configure.ac 2016-02-02 16:01:42.096702679 +0100 -@@ -131,7 +131,8 @@ AC_SUBST(BOOST_CPPFLAGS) +@@ -118,7 +118,8 @@ AC_SUBST(BOOST_CPPFLAGS) dnl How to specify include directories that may be system directories. # -I should not be used on system directories (GCC) if test "$GCC" = yes; then