From 15e360eabd5393cdeb9aea751332e30bb66ae961bc11feeebbdde7e536e4f42c Mon Sep 17 00:00:00 2001 From: Martin Pluskal Date: Wed, 15 Apr 2020 12:46:08 +0000 Subject: [PATCH] Accepting request 794144 from home:kwk:branches:devel:tools:building - Ruby 2.7 support (cherry-picked from upstream) 0001-Fix-code-generated-for-Ruby-global-variables.patch 0002-Add-support-for-Ruby-2.7.patch 0003-Move-new-macros-for-Ruby-to-their-dedicated-namespac.patch 0004-Improve-description-of-cast-macros-for-Ruby.patch OBS-URL: https://build.opensuse.org/request/show/794144 OBS-URL: https://build.opensuse.org/package/show/devel:tools:building/swig?expand=0&rev=116 --- ...-generated-for-Ruby-global-variables.patch | 534 ++++++++++++++++++ 0002-Add-support-for-Ruby-2.7.patch | 296 ++++++++++ ...for-Ruby-to-their-dedicated-namespac.patch | 76 +++ ...-description-of-cast-macros-for-Ruby.patch | 88 +++ swig.changes | 9 + swig.spec | 12 +- 6 files changed, 1013 insertions(+), 2 deletions(-) create mode 100644 0001-Fix-code-generated-for-Ruby-global-variables.patch create mode 100644 0002-Add-support-for-Ruby-2.7.patch create mode 100644 0003-Move-new-macros-for-Ruby-to-their-dedicated-namespac.patch create mode 100644 0004-Improve-description-of-cast-macros-for-Ruby.patch diff --git a/0001-Fix-code-generated-for-Ruby-global-variables.patch b/0001-Fix-code-generated-for-Ruby-global-variables.patch new file mode 100644 index 0000000..5c0eb0c --- /dev/null +++ b/0001-Fix-code-generated-for-Ruby-global-variables.patch @@ -0,0 +1,534 @@ +From 07ed9bf365202f0d608821327948b6d92d2580e9 Mon Sep 17 00:00:00 2001 +From: Thomas Reitmayr +Date: Sun, 27 Oct 2019 21:41:03 +0100 +Subject: [PATCH 1/4] 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 3cfd1292ca2b..6939a8a18613 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 5f7792810245..008916a5618e 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 000000000000..cd8cb184bae5 +--- /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 000000000000..66eb8545d2fe +--- /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 d75cdb058714..2c59029ec0ef 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 000000000000..c40896a867f9 +--- /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 000000000000..af55cfeb3450 +--- /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 000000000000..8453254eb306 +--- /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 000000000000..fda1ccf0f00d +--- /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 000000000000..dc49cd946740 +--- /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 000000000000..cf3145e80158 +--- /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 6a1e16d5dac7..c8f582679b04 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.26.0 + diff --git a/0002-Add-support-for-Ruby-2.7.patch b/0002-Add-support-for-Ruby-2.7.patch new file mode 100644 index 0000000..d94ebdd --- /dev/null +++ b/0002-Add-support-for-Ruby-2.7.patch @@ -0,0 +1,296 @@ +From ad338d40827f9ef2cf18ba41831c671f93e401b6 Mon Sep 17 00:00:00 2001 +From: Thomas Reitmayr +Date: Mon, 30 Dec 2019 20:11:03 +0100 +Subject: [PATCH 2/4] 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 f7b51bdcc51a..b345fcebeb97 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 90f07cf68365..9a0400eea971 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 3a848191cd78..4b078deea0ee 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 b9fb249d8024..221a68193964 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 c8f582679b04..01b75befa504 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.26.0 + diff --git a/0003-Move-new-macros-for-Ruby-to-their-dedicated-namespac.patch b/0003-Move-new-macros-for-Ruby-to-their-dedicated-namespac.patch new file mode 100644 index 0000000..f024a14 --- /dev/null +++ b/0003-Move-new-macros-for-Ruby-to-their-dedicated-namespac.patch @@ -0,0 +1,76 @@ +From 04be77635ca0198c6cbefaf2793d634c315a6d20 Mon Sep 17 00:00:00 2001 +From: Thomas Reitmayr +Date: Fri, 3 Jan 2020 21:45:53 +0100 +Subject: [PATCH 3/4] Move new macros for Ruby to their dedicated namespace + +--- + Lib/ruby/rubyhead.swg | 8 ++++---- + Lib/ruby/rubytracking.swg | 8 ++++++-- + Source/Modules/ruby.cxx | 2 +- + 3 files changed, 11 insertions(+), 7 deletions(-) + +diff --git a/Lib/ruby/rubyhead.swg b/Lib/ruby/rubyhead.swg +index 9a0400eea971..89d6f1466296 100644 +--- a/Lib/ruby/rubyhead.swg ++++ b/Lib/ruby/rubyhead.swg +@@ -114,14 +114,14 @@ + # 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)) ++# define SWIG_RUBY_VOID_ANYARGS_FUNC(f) ((void (*)(ANYARGS))(f)) ++# define SWIG_RUBY_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) ++# define SWIG_RUBY_VOID_ANYARGS_FUNC(f) (f) ++# define SWIG_RUBY_INT_ANYARGS_FUNC(f) (f) + #endif + + /* Don't use for expressions have side effect */ +diff --git a/Lib/ruby/rubytracking.swg b/Lib/ruby/rubytracking.swg +index 221a68193964..1edcc56819be 100644 +--- a/Lib/ruby/rubytracking.swg ++++ b/Lib/ruby/rubytracking.swg +@@ -69,7 +69,9 @@ SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) { + swig_ruby_trackings = (st_table*)NUM2SWIG(trackings_value); + } + +- rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", VALUEFUNC(swig_ruby_trackings_count), VOID_ANYARGS_FUNC((rb_gvar_setter_t*)NULL)); ++ rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", ++ VALUEFUNC(swig_ruby_trackings_count), ++ SWIG_RUBY_VOID_ANYARGS_FUNC((rb_gvar_setter_t*)NULL)); + } + + /* Add a Tracking from a C/C++ struct to a Ruby object */ +@@ -124,7 +126,9 @@ static int swig_ruby_internal_iterate_callback(st_data_t ptr, st_data_t obj, st_ + } + + SWIGRUNTIME void SWIG_RubyIterateTrackings( void(*meth)(void* ptr, VALUE obj) ) { +- st_foreach(swig_ruby_trackings, INT_ANYARGS_FUNC(swig_ruby_internal_iterate_callback), (st_data_t)meth); ++ st_foreach(swig_ruby_trackings, ++ SWIG_RUBY_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 01b75befa504..fcbcb7a5c1ba 100644 +--- a/Source/Modules/ruby.cxx ++++ b/Source/Modules/ruby.cxx +@@ -2274,7 +2274,7 @@ public: + if (CPlusPlus) { + Insert(getfname, 0, "VALUEFUNC("); + Append(getfname, ")"); +- Insert(setfname, 0, (use_virtual_var) ? "VOID_ANYARGS_FUNC(" : "VALUEFUNC("); ++ Insert(setfname, 0, (use_virtual_var) ? "SWIG_RUBY_VOID_ANYARGS_FUNC(" : "VALUEFUNC("); + Append(setfname, ")"); + } + +-- +2.26.0 + diff --git a/0004-Improve-description-of-cast-macros-for-Ruby.patch b/0004-Improve-description-of-cast-macros-for-Ruby.patch new file mode 100644 index 0000000..25fa72e --- /dev/null +++ b/0004-Improve-description-of-cast-macros-for-Ruby.patch @@ -0,0 +1,88 @@ +From cf53e727267e1f275a413804395092d8172e480a Mon Sep 17 00:00:00 2001 +From: Thomas Reitmayr +Date: Sat, 4 Jan 2020 18:21:10 +0100 +Subject: [PATCH 4/4] Improve description of cast macros for Ruby + +The macros for casting function pointers are now fully described and also +clarify why the macros act transparently for C even before Ruby 2.7. + +In addition, an "if (CPlusPlus)" was removed in the code generator for +global variables in order to keep the distinction between C and C++ in +one place, which is at the definition of said macros. +--- + Lib/ruby/rubyhead.swg | 32 ++++++++++++++++++++++++-------- + Source/Modules/ruby.cxx | 12 +++++------- + 2 files changed, 29 insertions(+), 15 deletions(-) + +diff --git a/Lib/ruby/rubyhead.swg b/Lib/ruby/rubyhead.swg +index 89d6f1466296..bf4e36248ecb 100644 +--- a/Lib/ruby/rubyhead.swg ++++ b/Lib/ruby/rubyhead.swg +@@ -98,17 +98,33 @@ + + + /* +- * Need to be very careful about how these macros are defined, especially +- * when compiling C++ code or C code with an ANSI C compiler. ++ * The following macros are used for providing the correct type of a ++ * function pointer to the Ruby C API. ++ * Starting with Ruby 2.7 (corresponding to RB_METHOD_DEFINITION_DECL being ++ * defined) these macros act transparently due to Ruby's moving away from ++ * ANYARGS and instead employing strict function signatures. + * +- * VALUEFUNC(f) is a macro used to typecast a C function that implements +- * a Ruby method so that it can be passed as an argument to API functions +- * like rb_define_method() and rb_define_singleton_method(). ++ * Note: In case of C (not C++) the macros are transparent even before ++ * Ruby 2.7 due to the fact that the Ruby C API used function declarators ++ * with empty parentheses, which allows for an unspecified number of ++ * arguments. + * +- * VOIDFUNC(f) is a macro used to typecast a C function that implements +- * either the "mark" or "free" stuff for a Ruby Data object, so that it +- * can be passed as an argument to API functions like Data_Wrap_Struct() ++ * PROTECTFUNC(f) is used for the function pointer argument of the Ruby ++ * C API function rb_protect(). ++ * ++ * VALUEFUNC(f) is used for the function pointer argument(s) of Ruby C API ++ * functions like rb_define_method() and rb_define_singleton_method(). ++ * ++ * VOIDFUNC(f) is used to typecast a C function that implements either ++ * the "mark" or "free" stuff for a Ruby Data object, so that it can be ++ * passed as an argument to Ruby C API functions like Data_Wrap_Struct() + * and Data_Make_Struct(). ++ * ++ * SWIG_RUBY_VOID_ANYARGS_FUNC(f) is used for the function pointer ++ * argument(s) of Ruby C API functions like rb_define_virtual_variable(). ++ * ++ * SWIG_RUBY_INT_ANYARGS_FUNC(f) is used for the function pointer ++ * argument(s) of Ruby C API functions like st_foreach(). + */ + #if defined(__cplusplus) && !defined(RB_METHOD_DEFINITION_DECL) + # define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f) +diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx +index fcbcb7a5c1ba..48b0efab36cd 100644 +--- a/Source/Modules/ruby.cxx ++++ b/Source/Modules/ruby.cxx +@@ -2270,13 +2270,11 @@ public: + Delete(setname); + } + +- /* define accessor method */ +- if (CPlusPlus) { +- Insert(getfname, 0, "VALUEFUNC("); +- Append(getfname, ")"); +- Insert(setfname, 0, (use_virtual_var) ? "SWIG_RUBY_VOID_ANYARGS_FUNC(" : "VALUEFUNC("); +- Append(setfname, ")"); +- } ++ /* define accessor methods */ ++ Insert(getfname, 0, "VALUEFUNC("); ++ Append(getfname, ")"); ++ Insert(setfname, 0, (use_virtual_var) ? "SWIG_RUBY_VOID_ANYARGS_FUNC(" : "VALUEFUNC("); ++ Append(setfname, ")"); + + String *s = NewString(""); + switch (current) { +-- +2.26.0 + diff --git a/swig.changes b/swig.changes index f5d2e25..e202e7a 100644 --- a/swig.changes +++ b/swig.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Wed Apr 15 08:52:15 UTC 2020 - Klaus Kämpf + +- Ruby 2.7 support (cherry-picked from upstream) + 0001-Fix-code-generated-for-Ruby-global-variables.patch + 0002-Add-support-for-Ruby-2.7.patch + 0003-Move-new-macros-for-Ruby-to-their-dedicated-namespac.patch + 0004-Improve-description-of-cast-macros-for-Ruby.patch + ------------------------------------------------------------------- Mon Sep 9 08:17:39 UTC 2019 - Klaus Kämpf diff --git a/swig.spec b/swig.spec index faa2cd9..541f74d 100644 --- a/swig.spec +++ b/swig.spec @@ -1,7 +1,7 @@ # # spec file for package swig # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -36,7 +36,15 @@ Group: Development/Languages/C and C++ URL: http://www.swig.org/ Source: https://github.com/%{name}/%{name}/archive/rel-%{version}.tar.gz Source1: %{name}.rpmlintrc -Patch2: swig308-isfinite.diff + +# ruby 2.7 support (cherry-picked from 4.0.2~pre) +Patch1: 0001-Fix-code-generated-for-Ruby-global-variables.patch +Patch2: 0002-Add-support-for-Ruby-2.7.patch +Patch3: 0003-Move-new-macros-for-Ruby-to-their-dedicated-namespac.patch +Patch4: 0004-Improve-description-of-cast-macros-for-Ruby.patch + +Patch308: swig308-isfinite.diff + BuildRequires: autoconf BuildRequires: automake BuildRequires: bison