Merge branch 'more_argcargv'

* more_argcargv:
  Document argc argv library
  argcargv.i cosmetic updates
  Typemaps for (int ARGC, char **ARGV) fixup
  Fix argcargv.i in Perl5, Tcl, PHP Add missing type map for type check. Add testing of argcargv.i for Perl5, Tcl, PHP and Ruby.
  Add Lua test for argcargv.i
  Add argcargv.i to more languages: Perl 5, Tcl, PHP
  Add argcargv.i to Lua
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a03ca74..6079115 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -167,7 +167,6 @@
           VER: '2.5'
         - SWIGLANG: ruby
           VER: '2.6'
-          continue-on-error: true # Sometimes fails, see https://github.com/swig/swig/issues/2115
         - SWIGLANG: ruby
           VER: '2.7'
         - SWIGLANG: ruby
diff --git a/CHANGES.current b/CHANGES.current
index 3818bdf..32ccc4f 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -13,6 +13,10 @@
 
             Document this library in Typemaps.html.
 
+2022-05-07: KrisThielemans
+            [Python] Fix "too many initializers for 'PyHeapTypeObject'" errors
+            using PyPy 3.8 and later.
+
 2022-05-04: wsfulton
             [C#] Add C# wchar_t * director typemaps
 
diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html
index 620f2e5..80e391e 100644
--- a/Doc/Manual/Varargs.html
+++ b/Doc/Manual/Varargs.html
@@ -512,7 +512,7 @@
 <pre>
 %typemap(in) (...)(char *vargs[10]) {
   int i;
-  int argc;
+  Py_ssize_t argc;
   for (i = 0; i &lt; 10; i++) vargs[i] = 0;
   argc = PyTuple_Size(varargs);
   if (argc &gt; 10) {
@@ -523,6 +523,7 @@
     PyObject *pyobj = PyTuple_GetItem(varargs, i);
     char *str = 0;
 %#if PY_VERSION_HEX&gt;=0x03000000
+    const char *strtmp = 0;
     PyObject *pystr;
     if (!PyUnicode_Check(pyobj)) {
       PyErr_SetString(PyExc_ValueError, "Expected a string");
@@ -532,7 +533,10 @@
     if (!pystr) {
       SWIG_fail;
     }
-    str = strdup(PyBytes_AsString(pystr));
+    strtmp = PyBytes_AsString(pystr);
+    str = (char *)malloc(strlen(strtmp) + 1);
+    if (str)
+      strcpy(str, strtmp);
     Py_DECREF(pystr);
 %#else  
     if (!PyString_Check(pyobj)) {
diff --git a/Examples/python/multimap/example.i b/Examples/python/multimap/example.i
index 3ff5d52..7087d42 100644
--- a/Examples/python/multimap/example.i
+++ b/Examples/python/multimap/example.i
@@ -39,12 +39,14 @@
 %#if PY_VERSION_HEX >= 0x03000000
     {
       PyObject *utf8str = PyUnicode_AsUTF8String(s);
-      const char *cstr;
+      const char *strtmp = 0;
       if (!utf8str) {
         SWIG_fail;
       }
-      cstr = PyBytes_AsString(utf8str);
-      $2[i] = strdup(cstr);
+      strtmp = PyBytes_AsString(utf8str);
+      $2[i] = (char *)malloc(strlen(strtmp) + 1);
+      if ($2[i])
+        strcpy($2[i], strtmp);
       Py_DECREF(utf8str);
     }
 %#else
diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in
index 7a34f58..43695ce 100644
--- a/Examples/test-suite/java/Makefile.in
+++ b/Examples/test-suite/java/Makefile.in
@@ -133,6 +133,7 @@
 	@if [ -d $(JAVA_PACKAGE) ]; then \
 	  rm -rf $(JAVA_PACKAGE); \
 	fi
+	@rm -f $*_runme.class
 
 clean:
 	@rm -f *.class hs_err*.log
diff --git a/Examples/test-suite/python_varargs_typemap.i b/Examples/test-suite/python_varargs_typemap.i
index d809bf1..65ce72f 100644
--- a/Examples/test-suite/python_varargs_typemap.i
+++ b/Examples/test-suite/python_varargs_typemap.i
@@ -17,21 +17,25 @@
     PyObject *pyobj = PyTuple_GetItem(varargs, i);
     char *str = 0;
 %#if PY_VERSION_HEX>=0x03000000
+    const char *strtmp = 0;
     PyObject *pystr;
     if (!PyUnicode_Check(pyobj)) {
-       PyErr_SetString(PyExc_ValueError, "Expected a string");
-       SWIG_fail;
+      PyErr_SetString(PyExc_ValueError, "Expected a string");
+      SWIG_fail;
     }
     pystr = PyUnicode_AsUTF8String(pyobj);
     if (!pystr) {
       SWIG_fail;
     }
-    str = strdup(PyBytes_AsString(pystr));
+    strtmp = PyBytes_AsString(pystr);
+    str = (char *)malloc(strlen(strtmp) + 1);
+    if (str)
+      strcpy(str, strtmp);
     Py_DECREF(pystr);
 %#else  
     if (!PyString_Check(pyobj)) {
-       PyErr_SetString(PyExc_ValueError, "Expected a string");
-       SWIG_fail;
+      PyErr_SetString(PyExc_ValueError, "Expected a string");
+      SWIG_fail;
     }
     str = PyString_AsString(pyobj);
 %#endif
diff --git a/Examples/test-suite/ruby/li_std_set_runme.rb b/Examples/test-suite/ruby/li_std_set_runme.rb
index efc163b..455a170 100644
--- a/Examples/test-suite/ruby/li_std_set_runme.rb
+++ b/Examples/test-suite/ruby/li_std_set_runme.rb
@@ -56,11 +56,15 @@
 s = LanguageSet.new
 s.insert([1,2])
 s.insert(1)
-s.insert("hello")
+# There is a reference count issue that needs fixing, see https://github.com/swig/swig/issues/2115
+# Workaround is to create hello variable containing a string and use it instead of just "hello"
+hello = "hello"
+s.insert(hello)
 #s.to_a == [1,[1,2],'hello']  # sort order: s.sort {|a,b| a.hash <=> b.hash}
 # Test above is flawed as LanguageSet sorts by each element's hash, so the order will change from one invocation to the next. Sort a conversion to array instead.
+GC.start
 sa = s.to_a.sort { |x, y| x.to_s <=> y.to_s }
-sa == [1,[1,2],'hello']
+sa == [1,[1,2],hello]
 
 EOF
 
diff --git a/Lib/java/std_wstring.i b/Lib/java/std_wstring.i
index 3e46225..efa9e63 100644
--- a/Lib/java/std_wstring.i
+++ b/Lib/java/std_wstring.i
@@ -88,9 +88,12 @@
 //%typemap(typecheck) wstring = wchar_t *;
 
 %typemap(throws) wstring
-%{ std::string message($1.begin(), $1.end());
-   SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
-   return $null; %}
+%{std::string message($1.size(), '\0');
+  for (size_t i = 0; i < $1.size(); ++i) {
+    message[i] = (char)$1[i];
+  }
+  SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
+  return $null; %}
 
 // const wstring &
 %typemap(jni) const wstring & "jstring"
@@ -166,9 +169,12 @@
 //%typemap(typecheck) const wstring & = wchar_t *;
 
 %typemap(throws) const wstring &
-%{ std::string message($1.begin(), $1.end());
-   SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
-   return $null; %}
+%{std::string message($1.size(), '\0');
+  for (size_t i = 0; i < $1.size(); ++i) {
+    message[i] = (char)$1[i];
+  }
+  SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
+  return $null; %}
 
 }
 
diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg
index 55c8e4b..5c8081a 100644
--- a/Lib/javascript/jsc/javascriptstrings.swg
+++ b/Lib/javascript/jsc/javascriptstrings.swg
@@ -75,6 +75,7 @@
 }
 
 %define %_typemap2_string(StringCode, CharCode,
+			 WarningLeakMsg,
 			 Char, CharName,
 			 SWIG_AsCharPtrAndSize,
 			 SWIG_FromCharPtrAndSize,
@@ -166,6 +167,7 @@
 
 %_typemap_string(StringCode,
                  Char,
+                 WarningLeakMsg,
                  SWIG_AsCharPtrAndSize,
                  SWIG_FromCharPtrAndSize,
                  SWIG_CharPtrLen,
diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg
index ec09223..f31fccf 100644
--- a/Lib/python/builtin.swg
+++ b/Lib/python/builtin.swg
@@ -6,7 +6,11 @@
 SwigPyObject_hash(PyObject *obj) {
   SwigPyObject *sobj = (SwigPyObject *)obj;
   void *ptr = sobj->ptr;
+#if PY_VERSION_HEX < 0x03020000
+  return (Py_hash_t)(Py_ssize_t)ptr;
+#else
   return (Py_hash_t)ptr;
+#endif
 }
 
 SWIGINTERN Py_hash_t
@@ -211,7 +215,11 @@
       sizeof(PyGetSetDescrObject),              /* tp_basicsize */
       0,                                        /* tp_itemsize */
       (destructor)SwigPyStaticVar_dealloc,      /* tp_dealloc */
-      0,                                        /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                             /* tp_print */
+#else
+      (Py_ssize_t)0,                            /* tp_vectorcall_offset */
+#endif
       0,                                        /* tp_getattr */
       0,                                        /* tp_setattr */
       0,                                        /* tp_compare */
@@ -295,7 +303,11 @@
       PyType_Type.tp_basicsize,                 /* tp_basicsize */
       0,                                        /* tp_itemsize */
       0,                                        /* tp_dealloc */
-      0,                                        /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                             /* tp_print */
+#else
+      (Py_ssize_t)0,                            /* tp_vectorcall_offset */
+#endif
       0,                                        /* tp_getattr */
       0,                                        /* tp_setattr */
       0,                                        /* tp_compare */
diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg
index 081bb2c..9358859 100644
--- a/Lib/python/pyrun.swg
+++ b/Lib/python/pyrun.swg
@@ -348,7 +348,11 @@
       sizeof(swig_varlinkobject),         /* tp_basicsize */
       0,                                  /* tp_itemsize */
       (destructor) swig_varlink_dealloc,  /* tp_dealloc */
-      0,                                  /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                       /*tp_print*/
+#else
+      (Py_ssize_t)0,                      /*tp_vectorcall_offset*/
+#endif
       (getattrfunc) swig_varlink_getattr, /* tp_getattr */
       (setattrfunc) swig_varlink_setattr, /* tp_setattr */
       0,                                  /* tp_compare */
@@ -914,7 +918,11 @@
       sizeof(SwigPyObject),                 /* tp_basicsize */
       0,                                    /* tp_itemsize */
       (destructor)SwigPyObject_dealloc,     /* tp_dealloc */
-      0,                                    /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                         /*tp_print*/
+#else
+      (Py_ssize_t)0,                        /*tp_vectorcall_offset*/
+#endif
       (getattrfunc)0,                       /* tp_getattr */
       (setattrfunc)0,                       /* tp_setattr */
 #if PY_VERSION_HEX >= 0x03000000
@@ -1090,7 +1098,11 @@
       sizeof(SwigPyPacked),                 /* tp_basicsize */
       0,                                    /* tp_itemsize */
       (destructor)SwigPyPacked_dealloc,     /* tp_dealloc */
-      0,                                    /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                         /*tp_print*/
+#else
+      (Py_ssize_t)0,                        /*tp_vectorcall_offset*/
+#endif
       (getattrfunc)0,                       /* tp_getattr */
       (setattrfunc)0,                       /* tp_setattr */
 #if PY_VERSION_HEX>=0x03000000
diff --git a/Lib/typemaps/string.swg b/Lib/typemaps/string.swg
index 4b70723..72f4aa5 100644
--- a/Lib/typemaps/string.swg
+++ b/Lib/typemaps/string.swg
@@ -30,6 +30,7 @@
 
 %include <typemaps/strings.swg>
 %typemaps_string(%checkcode(STRING), %checkcode(CHAR),
+		 SWIGWARN_TYPEMAP_CHARLEAK_MSG,
 		 char, Char, SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize,
 		 strlen, SWIG_strnlen,
 		"<limits.h>", CHAR_MIN, CHAR_MAX)
diff --git a/Lib/typemaps/strings.swg b/Lib/typemaps/strings.swg
index 87e97dd..e8ed401 100644
--- a/Lib/typemaps/strings.swg
+++ b/Lib/typemaps/strings.swg
@@ -19,6 +19,7 @@
 
 %define %_typemap_string(StringCode, 
 			 Char,
+			 WarningLeakMsg,
 			 SWIG_AsCharPtrAndSize,
 			 SWIG_FromCharPtrAndSize,
 			 SWIG_CharPtrLen,
@@ -86,7 +87,7 @@
   }
 }
 
-%typemap(varin,fragment=#SWIG_AsCharPtrAndSize,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const Char * {
+%typemap(varin,fragment=#SWIG_AsCharPtrAndSize,warning=WarningLeakMsg) const Char * {
   Char *cptr = 0; size_t csize = 0; int alloc = SWIG_NEWOBJ;
   int res = SWIG_AsCharPtrAndSize($input, &cptr, &csize, &alloc);
   if (!SWIG_IsOK(res)) {
@@ -117,7 +118,7 @@
   }
 }
 
-%typemap(memberin,noblock=1,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const Char * {
+%typemap(memberin,noblock=1,warning=WarningLeakMsg) const Char * {
   if ($input) {
     size_t size = SWIG_CharPtrLen(%reinterpret_cast(%reinterpret_cast($input, const Char *), const Char *)) + 1;
     $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
@@ -138,7 +139,7 @@
   }
 }
 
-%typemap(globalin,noblock=1,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const Char * {
+%typemap(globalin,noblock=1,warning=WarningLeakMsg) const Char * {
   if ($input) {
     size_t size = SWIG_CharPtrLen($input) + 1;
     $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
@@ -501,6 +502,7 @@
 
 #ifndef %_typemap2_string
 %define %_typemap2_string(StringCode, CharCode,
+			 WarningLeakMsg,
 			 Char, CharName,
 			 SWIG_AsCharPtrAndSize,
 			 SWIG_FromCharPtrAndSize,
@@ -591,6 +593,7 @@
 
 %_typemap_string(StringCode, 
 		 Char,
+		 WarningLeakMsg,
 		 SWIG_AsCharPtrAndSize,
 		 SWIG_FromCharPtrAndSize,
 		 SWIG_CharPtrLen,
@@ -609,6 +612,7 @@
  * ------------------------------------------------------------ */
 
 %define %typemaps_string(StringCode, CharCode,
+			 WarningLeakMsg,
 			 Char, CharName,
 			 SWIG_AsCharPtrAndSize,
 			 SWIG_FromCharPtrAndSize,
@@ -616,6 +620,7 @@
 			 SWIG_CharBufLen,
 			 FragLimits, CHAR_MIN, CHAR_MAX)
 %_typemap2_string(StringCode, CharCode,
+		  WarningLeakMsg,
 		  Char, CharName,
 		  SWIG_AsCharPtrAndSize,
 		  SWIG_FromCharPtrAndSize,
@@ -631,6 +636,7 @@
  * ------------------------------------------------------------ */
 
 %define %typemaps_string_alloc(StringCode, CharCode,
+			       WarningLeakMsg,
 			       Char, CharName,
 			       SWIG_AsCharPtrAndSize,
 			       SWIG_FromCharPtrAndSize,
@@ -640,6 +646,7 @@
 			       SWIG_DeleteCharArray,
 			       FragLimits, CHAR_MIN, CHAR_MAX)
 %_typemap2_string(StringCode, CharCode,
+		  WarningLeakMsg,
 		  Char, CharName,
 		  SWIG_AsCharPtrAndSize,
 		  SWIG_FromCharPtrAndSize,
diff --git a/Lib/typemaps/wstring.swg b/Lib/typemaps/wstring.swg
index cd409d1..d99c0bb 100644
--- a/Lib/typemaps/wstring.swg
+++ b/Lib/typemaps/wstring.swg
@@ -31,6 +31,7 @@
 
 %include <typemaps/strings.swg>
 %typemaps_string(%checkcode(UNISTRING), %checkcode(UNICHAR),
+		 SWIGWARN_TYPEMAP_WCHARLEAK_MSG,
 		 wchar_t, WChar, SWIG_AsWCharPtrAndSize, SWIG_FromWCharPtrAndSize,
 		 wcslen, SWIG_wcsnlen,
 		"<wchar.h>", WCHAR_MIN, WCHAR_MAX)
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index 7f19070..d393ad1 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -12,8 +12,8 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-#include <limits.h>		// for INT_MAX
 #include "cparse.h"
+#include <limits.h>		// for INT_MAX
 #include <ctype.h>
 
 /* Hash type used for upcalls from C/C++ */
diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx
index c30bf06..c70896a 100644
--- a/Source/Modules/guile.cxx
+++ b/Source/Modules/guile.cxx
@@ -12,7 +12,6 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-
 #include <ctype.h>
 
 // Note string broken in half for compilers that can't handle long strings
diff --git a/Source/Modules/interface.cxx b/Source/Modules/interface.cxx
index 76734dc..c0c0590 100644
--- a/Source/Modules/interface.cxx
+++ b/Source/Modules/interface.cxx
@@ -148,7 +148,7 @@
     process_interface_name(n);
     collect_interface_base_classes(n);
     List *methods = collect_interface_methods(n);
-    bool is_interface = GetFlag(n, "feature:interface");
+    bool is_interface = GetFlag(n, "feature:interface") ? true : false;
     for (Iterator mi = First(methods); mi.item; mi = Next(mi)) {
       if (!is_interface && GetFlag(mi.item, "abstract"))
 	continue;
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
index ae1e0fc..558231c 100644
--- a/Source/Modules/java.cxx
+++ b/Source/Modules/java.cxx
@@ -12,8 +12,8 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-#include <limits.h>		// for INT_MAX
 #include "cparse.h"
+#include <limits.h>		// for INT_MAX
 #include <ctype.h>
 #include "javadoc.h"
 
diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx
index 8080b93..64b6993 100644
--- a/Source/Modules/mzscheme.cxx
+++ b/Source/Modules/mzscheme.cxx
@@ -12,7 +12,6 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-
 #include <ctype.h>
 
 static const char *usage = "\
diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx
index 6e45309..97bb8cc 100644
--- a/Source/Modules/ocaml.cxx
+++ b/Source/Modules/ocaml.cxx
@@ -12,7 +12,6 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-
 #include <ctype.h>
 
 static const char *usage = "\
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 8d937e9..d61f6e4 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -13,7 +13,6 @@
  */
 
 #include "swigmod.h"
-
 #include <ctype.h>
 #include <errno.h>
 
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index cd87984..9aac916 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -12,13 +12,12 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-#include <limits.h>
 #include "cparse.h"
+#include <limits.h>
 #include <ctype.h>
 #include <errno.h>
-#include "pydoc.h"
-
 #include <stdint.h>
+#include "pydoc.h"
 
 #define PYSHADOW_MEMBER  0x2
 #define WARN_PYTHON_MULTIPLE_INH 405
@@ -4145,7 +4144,11 @@
     printSlot(f, getSlot(n, "feature:python:tp_basicsize", tp_basicsize), "tp_basicsize");
     printSlot(f, getSlot(n, "feature:python:tp_itemsize"), "tp_itemsize");
     printSlot(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor");
+    Printv(f, "#if PY_VERSION_HEX < 0x030800b4\n", NIL);
     printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc");
+    Printv(f, "#else\n", NIL);
+    printSlot(f, getSlot(n, "feature:python:tp_vectorcall_offset"), "tp_vectorcall_offset", "Py_ssize_t");
+    Printv(f, "#endif\n", NIL);
     printSlot(f, getSlot(n, "feature:python:tp_getattr"), "tp_getattr", "getattrfunc");
     printSlot(f, getSlot(n, "feature:python:tp_setattr"), "tp_setattr", "setattrfunc");
     Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx
index 1731b21..8c55364 100644
--- a/Source/Modules/scilab.cxx
+++ b/Source/Modules/scilab.cxx
@@ -11,9 +11,9 @@
  * Scilab language module for SWIG.
  * --------------------------------------------------------------------------*/
 
+#include "swigmod.h"
 #include <cstddef>
 #include <cstdlib>
-#include "swigmod.h"
 
 static const int SCILAB_IDENTIFIER_NAME_CHAR_MAX = 24;
 
diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx
index 2964ed3..0c1f87d 100644
--- a/Source/Modules/utils.cxx
+++ b/Source/Modules/utils.cxx
@@ -11,7 +11,7 @@
  * Various utility functions.
  * ----------------------------------------------------------------------------- */
 
-#include <swigmod.h>
+#include "swigmod.h"
 
 int is_public(Node *n) {
   String *access = Getattr(n, "access");