summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml112
-rw-r--r--.github/workflows/nuget.yml59
-rw-r--r--.gitignore9
-rw-r--r--.travis.yml499
-rw-r--r--ANNOUNCE10
-rw-r--r--CCache/ccache.yo2
-rw-r--r--CHANGES52
-rw-r--r--CHANGES.current964
-rw-r--r--CMakeLists.txt11
-rw-r--r--Doc/Devel/cmdopt.html4
-rw-r--r--Doc/Devel/engineering.html2
-rw-r--r--Doc/Devel/internals.html52
-rw-r--r--Doc/Devel/plan-gsoc-2012.txt6
-rw-r--r--Doc/Devel/scanner.html1
-rw-r--r--Doc/Devel/tree.html4
-rw-r--r--Doc/Manual/CCache.html2
-rw-r--r--Doc/Manual/CPlusPlus11.html437
-rw-r--r--Doc/Manual/CPlusPlus20.html30
-rw-r--r--Doc/Manual/CSharp.html8
-rw-r--r--Doc/Manual/Contents.html36
-rw-r--r--Doc/Manual/Customization.html2
-rw-r--r--Doc/Manual/D.html12
-rw-r--r--Doc/Manual/Doxygen.html18
-rw-r--r--Doc/Manual/Extending.html439
-rw-r--r--Doc/Manual/Go.html71
-rw-r--r--Doc/Manual/Guile.html19
-rw-r--r--Doc/Manual/Introduction.html10
-rw-r--r--Doc/Manual/Java.html44
-rw-r--r--Doc/Manual/Javascript.html26
-rw-r--r--Doc/Manual/Library.html449
-rw-r--r--Doc/Manual/Lisp.html604
-rw-r--r--Doc/Manual/Lua.html12
-rw-r--r--Doc/Manual/Makefile4
-rw-r--r--Doc/Manual/Modules.html8
-rw-r--r--Doc/Manual/Ocaml.html22
-rw-r--r--Doc/Manual/Octave.html42
-rw-r--r--Doc/Manual/Perl5.html34
-rw-r--r--Doc/Manual/Php.html157
-rw-r--r--Doc/Manual/Preface.html30
-rw-r--r--Doc/Manual/Preprocessor.html34
-rw-r--r--Doc/Manual/Python.html209
-rw-r--r--Doc/Manual/R.html6
-rw-r--r--Doc/Manual/Ruby.html2
-rw-r--r--Doc/Manual/SWIG.html188
-rw-r--r--Doc/Manual/SWIGPlus.html245
-rw-r--r--Doc/Manual/Scilab.html19
-rw-r--r--Doc/Manual/Tcl.html49
-rw-r--r--Doc/Manual/Typemaps.html125
-rw-r--r--Doc/Manual/Varargs.html10
-rw-r--r--Doc/Manual/Warnings.html13
-rw-r--r--Doc/Manual/Windows.html137
-rw-r--r--Doc/Manual/makechap.py10
-rw-r--r--Doc/Manual/maketoc.py14
-rw-r--r--Examples/Makefile.in1312
-rw-r--r--Examples/go/check.list1
-rw-r--r--Examples/go/goin/Makefile18
-rw-r--r--Examples/go/goin/example.i106
-rw-r--r--Examples/go/goin/index.html26
-rw-r--r--Examples/go/goin/runme.go38
-rw-r--r--Examples/go/index.html3
-rw-r--r--Examples/guile/multimap/example.i2
-rw-r--r--Examples/java/index.html2
-rw-r--r--Examples/javascript/exception/runme.js12
-rw-r--r--Examples/javascript/nspace/example.h4
-rw-r--r--Examples/lua/arrays/example.i4
-rw-r--r--Examples/lua/constants/runme.lua2
-rw-r--r--Examples/lua/embed/embed.c2
-rw-r--r--Examples/lua/embed2/embed2.c10
-rw-r--r--Examples/lua/embed3/embed3.cpp4
-rw-r--r--Examples/lua/nspace/example.h4
-rw-r--r--Examples/octave/module_load/runme.m12
-rw-r--r--Examples/octave/operator/@swig_ref/horzcat.m9
-rw-r--r--Examples/octave/operator/runme.m7
-rw-r--r--Examples/perl5/index.html2
-rw-r--r--Examples/perl5/multimap/example.i2
-rw-r--r--Examples/php/disown/example.cxx1
-rw-r--r--Examples/php/extend/runme.php2
-rw-r--r--Examples/python/import/runme.py8
-rw-r--r--Examples/python/import_packages/from_init1/Makefile2
-rw-r--r--Examples/python/import_packages/from_init1/runme.py2
-rw-r--r--Examples/python/import_packages/from_init2/Makefile2
-rw-r--r--Examples/python/import_packages/from_init2/runme.py2
-rw-r--r--Examples/python/import_packages/from_init3/Makefile2
-rw-r--r--Examples/python/import_packages/from_init3/runme.py2
-rw-r--r--Examples/python/import_packages/module_is_init/runme.py8
-rw-r--r--Examples/python/import_packages/namespace_pkg/nonpkg.py2
-rw-r--r--Examples/python/import_packages/namespace_pkg/normal.py2
-rw-r--r--Examples/python/import_packages/namespace_pkg/nstest.py2
-rw-r--r--Examples/python/import_packages/namespace_pkg/split.py2
-rw-r--r--Examples/python/import_packages/namespace_pkg/zipsplit.py2
-rw-r--r--Examples/python/import_packages/relativeimport1/Makefile2
-rw-r--r--Examples/python/import_packages/relativeimport1/runme.py2
-rw-r--r--Examples/python/import_packages/relativeimport2/Makefile2
-rw-r--r--Examples/python/import_packages/relativeimport2/runme.py2
-rw-r--r--Examples/python/import_packages/relativeimport3/Makefile2
-rw-r--r--Examples/python/import_packages/relativeimport3/runme.py2
-rw-r--r--Examples/python/import_packages/same_modnames1/runme.py2
-rw-r--r--Examples/python/import_packages/same_modnames2/runme.py2
-rw-r--r--Examples/python/import_packages/split_modules/README2
-rw-r--r--Examples/python/import_packages/split_modules/vanilla/runme.py4
-rw-r--r--Examples/python/import_packages/split_modules/vanilla_split/runme.py4
-rw-r--r--Examples/python/import_template/runme.py8
-rw-r--r--Examples/python/index.html4
-rw-r--r--Examples/python/multimap/example.i8
-rw-r--r--Examples/python/variables/runme.py4
-rw-r--r--Examples/ruby/exceptproxy/example.i2
-rw-r--r--Examples/ruby/free_function/example.h6
-rw-r--r--Examples/ruby/index.html2
-rw-r--r--Examples/ruby/mark_function/example.h6
-rw-r--r--Examples/tcl/index.html2
-rw-r--r--Examples/tcl/multimap/example.i2
-rw-r--r--Examples/test-suite/abstract_basecast.i20
-rw-r--r--Examples/test-suite/abstract_signature.i8
-rw-r--r--Examples/test-suite/aggregate.i2
-rw-r--r--Examples/test-suite/apply_signed_char.i2
-rw-r--r--Examples/test-suite/argcargvtest.i2
-rw-r--r--Examples/test-suite/autodoc.i8
-rw-r--r--Examples/test-suite/bools.i2
-rw-r--r--Examples/test-suite/callback.i10
-rw-r--r--Examples/test-suite/catches_strings.i17
-rw-r--r--Examples/test-suite/cffi/Makefile.in51
-rw-r--r--Examples/test-suite/char_strings.i5
-rw-r--r--Examples/test-suite/class_case.i18
-rw-r--r--Examples/test-suite/class_scope_namespace.i1
-rw-r--r--Examples/test-suite/clientdata_prop_a.h6
-rw-r--r--Examples/test-suite/command_line_define.i7
-rw-r--r--Examples/test-suite/common.mk110
-rw-r--r--Examples/test-suite/constant_expr.i36
-rw-r--r--Examples/test-suite/constant_expr_c.i56
-rw-r--r--Examples/test-suite/constant_pointers.i6
-rw-r--r--Examples/test-suite/contract.i3
-rw-r--r--Examples/test-suite/contract_c.i5
-rw-r--r--Examples/test-suite/cpp11_alternate_function_syntax.i6
-rw-r--r--Examples/test-suite/cpp11_attribute_specifiers.i54
-rw-r--r--Examples/test-suite/cpp11_constexpr.i9
-rw-r--r--Examples/test-suite/cpp11_final_class.i141
-rw-r--r--Examples/test-suite/cpp11_final_override.i2
-rw-r--r--Examples/test-suite/cpp11_initializer_list.i2
-rw-r--r--Examples/test-suite/cpp11_move_only.i61
-rw-r--r--Examples/test-suite/cpp11_move_only_helper.i71
-rw-r--r--Examples/test-suite/cpp11_move_only_valuewrapper.i180
-rw-r--r--Examples/test-suite/cpp11_move_typemaps.i12
-rw-r--r--Examples/test-suite/cpp11_raw_string_literals.i9
-rw-r--r--Examples/test-suite/cpp11_result_of.i35
-rw-r--r--Examples/test-suite/cpp11_rvalue_reference2.i10
-rw-r--r--Examples/test-suite/cpp11_rvalue_reference_move.i52
-rw-r--r--Examples/test-suite/cpp11_std_array.i2
-rw-r--r--Examples/test-suite/cpp11_std_unique_ptr.i107
-rw-r--r--Examples/test-suite/cpp11_template_explicit.i28
-rw-r--r--Examples/test-suite/cpp11_thread_local.i6
-rw-r--r--Examples/test-suite/cpp11_type_traits.i2
-rw-r--r--Examples/test-suite/cpp11_userdefined_literals.i7
-rw-r--r--Examples/test-suite/cpp14_binary_integer_literals.i28
-rw-r--r--Examples/test-suite/cpp17_hex_floating_literals.i32
-rw-r--r--Examples/test-suite/cpp17_nested_namespaces.i118
-rw-r--r--Examples/test-suite/cpp17_u8_char_literals.i23
-rw-r--r--Examples/test-suite/cpp20_lambda_template.i12
-rw-r--r--Examples/test-suite/cpp20_spaceship_operator.i28
-rw-r--r--Examples/test-suite/cpp_basic.i13
-rw-r--r--Examples/test-suite/cpp_typedef.i3
-rw-r--r--Examples/test-suite/csharp/Makefile.in5
-rw-r--r--Examples/test-suite/csharp/catches_strings_runme.cs32
-rw-r--r--Examples/test-suite/csharp/cpp11_move_only_runme.cs34
-rw-r--r--Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs33
-rw-r--r--Examples/test-suite/csharp/cpp11_move_typemaps_runme.cs37
-rw-r--r--Examples/test-suite/csharp/cpp11_rvalue_reference_move_runme.cs86
-rw-r--r--Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs131
-rw-r--r--Examples/test-suite/csharp/csharp_typemaps_runme.cs16
-rw-r--r--Examples/test-suite/csharp/director_basic_runme.cs2
-rw-r--r--Examples/test-suite/csharp/director_classes_runme.cs2
-rw-r--r--Examples/test-suite/csharp/director_default_runme.cs58
-rw-r--r--Examples/test-suite/csharp/director_pass_by_value_runme.cs2
-rw-r--r--Examples/test-suite/csharp/director_property_runme.cs64
-rw-r--r--Examples/test-suite/csharp/director_using_member_scopes_runme.cs70
-rw-r--r--Examples/test-suite/csharp/director_wstring_runme.cs56
-rw-r--r--Examples/test-suite/csharp/friends_runme.cs2
-rw-r--r--Examples/test-suite/csharp/li_std_auto_ptr_runme.cs135
-rw-r--r--Examples/test-suite/csharp/li_std_wstring_runme.cs90
-rw-r--r--Examples/test-suite/csharp/multiple_inheritance_interfaces_runme.cs2
-rw-r--r--Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs58
-rw-r--r--Examples/test-suite/csharp/preproc_constants_c_runme.cs2
-rw-r--r--Examples/test-suite/csharp/preproc_constants_runme.cs2
-rw-r--r--Examples/test-suite/csharp/typemap_out_optimal_runme.cs10
-rw-r--r--Examples/test-suite/csharp_typemaps.i39
-rw-r--r--Examples/test-suite/d/Makefile.in4
-rw-r--r--Examples/test-suite/d/catches_strings_runme.1.d32
-rw-r--r--Examples/test-suite/d/catches_strings_runme.2.d32
-rw-r--r--Examples/test-suite/d/cpp11_move_typemaps_runme.1.d42
-rw-r--r--Examples/test-suite/d/cpp11_move_typemaps_runme.2.d42
-rw-r--r--Examples/test-suite/d/cpp11_rvalue_reference_move_runme.1.d86
-rw-r--r--Examples/test-suite/d/cpp11_rvalue_reference_move_runme.2.d87
-rw-r--r--Examples/test-suite/d/cpp11_std_unique_ptr_runme.1.d123
-rw-r--r--Examples/test-suite/d/cpp11_std_unique_ptr_runme.2.d123
-rw-r--r--Examples/test-suite/d/li_std_auto_ptr_runme.1.d123
-rw-r--r--Examples/test-suite/d/li_std_auto_ptr_runme.2.d123
-rw-r--r--Examples/test-suite/d/preproc_constants_c_runme.1.d2
-rw-r--r--Examples/test-suite/d/preproc_constants_c_runme.2.d2
-rw-r--r--Examples/test-suite/d/preproc_constants_runme.1.d2
-rw-r--r--Examples/test-suite/d/preproc_constants_runme.2.d2
-rw-r--r--Examples/test-suite/d/typemap_out_optimal_runme.1.d1
-rw-r--r--Examples/test-suite/d/typemap_out_optimal_runme.2.d1
-rw-r--r--Examples/test-suite/default_arg_expressions.i39
-rw-r--r--Examples/test-suite/default_args.i61
-rw-r--r--Examples/test-suite/derived_byvalue.i2
-rw-r--r--Examples/test-suite/director_basic.i5
-rw-r--r--Examples/test-suite/director_binary_string.i1
-rw-r--r--Examples/test-suite/director_exception.i2
-rw-r--r--Examples/test-suite/director_multiple_inheritance.i71
-rw-r--r--Examples/test-suite/director_overload2.i5
-rw-r--r--Examples/test-suite/director_pass_by_value.i37
-rw-r--r--Examples/test-suite/director_property.i4
-rw-r--r--Examples/test-suite/director_simple.i42
-rw-r--r--Examples/test-suite/director_template.i28
-rw-r--r--Examples/test-suite/director_thread.i8
-rw-r--r--Examples/test-suite/director_unwrap_result.i93
-rw-r--r--Examples/test-suite/director_using_member_scopes.i55
-rw-r--r--Examples/test-suite/director_wstring.i9
-rw-r--r--Examples/test-suite/doxygen_autodoc_docstring.i75
-rw-r--r--Examples/test-suite/doxygen_parsing.i9
-rw-r--r--Examples/test-suite/doxygen_translate.i1
-rw-r--r--Examples/test-suite/duplicate_class_name_in_ns.i88
-rw-r--r--Examples/test-suite/enum_thorough.i2
-rw-r--r--Examples/test-suite/equality.i3
-rw-r--r--Examples/test-suite/errors/Makefile.in4
-rw-r--r--Examples/test-suite/errors/c_extra_rbrace.stderr2
-rw-r--r--Examples/test-suite/errors/c_missing_semi.stderr2
-rw-r--r--Examples/test-suite/errors/c_spaceship.i3
-rw-r--r--Examples/test-suite/errors/c_spaceship.stderr1
-rw-r--r--Examples/test-suite/errors/cpp_extra_brackets.stderr2
-rw-r--r--Examples/test-suite/errors/cpp_namewarn.i10
-rw-r--r--Examples/test-suite/errors/cpp_namewarn.stderr2
-rw-r--r--Examples/test-suite/errors/cpp_pp_expressions_bad.i6
-rw-r--r--Examples/test-suite/errors/cpp_pp_expressions_bad.stderr2
-rw-r--r--Examples/test-suite/errors/cpp_template_explicit_instantiation.i24
-rw-r--r--Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr4
-rw-r--r--Examples/test-suite/errors/cpp_typemap_out_optimal_bug.i45
-rw-r--r--Examples/test-suite/errors/cpp_typemap_out_optimal_bug.stderr4
-rw-r--r--Examples/test-suite/errors/cpp_using_declaration_overload.i9
-rw-r--r--Examples/test-suite/errors/cpp_using_declaration_overload.stderr2
-rw-r--r--Examples/test-suite/errors/cpp_using_rename.i22
-rw-r--r--Examples/test-suite/errors/cpp_using_rename.stderr7
-rw-r--r--Examples/test-suite/errors/doxygen_unclosed_tag.i6
-rw-r--r--Examples/test-suite/errors/doxygen_unclosed_tag.stderr1
-rw-r--r--Examples/test-suite/errors/pp_badeval.stderr2
-rw-r--r--Examples/test-suite/errors/pp_expressions_bad.i33
-rw-r--r--Examples/test-suite/errors/pp_expressions_bad.stderr30
-rw-r--r--Examples/test-suite/errors/pp_invalid_exponents.stderr4
-rw-r--r--Examples/test-suite/errors/pp_unknowndirective.i5
-rw-r--r--Examples/test-suite/errors/pp_unknowndirective.stderr2
-rw-r--r--Examples/test-suite/errors/pp_unknowndirective4.i7
-rw-r--r--Examples/test-suite/errors/pp_unknowndirective4.stderr1
-rw-r--r--Examples/test-suite/errors/pp_unknowndirective5.i20
-rw-r--r--Examples/test-suite/errors/pp_unknowndirective5.stderr1
-rw-r--r--Examples/test-suite/errors/swig_command_encoder.i6
-rw-r--r--Examples/test-suite/errors/swig_command_encoder.stderr1
-rw-r--r--Examples/test-suite/errors/swig_constant_missing_semi.i3
-rw-r--r--Examples/test-suite/errors/swig_constant_missing_semi.stderr1
-rw-r--r--Examples/test-suite/errors/swig_typemap_missing_value.i7
-rw-r--r--Examples/test-suite/errors/swig_typemap_missing_value.stderr2
-rw-r--r--Examples/test-suite/exception_memory_leak.i62
-rw-r--r--Examples/test-suite/extern_c.i10
-rw-r--r--Examples/test-suite/final_c.i13
-rw-r--r--Examples/test-suite/fragments.i106
-rw-r--r--Examples/test-suite/global_immutable_vars.i2
-rw-r--r--Examples/test-suite/global_immutable_vars_cpp.i2
-rw-r--r--Examples/test-suite/go/Makefile.in53
-rw-r--r--Examples/test-suite/go/catches_strings_runme.go32
-rw-r--r--Examples/test-suite/go/class_case_runme.go12
-rw-r--r--Examples/test-suite/go/cpp11_std_array_runme.go68
-rw-r--r--Examples/test-suite/go/friends_runme.go8
-rw-r--r--Examples/test-suite/go/go_director_inout_runme.go46
-rw-r--r--Examples/test-suite/go/go_inout_runme.go8
-rw-r--r--Examples/test-suite/go/smart_pointer_extend_runme.go4
-rw-r--r--Examples/test-suite/go/typemap_out_optimal_runme.go3
-rw-r--r--Examples/test-suite/go_director_inout.i125
-rw-r--r--Examples/test-suite/go_inout.i42
-rw-r--r--Examples/test-suite/go_subdir_import_a.i2
-rw-r--r--Examples/test-suite/guile/Makefile.in4
-rw-r--r--Examples/test-suite/guile/catches_strings_runme.scm3
-rw-r--r--Examples/test-suite/guile/cpp11_move_typemaps_runme.scm3
-rw-r--r--Examples/test-suite/guile/cpp11_rvalue_reference_move_runme.scm3
-rw-r--r--Examples/test-suite/guile/cpp11_std_unique_ptr_runme.scm3
-rw-r--r--Examples/test-suite/guile/guile_ext_test_external.cxx2
-rw-r--r--Examples/test-suite/guile/li_std_auto_ptr_runme.scm3
-rw-r--r--Examples/test-suite/guile/newobject1_runme.scm3
-rw-r--r--Examples/test-suite/guile/null_pointer_runme.scm3
-rw-r--r--Examples/test-suite/ignore_parameter.i18
-rw-r--r--Examples/test-suite/import_nomodule.i4
-rw-r--r--Examples/test-suite/integers.i35
-rw-r--r--Examples/test-suite/java/Makefile.in5
-rw-r--r--Examples/test-suite/java/catches_strings_runme.java41
-rw-r--r--Examples/test-suite/java/cpp11_move_only_runme.java51
-rw-r--r--Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java44
-rw-r--r--Examples/test-suite/java/cpp11_move_typemaps_runme.java51
-rw-r--r--Examples/test-suite/java/cpp11_rvalue_reference_move_runme.java97
-rw-r--r--Examples/test-suite/java/cpp11_std_unique_ptr_runme.java146
-rw-r--r--Examples/test-suite/java/director_classes_runme.java2
-rw-r--r--Examples/test-suite/java/director_default_runme.java31
-rw-r--r--Examples/test-suite/java/director_pass_by_value_runme.java2
-rw-r--r--Examples/test-suite/java/director_property_runme.java66
-rw-r--r--Examples/test-suite/java/director_using_member_scopes_runme.java64
-rw-r--r--Examples/test-suite/java/doxygen_parsing_runme.java8
-rw-r--r--Examples/test-suite/java/doxygen_translate_all_tags_runme.java2
-rw-r--r--Examples/test-suite/java/doxygen_translate_runme.java3
-rw-r--r--Examples/test-suite/java/friends_runme.java2
-rw-r--r--Examples/test-suite/java/java_typemaps_proxy_runme.java9
-rw-r--r--Examples/test-suite/java/li_std_auto_ptr_runme.java138
-rw-r--r--Examples/test-suite/java/multiple_inheritance_interfaces_runme.java12
-rw-r--r--Examples/test-suite/java/multiple_inheritance_overload_runme.java65
-rw-r--r--Examples/test-suite/java/typemap_out_optimal_runme.java12
-rw-r--r--Examples/test-suite/java_director_exception_feature.i2
-rw-r--r--Examples/test-suite/java_director_exception_feature_nspace.i2
-rw-r--r--Examples/test-suite/java_throws.i33
-rw-r--r--Examples/test-suite/java_typemaps_proxy.i33
-rw-r--r--Examples/test-suite/java_typemaps_typewrapper.i8
-rw-r--r--Examples/test-suite/javascript/Makefile.in10
-rw-r--r--Examples/test-suite/javascript/catches_strings_runme.js23
-rw-r--r--Examples/test-suite/javascript/cpp11_move_typemaps_runme.js30
-rw-r--r--Examples/test-suite/javascript/cpp11_rvalue_reference_move_runme.js87
-rw-r--r--Examples/test-suite/javascript/cpp11_std_unique_ptr_runme.js129
-rw-r--r--Examples/test-suite/javascript/li_std_auto_ptr_runme.js130
-rw-r--r--Examples/test-suite/javascript/voidtest_runme.js28
-rw-r--r--Examples/test-suite/kwargs_feature.i6
-rw-r--r--Examples/test-suite/li_boost_shared_ptr.i4
-rw-r--r--Examples/test-suite/li_cdata.i4
-rw-r--r--Examples/test-suite/li_cdata_cpp.i4
-rw-r--r--Examples/test-suite/li_factory.i23
-rw-r--r--Examples/test-suite/li_std_auto_ptr.i79
-rw-r--r--Examples/test-suite/li_std_except.i2
-rw-r--r--Examples/test-suite/li_std_vector.i10
-rw-r--r--Examples/test-suite/li_std_wstring.h5
-rw-r--r--Examples/test-suite/li_std_wstring.i83
-rw-r--r--Examples/test-suite/lua/Makefile.in6
-rw-r--r--Examples/test-suite/lua/argcargvtest_runme.lua26
-rw-r--r--Examples/test-suite/lua/catches_strings_runme.lua13
-rw-r--r--Examples/test-suite/lua/cpp11_move_typemaps_runme.lua28
-rw-r--r--Examples/test-suite/lua/cpp11_rvalue_reference_move_runme.lua66
-rw-r--r--Examples/test-suite/lua/cpp11_std_unique_ptr_runme.lua112
-rw-r--r--Examples/test-suite/lua/exception_memory_leak_runme.lua29
-rw-r--r--Examples/test-suite/lua/li_std_auto_ptr_runme.lua112
-rw-r--r--Examples/test-suite/lua/li_std_string_runme.lua2
-rw-r--r--Examples/test-suite/memberin_extend.i1
-rw-r--r--Examples/test-suite/minherit2.i20
-rw-r--r--Examples/test-suite/mod.h2
-rw-r--r--Examples/test-suite/multi_import.h10
-rw-r--r--Examples/test-suite/multi_import.list3
-rw-r--r--Examples/test-suite/multi_import_a.i7
-rw-r--r--Examples/test-suite/multi_import_b.i4
-rw-r--r--Examples/test-suite/multi_import_c.i5
-rw-r--r--Examples/test-suite/multi_import_d.i12
-rw-r--r--Examples/test-suite/multiple_inheritance_abstract.i3
-rw-r--r--Examples/test-suite/multiple_inheritance_interfaces.i29
-rw-r--r--Examples/test-suite/multiple_inheritance_nspace.i2
-rw-r--r--Examples/test-suite/multiple_inheritance_overload.i67
-rw-r--r--Examples/test-suite/multiple_inheritance_shared_ptr.i2
-rw-r--r--Examples/test-suite/mzscheme/Makefile.in9
-rw-r--r--Examples/test-suite/mzscheme/catches_strings_runme.scm18
-rw-r--r--Examples/test-suite/mzscheme/cpp11_move_typemaps_runme.scm35
-rw-r--r--Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_runme.scm68
-rw-r--r--Examples/test-suite/mzscheme/cpp11_std_unique_ptr_runme.scm109
-rw-r--r--Examples/test-suite/mzscheme/integers_runme.scm2
-rw-r--r--Examples/test-suite/mzscheme/li_std_auto_ptr_runme.scm109
-rw-r--r--Examples/test-suite/mzscheme/newobject1_runme.scm9
-rw-r--r--Examples/test-suite/mzscheme/null_pointer_runme.scm3
-rw-r--r--Examples/test-suite/name_warnings.i17
-rw-r--r--Examples/test-suite/namespace_struct.i8
-rw-r--r--Examples/test-suite/namespace_typemap.i3
-rw-r--r--Examples/test-suite/nested_class.i11
-rw-r--r--Examples/test-suite/nested_extend_c.i4
-rw-r--r--Examples/test-suite/nested_inheritance_interface.i2
-rw-r--r--Examples/test-suite/ocaml/Makefile.in13
-rw-r--r--Examples/test-suite/ocaml/catches_strings_runme.ml14
-rw-r--r--Examples/test-suite/ocaml/director_pass_by_value_runme.ml3
-rw-r--r--Examples/test-suite/ocaml/enum_rename_runme.ml10
-rw-r--r--Examples/test-suite/octave/Makefile.in4
-rw-r--r--Examples/test-suite/octave/catches_strings_runme.m32
-rw-r--r--Examples/test-suite/octave/cpp11_move_typemaps_runme.m37
-rw-r--r--Examples/test-suite/octave/cpp11_rvalue_reference_move_runme.m85
-rw-r--r--Examples/test-suite/octave/cpp11_std_unique_ptr_runme.m138
-rw-r--r--Examples/test-suite/octave/friends_runme.m2
-rw-r--r--Examples/test-suite/octave/li_std_auto_ptr_runme.m138
-rw-r--r--Examples/test-suite/octave/null_pointer_runme.m10
-rw-r--r--Examples/test-suite/operator_overload.i4
-rw-r--r--Examples/test-suite/operator_overload_break.i1
-rw-r--r--Examples/test-suite/operator_pointer_ref.i2
-rw-r--r--Examples/test-suite/overload_extend.i2
-rw-r--r--Examples/test-suite/overload_extend2.i2
-rw-r--r--Examples/test-suite/perl5/Makefile.in4
-rw-r--r--Examples/test-suite/perl5/argcargvtest_runme.pl20
-rw-r--r--Examples/test-suite/perl5/catches_strings_runme.pl15
-rw-r--r--Examples/test-suite/perl5/cpp11_move_typemaps_runme.pl34
-rw-r--r--Examples/test-suite/perl5/cpp11_rvalue_reference_move_runme.pl70
-rw-r--r--Examples/test-suite/perl5/cpp11_std_unique_ptr_runme.pl100
-rw-r--r--Examples/test-suite/perl5/li_std_auto_ptr_runme.pl100
-rw-r--r--Examples/test-suite/perl5/operator_overload_break_runme.pl11
-rw-r--r--Examples/test-suite/perl5/operator_overload_runme.pl29
-rw-r--r--Examples/test-suite/perl5/packageoption_runme.pl9
-rw-r--r--Examples/test-suite/php/Makefile.in18
-rw-r--r--Examples/test-suite/php/abstract_inherit_ok_runme.php17
-rw-r--r--Examples/test-suite/php/abstract_inherit_runme.php15
-rw-r--r--Examples/test-suite/php/argcargvtest_runme.php29
-rw-r--r--Examples/test-suite/php/argout_runme.php13
-rw-r--r--Examples/test-suite/php/arrays_scope_runme.php4
-rw-r--r--Examples/test-suite/php/catches_strings_runme.php23
-rw-r--r--Examples/test-suite/php/cpp11_attribute_specifiers_runme.php14
-rw-r--r--Examples/test-suite/php/cpp11_final_directors_runme.php16
-rw-r--r--Examples/test-suite/php/cpp11_move_typemaps_runme.php32
-rw-r--r--Examples/test-suite/php/cpp11_rvalue_reference_move_runme.php80
-rw-r--r--Examples/test-suite/php/cpp11_std_unique_ptr_runme.php108
-rw-r--r--Examples/test-suite/php/cpp11_strongly_typed_enumerations_runme.php2
-rw-r--r--Examples/test-suite/php/cpp20_spaceship_operator_runme.php23
-rw-r--r--Examples/test-suite/php/cpp_basic_runme.php4
-rw-r--r--Examples/test-suite/php/cpp_static_runme.php4
-rw-r--r--Examples/test-suite/php/default_args_runme.php161
-rw-r--r--Examples/test-suite/php/director_abstract_runme.php6
-rw-r--r--Examples/test-suite/php/director_alternating_runme.php11
-rw-r--r--Examples/test-suite/php/director_classes_runme.php114
-rw-r--r--Examples/test-suite/php/director_detect_runme.php2
-rw-r--r--Examples/test-suite/php/director_exception_catches_runme.php26
-rw-r--r--Examples/test-suite/php/director_exception_nothrow_runme.php23
-rw-r--r--Examples/test-suite/php/director_exception_runme.php4
-rw-r--r--Examples/test-suite/php/director_extend_runme.php2
-rw-r--r--Examples/test-suite/php/director_ignore_runme.php24
-rw-r--r--Examples/test-suite/php/director_ownership_runme.php28
-rw-r--r--Examples/test-suite/php/director_pass_by_value_runme.php3
-rw-r--r--Examples/test-suite/php/director_stl_runme.php2
-rw-r--r--Examples/test-suite/php/director_string_runme.php2
-rw-r--r--Examples/test-suite/php/director_wombat_runme.php52
-rw-r--r--Examples/test-suite/php/exception_memory_leak_runme.php35
-rw-r--r--Examples/test-suite/php/exception_order_runme.php6
-rw-r--r--Examples/test-suite/php/friends_runme.php37
-rw-r--r--Examples/test-suite/php/ignore_parameter_runme.php4
-rw-r--r--Examples/test-suite/php/import_nomodule_runme.php3
-rw-r--r--Examples/test-suite/php/li_factory_runme.php3
-rw-r--r--Examples/test-suite/php/li_std_auto_ptr_runme.php108
-rw-r--r--Examples/test-suite/php/long_long_runme.php65
-rw-r--r--Examples/test-suite/php/member_pointer_const_runme.php2
-rw-r--r--Examples/test-suite/php/newobject1_runme.php7
-rw-r--r--Examples/test-suite/php/newobject2_runme.php17
-rw-r--r--Examples/test-suite/php/newobject3_runme.php2
-rw-r--r--Examples/test-suite/php/overload_bool_runme.php42
-rw-r--r--Examples/test-suite/php/overload_complicated_runme.php39
-rw-r--r--Examples/test-suite/php/overload_copy_runme.php13
-rw-r--r--Examples/test-suite/php/overload_extend2_runme.php16
-rw-r--r--Examples/test-suite/php/overload_extend_c_runme.php11
-rw-r--r--Examples/test-suite/php/overload_extend_runme.php11
-rw-r--r--Examples/test-suite/php/overload_return_type_runme.php2
-rw-r--r--Examples/test-suite/php/overload_simple_runme.php195
-rw-r--r--Examples/test-suite/php/overload_subtype_runme.php11
-rw-r--r--Examples/test-suite/php/overload_template_fast_runme.php110
-rw-r--r--Examples/test-suite/php/overload_template_runme.php110
-rw-r--r--Examples/test-suite/php/php_pragma_runme.php7
-rw-r--r--Examples/test-suite/php/prefix_runme.php8
-rw-r--r--Examples/test-suite/php/preproc_constants_c_runme.php4
-rw-r--r--Examples/test-suite/php/preproc_constants_runme.php2
-rw-r--r--Examples/test-suite/php/rename_camel_runme.php13
-rw-r--r--Examples/test-suite/php/swig_exception_runme.php2
-rw-r--r--Examples/test-suite/php/tests.php54
-rw-r--r--Examples/test-suite/php/threads_exception_runme.php6
-rw-r--r--Examples/test-suite/php/virtual_vs_nonvirtual_base_runme.php4
-rw-r--r--Examples/test-suite/php_iterator.i2
-rw-r--r--Examples/test-suite/php_namewarn_rename.i14
-rw-r--r--Examples/test-suite/prefix.i10
-rw-r--r--Examples/test-suite/preproc.i102
-rw-r--r--Examples/test-suite/preproc_constants.i8
-rw-r--r--Examples/test-suite/preproc_cpp.i36
-rw-r--r--Examples/test-suite/preproc_defined.i2
-rw-r--r--Examples/test-suite/preproc_expr.i34
-rw-r--r--Examples/test-suite/preproc_predefined.h27
-rw-r--r--Examples/test-suite/preproc_predefined.i62
-rw-r--r--Examples/test-suite/python/Makefile.in26
-rw-r--r--Examples/test-suite/python/README9
-rw-r--r--Examples/test-suite/python/abstract_basecast_runme.py15
-rw-r--r--Examples/test-suite/python/autodoc_runme.py68
-rw-r--r--Examples/test-suite/python/callback_runme.py12
-rw-r--r--Examples/test-suite/python/catches_strings_runme.py21
-rw-r--r--Examples/test-suite/python/contract_runme.py6
-rw-r--r--Examples/test-suite/python/cpp11_final_class_runme.py65
-rw-r--r--Examples/test-suite/python/cpp11_move_only_runme.py27
-rw-r--r--Examples/test-suite/python/cpp11_move_typemaps_runme.py29
-rw-r--r--Examples/test-suite/python/cpp11_rvalue_reference_move_runme.py69
-rw-r--r--Examples/test-suite/python/cpp11_rvalue_reference_runme.py10
-rw-r--r--Examples/test-suite/python/cpp11_std_unique_ptr_runme.py109
-rw-r--r--Examples/test-suite/python/cpp11_template_explicit_runme.py15
-rw-r--r--Examples/test-suite/python/cpp14_binary_integer_literals_runme.py9
-rw-r--r--Examples/test-suite/python/cpp20_spaceship_operator_runme.py19
-rw-r--r--Examples/test-suite/python/default_args_runme.py2
-rw-r--r--Examples/test-suite/python/director_abstract_runme.py2
-rw-r--r--Examples/test-suite/python/director_basic_runme.py8
-rw-r--r--Examples/test-suite/python/director_multiple_inheritance_runme.py36
-rw-r--r--Examples/test-suite/python/director_nested_runme.py2
-rw-r--r--Examples/test-suite/python/director_pass_by_value_runme.py2
-rw-r--r--Examples/test-suite/python/director_property_runme.py37
-rw-r--r--Examples/test-suite/python/director_wstring_runme.py16
-rw-r--r--Examples/test-suite/python/doxygen_autodoc_docstring_runme.py44
-rw-r--r--Examples/test-suite/python/doxygen_translate_runme.py1
-rw-r--r--Examples/test-suite/python/extern_c_runme.py7
-rw-r--r--Examples/test-suite/python/final_c_runme.py6
-rw-r--r--Examples/test-suite/python/friends_runme.py2
-rw-r--r--Examples/test-suite/python/ignore_parameter_runme.py1
-rw-r--r--Examples/test-suite/python/kwargs_feature_runme.py11
-rw-r--r--Examples/test-suite/python/li_boost_shared_ptr_director_runme.py42
-rw-r--r--Examples/test-suite/python/li_boost_shared_ptr_runme.py15
-rw-r--r--Examples/test-suite/python/li_factory_runme.py4
-rw-r--r--Examples/test-suite/python/li_std_auto_ptr_runme.py104
-rw-r--r--Examples/test-suite/python/li_std_string_extra_runme.py5
-rw-r--r--Examples/test-suite/python/multivalue_runme.py19
-rw-r--r--Examples/test-suite/python/name_warnings_runme.py9
-rw-r--r--Examples/test-suite/python/operator_overload_runme.py2
-rw-r--r--Examples/test-suite/python/overload_simple_runme.py12
-rw-r--r--Examples/test-suite/python/overload_template_runme.py2
-rw-r--r--Examples/test-suite/python/preproc_cpp_runme.py4
-rw-r--r--Examples/test-suite/python/python_abstractbase_runme.py31
-rw-r--r--Examples/test-suite/python/python_annotations_c_runme.py31
-rw-r--r--Examples/test-suite/python/python_annotations_variable_c_runme.py24
-rw-r--r--Examples/test-suite/python/python_flatstaticmethod_runme.py92
-rw-r--r--Examples/test-suite/python/python_nondynamic_runme.py10
-rw-r--r--Examples/test-suite/python/python_overload_simple_cast_runme.py12
-rw-r--r--Examples/test-suite/python/python_pickle_runme.py4
-rw-r--r--Examples/test-suite/python/python_runtime_data_runme.py15
-rw-r--r--Examples/test-suite/python/refcount_runme.py6
-rw-r--r--Examples/test-suite/python/return_const_value_runme.py4
-rw-r--r--Examples/test-suite/python/special_variable_macros_runme.py5
-rw-r--r--Examples/test-suite/python/template_static_runme.py2
-rw-r--r--Examples/test-suite/python/typemap_out_optimal_runme.py7
-rw-r--r--Examples/test-suite/python/using_member_runme.py24
-rw-r--r--Examples/test-suite/python/virtual_poly_runme.py4
-rw-r--r--Examples/test-suite/python/voidtest_runme.py2
-rw-r--r--Examples/test-suite/python_abstractbase.i6
-rw-r--r--Examples/test-suite/python_annotations_c.i40
-rw-r--r--Examples/test-suite/python_annotations_variable_c.i44
-rw-r--r--Examples/test-suite/python_builtin.i1
-rw-r--r--Examples/test-suite/python_flatstaticmethod.i40
-rw-r--r--Examples/test-suite/python_pickle.i6
-rw-r--r--Examples/test-suite/python_runtime_data.list2
-rw-r--r--Examples/test-suite/python_runtime_data_builtin.i15
-rw-r--r--Examples/test-suite/python_runtime_data_nobuiltin.i3
-rw-r--r--Examples/test-suite/python_varargs_typemap.i14
-rw-r--r--Examples/test-suite/r/Makefile.in5
-rw-r--r--Examples/test-suite/r/catches_strings_runme.R24
-rw-r--r--Examples/test-suite/r/constant_pointers_runme.R13
-rw-r--r--Examples/test-suite/r/exception_memory_leak_runme.R (renamed from Examples/test-suite/r/r_memory_leak_runme.R)19
-rw-r--r--Examples/test-suite/r/namespace_struct_runme.R11
-rw-r--r--Examples/test-suite/r_memory_leak.i40
-rw-r--r--Examples/test-suite/refcount.h6
-rw-r--r--Examples/test-suite/rename_camel.i63
-rw-r--r--Examples/test-suite/ruby/Makefile.in4
-rw-r--r--Examples/test-suite/ruby/argcargvtest_runme.rb32
-rw-r--r--Examples/test-suite/ruby/catches_strings_runme.rb31
-rw-r--r--Examples/test-suite/ruby/cpp11_move_typemaps_runme.rb36
-rw-r--r--Examples/test-suite/ruby/cpp11_rvalue_reference_move_runme.rb106
-rw-r--r--Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb151
-rw-r--r--Examples/test-suite/ruby/director_unwrap_result_runme.rb120
-rw-r--r--Examples/test-suite/ruby/ignore_parameter_runme.rb1
-rw-r--r--Examples/test-suite/ruby/li_std_auto_ptr_runme.rb124
-rw-r--r--Examples/test-suite/ruby/li_std_set_runme.rb8
-rw-r--r--Examples/test-suite/ruby/ruby_naming_bugs_runme.rb16
-rw-r--r--Examples/test-suite/ruby_manual_proxy.i2
-rw-r--r--Examples/test-suite/ruby_naming_bugs.i9
-rw-r--r--Examples/test-suite/schemerunme/catches_strings.scm9
-rw-r--r--Examples/test-suite/schemerunme/cpp11_move_typemaps.scm23
-rw-r--r--Examples/test-suite/schemerunme/cpp11_rvalue_reference_move.scm57
-rw-r--r--Examples/test-suite/schemerunme/cpp11_std_unique_ptr.scm95
-rw-r--r--Examples/test-suite/schemerunme/li_std_auto_ptr.scm95
-rw-r--r--Examples/test-suite/schemerunme/newobject1.scm18
-rw-r--r--Examples/test-suite/schemerunme/null_pointer.scm8
-rw-r--r--Examples/test-suite/scilab/Makefile.in4
-rw-r--r--Examples/test-suite/scilab/allprotected_runme.sci24
-rw-r--r--Examples/test-suite/scilab/catches_strings_runme.sci17
-rw-r--r--Examples/test-suite/scilab/li_std_except_runme.sci4
-rw-r--r--Examples/test-suite/scilab/li_std_string_extra_runme.sci8
-rw-r--r--Examples/test-suite/scilab/scilab_identifier_name_runme.sci31
-rw-r--r--Examples/test-suite/scilab/swigtest.start9
-rw-r--r--Examples/test-suite/smart_pointer_const_overload.i4
-rw-r--r--Examples/test-suite/special_variable_macros.i8
-rw-r--r--Examples/test-suite/string_simple.i1
-rw-r--r--Examples/test-suite/tcl/Makefile.in4
-rw-r--r--Examples/test-suite/tcl/argcargvtest_runme.tcl28
-rw-r--r--Examples/test-suite/tcl/catches_strings_runme.tcl31
-rw-r--r--Examples/test-suite/tcl/cpp11_move_typemaps_runme.tcl35
-rw-r--r--Examples/test-suite/tcl/cpp11_rvalue_reference_move_runme.tcl82
-rw-r--r--Examples/test-suite/tcl/cpp11_std_unique_ptr_runme.tcl163
-rw-r--r--Examples/test-suite/tcl/integers_runme.tcl26
-rw-r--r--Examples/test-suite/tcl/li_std_auto_ptr_runme.tcl134
-rw-r--r--Examples/test-suite/tcl/li_std_vector_runme.tcl15
-rw-r--r--Examples/test-suite/template_arg_replace.i2
-rw-r--r--Examples/test-suite/template_construct.i6
-rw-r--r--Examples/test-suite/template_default_vw.i2
-rw-r--r--Examples/test-suite/template_typedef_cplx2.h8
-rw-r--r--Examples/test-suite/template_whitespace.i6
-rw-r--r--Examples/test-suite/testdir/inctest/subdir2/hello.i1
-rw-r--r--Examples/test-suite/threads.i1
-rw-r--r--Examples/test-suite/threads_exception.i1
-rw-r--r--Examples/test-suite/typedef_struct.i1
-rw-r--r--Examples/test-suite/typemap_array_qualifiers.i6
-rw-r--r--Examples/test-suite/typemap_out_optimal.i31
-rw-r--r--Examples/test-suite/typemap_qualifier_strip.i12
-rw-r--r--Examples/test-suite/typemap_variables.i12
-rw-r--r--Examples/test-suite/typemap_various.i4
-rw-r--r--Examples/test-suite/using2.i2
-rw-r--r--Examples/test-suite/using_member.i71
-rw-r--r--Examples/test-suite/using_member_scopes.i85
-rw-r--r--Examples/test-suite/valuewrapper_base.i2
-rw-r--r--Examples/test-suite/valuewrapper_opaque.i2
-rw-r--r--Examples/test-suite/varargs.i4
-rw-r--r--Examples/test-suite/voidtest.i3
-rw-r--r--Examples/xml/example_apply.expected-xml5
-rw-r--r--Examples/xml/example_xml.expected-xml5
-rw-r--r--Lib/allkw.swg6
-rw-r--r--Lib/carrays.i6
-rw-r--r--Lib/cdata.i6
-rw-r--r--Lib/cffi/cffi.swg294
-rw-r--r--Lib/cpointer.i18
-rw-r--r--Lib/csharp/boost_intrusive_ptr.i4
-rw-r--r--Lib/csharp/boost_shared_ptr.i6
-rw-r--r--Lib/csharp/csharp.swg46
-rw-r--r--Lib/csharp/csharphead.swg2
-rw-r--r--Lib/csharp/csharpkw.swg4
-rw-r--r--Lib/csharp/std_array.i2
-rw-r--r--Lib/csharp/std_auto_ptr.i51
-rw-r--r--Lib/csharp/std_list.i2
-rw-r--r--Lib/csharp/std_map.i2
-rw-r--r--Lib/csharp/std_set.i2
-rw-r--r--Lib/csharp/std_string.i8
-rw-r--r--Lib/csharp/std_unique_ptr.i38
-rw-r--r--Lib/csharp/std_vector.i4
-rw-r--r--Lib/csharp/std_wstring.i66
-rw-r--r--Lib/csharp/swigmove.i16
-rw-r--r--Lib/csharp/wchar.i268
-rw-r--r--Lib/d/boost_shared_ptr.i6
-rw-r--r--Lib/d/cpointer.i8
-rw-r--r--Lib/d/dclassgen.swg32
-rw-r--r--Lib/d/dhead.swg2
-rw-r--r--Lib/d/dkw.swg2
-rw-r--r--Lib/d/dswigtype.swg50
-rw-r--r--Lib/d/std_auto_ptr.i42
-rw-r--r--Lib/d/std_unique_ptr.i42
-rw-r--r--Lib/d/swigmove.i16
-rw-r--r--Lib/exception.i8
-rw-r--r--Lib/go/go.swg55
-rw-r--r--Lib/go/gokw.swg2
-rw-r--r--Lib/go/goruntime.swg12
-rw-r--r--Lib/go/std_array.i43
-rw-r--r--Lib/go/std_string.i71
-rw-r--r--Lib/go/swigmove.i15
-rw-r--r--Lib/guile/guile_scm_run.swg57
-rw-r--r--Lib/guile/list-vector.i16
-rw-r--r--Lib/guile/std_auto_ptr.i39
-rw-r--r--Lib/guile/std_common.i2
-rw-r--r--Lib/guile/std_string.i17
-rw-r--r--Lib/guile/std_unique_ptr.i39
-rw-r--r--Lib/guile/swigmove.i19
-rw-r--r--Lib/guile/swigrun.i2
-rw-r--r--Lib/guile/typemaps.i61
-rw-r--r--Lib/java/boost_intrusive_ptr.i4
-rw-r--r--Lib/java/boost_shared_ptr.i4
-rw-r--r--Lib/java/director.swg33
-rw-r--r--Lib/java/java.swg44
-rw-r--r--Lib/java/javahead.swg2
-rw-r--r--Lib/java/javakw.swg2
-rw-r--r--Lib/java/std_auto_ptr.i56
-rw-r--r--Lib/java/std_unique_ptr.i41
-rw-r--r--Lib/java/std_wstring.i26
-rw-r--r--Lib/java/swiginterface.i2
-rw-r--r--Lib/java/swigmove.i16
-rw-r--r--Lib/javascript/jsc/javascriptrun.swg27
-rw-r--r--Lib/javascript/jsc/javascriptstrings.swg2
-rw-r--r--Lib/javascript/jsc/javascripttypemaps.swg2
-rw-r--r--Lib/javascript/jsc/std_auto_ptr.i39
-rw-r--r--Lib/javascript/jsc/std_unique_ptr.i39
-rw-r--r--Lib/javascript/jsc/swigmove.i1
-rw-r--r--Lib/javascript/jsc/typemaps.i2
-rw-r--r--Lib/javascript/v8/javascriptcode.swg96
-rw-r--r--Lib/javascript/v8/javascripthelpers.swg30
-rw-r--r--Lib/javascript/v8/javascriptinit.swg8
-rw-r--r--Lib/javascript/v8/javascriptrun.swg265
-rw-r--r--Lib/javascript/v8/javascriptruntime.swg39
-rw-r--r--Lib/javascript/v8/javascriptstrings.swg8
-rw-r--r--Lib/javascript/v8/javascripttypemaps.swg2
-rw-r--r--Lib/javascript/v8/std_auto_ptr.i39
-rw-r--r--Lib/javascript/v8/std_unique_ptr.i39
-rw-r--r--Lib/javascript/v8/swigmove.i1
-rw-r--r--Lib/javascript/v8/typemaps.i2
-rw-r--r--Lib/lua/argcargv.i57
-rw-r--r--Lib/lua/lua.swg8
-rw-r--r--Lib/lua/lua_fnptr.i2
-rw-r--r--Lib/lua/luakw.swg2
-rw-r--r--Lib/lua/luarun.swg42
-rw-r--r--Lib/lua/luatypemaps.swg28
-rw-r--r--Lib/lua/std_auto_ptr.i39
-rw-r--r--Lib/lua/std_unique_ptr.i39
-rw-r--r--Lib/lua/swigmove.i18
-rw-r--r--Lib/lua/typemaps.i14
-rw-r--r--Lib/mzscheme/mzrun.swg60
-rw-r--r--Lib/mzscheme/std_auto_ptr.i39
-rw-r--r--Lib/mzscheme/std_string.i7
-rw-r--r--Lib/mzscheme/std_unique_ptr.i39
-rw-r--r--Lib/mzscheme/swigmove.i19
-rw-r--r--Lib/mzscheme/typemaps.i43
-rw-r--r--Lib/ocaml/ocaml.swg25
-rw-r--r--Lib/ocaml/ocamlrun.swg2
-rw-r--r--Lib/ocaml/ocamlrundec.swg2
-rw-r--r--Lib/ocaml/std_string.i12
-rw-r--r--Lib/ocaml/swigmove.i11
-rw-r--r--Lib/octave/argcargv.i44
-rw-r--r--Lib/octave/boost_shared_ptr.i6
-rw-r--r--Lib/octave/octcontainer.swg11
-rw-r--r--Lib/octave/octheaders.hpp6
-rw-r--r--Lib/octave/octrun.swg163
-rw-r--r--Lib/octave/octruntime.swg14
-rw-r--r--Lib/octave/octtypemaps.swg11
-rw-r--r--Lib/octave/std_auto_ptr.i39
-rw-r--r--Lib/octave/std_unique_ptr.i39
-rw-r--r--Lib/octave/swigmove.i1
-rw-r--r--Lib/perl5/argcargv.i32
-rw-r--r--Lib/perl5/perlhead.swg37
-rw-r--r--Lib/perl5/perlinit.swg4
-rw-r--r--Lib/perl5/perlrun.swg77
-rw-r--r--Lib/perl5/std_auto_ptr.i39
-rw-r--r--Lib/perl5/std_unique_ptr.i39
-rw-r--r--Lib/perl5/swigmove.i1
-rw-r--r--Lib/php/argcargv.i40
-rw-r--r--Lib/php/const.i24
-rw-r--r--Lib/php/director.swg9
-rw-r--r--Lib/php/factory.i2
-rw-r--r--Lib/php/php.swg185
-rw-r--r--Lib/php/phpinit.swg4
-rw-r--r--Lib/php/phpinterfaces.i2
-rw-r--r--Lib/php/phpkw.swg15
-rw-r--r--Lib/php/phppointers.i36
-rw-r--r--Lib/php/phprun.swg158
-rw-r--r--Lib/php/std_auto_ptr.i41
-rw-r--r--Lib/php/std_string.i14
-rw-r--r--Lib/php/std_unique_ptr.i41
-rw-r--r--Lib/php/swigmove.i24
-rw-r--r--Lib/php/typemaps.i57
-rw-r--r--Lib/php/utils.i12
-rw-r--r--Lib/pointer.i2
-rw-r--r--Lib/python/README1
-rw-r--r--Lib/python/argcargv.i13
-rw-r--r--Lib/python/boost_shared_ptr.i6
-rw-r--r--Lib/python/builtin.swg20
-rw-r--r--Lib/python/defarg.swg37
-rw-r--r--Lib/python/embed.i14
-rw-r--r--Lib/python/pyabc.i20
-rw-r--r--Lib/python/pyclasses.swg2
-rw-r--r--Lib/python/pycontainer.swg28
-rw-r--r--Lib/python/pydocs.swg48
-rw-r--r--Lib/python/pyerrors.swg1
-rw-r--r--Lib/python/pyhead.swg33
-rw-r--r--Lib/python/pyinit.swg251
-rw-r--r--Lib/python/pyrun.swg319
-rw-r--r--Lib/python/pyruntime.swg22
-rw-r--r--Lib/python/pythonkw.swg2
-rw-r--r--Lib/python/pytypemaps.swg2
-rw-r--r--Lib/python/std_auto_ptr.i44
-rw-r--r--Lib/python/std_unique_ptr.i39
-rw-r--r--Lib/python/swigmove.i1
-rw-r--r--Lib/python/typemaps.i2
-rw-r--r--Lib/r/boost_shared_ptr.i6
-rw-r--r--Lib/r/r.swg12
-rw-r--r--Lib/r/rkw.swg4
-rw-r--r--Lib/r/rtype.swg47
-rw-r--r--Lib/r/std_vector.i14
-rw-r--r--Lib/r/swigmove.i1
-rw-r--r--Lib/ruby/argcargv.i18
-rw-r--r--Lib/ruby/boost_shared_ptr.i6
-rw-r--r--Lib/ruby/rubyclasses.swg4
-rw-r--r--Lib/ruby/rubycomplex.swg4
-rw-r--r--Lib/ruby/rubycontainer.swg6
-rw-r--r--Lib/ruby/rubyhead.swg17
-rw-r--r--Lib/ruby/rubykw.swg2
-rw-r--r--Lib/ruby/rubyrun.swg14
-rw-r--r--Lib/ruby/std_auto_ptr.i42
-rw-r--r--Lib/ruby/std_map.i2
-rw-r--r--Lib/ruby/std_multimap.i2
-rw-r--r--Lib/ruby/std_set.i7
-rw-r--r--Lib/ruby/std_unique_ptr.i39
-rw-r--r--Lib/ruby/std_unordered_map.i2
-rw-r--r--Lib/ruby/std_unordered_multimap.i2
-rw-r--r--Lib/ruby/swigmove.i1
-rw-r--r--Lib/ruby/timeval.i2
-rw-r--r--Lib/ruby/typemaps.i6
-rw-r--r--Lib/scilab/boost_shared_ptr.i6
-rw-r--r--Lib/scilab/scirun.swg10
-rw-r--r--Lib/scilab/sciruntime.swg2
-rw-r--r--Lib/scilab/std_string.i8
-rw-r--r--Lib/scilab/swigmove.i1
-rw-r--r--Lib/std/std_basic_string.i11
-rw-r--r--Lib/swig.swg100
-rw-r--r--Lib/swigerrors.swg3
-rw-r--r--Lib/swigfragments.swg4
-rw-r--r--Lib/swigrun.swg18
-rw-r--r--Lib/swigwarnings.swg2
-rw-r--r--Lib/tcl/Makefile.in2
-rw-r--r--Lib/tcl/argcargv.i29
-rw-r--r--Lib/tcl/mactkinit.c233
-rw-r--r--Lib/tcl/std_auto_ptr.i39
-rw-r--r--Lib/tcl/std_unique_ptr.i39
-rw-r--r--Lib/tcl/std_vector.i55
-rw-r--r--Lib/tcl/swigmove.i1
-rw-r--r--Lib/tcl/tclinit.swg5
-rw-r--r--Lib/tcl/tclprimtypes.swg27
-rw-r--r--Lib/tcl/tclrun.swg53
-rw-r--r--Lib/tcl/tclsh.i32
-rw-r--r--Lib/tcl/tcltypemaps.swg5
-rw-r--r--Lib/tcl/tclwstrings.swg1
-rw-r--r--Lib/tcl/wish.i37
-rw-r--r--Lib/typemaps/attribute.swg126
-rw-r--r--Lib/typemaps/cpointer.swg8
-rw-r--r--Lib/typemaps/cstrings.swg12
-rw-r--r--Lib/typemaps/exception.swg3
-rw-r--r--Lib/typemaps/fragments.swg4
-rw-r--r--Lib/typemaps/ptrtypes.swg2
-rw-r--r--Lib/typemaps/string.swg1
-rw-r--r--Lib/typemaps/strings.swg23
-rw-r--r--Lib/typemaps/swigmacros.swg10
-rw-r--r--Lib/typemaps/swigmove.swg19
-rw-r--r--Lib/typemaps/swigobject.swg6
-rw-r--r--Lib/typemaps/swigtype.swg73
-rw-r--r--Lib/typemaps/swigtypemaps.swg1
-rw-r--r--Lib/typemaps/valtypes.swg4
-rw-r--r--Lib/typemaps/void.swg4
-rw-r--r--Lib/typemaps/wstring.swg1
-rw-r--r--Makefile.in182
-rw-r--r--README12
-rw-r--r--RELEASENOTES24
-rw-r--r--Source/CParse/cparse.h8
-rw-r--r--Source/CParse/cscanner.c61
-rw-r--r--Source/CParse/parser.y393
-rw-r--r--Source/CParse/templ.c117
-rw-r--r--Source/CParse/util.c2
-rw-r--r--Source/DOH/base.c36
-rw-r--r--Source/DOH/doh.h83
-rw-r--r--Source/DOH/dohint.h8
-rw-r--r--Source/DOH/file.c14
-rw-r--r--Source/DOH/fio.c2
-rw-r--r--Source/DOH/hash.c7
-rw-r--r--Source/DOH/list.c12
-rw-r--r--Source/DOH/memory.c70
-rw-r--r--Source/DOH/string.c43
-rw-r--r--Source/DOH/void.c2
-rw-r--r--Source/Doxygen/doxycommands.h4
-rw-r--r--Source/Doxygen/doxyentity.cxx2
-rw-r--r--Source/Doxygen/doxyentity.h6
-rw-r--r--Source/Doxygen/doxyparser.cxx11
-rw-r--r--Source/Doxygen/doxyparser.h8
-rw-r--r--Source/Doxygen/doxytranslator.cxx2
-rw-r--r--Source/Doxygen/doxytranslator.h6
-rw-r--r--Source/Doxygen/javadoc.cxx10
-rw-r--r--Source/Doxygen/javadoc.h6
-rw-r--r--Source/Doxygen/pydoc.cxx4
-rw-r--r--Source/Doxygen/pydoc.h6
-rw-r--r--Source/Include/swigwarn.h18
-rw-r--r--Source/Makefile.am6
-rw-r--r--Source/Modules/allocate.cxx10
-rw-r--r--Source/Modules/browser.cxx421
-rw-r--r--Source/Modules/cffi.cxx1184
-rw-r--r--Source/Modules/contract.cxx2
-rw-r--r--Source/Modules/csharp.cxx85
-rw-r--r--Source/Modules/d.cxx40
-rw-r--r--Source/Modules/directors.cxx39
-rw-r--r--Source/Modules/emit.cxx2
-rw-r--r--Source/Modules/go.cxx501
-rw-r--r--Source/Modules/guile.cxx30
-rw-r--r--Source/Modules/interface.cxx72
-rw-r--r--Source/Modules/java.cxx61
-rw-r--r--Source/Modules/javascript.cxx57
-rw-r--r--Source/Modules/lang.cxx187
-rw-r--r--Source/Modules/lua.cxx62
-rw-r--r--Source/Modules/main.cxx121
-rw-r--r--Source/Modules/mzscheme.cxx9
-rw-r--r--Source/Modules/nested.cxx4
-rw-r--r--Source/Modules/ocaml.cxx68
-rw-r--r--Source/Modules/octave.cxx12
-rw-r--r--Source/Modules/overload.cxx4
-rw-r--r--Source/Modules/perl5.cxx25
-rw-r--r--Source/Modules/php.cxx1278
-rw-r--r--Source/Modules/python.cxx443
-rw-r--r--Source/Modules/r.cxx27
-rw-r--r--Source/Modules/ruby.cxx45
-rw-r--r--Source/Modules/scilab.cxx345
-rw-r--r--Source/Modules/swigmain.cxx24
-rw-r--r--Source/Modules/swigmod.h19
-rw-r--r--Source/Modules/tcl8.cxx17
-rw-r--r--Source/Modules/typepass.cxx123
-rw-r--r--Source/Modules/utils.cxx4
-rw-r--r--Source/Modules/xml.cxx34
-rw-r--r--Source/Preprocessor/cpp.c46
-rw-r--r--Source/Preprocessor/expr.c112
-rw-r--r--Source/Preprocessor/preprocessor.h6
-rw-r--r--Source/Swig/cwrap.c29
-rw-r--r--Source/Swig/deprecate.c2
-rw-r--r--Source/Swig/error.c6
-rw-r--r--Source/Swig/extend.c2
-rw-r--r--Source/Swig/fragment.c2
-rw-r--r--Source/Swig/getopt.c14
-rw-r--r--Source/Swig/include.c10
-rw-r--r--Source/Swig/misc.c154
-rw-r--r--Source/Swig/naming.c52
-rw-r--r--Source/Swig/parms.c4
-rw-r--r--Source/Swig/scanner.c85
-rw-r--r--Source/Swig/stype.c2
-rw-r--r--Source/Swig/swig.h13
-rw-r--r--Source/Swig/swigfile.h8
-rw-r--r--Source/Swig/swigopt.h2
-rw-r--r--Source/Swig/swigparm.h2
-rw-r--r--Source/Swig/swigscan.h6
-rw-r--r--Source/Swig/swigtree.h3
-rw-r--r--Source/Swig/swigwrap.h2
-rw-r--r--Source/Swig/symbol.c25
-rw-r--r--Source/Swig/tree.c70
-rw-r--r--Source/Swig/typemap.c133
-rw-r--r--Source/Swig/typeobj.c78
-rw-r--r--Source/Swig/typesys.c127
-rw-r--r--Source/Swig/wrapfunc.c6
-rw-r--r--TODO81
-rw-r--r--Tools/CI-linux-environment.sh6
-rw-r--r--Tools/CI-linux-install.sh60
-rwxr-xr-xTools/brew-install25
-rw-r--r--Tools/cmake/FindPCRE.cmake37
-rw-r--r--Tools/cmake/FindPCRE2.cmake21
-rw-r--r--Tools/cmake/swigconfig.h.in2
-rw-r--r--Tools/config/m4_ax_cxx_compile_stdcxx.m451
-rw-r--r--Tools/javascript/Makefile.in8
-rw-r--r--Tools/javascript/jsc_shell.cxx2
-rw-r--r--Tools/javascript/v8_shell.cxx52
-rwxr-xr-xTools/mkdist.py12
-rwxr-xr-xTools/mkwindows.sh13
-rw-r--r--Tools/nuget-install.cmd28
-rwxr-xr-xTools/pcre-build.sh30
-rwxr-xr-xTools/travis-linux-install.sh11
-rwxr-xr-xTools/travis-osx-install.sh41
-rw-r--r--appveyor.yml80
-rw-r--r--configure.ac2951
-rw-r--r--swig.spec.in70
936 files changed, 26230 insertions, 11984 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ab8c68d1f..35c6d31cb 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,6 +13,9 @@ on:
- 'Doc/**'
- 'appveyor.yml'
+permissions:
+ contents: read
+
jobs:
build:
@@ -24,12 +27,13 @@ jobs:
# By default, the name of the build is the language used and SWIG options, but matrix entries
# can define the additional "desc" field with any additional information to include in the name.
- name: ${{ matrix.SWIGLANG || 'none' }}${{ matrix.PY3 }} ${{ matrix.ENGINE}} ${{ matrix.VER }} ${{ matrix.SWIG_FEATURES }} ${{ (matrix.compiler || 'gcc') }}${{ matrix.GCC }} ${{ matrix.CPPSTD }} ${{ matrix.CSTD }} ${{ matrix.desc }} ${{ matrix.continue-on-error && '(can fail)' }}
+ name: ${{ matrix.SWIGLANG || 'none' }}${{ matrix.PY2 }} ${{ matrix.ENGINE}} ${{ matrix.VER }} ${{ matrix.SWIG_FEATURES }} ${{ (matrix.compiler || 'gcc') }}${{ matrix.GCC }} ${{ matrix.CPPSTD }} ${{ matrix.CSTD }} ${{ matrix.desc }} ${{ matrix.continue-on-error && '(can fail)' }}
strategy:
matrix:
include:
- SWIGLANG: ""
+ CPPFLAGS: "-DDOH_POISON"
- SWIGLANG: ""
GCC: 7
- SWIGLANG: ""
@@ -41,6 +45,9 @@ jobs:
- SWIGLANG: ""
GCC: 11
- SWIGLANG: ""
+ GCC: 12
+ os: ubuntu-22.04
+ - SWIGLANG: ""
compiler: clang
- SWIGLANG: csharp
# D support can't be enabled because dmd 2.066 fails to build anything
@@ -63,20 +70,37 @@ jobs:
- SWIGLANG: go
VER: '1.17'
- SWIGLANG: guile
+ - SWIGLANG: guile
+ VER: '2.2'
+ - SWIGLANG: guile
+ VER: '3.0'
- SWIGLANG: java
- SWIGLANG: javascript
ENGINE: node
+ VER: '6'
+ CPPSTD: c++11
+ os: ubuntu-18.04
+ - SWIGLANG: javascript
+ ENGINE: node
+ VER: '8'
+ CPPSTD: c++11
+ os: ubuntu-18.04
+ - SWIGLANG: javascript
+ ENGINE: node
+ VER: '10'
+ CPPSTD: c++11
+ os: ubuntu-18.04
+ - SWIGLANG: javascript
+ ENGINE: node
VER: '12'
CPPSTD: c++11
- SWIGLANG: javascript
ENGINE: node
- VER: '17'
+ VER: '18'
CPPSTD: c++14
- SWIGLANG: javascript
ENGINE: jsc
- - SWIGLANG: javascript
- ENGINE: v8
- os: ubuntu-18.04 # libv8-dev only actually provides v8 in 18.04.
+ VER: '4.0'
- SWIGLANG: lua
- SWIGLANG: lua
VER: '5.3'
@@ -84,48 +108,52 @@ jobs:
CPPSTD: c++11
- SWIGLANG: perl5
- SWIGLANG: php
+ VER: '7.0'
+ - SWIGLANG: php
+ VER: '7.1'
+ - SWIGLANG: php
+ VER: '7.2'
+ - SWIGLANG: php
+ VER: '7.3'
+ - SWIGLANG: php
VER: '7.4'
- SWIGLANG: php
+ VER: '8.0'
+ - SWIGLANG: php
+ VER: '8.1'
+ - SWIGLANG: php
+ VER: '8.2'
- SWIGLANG: python
+ PY2: 2
- SWIGLANG: python
- PY3: 3
- VER: '3.2'
- os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
- - SWIGLANG: python
- PY3: 3
VER: '3.3'
os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
- SWIGLANG: python
- PY3: 3
VER: '3.4'
os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
- SWIGLANG: python
- PY3: 3
VER: '3.5'
- SWIGLANG: python
- PY3: 3
VER: '3.6'
- SWIGLANG: python
- PY3: 3
VER: '3.7'
- SWIGLANG: python
- PY3: 3
VER: '3.8'
- SWIGLANG: python
- PY3: 3
VER: '3.9'
- SWIGLANG: python
- PY3: 3
VER: '3.10'
- SWIGLANG: python
+ VER: '3.11'
+ - SWIGLANG: python
+ PY2: 2
SWIG_FEATURES: -builtin
- SWIGLANG: python
+ PY2: 2
SWIG_FEATURES: -builtin -O
- SWIGLANG: python
- PY3: 3
SWIG_FEATURES: -builtin
- SWIGLANG: python
- PY3: 3
SWIG_FEATURES: -builtin -O
- SWIGLANG: r
- SWIGLANG: ruby
@@ -154,8 +182,14 @@ jobs:
- SWIGLANG: ruby
VER: '3.0'
CPPSTD: c++11
+ - SWIGLANG: ruby
+ VER: '3.1'
+ CPPSTD: c++11
+ - SWIGLANG: scilab
+ VER: '5.5.2'
+ - SWIGLANG: scilab
+ os: ubuntu-18.04 # scilab 6.0
- SWIGLANG: scilab
- os: ubuntu-18.04 # scilab-6.1 in ubuntu-20.04 not yet working
- SWIGLANG: tcl
# c++11 testing
- SWIGLANG: csharp
@@ -169,13 +203,16 @@ jobs:
- SWIGLANG: java
CPPSTD: c++11
- SWIGLANG: javascript
+ ENGINE: jsc
+ VER: '4.1'
+ os: ubuntu-22.04
+ CPPSTD: c++11
+ - SWIGLANG: javascript
ENGINE: node
VER: '14'
CPPSTD: c++11
- SWIGLANG: lua
CPPSTD: c++11
- # - SWIGLANG: octave
- # CPPSTD: c++11
- SWIGLANG: perl5
CPPSTD: c++11
- SWIGLANG: php
@@ -183,14 +220,12 @@ jobs:
CSTD: gnu11
- SWIGLANG: python
CPPSTD: c++11
- PY3: 3
- SWIGLANG: r
CPPSTD: c++11
- SWIGLANG: ruby
CPPSTD: c++11
- SWIGLANG: scilab
CPPSTD: c++11
- os: ubuntu-18.04 # scilab-6.1 in ubuntu-20.04 not yet working
- SWIGLANG: tcl
CPPSTD: c++11
# c++14 testing
@@ -219,14 +254,12 @@ jobs:
CSTD: gnu11
- SWIGLANG: python
CPPSTD: c++14
- PY3: 3
- SWIGLANG: r
CPPSTD: c++14
- SWIGLANG: ruby
CPPSTD: c++14
- SWIGLANG: scilab
CPPSTD: c++14
- os: ubuntu-18.04 # scilab-6.1 in ubuntu-20.04 not yet working
- SWIGLANG: tcl
CPPSTD: c++14
# c++17 testing (using gcc11)
@@ -246,7 +279,7 @@ jobs:
GCC: 11
- SWIGLANG: javascript
ENGINE: node
- VER: '17'
+ VER: '18'
CPPSTD: c++17
GCC: 11
- SWIGLANG: lua
@@ -265,7 +298,6 @@ jobs:
- SWIGLANG: python
CPPSTD: c++17
GCC: 11
- PY3: 3
- SWIGLANG: r
CPPSTD: c++17
GCC: 11
@@ -275,14 +307,21 @@ jobs:
- SWIGLANG: scilab
CPPSTD: c++17
GCC: 11
- os: ubuntu-18.04 # scilab-6.1 in ubuntu-20.04 not yet working
- SWIGLANG: tcl
CPPSTD: c++17
GCC: 11
+ # c++20 testing (using gcc12)
+ # ubuntu-22.04 is currently experimental on Github Actions, so limit to just one language for now
+ - SWIGLANG: python
+ CPPSTD: c++20
+ GCC: 12
+ os: ubuntu-22.04
# Experimental languages (these are allowed to fail)
- SWIGLANG: mzscheme
continue-on-error: true
- SWIGLANG: ocaml
+ CPPSTD: c++17
+ GCC: 11
continue-on-error: true
os: ubuntu-18.04 # ocaml-4.08 in ubuntu-20.04 not yet working
# Run all of them, as opposed to aborting when one fails
@@ -290,13 +329,14 @@ jobs:
env:
SWIGLANG: ${{ matrix.SWIGLANG }}
- PY3: ${{ matrix.PY3 }}
+ PY2: ${{ matrix.PY2 }}
VER: ${{ matrix.VER }}
ENGINE: ${{ matrix.ENGINE }}
SWIG_FEATURES: ${{ matrix.SWIG_FEATURES }}
GCC: ${{ matrix.GCC }}
CSTD: ${{ matrix.CSTD }}
CPPSTD: ${{ matrix.CPPSTD }}
+ CPPFLAGS: ${{ matrix.CPPFLAGS }}
steps:
- name: Checkout
@@ -309,6 +349,10 @@ jobs:
with:
key: ${{ matrix.os || 'ubuntu-20.04' }}-${{ matrix.compiler || 'gcc' }}${{ matrix.GCC }}
+# Uncomment to debug via ssh, see https://github.com/mxschmitt/action-tmate
+# - name: Setup tmate session
+# uses: mxschmitt/action-tmate@v3
+
- name: Install Dependencies
run: |
set -x
@@ -369,10 +413,12 @@ jobs:
c++11) export CSTD=c11 ;;
c++14) export CSTD=c11 ;;
c++17) export CSTD=c17 ;;
+ c++20) export CSTD=c17 ;;
esac
echo CSTD="$CSTD" >> $GITHUB_ENV
fi
- if test -n "$CPPSTD"; then CONFIGOPTS+=(--enable-cpp11-testing "CXXFLAGS=-std=$CPPSTD $CXXFLAGS"); fi
+ if test -z "$CPPSTD"; then CONFIGOPTS+=("--disable-cpp11-testing"); fi
+ if test -n "$CPPSTD"; then CONFIGOPTS+=("CXXFLAGS=-std=$CPPSTD $CXXFLAGS"); fi
if test -n "$CSTD"; then CONFIGOPTS+=("CFLAGS=-std=$CSTD $CFLAGS"); fi
if test -n "$SWIGLANG"; then CONFIGOPTS+=(--without-alllang --with-$WITHLANG); fi
echo "${CONFIGOPTS[@]}"
@@ -409,8 +455,8 @@ jobs:
esac
# Stricter compile flags for examples. Various headers and SWIG generated code prevents full use of -pedantic.
- cflags=$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cflags --std=$CSTD --compiler=$CC) && echo $cflags
- cxxflags=$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cxxflags --std=$CPPSTD --compiler=$CC) && echo $cxxflags
+ cflags=$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cflags --std=$CSTD --compiler=$CC)
+ cxxflags=$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cxxflags --std=$CPPSTD --compiler=$CC)
make check-$SWIGLANG-version
make check-$SWIGLANG-enabled
make $SWIGJOBS check-$SWIGLANG-examples CFLAGS="$cflags" CXXFLAGS="$cxxflags"
diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml
new file mode 100644
index 000000000..7b8174a1e
--- /dev/null
+++ b/.github/workflows/nuget.yml
@@ -0,0 +1,59 @@
+name: Windows Nuget Build
+
+on:
+ push:
+ paths-ignore:
+ - 'CHANGES*'
+ - 'Doc/**'
+ - 'appveyor.yml'
+ pull_request:
+ branches: master
+ paths-ignore:
+ - 'CHANGES*'
+ - 'Doc/**'
+ - 'appveyor.yml'
+
+jobs:
+ build:
+
+ runs-on: windows-2019
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ submodules: recursive
+
+ - name: Install Dependencies
+ shell: powershell
+ run: |
+ nuget install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake
+ nuget install Bison -Version 3.7.4 -OutputDirectory C:\Tools\bison
+ nuget install PCRE2 -Version 10.39 -OutputDirectory C:\Tools\pcre2
+
+ - name: Build
+ shell: powershell
+ run: |
+ $env:PATH="C:\Tools\CMake\CMake-win64.3.15.5\bin;C:\Tools\bison\Bison.3.7.4\bin;" + $env:PATH
+ $PCRE_ROOT="C:\Tools\pcre2\PCRE2.10.39.0"
+ $PCRE_PLATFORM="x64"
+ $WORKING_DIR=(Get-Location).ToString() -replace "\\","/"
+ cmake -G "Visual Studio 16 2019" -A "x64" `
+ -DCMAKE_INSTALL_PREFIX="$WORKING_DIR/install2" `
+ -DCMAKE_C_FLAGS="/DPCRE2_STATIC" `
+ -DCMAKE_CXX_FLAGS="/DPCRE2_STATIC" `
+ -DPCRE2_INCLUDE_DIR="$PCRE_ROOT/include" `
+ -DPCRE2_LIBRARY="$PCRE_ROOT/lib/pcre2-8-static.lib" `
+ -S . -B build
+ cmake --build build --config Release
+
+ - name: Install
+ shell: powershell
+ run: |
+ cmake --install build --config Release
+
+ - name: Test
+ shell: powershell
+ working-directory: install2/bin
+ run: |
+ swig.exe -version
diff --git a/.gitignore b/.gitignore
index b51da0fdf..307def526 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,7 +81,6 @@ Tools/javascript/Makefile
config.log
config.status
preinst-swig
-swig.spec
# Build Artifacts
.dirstamp
@@ -160,6 +159,14 @@ Examples/java/doxygen/javadocs
Examples/test-suite/javascript/*/
*.gyp
+# Lua
+Examples/lua/dual/dual
+Examples/lua/dual/swigluarun.h
+Examples/lua/embed/embed
+Examples/lua/embed2/embed2
+Examples/lua/embed3/embed3
+Examples/lua/embed3/swigluarun.h
+
# OCaml
Examples/test-suite/ocaml/*.ml*
Examples/test-suite/ocaml/*.cm*
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c11479fed..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,499 +0,0 @@
-language: cpp
-matrix:
- include:
- - compiler: clang
- os: linux
- env: SWIGLANG=
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG= BUILDSYSTEM=cmake
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=4.4
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=4.6
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=4.7
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=4.8
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=4.9
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=6
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=7
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=8
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=9
- dist: xenial
- - os: linux
- env: SWIGLANG= GCC=10
- dist: focal
- - compiler: gcc
- os: linux
- env: SWIGLANG=csharp
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=d VER=2.066.0
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=d VER=2.086.1
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=go VER=1.3
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=go VER=1.8
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=go VER=1.12 CSTD=gnu99
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=go VER=1.16 CSTD=gnu99
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=guile
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=java
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=javascript ENGINE=node VER=6 CPP11=1
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=javascript ENGINE=node VER=8 CPP11=1
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=javascript ENGINE=node VER=10 CPP11=1
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=javascript ENGINE=node VER=12 CPP11=1
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=javascript ENGINE=node VER=14 CPP11=1
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=javascript ENGINE=node VER=16 CPP14=1
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=javascript ENGINE=jsc
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=javascript ENGINE=v8
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=lua
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=lua VER=5.3
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=mzscheme
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ocaml
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=octave SWIGJOBS=-j2
- dist: xenial # Octave v4.0.0
- - compiler: gcc
- os: linux
- env: SWIGLANG=octave SWIGJOBS=-j2 CPP11=1
- dist: bionic # Octave v4.2.2
- - compiler: gcc
- os: linux
- env: SWIGLANG=perl5
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=php VER=7.4
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=php VER=8.0
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=php VER=7.0 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
- dist: bionic
- - compiler: gcc
- os: linux
- env: SWIGLANG=php VER=7.1 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
- dist: bionic
- - compiler: gcc
- os: linux
- env: SWIGLANG=php VER=7.2 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
- dist: bionic
- - compiler: gcc
- os: linux
- env: SWIGLANG=php VER=7.3 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
- dist: bionic
- - compiler: gcc
- os: linux
- env: SWIGLANG=php VER=7.4 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
- dist: bionic
- - compiler: gcc
- os: linux
- env: SWIGLANG=php VER=8.0 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
- dist: bionic
- - compiler: gcc
- os: linux
- env: SWIGLANG=python # 2.7
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python PY3=3 VER=3.2
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python PY3=3 VER=3.3
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python PY3=3 VER=3.4
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python PY3=3 VER=3.5
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python PY3=3 VER=3.6
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python PY3=3 VER=3.7
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python PY3=3 VER=3.8
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python PY3=3 VER=3.9
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES=-builtin
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES="-builtin -O"
- dist: xenial
- - os: linux
- env: SWIGLANG=python SWIG_FEATURES=-builtin GCC=6 CPP11=1
- dist: xenial
- - os: linux
- env: SWIGLANG=python SWIG_FEATURES=-builtin GCC=6 CPP11=1 PY3=3 VER=3.9
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.7
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.8
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.9
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES="-builtin -O" PY3=3 VER=3.9
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.9 SWIGOPTPY3=
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES=-O
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=python SWIG_FEATURES=-O PY3=3 VER=3.9
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=r
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=1.9
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=2.0
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=2.1
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=2.2
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=2.3
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=2.4
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=2.5
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=2.6
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=2.7
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ruby VER=3.0 CSTD=c99
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=scilab
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=tcl
- dist: xenial
- - os: linux
- env: SWIGLANG=csharp CPP11=1
- dist: xenial
- - os: linux
- env: SWIGLANG=go VER=1.6 CPP11=1
- dist: xenial
- - os: linux
- env: SWIGLANG=java CPP11=1
- dist: xenial
- - os: linux
- env: SWIGLANG=python CPP11=1
- dist: xenial
- - os: linux
- env: SWIGLANG=r CPP11=1 # Note: making 'R CMD SHLIB' use a different compiler is non-trivial
- dist: xenial
- - os: linux
- env: SWIGLANG=ruby CPP11=1
- dist: xenial
- - os: linux
- env: SWIGLANG=tcl CPP11=1
- dist: xenial
- - os: linux
- env: SWIGLANG=csharp GCC=6 CPP14=1
- dist: xenial
- - os: linux
- env: SWIGLANG=go VER=1.6 GCC=6 CPP14=1
- dist: xenial
- - os: linux
- env: SWIGLANG=java GCC=6 CPP14=1
- dist: xenial
- - os: linux
- env: SWIGLANG=python GCC=6 CPP14=1
- dist: xenial
- - os: linux
- env: SWIGLANG=ruby GCC=6 CPP14=1
- dist: xenial
- - os: linux
- env: SWIGLANG=tcl GCC=6 CPP14=1
- dist: xenial
- - os: linux
- env: SWIGLANG=java GCC=7 CPP14=1
- dist: xenial
- - os: linux
- env: SWIGLANG=python GCC=7 CPP14=1
- dist: xenial
- - os: linux
- env: SWIGLANG=csharp GCC=8 CPP17=1
- dist: xenial
- - os: linux
- env: SWIGLANG=java GCC=8 CPP17=1
- dist: xenial
- - os: linux
- env: SWIGLANG=python GCC=8 CPP17=1 PY3=3 VER=3.9
- dist: xenial
- - os: linux
- env: SWIGLANG=csharp GCC=9 CPP17=1
- dist: xenial
- - os: linux
- env: SWIGLANG=java GCC=9 CPP17=1
- dist: xenial
- - os: linux
- env: SWIGLANG=python GCC=9 CPP17=1 PY3=3 VER=3.9
- dist: xenial
- - os: linux
- arch: s390x
- env: SWIGLANG=ruby CPP11=1
- dist: xenial
- - compiler: gcc
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG= BUILDSYSTEM=cmake
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=csharp
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=go CSTD=gnu99
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=guile CSTD=c11
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=java
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=lua
-# octave-6.1 not working
-# - compiler: clang
-# os: osx
-# osx_image: xcode12.2
-# env: SWIGLANG=octave SWIGJOBS=-j2 CPP11=1
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=perl5
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=python
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=python PY3=3
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=ruby
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=tcl
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=java CPP17=1
- - compiler: clang
- os: osx
- osx_image: xcode12.2
- env: SWIGLANG=python PY3=3 CPP17=1
-
- allow_failures:
- # Newer version of D not yet working/supported
- - compiler: gcc
- os: linux
- env: SWIGLANG=d VER=2.086.1
- dist: xenial
- # Experimental languages
- - compiler: gcc
- os: linux
- env: SWIGLANG=mzscheme
- dist: xenial
- - compiler: gcc
- os: linux
- env: SWIGLANG=ocaml
- dist: xenial
-
-before_install:
- - date -u
- - uname -a
- - if test "$TRAVIS_OS_NAME" = "linux"; then lscpu; grep "model name" /proc/cpuinfo || echo 'Unknown CPU model'; grep "MemTotal" /proc/meminfo || echo 'Unknown system memory amount'; fi
- - if test "$TRAVIS_OS_NAME" = "osx"; then sysctl -a | grep brand_string; fi
- # Travis overrides CC environment with compiler predefined values
- - if test -n "$GCC"; then export CC="gcc-$GCC" && export CXX="g++-$GCC"; fi
-install:
- - if test "$TRAVIS_OS_NAME" = "linux"; then source Tools/travis-linux-install.sh; fi
- - if test "$TRAVIS_OS_NAME" = "osx"; then source Tools/travis-osx-install.sh; fi
- - ls -la $(which $CC) $(which $CXX) && $CC --version && $CXX --version
-script:
- - if test "$BUILDSYSTEM" = "cmake"; then cmake --version && mkdir -p build/build && cd build/build && CXXFLAGS="-Wall -Wextra -Werror" CFLAGS="-Wall -Wextra -Werror" cmake -DCMAKE_INSTALL_PREFIX=~/.local ../.. && make install && ctest --output-on-failure -V && exit 0; fi
- - echo 'Configuring...' && echo -en 'travis_fold:start:script.1\\r'
- - if test -n "$CPP11"; then CONFIGOPTS+=(--enable-cpp11-testing "CXXFLAGS=-std=c++11 $CXXFLAGS" "CFLAGS=-std=c11 $CFLAGS") && export CSTD=c11 && export CPPSTD=c++11; fi
- - if test -n "$CPP14"; then CONFIGOPTS+=(--enable-cpp11-testing "CXXFLAGS=-std=c++14 $CXXFLAGS" "CFLAGS=-std=c11 $CFLAGS") && export CSTD=c11 && export CPPSTD=c++14; fi
- - if test -n "$CPP17"; then CONFIGOPTS+=(--enable-cpp11-testing "CXXFLAGS=-std=c++17 $CXXFLAGS" "CFLAGS=-std=c17 $CFLAGS") && export CSTD=c17 && export CPPSTD=c++17; fi
- - if test -n "$SWIGLANG"; then CONFIGOPTS+=(--without-alllang --with-$WITHLANG); fi
- - echo "${CONFIGOPTS[@]}"
- - ./autogen.sh && mkdir -p build/build && cd build/build && ../../configure "${CONFIGOPTS[@]}"
- - echo -en 'travis_fold:end:script.1\\r'
- - make -s $SWIGJOBS
- - ./swig -version && ./swig -pcreversion
- - if test -z "$SWIGLANG"; then make -s $SWIGJOBS check-ccache; fi
- - if test -z "$SWIGLANG"; then make -s $SWIGJOBS check-errors-test-suite; fi
- - echo 'Installing...' && echo -en 'travis_fold:start:script.2\\r'
- - if test -z "$SWIGLANG"; then sudo make -s install && swig -version && ccache-swig -V; fi
- - echo -en 'travis_fold:end:script.2\\r'
- # Stricter compile flags for examples. Various headers and SWIG generated code prevents full use of -pedantic.
- - if test -n "$SWIGLANG"; then cflags=$($TRAVIS_BUILD_DIR/Tools/testflags.py --language $SWIGLANG --cflags --std=$CSTD --compiler=$CC) && echo $cflags; fi
- - if test -n "$SWIGLANG"; then cxxflags=$($TRAVIS_BUILD_DIR/Tools/testflags.py --language $SWIGLANG --cxxflags --std=$CPPSTD --compiler=$CC) && echo $cxxflags; fi
- - if test -n "$SWIGLANG"; then make -s check-$SWIGLANG-version; fi
- - if test -n "$SWIGLANG"; then make check-$SWIGLANG-enabled; fi
- - if test -n "$SWIGLANG"; then make $SWIGJOBS check-$SWIGLANG-examples CFLAGS="$cflags" CXXFLAGS="$cxxflags"; fi
- - if test -n "$SWIGLANG"; then make $SWIGJOBS check-$SWIGLANG-test-suite CFLAGS="$cflags" CXXFLAGS="$cxxflags"; fi
- - echo 'Cleaning...' && echo -en 'travis_fold:start:script.3\\r'
- # Skip on osx as often fails with: rm: Resource temporarily unavailable
- - if test "$TRAVIS_OS_NAME" != "osx"; then make check-maintainer-clean && ../../configure $CONFIGOPTS; fi
- - echo -en 'travis_fold:end:script.3\\r'
diff --git a/ANNOUNCE b/ANNOUNCE
index e50bcd463..90ac94f52 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,6 +1,6 @@
*** ANNOUNCE: SWIG 4.1.0 (in progress) ***
-http://www.swig.org
+https://www.swig.org
We're pleased to announce SWIG-4.1.0, the latest SWIG release.
@@ -19,20 +19,20 @@ and user interface development for large C/C++ systems.
Release Notes
=============
Detailed release notes are available with the release and are also
-published on the SWIG web site at http://swig.org/release.html.
+published on the SWIG web site at https://swig.org/release.html.
Availability
============
The release is available for download on Sourceforge at
- http://prdownloads.sourceforge.net/swig/swig-4.1.0.tar.gz
+ https://prdownloads.sourceforge.net/swig/swig-4.1.0.tar.gz
A Windows version is also available at
- http://prdownloads.sourceforge.net/swig/swigwin-4.1.0.zip
+ https://prdownloads.sourceforge.net/swig/swigwin-4.1.0.zip
Please report problems with this release to the swig-devel mailing list,
-details at http://www.swig.org/mail.html.
+details at https://www.swig.org/mail.html.
--- The SWIG Developers
diff --git a/CCache/ccache.yo b/CCache/ccache.yo
index 2477662dc..fd5ba89c3 100644
--- a/CCache/ccache.yo
+++ b/CCache/ccache.yo
@@ -409,7 +409,7 @@ ccache was adapted to create ccache-swig for use with SWIG by William Fulton.
If you wish to report a problem or make a suggestion then please email
the SWIG developers on the swig-devel mailing list, see
-url(http://www.swig.org/mail.html)(http://www.swig.org/mail.html)
+url(https://www.swig.org/mail.html)(https://www.swig.org/mail.html)
ccache is released under the GNU General Public License version 2 or
later. Please see the file COPYING for license details.
diff --git a/CHANGES b/CHANGES
index 05834910a..8f3cb9e26 100644
--- a/CHANGES
+++ b/CHANGES
@@ -115,7 +115,7 @@ Version 4.0.2 (8 Jun 2020)
2020-01-13: wsfulton
[Python] #1595 Python -builtin constructors silently ignored keyword arguments.
- Instead of silenty ignoring them, now a "TypeError: f() takes no keyword arguments"
+ Instead of silently ignoring them, now a "TypeError: f() takes no keyword arguments"
exception is thrown if keyword arguments are used. Hence constructors and normal methods/
functions behave in the same way. Note, -keyword should be used with -builtin to obtain
keyword argument support.
@@ -200,7 +200,7 @@ Version 4.0.1 (21 Aug 2019)
VectorOverload(std::vector< Number,std::allocator< Number > >)
VectorOverload(std::vector< int,std::allocator< int > >)
- The problem was due to some error handling that was not cleared during typehecking.
+ The problem was due to some error handling that was not cleared during typechecking.
In this case an error was not cleared when the elements in the list failed the
typecheck for converting to X. Only occurs in Python 3+.
@@ -3137,7 +3137,7 @@ Version 3.0.3 (30 Dec 2014)
2014-09-12: olly
[PHP] Add support for specifying any PHP interfaces a wrapped class
- implements, e.g.: %typemap("phpinterfaces") MyIterator "Iterator";
+ implements, e.g.: %typemap("phpinterfaces") MyIterator "Iterator"
2014-09-11: olly
[PHP] Fix throwing a PHP exception through C++ from a subclassed
@@ -3302,7 +3302,7 @@ Version 3.0.0 (16 Mar 2014)
project has been further extended. The C++11 support is comprehensive, but by no means complete
or without limitations. Full details for each new feature in C++11 is covered in the
CPlusPlus11.html chapter in the documentation which is included in SWIG and also available
- online at http://www.swig.org/Doc3.0/CPlusPlus11.html.
+ online at https://www.swig.org/Doc3.0/CPlusPlus11.html.
2014-03-14: v-for-vandal
[Lua] Numerous Lua improvements:
@@ -5784,7 +5784,7 @@ Version 2.0.0 (2 June 2010)
2010-02-27: wsfulton
License code changes: SWIG Source is GPL-v3 and library code license is now clearer
- and is provided under a very permissive license. See http://www.swig.org/legal.html.
+ and is provided under a very permissive license. See https://www.swig.org/legal.html.
2010-02-13: wsfulton
[Ruby] A few fixes for compiling under ruby-1.9.x including patch from 'Nibble'.
@@ -8396,8 +8396,8 @@ Version 1.3.30 (November 13, 2006)
javabase/csbase typemap, eg in the following, 'Me' will be the base class,
no matter what Foo is really derived from in the C++ layer.
- %typemap(javabase, replace="1") Foo "Me";
- %typemap(csbase, replace="1") Foo "Me";
+ %typemap(javabase, replace="1") Foo "Me"
+ %typemap(csbase, replace="1") Foo "Me"
Previously it was not possible for the javabase/csbase typemaps to override the C++ base.
@@ -9884,7 +9884,7 @@ Version 1.3.28 (February 12, 2006)
solutions is to write:
%typemap(in) A * {...}
- %typemap(freeag) A * "";
+ %typemap(freeag) A * ""
overload 'freearg' with an empty definition.
@@ -11314,20 +11314,20 @@ Version 1.3.27 (October 15, 2005)
then the typemap will be inserted without the block
imposed by the brackets, similar to
- %typemap(in) Hello "...";
+ %typemap(in) Hello "..."
So, why you don't just use the quote style?, because:
1.- The quote style doesn't get preprocessed, for example
- %typemap(in) Hello "$1= SWIG_macro($1);";
+ %typemap(in) Hello "$1= SWIG_macro($1);"
here, SWIG_macro doesn't get expanded
2.- Inside a quote typemap, you have to use
quotes carefully
- %typemap(in) Hello "$1 = \"hello\" ";
+ %typemap(in) Hello "$1 = \"hello\" "
3.- You can't make emacs and/or other editors
to indent inside a string!.
@@ -11529,7 +11529,7 @@ Version 1.3.26 (October 9, 2005)
%define hello(name, Type)
%define name ## a(Type)
- %typemap(in) Type "hello;";
+ %typemap(in) Type "hello;"
%enddef
%enddef
@@ -13525,7 +13525,7 @@ Version 1.3.23 (November 11, 2004)
whereupon the default of 0 was used. You can get the same behaviour for C
code by using the "default" typemap:
- %typemap(default) int val "$1 = 0;";
+ %typemap(default) int val "$1 = 0;"
%{
void foo(int val);
%}
@@ -13854,9 +13854,11 @@ Version 1.3.22 (September 4, 2004)
specifiers from the C type. This makes it possible, for instance, to control
whether a C "char" argument takes a Lisp character or a Lisp integer value.
The default (taking Lisp characters) is done by these built-in typemaps:
- %typemap(ffitype) char ":char"; %typemap(lisptype) char "character";
+ %typemap(ffitype) char ":char"
+ %typemap(lisptype) char "character"
If char means an integer instead, use these typemaps:
- %typemap(ffitype) char ":char"; %typemap(lisptype) char "integer";
+ %typemap(ffitype) char ":char"
+ %typemap(lisptype) char "integer"
08/22/2004: wsfulton
As discussed in bug #772453, the SWIG library directory is now installed
@@ -18874,9 +18876,9 @@ Version 1.3.14 (August 12, 2002)
shadowinterface
Note that it is possible to target a particular proxy class:
- %typemap(javaimports) Foo "import java.util.*";
+ %typemap(javaimports) Foo "import java.util.*"
or a particular type wrapper class:
- %typemap(javaimports) double* "import java.math.*";
+ %typemap(javaimports) double* "import java.math.*"
Note that $javaclassname in these typemaps are substituted with either the proxy
classname when using proxy classes or the SWIGTYPE class name.
@@ -19614,8 +19616,8 @@ Version 1.3.12 (June 2, 2002)
typemap must exactly match up with the "in" or "ignore"
typemap. For example:
- %typemap(in) (char *data, int len) { ... };
- %typemap(freearg) char *data { ... };
+ %typemap(in) (char *data, int len) { ... }
+ %typemap(freearg) char *data { ... }
void foo(char *data, int len);
@@ -21071,7 +21073,7 @@ Version 1.3.11 (January 31, 2002)
Second, a typemap can force a no-match by defining
- %typemap(in) sometype "pass";
+ %typemap(in) sometype "pass"
If this is used, the typemap system will *not* record a
typemap match for "sometype". This can be used to block
@@ -21079,7 +21081,7 @@ Version 1.3.11 (January 31, 2002)
a typemap feature for some type, you could do this.
// Do not allow global variables of type 'const char *' to be set.
- %typemap(varin) const char * "pass";
+ %typemap(varin) const char * "pass"
It might also be possible to use this to do subtle and
strange things with typemaps. For example, if you wanted to
@@ -21093,8 +21095,8 @@ Version 1.3.11 (January 31, 2002)
... return a value ...
}
/* Block unqualified typemaps defined above */
- %typemap(ignore) const blah * "pass";
- %typemap(argout) const blah * "pass";
+ %typemap(ignore) const blah * "pass"
+ %typemap(argout) const blah * "pass"
%typemap(in) const blah * {
... get input value ...
}
@@ -21871,7 +21873,7 @@ Version 1.3.10 (December 10, 2001)
%typemap directive can now accept nearly arbitrary keyword parameters.
For example:
- %typemap(in,parse="i",doc="integer") int "...";
+ %typemap(in,parse="i",doc="integer") int "..."
The purpose of the keyword parameters is to supply code generation
hints to the target language module. The intepretation of the
@@ -23949,7 +23951,7 @@ Version 1.3 Alpha 4 (September 4, 2000)
Typemaps can now be specified using string literals like
this:
- %typemap(in) int "$target = SvIV($source);";
+ %typemap(in) int "$target = SvIV($source);"
When code is specified like this, it is *NOT* enclosed
inside a local scope (as with older typemap declarations).
diff --git a/CHANGES.current b/CHANGES.current
index 0abed204a..ae2fb8ffe 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,969 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-10-14: olly
+ [R] Arrange that destructors of local C++ objects in the wrapper
+ function get run on SWIG_fail (which calls Rf_error() which calls
+ longjmp()).
+
+2022-10-14: olly
+ [Lua] Arrange that destructors of local C++ objects in the wrapper
+ function get run on SWIG_fail (which calls lua_error() which calls
+ longjmp()).
+
+2022-10-13: wsfulton
+ [R] Add missing SWIGTYPE *const& typemaps for supporting pointers
+ by const reference.
+
+2022-10-10: wsfulton
+ #2160 Fix compile error when using templates with more than one template
+ parameter and used as an input parameter in a virtual method in a
+ director class (problem affecting most of the scripting languages).
+
+2022-10-10: treitmayr, wsfulton
+ [Python, Ruby] #1811 #1823 Fix invalid code generated in some cases when
+ returning a pointer or reference to a director-enabled class instance.
+ This previously only worked in very simple cases, now return types are
+ resolved to fix. A bug in template instantiations using pointers also
+ works now.
+
+2022-10-06: wsfulton
+ [CFFI] #1966 #2200 Remove code for Common Lisp CFFI. We dropped support
+ for it in SWIG 4.0.0 by disabling it as the first stage. This is the
+ final stage for complete removal as there has been no meaningful
+ progress to revive it to the status of experimental language.
+
+2022-10-06: olly
+ [Python] #2390 Remove deprecated and apparently useless defarg.swg
+
+ The only documentation is in the file itself and describes a Python
+ wrapper around the C function defined here, but digging though the
+ git history this Python wrapper doesn't seem to have ever actually
+ been generated by SWIG.
+
+ This file was also marked as deprecated in 2005.
+
+2022-10-06: wsfulton
+ [Java] #2048 Fix quoting for doxygen \image command to quote the output
+ file name generated into the html src attribute.
+
+2022-10-05: benjamin-sch
+ [Python] added an interpreter counter to fix deinitialization
+ issues if multiple subinterpreters are used
+
+2022-10-05: olly, wsfulton
+ #672 Add support for parsing C++11 final classes such as:
+
+ class X final {};
+
+ This no longer gives a syntax error.
+
+2022-10-05: wsfulton
+ [OCaml] Fix %rename for enum items. Previously the rename had no effect.
+
+2022-10-05: olly
+ #1465 Report errors in preprocessor expressions by default
+
+ Until now SWIG quietly ignored such errors unless -Wextra (or -Wall
+ which implies -Wextra) was passed, but this is unhelpful as it tends
+ to hide genuine problems. To illustrate this point, enabling this
+ warning by default revealed a typo in the preproc_defined.i
+ testcase in SWIG's own testsuite.
+
+ If you really don't want to see this warning, you can suppress it
+ with command line option -w202 or by using this in your interface
+ file:
+
+ %warnfilter(SWIGWARN_PP_EVALUATION);
+
+ Both will work with older versions of SWIG too.
+
+2022-10-04: olly
+ #1050 Consistently define SWIG_VERSION both at SWIG-time and in
+ the generated wrapper. Best practice remains to check at SWIG-time
+ where possible because that results in smaller generated wrapper
+ sources.
+
+ SWIGGO and SWIGJAVASCRIPT are now defined in the generated wrappers
+ to match behaviour for all other target languages.
+
+ The undocumented SWIGVERSION macro is no longer defined.
+
+2022-09-29: olly
+ #2303 SWIG's internal hash tables now use a better hash function.
+
+ The old hash function only considerd the last five characters
+ plus the least significant bit of the last-but-sixth character,
+ which as you might guess generated a lot of many-way collisions.
+
+ This change seems to give about a 4% reduction in wallclock time
+ for processing li_std_list_wrap.i from the testsuite for Python.
+ The hash collision rate for this example drops from 39% to 0!
+
+2022-09-29: wsfulton
+ #2303 Type tables are now output in a fixed order whereas previously
+ the order may change with any minor input code change. This shouldn't
+ affect users except SWIG_TypePrettyName may output a different C/C++
+ typedef to a type - it's used mostly for showing errors when the type
+ passed to a function is wrong.
+
+2022-09-29: olly
+ [PHP] Dynamic class properties are no longer supported by default.
+
+ Historically PHP has supported dynamic class properties and SWIG
+ has implemented them too (because we implement the magic __get(),
+ __set() and __isset() methods we need to include explicit
+ handling).
+
+ PHP 8.2 deprecates dynamic class properties - initially they'll
+ warn, and apparently they'll not work by default in PHP 9.0:
+ https://wiki.php.net/rfc/deprecate_dynamic_properties
+
+ In PHP code dynamic properties can be enabled for a class by
+ marking that class with the attribute `#[AllowDynamicProperties]`.
+
+ To follow this PHP change, in SWIG you now need to specify
+ `%feature("php:allowdynamicproperties", 1) Foo;` (or
+ `%feature("php:allowdynamicproperties", 1)` to enable it for
+ all wrapped classes). Unknown features are ignored, so you can add
+ it unconditionally and it'll work with older SWIG too.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-09-19: wsfulton
+ #1484 Fixes for class inheritance with the same name in different namespaces
+ such as:
+
+ namespace A { class Bar {}; }
+ namespace B { template<typename T, typename U> class Bar : public A::Bar {}; }
+
+2022-09-19: wsfulton
+ #2316 Remove swig.spec file and srcrpm makefile target. These are very out of date
+ and don't seem to be used by RPM based Linux distributions which have their
+ own version of swig.spec.
+
+2022-09-17: wsfulton
+ [Go, Guile, Racket, Scilab] Add throws typemaps for std::string so that thrown
+ string exception messages can be seen.
+
+2022-09-17: wsfulton
+ [Racket] Add throws typemaps for char * so that thrown string exception
+ messages can be seen from Racket.
+
+2022-09-17: wsfulton
+ [Javascript, Octave, R] Improve exceptions for %catches and exception
+ specifications for native types. String exception messages are shown as
+ the exception message instead of just the type of the exception.
+
+2022-09-17: wsfulton
+ Add missing typecheck typemaps for std::auto_ptr and std::unique_ptr to
+ fix overloading when using these types.
+
+2022-09-17: wsfulton
+ [Guile] Add error checking to SWIGTYPE and SWIGTYPE & in typemaps to prevent
+ seg faults when passing #nil to these parameter types.
+
+2022-09-16: wsfulton
+ #999 Provide SWIGTYPE MOVE typemaps in swigmove.i for implementing full
+ move semantics when passing parameters by value.
+
+2022-08-31: wsfulton
+ #999 Improve move semantics when using rvalue references.
+ The SWIGTYPE && input typemaps now assume the object has been moved.
+
+ These typemaps have been changed assuming that after the function call,
+ the rvalue reference parameter has been moved. The parameter's proxy class
+ that owns the C++ object thus has the underlying pointer set to null
+ so that the (moved from, but still valid) C++ object cannot be used again
+ and the object is additionally deleted.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-08-28: wsfulton
+ [Octave] SWIG now marshals a C/C++ NULL pointer into the null matrix, [].
+ SWIG has always marshalled the null matrix into a NULL pointer; this remains
+ and now we have consistency in representing a NULL pointer.
+
+2022-08-26: wsfulton
+ [Racket] SWIG now marshals a C/C++ NULL pointer into a null value by calling
+ scheme_make_null(), so that scheme's null? is true for a NULL C/C++ pointer value.
+
+2022-08-18: wsfulton
+ [Racket] Add support for std::unique_ptr in std_unique_ptr.i.
+ Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-13: wsfulton
+ [Guile] Add support for std::unique_ptr in std_unique_ptr.i.
+ Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-11: wsfulton
+ [Lua] Add support for std::unique_ptr in std_unique_ptr.i.
+ Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-05: wsfulton
+ [D] Fix occasional undefined behaviour with inheritance hierarchies, particularly
+ when using virtual inheritance as the pointers weren't correctly upcast from derived
+ class to base class when stored in the base's proxy class.
+
+2022-08-05: wsfulton
+ [D] Add support for std::unique_ptr in std_unique_ptr.i.
+ Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-03: wsfulton
+ [Javascript] Add support for std::unique_ptr in std_unique_ptr.i.
+ Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-02: wsfulton
+ [Octave] Add support for std::unique_ptr in std_unique_ptr.i.
+ Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-01: wsfulton
+ [Python] Add initialisers for additional members in PyHeapTypeObject
+ (builtin mode) for Python-3.11 - _ht_tpname, _spec_cache.
+
+2022-07-30: wsfulton
+ C++20 has deprecated std::basic_string<>::reserve() and the C++11 method
+ std::basic_string<>::shrink_to_fit() is a replacement that can be used.
+ std_string.i and std_wstring.i provided wrappers for reserve with the following
+ template instantiations:
+
+ %template(string) std::basic_string<char>;
+ %template(wstring) std::basic_string<wchar_t>;
+
+ The reserve method is no longer wrapped, however the shrink_to_fit() method
+ can be used as an alternative from the target language (the generated wrappers
+ call reserve() instead if C++<=20).
+
+ Note that std::basic_string<>::reserve(size_t n) is still wrapped unchanged.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-07-30: wsfulton
+ [Tcl] Add support for std::unique_ptr in std_unique_ptr.i.
+ Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-07-27: ZackerySpytz, olly
+ #1678 Support parsing C++20 templated lambdas.
+
+2022-07-27: ZackerySpytz, olly
+ #1622 Add support for the C++20 spaceship operator (<=>).
+
+2022-07-26: olly
+ [Tcl] https://sourceforge.net/p/swig/bugs/977/
+ Fix handling of long long on 32-bit platforms. This fix raises
+ SWIG's minimum supported Tcl version to 8.4.0 (which was released
+ just under 20 years ago).
+
+2022-07-26: olly
+ Fix incorrect operator precedence in preprocessor expressions.
+
+2022-07-25: olly
+ Support for C++14 binary integer literals in preprocessor expressions.
+
+2022-07-20: wsfulton
+ [C#, Java] Ensure the order of interfaces generated in proxy interfaces for the
+ %interface family of macros is the same as that parsed from the bases in C++.
+
+2022-07-20: jicks, Ingener74, olly
+ #422 [Python] Fix mishandling of a Python class inheriting from
+ multiple SWIG-wrapped director classes.
+
+2022-07-19: wsfulton
+ #692 [C#, Java, Perl, Python, Ruby] std::unique_ptr and std::auto_ptr typemaps
+ provided for inputs types in std_unique_ptr.i and std_auto_ptr.i.
+
+ Now these smart pointers can be used as input parameters to functions. A proxy
+ class instance transfers memory ownership of the underlying C++ object from the
+ proxy class to a smart pointer instance passed to the wrapped function.
+
+2022-07-19: jschueller
+ [Python] #2314 Drop support for Python 3.2.
+
+2022-07-19: olly
+ Remove remaining support code for classic macos, which has not been
+ supported by Apple for over 20 years now.
+
+2022-07-12: wsfulton
+ #999 Performance optimisation for parameters passed by value that are C++11 movable.
+ The C++ wrappers create a temporary variable for a parameter to be passed to a
+ function. This is initially default constructed and then copy assigned from the
+ instance being passed in from the target language. This is unchanged, however,
+ when the temporary variable is passed to the wrapped function, it is now done using
+ std::move. If the type is move constructible, the move constructor will be used
+ instead of the copy constructor.
+
+2022-07-12: wsfulton
+ [Perl] Add std::auto_ptr support in std_auto_ptr.i library file.
+
+2022-07-12: erezgeva
+ [Perl] Add std::unique_ptr support in std_unique_ptr.i library file.
+
+2022-07-07: jmarrec
+ #1158 #2286 Add basic support for C++11 attributes. These are now
+ crudely ignored by SWIG's parser's tokeniser, which is better that
+ failing with a parse error.
+
+2022-07-05: ianlancetaylor
+ [Go] #2245 Handle NULL pointers for string* conversions.
+ Rearrange generation of director methods and rename
+ receiver argument from p to swig_p.
+
+2022-07-03: wsfulton
+ #999 Performance optimisation for directors for classes passed by value. The directorin
+ typemaps in the director methods now use std::move on the input parameter when
+ copying the object from the stack to the heap prior to the callback into the target
+ language, thereby taking advantage of move semantics if available.
+
+2022-07-02: wsfulton
+ #1722 [C#, Java, Python, Ruby] Add std::unique_ptr support. Ported from std::auto_ptr.
+ Use the %unique_ptr(T) macro as follows for usage std::unique_ptr<T>. For example, for
+ a class called Klass:
+
+ %include "std_unique_ptr.i"
+ %unique_ptr(Klass)
+
+ Support is currently limited to only returning a std::unique_ptr from a function.
+
+2022-06-29: wsfulton
+ #999 #1044 Enhance SWIGTYPE "out" typemaps to use std::move when copying
+ objects, thereby making use of move semantics when wrapping a function returning
+ by value if the returned type supports move semantics.
+
+ Wrapping functions that return move only types 'by value' now work out the box
+ without having to provide custom typemaps.
+
+ The implementation removed all casts in the "out" typemaps to allow the compiler to
+ appropriately choose calling a move constructor, where possible, otherwise a copy
+ constructor. The implementation also required modifying SwigValueWrapper to
+ change a cast operator from:
+
+ SwigValueWrapper::operator T&() const;
+
+ to
+
+ #if __cplusplus >=201103L
+ SwigValueWrapper::operator T&&() const;
+ #else
+ SwigValueWrapper::operator T&() const;
+ #endif
+
+ This is not backwards compatible for C++11 and later when using the valuewrapper feature
+ if a cast is explicitly being made in user supplied "out" typemaps. Suggested change
+ in custom "out" typemaps for C++11 and later code:
+
+ 1. Try remove the cast altogether to let the compiler use an appropriate implicit cast.
+ 2. Change the cast, for example, from static_cast<X &> to static_cast<X &&>, using the
+ __cplusplus macro if all versions of C++ need to be supported.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-06-15: wsfulton
+ #2039 Add move assignment operator to SwigValueWrapper used by the
+ valuewrapper feature.
+
+2022-06-04: sethrj
+ Enhance $typemap to support typemap attributes.
+
+ $typemap(method:attribute, typepattern)
+
+ For example:
+
+ %typemap(cstype, out="object") XClass "XClass"
+ %typemap(cscode) BarClass %{
+ $typemap(cstype:out, XClass) bar() {
+ return null;
+ }
+
+ which expands to
+
+ object bar() {
+ return null;
+ }
+
+2022-05-30: wsfulton
+ [C#, D] Add new special variable expansion: $imfuncname.
+ Expands to the function name called in the intermediary class.
+
+2022-05-30: LindleyF
+ [Java] #2042 Add new special variable expansion: $imfuncname.
+ Expands to the function name called in the intermediary class.
+
+2022-05-28: jkuebart
+ [Java] On some versions of Android, specifically Android 6,
+ detaching the current thread from the JVM after every invocation
+ causes a memory leak.
+
+ Offer SWIG_JAVA_DETACH_ON_THREAD_END to configure a behaviour
+ where the JVM is only detached in the thread destructor.
+
+ See https://developer.android.com/training/articles/perf-jni#threads.
+
+2022-05-27: xypron
+ [Python] #2277 Define PY_SSIZE_T_CLEAN macro before #include "Python.h" as
+ recommended in Python 3.7 and later.
+
+ To avoid this macro definition, add the following to your interface file so
+ that SWIG_NO_PY_SSIZE_T_CLEAN is defined at the beginning of the C++ wrappers:
+
+ %begin %{
+ #define SWIG_NO_PY_SSIZE_T_CLEAN
+ %}
+
+2022-05-26: rokups
+ [C#] #1323 Modify SwigDerivedClassHasMethod for a more efficient director
+ implementation when calling virtual methods that are not overridden.
+
+2022-05-15: erezgeva, eiselekd
+ [Lua, Perl, Octave, PHP, Tcl] #2275 #2276 #2283 Add argcargv.i library containing
+ (int ARGC, char **ARGV) multi-argument typemaps.
+
+ 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
+
+2022-04-20: cminyard
+ Fix an issue where newlines were not properly generated
+ for godirectorin typemaps. If you have a virtual function
+ not assigned to zero, in some cases it won't generate a
+ newline and you will see errors:
+ example.go:1508:3: expected ';', found swig_r
+ when compiling the go code.
+
+ Also add an example of using goin and godirectorin and add
+ a test for this situation.
+
+2022-04-29: jason-daly, JerryJoyce, wsfulton
+ [C#] #1233 Add wchar_t * and std::wstring Unicode string support on Linux.
+
+2022-04-11: robinst
+ #2257 Fix new Ruby 3.2 warning "undefining the allocator of T_DATA
+ class swig_runtime_data".
+
+2022-04-07: olly
+ #1750 SWIG now recognises and ignores Doxygen group commands `@{` and `@}`.
+
+2022-04-06: wsfulton
+ ./configure now enables C++11 and later C++ standards testing by default (when
+ running: 'make check').
+
+ The options to control this testing are the same:
+
+ ./configure --enable-cpp11-testing
+ ./configure --disable-cpp11-testing
+
+ But the former is now the default and the latter can be used to turn off C++11 and
+ later C++ standards testing.
+
+2022-04-06: wsfulton
+ [Python] #1635 The "autodoc" feature no longer overrides Doxygen comments
+ in the generated docstring.
+
+ If a "docstring" feature is present it will still override a Doxygen comment.
+ If the "autodoc" feature is also present, the combined "autodoc" and "docstring"
+ will override the Doxygen comment. If no "docstring" is present then the
+ "autodoc" feature will not be generated when there is a Doxygen comment.
+
+ This way the "autodoc" feature can be specified and used to provide documentation
+ for 'missing' Doxygen comments.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-04-01: olly
+ Remove undocumented and non-functional -browse command line option.
+
+2022-03-26: eltoder
+ [Python] #1684 Use different capsule names with and without -builtin
+
+ Types generated with and without -builtin are not compatible. Mixing
+ them in a common type list leads to crashes. Avoid this by using
+ different capsule names: "type_pointer_capsule" without -builtin and
+ "type_pointer_capsule_builtin" with.
+
+2022-03-25: wsfulton
+ The debug command line options that display parse tree nodes
+ (-debug-module, -debug-top, -debug-symtabs) now display previously hidden
+ linked list pointers which are useful for debugging parse trees.
+
+ Added new command line option -debug-quiet. This suppresses the display
+ of most linked list pointers and symbol table pointers in the parse tree nodes.
+
+ The keys in the parse tree node are now shown in alphabetical order.
+
+2022-03-24: wsfulton
+ #2244 Fix using declaration in derived class bugs when all the base
+ class's overloaded methods were overridden in the derived class -
+ fixes "multiply defined" errors.
+
+2022-03-23: wsfulton
+ [Python] #1779 The -py3 option is deprecated and now has no effect on the
+ code generated. Use of this option results in a deprecated warning.
+ The related SWIGPYTHON_PY3 macro that this option defined is no longer generated.
+
+ Note that %pythonnondynamic feature generates a metaclass that works on both
+ Python 2 and Python 3.
+
+2022-03-21: wsfulton
+ [Python] #1779 pyabc.i for abstract base classes now supports versions of
+ Python prior to 3.3 by using the collection module for these older versions.
+ Python-3.3 and later continue to use the collections.abc module.
+ The -py3 option no longer has any effect on the %pythonabc feature.
+
+2022-03-21: jschueller, jim-easterbrook, wsfulton
+ [Python] #2137 C++ static member functions no longer generate a "flattened"
+ name in the Python module. For example:
+
+ s = example.Spam()
+ s.foo() # Spam::foo() via an instance
+ example.Spam.foo() # Spam::foo() using class method
+ example.Spam_foo() # Spam::foo() "flattened" name
+
+ The "flattened" name is no longer generated, but can be generated
+ by using the new -flatstaticmethod option.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-03-18: ianlancetaylor
+ [Go] #337 Implement %extend base methods in child classes.
+
+2022-03-17: olly
+ [Python] #1779 SWIG's Python test-suite and examples are now
+ run with Python 3 by default. To run them with Python 2, set
+ PY2 to a non-empty value, e.g.:
+
+ make check-python-test-suite PY2=1
+
+2022-03-16: olly
+ [Go] #683 -intgosize is now optional - if not specified the
+ generated C/C++ wrapper code will use ptrdiff_t for intgo and
+ size_t for uintgo.
+
+2022-03-15: ianlancetaylor
+ [Go] Add typemaps for std::string*.
+
+2022-03-15: ianlancetaylor
+ [Go] Don't convert arrays to pointers if there is a "gotype"
+ typemap entry.
+
+2022-03-15: ianlancetaylor
+ [Go] Add documentation note about Go and C++ exceptions.
+
+2022-03-12: wsfulton
+ #1524 %interface family of macros no longer contain the getter/setter
+ methods for wrapping variables. The interface only contains
+ virtual and non-virtual instance methods, that is, no static methods.
+ Enums are also no longer added to the interface (affects Java only where
+ they were missing from the proxy class, C# never had them in the interface).
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-03-12: wsfulton
+ #1277 Fixes for the family of %interface macros, %interface,
+ %interface_impl and %interface_custom fixes for overloaded methods
+ in an inheritance chain.
+
+ When C++ methods are not able to be overloaded in a derived class,
+ such as when they differ by just const, or the target language
+ parameters types are identical even when the C++ parameter types
+ are different, SWIG will ignore one of the overloaded methods with
+ a warning. A %ignore is required to explicitly ignore one of the
+ overloaded methods to avoid the warning message. Methods added
+ in the derived classes due to one of the %interface macros are now
+ similarly ignored/not added to the derived class.
+
+ The methods added to the derived classes can now also be modified
+ via %feature and %rename.
+
+2022-03-08: ianlancetaylor
+ [Go] Treat a nil argument as a NULL pointer.
+
+2022-03-08: ianlancetaylor
+ [Go] Add documentation notes about thread local storage.
+
+2022-03-08: olly
+ #1006 SWIG now copes with an interface filename specified on the
+ command line which contains a closing parenthesis `)`, and more
+ generally with attributes to `%include` and `%import` which
+ are quoted and contain parentheses.
+
+2022-03-07: Omar Medina
+ [Tcl] https://sourceforge.net/p/swig/bugs/1290/
+ Fix SWIG_AsWCharPtrAndSize() to actually assign to result
+ variable. It looks like SWIG/Tcl wide character handling is
+ currently fundamentally broken except on systems which use wide
+ characters as the system encoding, but this should fix wrapping
+ functions which take a wide string as a parameter on Microsoft
+ Windows.
+
+2022-03-07: olly
+ [Javascript] #682 Fix handling of functions which take void*.
+
+2022-03-06: olly
+ SWIG should now reliably exit with status 0 if the run was
+ successful and status 1 if there was an error (or a warning and
+ -Werror was in effect).
+
+ Previously in some situations SWIG would try to exit with the
+ status set to the number of errors encountered, but that's
+ problematic - for example if there were 256 errors this would
+ result in exit status 0 on most platforms. Also some error
+ statuses have special meanings e.g. those defined by <sysexits.h>.
+ Also SWIG/Javascript tried to exit with status -1 in a few places
+ (which typically results in exit status 255).
+
+2022-03-05: wsfulton
+ #1441 Fix using declaration in derived class incorrectly introducing a method
+ from a base class when the using declaration is declared before the method
+ declaration. Problem occurred when within a namespace and the parameter types
+ in the method signatures were not fully qualified.
+2022-03-05: ianlancetaylor
+ [Go] Treat non-const references as pointers.
+
+2022-03-05: ianlancetaylor
+ In SWIG Go testsuite, fail test if "go build" fails.
+
+2022-03-03: olly
+ #1901 #2223 SWIG should now always exit cleanly if memory
+ allocation fails, including removing any output files created
+ during the current run.
+
+ Previously most places in the code didn't check for a NULL return
+ from malloc()/realloc()/calloc() at all, typically resulting in
+ undefined behaviour; some places used assert() to check for a NULL
+ return (which is a misuse of assert() and such checks disappear if
+ built with NDEBUG defined leaving us back with undefined
+ behaviour).
+
+2022-03-03: olly
+ #891 Report errors for typemap attributes without a value
+ (previously SWIG segfaulted) and for typemap types with a value
+ (previously the value was quietly ignored).
+
+ The old way of specifying a language name in the typemap attributes
+ is no longer supported (it has been deprecated for 16 years).
+
+2022-03-02: geographika, wsfulton
+ [Python] #1951 Add Python variable annotations support.
+
+ Both function annotations and variable annotations are turned on using the
+ "python:annotations" feature. Example:
+
+ %feature("python:annotations", "c");
+
+ struct V {
+ float val;
+ };
+
+ The generated code contains a variable annotation containing the C float type:
+
+ class V(object):
+ val: "float" = property(_example.V_val_get, _example.V_val_set)
+ ...
+
+ Python 3.5 and earlier do not support variable annotations, so variable
+ annotations can be turned off with a "python:annotations:novar" feature flag.
+ Example turning on function annotations but not variable annotations globally:
+
+ %feature("python:annotations", "c");
+ %feature("python:annotations:novar");
+
+ or via the command line:
+
+ -features python:annotations=c,python:annotations:novar
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-02-27: wsfulton
+ [Python] #735 #1561 Function annotations containing C/C++ types are no longer
+ generated when using the -py3 option. Function annotations support has been
+ moved to a feature to provide finer grained control. It can be turned on
+ globally by adding:
+
+ %feature("python:annotations", "c");
+
+ or by using the command line argument:
+
+ -features python:annotations=c
+
+ Also see entry dated 2022-03-02, regarding variable annotations.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-02-26: wsfulton
+ #655 #1840 Add new warning WARN_LANG_USING_NAME_DIFFERENT to warn when a
+ method introduced by a using declaration in a derived class cannot
+ be used due to a conflict in names.
+
+2022-02-24: olly
+ #1465 An invalid preprocessor expression is reported as a pair of
+ warnings with the second giving a more detailed message from the
+ expression evaluator. Previously SWIG prefixed the second message
+ with "Error:" - that was confusing as it's actually only a warning
+ by default so we've now dropped this prefix.
+
+ Before:
+
+ x.i:1: Warning 202: Could not evaluate expression '1.2'
+ x.i:1: Warning 202: Error: 'Floating point constant in preprocessor expression'
+
+ Now:
+
+ x.i:1: Warning 202: Could not evaluate expression '1.2'
+ x.i:1: Warning 202: Floating point constant in preprocessor expression
+
+2022-02-23: olly
+ #1384 Fix a preprocessor expression evaluation bug. A
+ subexpression in parentheses lost its string/int type flag and
+ instead used whatever type was left in the stack entry from
+ previous use. In practice we mostly got away with this because
+ most preprocessor expressions are integer, but it could have
+ resulted in a preprocessor expression incorrectly evaluating as
+ zero. If -Wextra was in use you got a warning:
+
+ Warning 202: Error: 'Can't mix strings and integers in expression'
+
+2022-02-21: davidcl
+ [Scilab] Improve 5.5.2, 6.0.0 and 6.1.0 support.
+
+ For Scilab 5, long names are reduced to small names preserving the
+ class prefix and accessor suffix (get or set).
+
+ For Scilab 6, long names with the class prefix and accessor suffix
+ should be used on the user code.
+
+ The `-targetversion` option has been removed as the generated code
+ now detects the Scilab version in loader.sce or builder.sce.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-02-20: wsfulton
+ Fix %warnfilter warning suppress for warning 315 SWIGWARN_PARSE_USING_UNDEF.
+
+2022-02-17: olly
+ [PHP] https://sourceforge.net/p/swig/bugs/1211/
+ Fix to call cleanup code in exception situations and not to invoke
+ the freearg typemap twice in certain situations.
+
+2022-02-15: olly
+ #300 #368 Improve parser handling of % followed immediately by
+ an identifier. If it's not a recognised directive the scanner
+ now emits MODULO and then rescans what follows, and if the parser
+ then gives a syntax error we report it as an unknown directive.
+ This means that `a%b` is now allowed in an expression, and that
+ things like `%std::vector<std::string>` now give an error rather
+ than being quietly ignored.
+
+2022-02-11: adr26
+ [Python] #2154 Fix memory leak.
+
+ SWIG python objects were being freed after the corresponding SWIG
+ module information was destroyed in Python 3, causing leaks when as
+ a result the object destructor could not be invoked. To prevent this
+ misordering, SWIG python objects now obtain a reference to the
+ Python capsule wrapping the module information, so that the module
+ information is correctly destroyed after all SWIG python objects
+ have been freed (and corresponding destructors invoked).
+
+2022-02-10: olly
+ [Tcl] https://sourceforge.net/p/swig/bugs/1207/
+ https://sourceforge.net/p/swig/bugs/1213/
+
+ Fix Tcl generic input typemap for std::vector.
+
+2022-02-07: sethrj
+ #2196 Add alternative syntax for specifying fragments in typemaps.
+
+ New syntax:
+ %typemap("in", fragment="frag1", fragment="frag2", fragment="frag3") {...}
+ which is equivalent to:
+ %typemap(in, fragment="frag1,frag2,frag3") {...}
+
+
+2022-02-07: olly
+ #1806 Remove support for the "command" encoder, which was mostly
+ intended for use in `%rename` - most uses can be achieved using
+ the "regex" encoder, so we recommend using that instead.
+
+ The "command" encoder suffers from a number of issues - as the
+ documentation for it admitted, "[it] is extremely slow compared to
+ all the other [encoders] as it involves spawning a separate process
+ and using it for many declarations is not recommended" and that it
+ "should generally be avoided because of performance
+ considerations".
+
+ But it's also not portable. The design assumes that `/bin/sh`
+ supports `<<<` but that's a bash-specific feature so it doesn't
+ work on platforms where `/bin/sh` is not bash - it fails on
+ Debian, Ubuntu and probably some other Linux distros, plus most
+ non-Linux platforms. Microsoft Windows doesn't even have a
+ /bin/sh as standard.
+
+ Finally, no escaping of the passed string is done, so it has
+ potential security issues (though at least with %rename the input
+ is limited to valid C/C++ symbol names).
+
+2022-02-06: olly
+ #2193 -DFOO on the SWIG command line now sets FOO to 1 for
+ consistency with C/C++ compiler preprocessors. Previously
+ SWIG set FOO to an empty value.
+
+ Existing invocations of SWIG with `-DFOO` where the empty value
+ matters can be updated to `-DFOO=` which should work with both
+ old and new releases of SWIG.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2022-02-06: sethrj
+ #2194 Classes that are non-assignable due to const data or const
+ reference members are now automatically detected.
+
+2022-02-04: friedrichatgc
+ [Octave] #1672 Fix for isobject for Octave 4.4 - 6.0.
+
+2022-02-03: olly
+ [C#] #283 #998 Fix memory leak in directorin typemap for
+ std::string.
+
+2022-02-03: olly
+ [Python] #967 Make `self` parameter available to user typemaps.
+
+2022-02-03: teythoon
+ [Python] #801 Fix -Wunused-parameter warnings with builtin,
+
+2022-02-03: teythoon
+ #801 Fix -Wstrict-prototypes warnings in generated pointer
+ functions.
+
+2022-02-03: olly
+ #660 https://sourceforge.net/p/swig/bugs/1081/
+ Default parameter values containing method calls are now parsed and
+ handled - e.g. `x->foo(3,4)` and `y.z()`.
+
+2022-02-02: olly
+ [Ruby] https://sourceforge.net/p/swig/bugs/1136/ Fix remove of prefix
+ from method name to only remove it at the start.
+
+2022-02-01: olly
+ #231 Handle returning an object by reference in a C++ trailing
+ return type.
+
+2022-02-01: davidcl
+ [Scilab] #745 use SWIG_<module>_Init() as a C module init function.
+
+2022-02-01: olly
+ [OCaml] #2083 Fix to work when CAML_SAFE_STRING is on, which it is
+ by default in recent Ocaml releases.
+
+2022-01-31: mreeez
+ https://sourceforge.net/p/swig/bugs/1147/
+ Fix copyToR() generated for a struct in a namespace.
+
+2022-01-29: fschlimb
+ #655 Better handling of using declarations.
+
+2022-01-29: dontpanic92
+ [Go] #676 Fix code generated for a C++ class with a non-capitalised
+ name.
+
+2022-01-26: trex58
+ #1919 #1921 #1923 Various fixes for AIX portability.
+
+2022-01-26: olly
+ #1935 Don't crash on an unclosed HTML tag in a doxygen comment
+ when -doxygen is specified.
+
+2022-01-25: olly
+ Constant expressions now support member access with `.` such as
+ `foo.bar`. Previous this only worked in a case like `x->foo.bar`.
+
+2022-01-25: olly
+ #2091 Support most cases of `sizeof` applied to an expression
+ in constant expressions. Previously there was only support for
+ `sizeof(<type>)` and expressions which syntactically look like a
+ type (such as `sizeof(foo)`).
+
+2022-01-25: olly
+ #80 #635 https://sourceforge.net/p/swig/bugs/1139/
+ Add support for parsing common cases of `<` and `>` comparisons
+ in constant expressions. Adding full support for these seems hard
+ to do without introducing conflicts into the parser grammar, but in
+ fact all reported cases have had parentheses around the comparison
+ and we can support that with a few restrictions on the left side of
+ `<`.
+
+2022-01-25: wsfulton
+ New warning 327 for extern templates, eg:
+
+ extern template class std::vector<int>;
+ extern template void Func<int>();
+
+ results in warning
+
+ example.i:3: Warning 327: Extern template ignored.
+ example.i:4: Warning 327: Extern template ignored.
+
+ Extern template classes previously resulted in warning 320.
+
+2022-01-24: romintomasetti
+ #2131 #2157 C++11 extern function template parsing error fix.
+
+2022-01-21: wsfulton
+ #2120 #2138 Replace legacy PCRE dependency with PCRE2.
+ This requires changes for building SWIG from source. See updated
+ html documentation in Preface.html and Windows.html. Updated
+ instructions are also shown when running ./configure if PCRE2 is not
+ found. Note that debian based systems can install PCRE2 using:
+
+ apt install libpcre2-dev
+
+ Note that https://github.com/swig/swig/wiki/Getting-Started also has
+ updated information for building from source.
+
+2022-01-19: olly
+ [PHP] #2027 Automatically generate PHP type declarations for PHP 8.
+ The generate code still compiles for PHP 7.x, but without type
+ declarations since PHP 7.x has much more limited type declaration
+ support.
+
+2022-01-18: olly
+ [Perl] #1629 Perl 5.8.0 is now the oldest version we aim to support.
+
+2022-01-14: wsfulton
+ [Python] Fix %callback and specifying the callback function as a
+ static member function using Python staticmethod syntax, such as
+ Klass.memberfunction instead of Klass_memberfunction when using
+ -builtin and -fastproxy.
+
+2022-01-11: wsfulton
+ [Python] Accept keyword arguments accessing static member functions when
+ using -builtin and kwargs feature and Python class staticmethod syntax.
+ The missing keyword argument support was only when using the
+ class staticmethod syntax, such as Klass.memberfunction, and not when
+ using the flat static method syntax, such as Klass_memberfunction.
+
+2022-01-04: juierror
+ [Go] #2045 Add support for std::array in std_array.i.
+
+2021-12-18: olly
+ [PHP] Add PHP keyword 'readonly' (added in 8.1) to the list SWIG
+ knows to automatically rename. This keyword is special in that PHP
+ allows it to be used as a function (or method) name.
+
+2021-12-07: vstinner
+ [Python] #2116 Python 3.11 support: use Py_SET_TYPE()
+
+2021-12-05: rwf1
+ [Octave] #2020 #1893 Add support for Octave 6 up to and including 6.4.
+ Also add support for compiling with -Bsymbolic which is used by default
+ by mkoctfile.
+
+2021-12-02: jsenn
+ [Python] #2102 Fixed crashes when using embedded Python interpreters.
+
2021-11-12: wsfulton
[Javascript] v8 and node only. Fix mismatched new char[] and free()
when wrapping C code char arrays. Now calloc is now used instead of
@@ -257,7 +1220,6 @@ Version 4.1.0 (in progress)
%typemap(csinterfacemodifiers) X "internal interface"
-
2020-09-24: geefr
[C#] #1868 Fix wchar_t* csvarout typemap for member variable wrappers.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8a195de54..8a8862f63 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -73,11 +73,11 @@ if (MSVC)
set (CMAKE_CXX_FLAGS "/EHsc ${CMAKE_CXX_FLAGS}")
endif ()
-option (WITH_PCRE "Enable pcre" ON)
+option (WITH_PCRE "Enable PCRE" ON)
if (WITH_PCRE)
- find_package (PCRE REQUIRED)
+ find_package (PCRE2 REQUIRED)
set (HAVE_PCRE 1)
- include_directories (${PCRE_INCLUDE_DIRS})
+ include_directories (${PCRE2_INCLUDE_DIRS})
endif()
if (WIN32)
@@ -145,8 +145,8 @@ add_executable (swig
${PROJECT_BINARY_DIR}/Source/CParse/parser.c
${PROJECT_BINARY_DIR}/Source/CParse/parser.h
)
-if (PCRE_FOUND)
- target_link_libraries (swig ${PCRE_LIBRARIES})
+if (PCRE2_FOUND)
+ target_link_libraries (swig ${PCRE2_LIBRARIES})
endif ()
install (TARGETS swig DESTINATION bin)
@@ -160,6 +160,7 @@ include (CPack)
# few tests
enable_testing ()
add_test (NAME cmd_version COMMAND swig -version)
+add_test (NAME cmd_pcreversion COMMAND swig -pcreversion)
add_test (NAME cmd_swiglib COMMAND swig -swiglib)
add_test (NAME cmd_external_runtime COMMAND swig -external-runtime ext_rt.h)
set_tests_properties(cmd_external_runtime PROPERTIES ENVIRONMENT "SWIG_LIB=${PROJECT_SOURCE_DIR}/Lib")
diff --git a/Doc/Devel/cmdopt.html b/Doc/Devel/cmdopt.html
index 5e90d2aba..10dc73170 100644
--- a/Doc/Devel/cmdopt.html
+++ b/Doc/Devel/cmdopt.html
@@ -60,7 +60,7 @@ and issues an error message if any unconsumed arguments are found.
<b><tt>void Swig_check_options()</tt></b>
<blockquote>
Checks all command line options to see if they have all been processed. If not, an error message is generated and
-execution terminates with a call to <tt>exit()</tt>. This function is currently invoked in <tt>Source/Modules/main.cxx</tt> just before SWIG starts any processing of input files.
+SWIG exits. This function is currently invoked in <tt>Source/Modules/main.cxx</tt> just before SWIG starts any processing of input files.
</blockquote>
<h2>Utility Function</h2>
@@ -68,7 +68,7 @@ execution terminates with a call to <tt>exit()</tt>. This function is currentl
<b><tt>void Swig_arg_error())</tt></b>
<blockquote>
-A generic function that issues an error message about being unable to parse command line options. SWIG is terminated by a call to <tt>exit()</tt>.
+A generic function that issues an error message about being unable to parse command line options and SWIG exits.
</body>
</html>
diff --git a/Doc/Devel/engineering.html b/Doc/Devel/engineering.html
index c12eb1328..c2cad4804 100644
--- a/Doc/Devel/engineering.html
+++ b/Doc/Devel/engineering.html
@@ -130,7 +130,7 @@ like this:
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* xxx.c
*
diff --git a/Doc/Devel/internals.html b/Doc/Devel/internals.html
index c9082d3f6..d003d9dea 100644
--- a/Doc/Devel/internals.html
+++ b/Doc/Devel/internals.html
@@ -441,12 +441,12 @@ Resulting output:
<blockquote>
<pre>
-hash len: 5
-get: hashval2
-hash item: hashval5 [h5]
-hash item: hashval1 [h1]
-hash item: hashval2 [h2]
-hash item: hashval3 [h3]
+list len: 5
+get: listval2
+list item: newlistval1
+list item: listval2
+list item: listval3
+list item: listval5
</pre>
</blockquote>
@@ -494,12 +494,12 @@ Resulting output:
<blockquote>
<pre>
-list len: 5
-get: listval2
-list item: newlistval1
-list item: listval2
-list item: listval3
-list item: listval5
+hash len: 5
+get: hashval2
+hash item: hashval5 [h5]
+hash item: hashval1 [h1]
+hash item: hashval2 [h2]
+hash item: hashval3 [h3]
</pre>
</blockquote>
@@ -519,7 +519,27 @@ list item: listval5
<h3>2.10 Utility functions </h3>
</a>
-[ TODO ]
+<p>
+DOH wraps some standard C library functions - these wrapped versions should
+always be used in code in the SWIG tool itself (but not in generated code).
+When compiling with GCC or clang, the original library function names are
+marked as "poisoned" symbols so you should get an error if you accidentally
+use one of the unwrapped functions. These functions are:
+
+<ul>
+ <li><tt>Calloc(m,n)</tt> : wrapper for <tt>calloc(m,n)</tt> which exits on memory failure so never returns <tt>NULL</tt>.
+ <li><tt>Malloc(n)</tt> : wrapper for <tt>malloc(n)</tt> which exits on memory failure so never returns <tt>NULL</tt>.
+ <li><tt>Realloc(p,n)</tt> : wrapper for <tt>realloc(p,n)</tt> which exits on memory failure so never returns <tt>NULL</tt>.
+ <li><tt>Free(p)</tt> : wrapper for <tt>free(p)</tt> (doesn't currently do anything special, really done for consistency with <tt>Malloc()</tt> etc).
+ <li><tt>Exit(r)</tt> : wrapper for <tt>exit(r)</tt> which for SWIG removes generated files if <tt>r&gt;0</tt>.
+</ul>
+
+<tt>abort()</tt> is also poisoned - please use <tt>Exit(EXIT_FAILURE)</tt> instead so that generated files are removed.
+</p>
+
+<p>
+[ TODO document others ]
+</p>
<a name="3" href="#i3">
<h2>3. Types and Typemaps</h2>
@@ -1194,12 +1214,12 @@ that are used after they have been deleted. This is because the DOH memory alloc
grabs a chunk of memory from the C memory allocator and manages the usage internally.
Stale DOH object usage can be checked for by defining <tt>DOH_DEBUG_MEMORY_POOLS</tt> in
<tt>memory.c</tt>. If an attempt to use an object is made after the reference count is
-zero, an assertion is triggered instead of quietly re-using the stale object...
+zero, a fatal error is triggered instead of quietly re-using the stale object:
</p>
<blockquote>
<pre>
-swig: DOH/memory.c:91: DohCheck: Assertion `!DOH_object_already_deleted' failed.
+Fatal internal error: Attempt to delete a non-DOH object.
</pre>
</blockquote>
@@ -1209,7 +1229,7 @@ only recommended for diagnosing memory corruption problems.
</p>
<hr>
-Copyright (C) 1999-2010 SWIG Development Team.
+Copyright (C) 1999-2022 SWIG Development Team.
</body>
</html>
diff --git a/Doc/Devel/plan-gsoc-2012.txt b/Doc/Devel/plan-gsoc-2012.txt
index ac764fb2a..c217dad8d 100644
--- a/Doc/Devel/plan-gsoc-2012.txt
+++ b/Doc/Devel/plan-gsoc-2012.txt
@@ -45,7 +45,7 @@ Functionality
-----------------
Note:
- See 'http://www.stack.nl/~dimitri/doxygen/docblocks.html' for
+ See 'https://www.doxygen.nl/manual/docblocks.html' for
the detailed description of Doxygen syntax and terms used in this
section.
@@ -72,10 +72,10 @@ Functionality
----
This section contains all doxygen tags taken from
- http://www.stack.nl/~dimitri/doxygen/commands.html. If a tag is
+ https://www.doxygen.nl/manual/commands.html. If a tag is
marked as 'ignored', then the tag is ignored, but the text is copied
to the destination documentation. 'Not implemented' means that the
- tag with it's contents is stripped out of the output.
+ tag with its contents is stripped out of the output.
Doxygen tags:
diff --git a/Doc/Devel/scanner.html b/Doc/Devel/scanner.html
index 65ef1d8e9..d620c3d98 100644
--- a/Doc/Devel/scanner.html
+++ b/Doc/Devel/scanner.html
@@ -204,6 +204,7 @@ SWIG_TOKEN_LESSTHAN &lt;
SWIG_TOKEN_GREATERTHAN &gt;
SWIG_TOKEN_LTEQUAL &lt;=
SWIG_TOKEN_GTEQUAL &gt;=
+SWIG_TOKEN_LTEQUALGT &lt;=&gt;
SWIG_TOKEN_NOT ~
SWIG_TOKEN_LNOT !
SWIG_TOKEN_LBRACKET [
diff --git a/Doc/Devel/tree.html b/Doc/Devel/tree.html
index 5bb4b6a1e..2b9ac75dd 100644
--- a/Doc/Devel/tree.html
+++ b/Doc/Devel/tree.html
@@ -183,8 +183,8 @@ this function merely records that those attributes did not exist in the original
<b><tt>void Swig_require(const char *namespace, Node *n, ...)</tt></b>
<blockquote>
-This function is similar to <tt>Swig_save()</tt> except that adds additional attribute checking. There are different interpretations
-of the attribute names. A name of "attr" merely requests that the function check for the presence of an attribute. If the attribute is missing, SWIG will exit with a failed assertion. An attribute name of "?attr" specifies that the attribute "attr" is optional and
+This function is similar to <tt>Swig_save()</tt> except that it performs additional attribute checking. There are different interpretations
+of the attribute names. A name of "attr" merely requests that the function check for the presence of an attribute. If the attribute is missing, SWIG will exit with a fatal error. An attribute name of "?attr" specifies that the attribute "attr" is optional and
that its old value must be saved (if any). An attribute name of "*attr" specifies that the attribute is required and that
its value must be saved. The saving of attributes is performed in the same manner as with <tt>Swig_save()</tt>. Here is an example:
diff --git a/Doc/Manual/CCache.html b/Doc/Manual/CCache.html
index 1a94709ae..e6935b895 100644
--- a/Doc/Manual/CCache.html
+++ b/Doc/Manual/CCache.html
@@ -463,7 +463,7 @@ ccache was adapted to create ccache-swig for use with SWIG by William Fulton.
<p>
If you wish to report a problem or make a suggestion then please email
the SWIG developers on the swig-devel mailing list, see
-<a href="http://www.swig.org/mail.html">http://www.swig.org/mail.html</a>
+<a href="https://www.swig.org/mail.html">https://www.swig.org/mail.html</a>
<p>
ccache is released under the GNU General Public License version 2 or
later. Please see the file COPYING for license details.
diff --git a/Doc/Manual/CPlusPlus11.html b/Doc/Manual/CPlusPlus11.html
index e5d7fbc2d..a84ca5f51 100644
--- a/Doc/Manual/CPlusPlus11.html
+++ b/Doc/Manual/CPlusPlus11.html
@@ -15,6 +15,11 @@
<li><a href="#CPlusPlus11_core_language_changes">Core language changes</a>
<ul>
<li><a href="#CPlusPlus11_rvalue_reference_and_move_semantics">Rvalue reference and move semantics</a>
+<ul>
+<li><a href="#CPlusPlus11_rvalue_reference_inputs">Rvalue reference inputs</a>
+<li><a href="#CPlusPlus11_rvalue_reference_outputs">Rvalue reference outputs</a>
+<li><a href="#CPlusPlus11_move_only">Movable and move-only types by value</a>
+</ul>
<li><a href="#CPlusPlus11_generalized_constant_expressions">Generalized constant expressions</a>
<li><a href="#CPlusPlus11_extern_template">Extern template</a>
<li><a href="#CPlusPlus11_initializer_lists">Initializer lists</a>
@@ -95,6 +100,7 @@ class MyClass {
...
std::vector&lt;int&gt; numbers;
public:
+ MyClass() : numbers() {}
MyClass(MyClass &amp;&amp;other) : numbers(std::move(other.numbers)) {}
MyClass &amp; operator=(MyClass &amp;&amp;other) {
numbers = std::move(other.numbers);
@@ -104,8 +110,8 @@ public:
</pre></div>
<p>
-Rvalue references are designed for C++ temporaries and so are not very useful when used from non-C++ target languages.
-Generally you would just ignore them via <tt>%ignore</tt> before parsing the class.
+Rvalue references are designed for C++ temporaries and are not particularly useful when used from non-C++ target languages.
+One option is to just ignore them via <tt>%ignore</tt>.
For example, ignore the move constructor:
</p>
@@ -113,8 +119,49 @@ For example, ignore the move constructor:
%ignore MyClass::MyClass(MyClass &amp;&amp;);
</pre></div>
+<H4><a name="CPlusPlus11_rvalue_reference_inputs">7.2.1.1 Rvalue reference inputs</a></H4>
+
+
+<p>
+Rvalue reference parameters are useful as input parameters in C++ for implementing move semantics, such as,
+in the move constructor and move assignment operator.
+This type of usage can be useful from target languages too to avoid copying large objects.
+</p>
+
+<p>
+If you do wrap a function/contructor with an rvalue reference parameter and pass a proxy class to it, SWIG will assume that after the call, the rvalue reference parameter object will have been 'moved'.
+The proxy class passed as the rvalue reference, will own the underlying C++ object up until it is used as an rvalue reference parameter.
+Afterwards, the proxy class will have the underlying C++ pointer set to the nullptr so that the proxy class instance cannot be used again and the underlying (moved from) C++ object will be deleted after the function/constructor call has returned.
+</p>
+
+<p>
+In this way, the SWIG proxy class works much like an exclusively owned smart pointer (think of <tt>std::unique_ptr</tt>), passing ownership to the called C++ function/constructor.
+Let's consider an example in Java using the wrapped proxy class from above:
+</p>
+
+<div class="targetlang"><pre>
+MyClass mc = new MyClass();
+MyClass mc1 = new MyClass(mc); // move constructor
+MyClass mc2 = new MyClass(mc); // move constructor fails
+</pre></div>
+
<p>
-The plan is to ignore move constructors by default in a future version of SWIG. Note that both normal assignment operators as well as move assignment operators are ignored by default in most target languages with the following warning:
+The second call to the move constructor will fail as the <tt>mc</tt> proxy instance has been moved.
+Each target language handles the moved proxy class slightly differently when attempting to move it again, but typically you'll get an exception such as in Java:
+</p>
+
+<div class="shell">
+<pre>
+Exception in thread "main" java.lang.RuntimeException: Cannot release ownership as memory is not owned
+ at MyClass.swigRelease(MyClass.java:27)
+ at MyClass.&lt;init&gt;(MyClass.java:55)
+ at runme.main(runme.java:18)
+</pre>
+</div>
+
+
+<p>
+Note that both normal copy assignment operators as well as move assignment operators are ignored by default in the target languages with the following warning:
</p>
<div class="shell">
@@ -123,6 +170,332 @@ example.i:18: Warning 503: Can't wrap 'operator =' unless renamed to a valid ide
</pre>
</div>
+<p>
+Using a <tt>%rename</tt> will remove the warning and also makes the move assignment operator available from the target language:
+</p>
+<div class="code"><pre>
+%rename(MoveAssign) MyClass::operator=(MyClass &amp;&amp;);
+</pre></div>
+
+<p>
+You can then use it, but like the move constructor example above, you cannot use
+a proxy class once it has already been moved:
+</p>
+
+<div class="targetlang"><pre>
+MyClass mc = new MyClass();
+MyClass mc2 = mc.MoveAssign(mc);
+MyClass mc3 = mc.MoveAssign(mc); // Use of mc again will fail
+</pre></div>
+
+<p>
+It is of course perfectly possible in C++ for a function/constructor to not move an object passed to it in an rvalue reference parameter. The assumption that SWIG makes would then not hold and customisation of the appropriate input typemaps would be required.
+For scripting languages, this would be for the 'in' typemap and for the non-scripting languages additional typemaps such as the 'javain' typemap, which is used to set the memory ownership of the underlying C++ object for Java, would also need copying and modifying appropriately.
+</p>
+
+<p>
+<b>Compatibility note:</b>
+SWIG-4.1.0 changed the way that rvalue reference parameters were handled and implemented typemaps assuming that the
+proxy class owns the underlying C++ object and transfers ownership of the object when a function/constructor with an rvalue reference parameter is called.
+</p>
+
+<H4><a name="CPlusPlus11_rvalue_reference_outputs">7.2.1.2 Rvalue reference outputs</a></H4>
+
+
+<p>
+While rvalue reference parameter inputs are not uncommon in C++ and can be usefully utilised from target languages, this cannot be said for rvalue reference outputs.
+Firstly, it is quite unusual in C++ to have functions that return an rvalue reference.
+Secondly, these cases are nigh on impossible to use from a target language.
+The main problem is these references are for C++ compiler temporaries used on the stack and the target languages use objects on the heap
+and the concept of compiler temporary objects doesn't make sense from another language.
+</p>
+
+<p>
+Using <tt>MyClass</tt> from earlier and this C++ code:
+</p>
+
+<div class="code"><pre>
+void use(MyClass &amp;&amp;mc);
+MyClass &amp;&amp; get1();
+MyClass &amp; get2();
+</pre></div>
+
+<p>
+SWIG wraps the <tt>get1</tt> and <tt>get2</tt> functions more or less identically.
+The returned references are converted into pointers that are not owned by the target language.
+It means that the following perfectly valid C++ has no equivalent in any of the target languages:
+</p>
+
+<div class="code"><pre>
+use(get1());
+use(std::move(get2()));
+</pre></div>
+
+<p>
+An attempt to call the equivalent <tt>use(get1())</tt> from one of the target languages will result in the ownership failure mentioned in the previous section as the object being passed to the <tt>use</tt> function is not owned by the proxy class.
+In order to own the object, it would need to be cloned for the object to move from the stack to the heap, for which an appropriate clone function would be required, but may not even be available.
+Note that a move constructor or copy constructor may slice the object when inheritance is involved.
+Alternatively, customising the input rvalue reference typemap, as mentioned in the previous section, could remove the ownership requirement.
+Another alternative would be to modify the output rvalue reference typemap to always clone the rvalue reference object.
+Fortunately you're highly unlikely to have to solve any of these issues!
+</p>
+
+<H4><a name="CPlusPlus11_move_only">7.2.1.3 Movable and move-only types by value</a></H4>
+
+
+<p>
+SWIG has traditionally relied on wrapped C++ types to be copy constructible or copy assignable, either via an explicit or implicit copy constructor and copy assignment operator.
+Prior to C++11, a function could not return nor take a type by value that was not copyable.
+In C++11 this is no longer the case. A type can also be movable if it has has a move constructor and a move assignment operator.
+A move-only type is movable but not copyable; it has both the copy constructor and copy assignment operator deleted.
+Movable types can appear in function signatures for passing 'by value' and in C++11 the object can then be moved rather than copied.
+</p>
+
+<p>
+SWIG has support for both copyable and/or movable types.
+Support for move semantics is quite seamless when returning by value from a function.
+Support for move semantics is less so and may require some customisation when passing by value to a function.
+First let's consider returning by value from a function.
+</p>
+
+<p>
+The support for function return values is generically implemented in the "out" <tt>SWIGTYPE</tt> typemap which supports any type, including copyable, movable and move-only types.
+The typemap code is very simple and written so that the compiler will call the move constructor if possible,
+otherwise the copy constructor:
+</p>
+
+<div class="code"><pre>
+%typemap(out) SWIGTYPE %{
+ $result = new $1_ltype($1);
+%}
+</pre></div>
+
+<p>
+The above typemap is for C# and when used to wrap a move-only type such as:
+</p>
+
+<div class="code"><pre>
+struct MoveOnly {
+ int val;
+ MoveOnly(): val(0) {}
+
+ MoveOnly(const MoveOnly &amp;) = delete;
+ MoveOnly(MoveOnly &amp;&amp;) = default;
+
+ MoveOnly &amp; operator=(const MoveOnly &amp;) = delete;
+ MoveOnly &amp; operator=(MoveOnly &amp;&amp;) = default;
+
+ static MoveOnly create() { return MoveOnly(); }
+ static void take(MoveOnly mo);
+};
+</pre></div>
+
+<p>
+will generate wrapper code for the <tt>create</tt> factory method:
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void * SWIGSTDCALL CSharp_MoveOnly_create() {
+ void * jresult ;
+ SwigValueWrapper&lt; MoveOnly &gt; result;
+
+ result = MoveOnly::create();
+ jresult = new MoveOnly(result);
+ return jresult;
+}
+</pre></div>
+
+<p>
+<tt>SwigValueWrapper</tt> is covered in <a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a>.
+Note that the generated code could be optimised further using the <a href="Typemaps.html#Typemaps_optimal">"optimal" attribute</a>
+in the "out" typemap, so if the above typemap is customised as follows (note that this is C# specific):
+</p>
+
+<div class="code"><pre>
+%typemap(out, optimal="1") MoveOnly %{
+ $result = new $1_ltype($1);
+%}
+</pre></div>
+
+<p>
+then the generated code will result in the object being optimally moved:
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void * SWIGSTDCALL CSharp_MoveOnly_create() {
+ void * jresult ;
+ jresult = new MoveOnly(MoveOnly::create());
+ return jresult;
+}
+</pre></div>
+
+<p>
+Now let's consider passing by value.
+We'll consider three cases; namely types that are:
+</p>
+
+<ol>
+ <li> Copyable and not movable - <tt>CopyOnly</tt>.</li>
+ <li> Copyable and movable - <tt>MovableCopyable</tt>.</li>
+ <li> Movable and not copyable - <tt>MoveOnly</tt>.</li>
+</ol>
+
+<p>
+and for clarification, define these two additional types as follows:
+</p>
+
+<div class="code"><pre>
+struct CopyOnly {
+ int val;
+ CopyOnly(): val(0) {}
+
+ CopyOnly(const CopyOnly &amp;) = default;
+ CopyOnly &amp; operator=(const CopyOnly &amp;) = default;
+
+ static CopyOnly create() { return CopyOnly(); }
+ static void take(CopyOnly co);
+};
+
+struct MovableCopyable {
+ int val;
+ MovableCopyable(): val(0) {}
+
+ MovableCopyable(const MovableCopyable &amp;) = default;
+ MovableCopyable(MovableCopyable &amp;&amp;) = default;
+ MovableCopyable &amp; operator=(const MovableCopyable &amp;) = default;
+ MovableCopyable &amp; operator=(MovableCopyable &amp;&amp;) = default;
+
+ static MovableCopyable create() { return MovableCopyable(); }
+ static void take(MovableCopyable mc);
+};
+</pre></div>
+
+<p>
+The generated code is shown below for <tt>CopyOnly::take</tt> (with additional comments for when constructors and assignment operators are called).
+While the code shown is C# specific, the generated constructor and/or assignment operator calls are ultimately the same for all target languages.
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void SWIGSTDCALL CSharp_CopyOnly_take(void * jarg1) {
+ CopyOnly arg1 ; // (a) Default constructor
+ CopyOnly *argp1 ;
+
+ argp1 = (CopyOnly *)jarg1;
+ if (!argp1) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null CopyOnly", 0);
+ return ;
+ }
+ arg1 = *argp1; // (b) Copy assignment
+ CopyOnly::take(SWIG_STD_MOVE(arg1)); // (c) Copy constructor
+}
+</pre></div>
+
+<p>
+Note that <tt>SWIG_STD_MOVE</tt> is a macro defined as shown below to use <tt>std::move</tt> which is only available from C++11 onwards:
+</p>
+
+<div class="code"><pre>
+#if __cplusplus &gt;=201103L
+# define SWIG_STD_MOVE(OBJ) std::move(OBJ)
+#else
+# define SWIG_STD_MOVE(OBJ) OBJ
+#endif
+</pre></div>
+
+<p>
+Also note: <i>(c) Copy constructor</i>.
+Yes, when passing by value the copy constructor is called for all versions of C++, even C++11 and later even though std::move is specified.
+It's a C++ language feature for types that don't have move semantics!
+</p>
+
+<p>
+The generated code for <tt>MovableCopyable::take</tt> is the same as for <tt>CopyOnly::take</tt>, however, the C++ compiler will choose the move constructor this time where commented <i>(c) Move constructor</i>:
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void SWIGSTDCALL CSharp_MovableCopyable_take(void * jarg1) {
+ MovableCopyable arg1 ; // (a) Default constructor
+ MovableCopyable *argp1 ;
+
+ argp1 = (MovableCopyable *)jarg1;
+ if (!argp1) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null MovableCopyable", 0);
+ return ;
+ }
+ arg1 = *argp1; // (b) Copy assignment
+ MovableCopyable::take(SWIG_STD_MOVE(arg1)); // (c) Move constructor
+}
+</pre></div>
+
+<p>
+There are two optimisation opportunities available.
+</p>
+<ol>
+ <li> Remove the default constructor call with the <tt>%feature("valuewrapper")</tt> covered in <a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a> and replace it with <tt>SwigValueWrapper</tt>.
+ </li>
+ <li> Apply the SWIGTYPE MOVE typemaps which are designed specifically to implement full move semantics when passing parameters by value.
+ They replace the copy assignment with a call to <tt>SwigValueWrapper::reset</tt>, which works much like <tt>std::unique_ptr::reset</tt>.
+ These typemaps could alternatively have replaced the copy assignment with a move assignment, but this is not maximally optimal.
+ </li>
+</ol>
+<p>
+Simply add the following before the <tt>MovableCopyable::take</tt> method is parsed:
+</p>
+
+<div class="code"><pre>
+%valuewrapper MovableCopyable;
+%include &lt;swigmove.i&gt;
+%apply SWIGTYPE MOVE { MovableCopyable }
+</pre></div>
+
+<p>
+will result in this optimal code where just one move constructor is invoked:
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void SWIGSTDCALL CSharp_MovableCopyable_take(void * jarg1) {
+ SwigValueWrapper&lt; MovableCopyable &gt; arg1 ; // (a) No constructors invoked
+ MovableCopyable *argp1 ;
+
+ argp1 = (MovableCopyable *)jarg1;
+ if (!argp1) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null MovableCopyable", 0);
+ return ;
+ }
+ SwigValueWrapper&lt; MovableCopyable &gt;::reset(arg1, argp1); // (b) No constructor or assignment operator invoked
+ MovableCopyable::take(SWIG_STD_MOVE(arg1)); // (c) Move constructor
+}
+</pre></div>
+
+<p>
+Note that <tt>SwigValueWrapper</tt> will call the destructor for the pointer passed to it in the <tt>reset</tt> function.
+This pointer is the underlying C++ object that the proxy class owns.
+The details aren't shown, but the 'csin' typemap also generates C# code to ensure that the proxy class releases ownership of the object.
+Please see the 'SWIGTYPE MOVE' typemaps in the swigmove.i file provided for each target language.
+Therefore full move semantics are implemented; ownership is moved from the proxy class into the C++ layer and the net effect
+is the same as using an <a href="#CPlusPlus11_rvalue_reference_inputs">rvalue reference parameter</a> discussed earlier.
+</p>
+
+<p>
+Lastly, let's consider the <tt>MoveOnly::take</tt> function defined earlier.
+By default the generated code fails to compile as <tt>MoveOnly</tt> does not have a copy assignment operator.
+SWIG is not designed to select a different typemap automatically for move-only types and the user
+must apply the SWIGTYPE MOVE typemaps to ensure that only move-only semantics are used.
+However, SWIG is able to automatically use <tt>%feature("valuewrapper")</tt> for move-only
+types so it is not necessary to explicitly use this feature.
+So in this move-only case, simply add the following before <tt>MoveOnly::take</tt> is parsed, which results in the same optimal code shown above for <tt>MovableCopyable</tt>:
+</p>
+
+<div class="code"><pre>
+%include &lt;swigmove.i&gt;
+%apply SWIGTYPE MOVE { MoveOnly }
+</pre></div>
+
+<p>
+<b>Compatibility note:</b>
+SWIG-4.1.0 introduced support for taking advantage of types with move semantics and making it possible to easily use move only types.
+</p>
+
<H3><a name="CPlusPlus11_generalized_constant_expressions">7.2.2 Generalized constant expressions</a></H3>
@@ -144,14 +517,39 @@ When either of these is used from a target language, a runtime call is made to o
<H3><a name="CPlusPlus11_extern_template">7.2.3 Extern template</a></H3>
-<p>SWIG correctly parses the keywords <tt>extern template</tt>.
+<p>SWIG correctly parses <tt>extern template</tt> explicit instantiation declarations.
However, this template instantiation suppression in a translation unit has no relevance outside of the C++ compiler and so is not used by SWIG.
-SWIG only uses <tt>%template</tt> for instantiating and wrapping templates.</p>
+SWIG only uses <tt>%template</tt> for instantiating and wrapping templates.
+Consider the class template below:
+</p>
+
+<div class="code"><pre>
+// Class template
+template class std::vector&lt;int&gt;; // C++03 template explicit instantiation definition in C++
+extern template class std::vector&lt;int&gt;; // C++11 template explicit instantiation declaration (extern template)
+%template(VectorInt) std::vector&lt;int&gt;; // SWIG template instantiation
+</pre></div>
+
+<p>
+The above result in warnings:
+</p>
+
+<div class="shell">
+<pre>
+example.i:2: Warning 320: Explicit template instantiation ignored.
+example.i:3: Warning 327: Extern template ignored.
+</pre>
+</div>
+
+<p>
+Similarly for the function template below:
+</p>
<div class="code"><pre>
-template class std::vector&lt;int&gt;; // C++03 explicit instantiation in C++
-extern template class std::vector&lt;int&gt;; // C++11 explicit instantiation suppression in C++
-%template(VectorInt) std::vector&lt;int&gt;; // SWIG instantiation
+// Function template
+template void Func&lt;int&gt;(); // C++03 template explicit instantiation definition in C++
+extern template void Func&lt;int&gt;(); // C++11 template explicit instantiation declaration (extern template)
+%template(FuncInt) Func&lt;int&gt;; // SWIG template instantiation
</pre></div>
<H3><a name="CPlusPlus11_initializer_lists">7.2.4 Initializer lists</a></H3>
@@ -493,6 +891,19 @@ struct DerivedStruct : BaseStruct {
};
</pre></div>
+<p>
+Classes can also be marked as final, such as
+</p>
+
+<div class="code"><pre>
+struct FinalDerivedStruct final : BaseStruct {
+ virtual void ab() const override;
+};
+</pre></div>
+
+<p>
+<b>Compatibility note:</b> Final methods were supported much earlier than final classes. SWIG-4.1.0 was the first version to support classes marked as final.
+</p>
<H3><a name="CPlusPlus11_null_pointer_constant">7.2.12 Null pointer constant</a></H3>
@@ -985,7 +1396,9 @@ Use the preprocessor to work around this for now:
<p>
-Attributes such as those shown below, are not yet supported and will give a syntax error.
+Attributes such as those shown below, are supported since SWIG 4.1.0 but are
+currently crudely ignored by the parser's tokeniser so they have no effect on
+SWIG's code generation.
</p>
<div class="code"><pre>
@@ -1132,8 +1545,10 @@ While SWIG could provide wrappers for the new C++11 regular expressions classes,
<p>
SWIG provides special smart pointer handling for <tt>std::shared_ptr</tt> in the same way it has support for <tt>boost::shared_ptr</tt>.
-Please see the <a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a> library section.
-There is no special smart pointer handling available for <tt>std::weak_ptr</tt> and <tt>std::unique_ptr</tt> yet.
+Please see the <a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a>
+and <a href="Library.html#Library_std_unique_ptr">unique_ptr smart pointer</a> library sections.
+There is no special smart pointer handling available for <tt>std::weak_ptr</tt>.
+
</p>
<H3><a name="CPlusPlus11_extensible_random_number_facility">7.3.6 Extensible random number facility</a></H3>
diff --git a/Doc/Manual/CPlusPlus20.html b/Doc/Manual/CPlusPlus20.html
index 0a8b0027f..a289d776f 100644
--- a/Doc/Manual/CPlusPlus20.html
+++ b/Doc/Manual/CPlusPlus20.html
@@ -13,6 +13,10 @@
<ul>
<li><a href="#CPlusPlus20_introduction">Introduction</a>
<li><a href="#CPlusPlus20_core_language_changes">Core language changes</a>
+<ul>
+<li><a href="#CPlusPlus20_spaceship_operator">Spaceship operator</a>
+<li><a href="#CPlusPlus20_lambda_templates">Lambda templates</a>
+</ul>
<li><a href="#CPlusPlus20_standard_library_changes">Standard library changes</a>
</ul>
</div>
@@ -35,6 +39,32 @@ Work has only just begun on adding C++20 support.
<H2><a name="CPlusPlus20_core_language_changes">10.2 Core language changes</a></H2>
+<H3><a name="CPlusPlus20_spaceship_operator">10.2.1 Spaceship operator</a></H3>
+
+
+<p>
+SWIG supports the spaceship operator <tt>&lt;=&gt;</tt> in constant
+expressions. To simplify handling of the return value type, it is currently
+treated as an integer rather than <tt>std::strong_ordering</tt>, etc.
+In practice we think that should do the right thing in most cases.
+</p>
+
+<p>
+SWIG also recognises <tt>operator&lt;=&gt;</tt> which can be wrapped
+if renamed. There is not currently any default renaming for the operator
+or any attempt to automatically map it to a three-way comparison operator
+in any of the target languages.
+</p>
+
+<H3><a name="CPlusPlus20_lambda_templates">10.2.2 Lambda templates</a></H3>
+
+
+<p>
+SWIG should parse lambda templates, but like
+<a href="CPlusPlus11.html#CPlusPlus11_lambda_functions_and_expressions">
+non-templated lambdas</a> they aren't currently wrapped.
+</p>
+
<H2><a name="CPlusPlus20_standard_library_changes">10.3 Standard library changes</a></H2>
diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html
index fe8f7c4bd..3cfff6e68 100644
--- a/Doc/Manual/CSharp.html
+++ b/Doc/Manual/CSharp.html
@@ -551,6 +551,12 @@ unless the imclassname attribute is specified in the <a href="CSharp.html#CSharp
</p>
<p>
+<b><tt>$imfuncname</tt></b><br>
+This special variable expands to the name of the function in the intermediary class that will be used in $imcall.
+Like, $imcall, this special variable is only expanded in the "csout", "csvarin" and "csvarout" typemaps.
+</p>
+
+<p>
The directory <tt>Examples/csharp</tt> has a number of simple examples.
Visual Studio .NET 2003 solution and project files are available for compiling with the Microsoft .NET C#
compiler on Windows. This also works with newer versions of Visual Studio if you allow
@@ -560,7 +566,7 @@ After SWIG has run and both the C# and C/C++ compilers have finished building,
the examples will be run, by either running <tt>runme.exe</tt> or by running
<tt>mono runme.exe</tt> (Mono C# compiler).
Windows users can also get the examples working using a
-<a href="http://www.cygwin.com">Cygwin</a> or <a href="http://www.mingw.org">MinGW</a> environment for automatic configuration of the example makefiles.
+<a href="http://www.cygwin.com">Cygwin</a> or <a href="https://osdn.net/projects/mingw/">MinGW</a> environment for automatic configuration of the example makefiles.
Any one of the C# compilers (Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path.
<H2><a name="CSharp_void_pointers">23.3 Void pointers</a></H2>
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index 47b41186e..fd74ab299 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -91,17 +91,16 @@
</ul>
<li><a href="Windows.html#Windows_other_compilers">Instructions for using the Examples with other compilers</a>
</ul>
-<li><a href="Windows.html#Windows_cygwin_mingw">SWIG on Cygwin and MinGW</a>
-<ul>
<li><a href="Windows.html#Windows_swig_exe">Building swig.exe on Windows</a>
<ul>
<li><a href="Windows.html#Windows_cmake">Building swig.exe using CMake</a>
-<li><a href="Windows.html#Windows_mingw_msys">Building swig.exe using MSYS2</a>
+<li><a href="Windows.html#Windows_msys2">Building swig.exe using MSYS2</a>
<li><a href="Windows.html#Windows_mingw_msys">Building swig.exe using MinGW and MSYS</a>
<li><a href="Windows.html#Windows_cygwin">Building swig.exe using Cygwin</a>
-</ul>
+<ul>
<li><a href="Windows.html#Windows_examples_cygwin">Running the examples on Windows using Cygwin</a>
</ul>
+</ul>
<li><a href="Windows.html#Windows_interface_file">Microsoft extensions and other Windows quirks</a>
</ul>
</div>
@@ -172,6 +171,7 @@
<li><a href="SWIG.html#SWIG_rename_ignore">Renaming and ignoring declarations</a>
<ul>
<li><a href="SWIG.html#SWIG_nn29">Simple renaming of specific identifiers</a>
+<li><a href="SWIG.html#SWIG_ignore">Ignoring identifiers</a>
<li><a href="SWIG.html#SWIG_advanced_renaming">Advanced renaming support</a>
<li><a href="SWIG.html#SWIG_limiting_renaming">Limiting global renaming rules</a>
<li><a href="SWIG.html#SWIG_chosen_unignore">Ignoring everything then wrapping a few selected symbols</a>
@@ -251,6 +251,9 @@
</ul>
<li><a href="SWIGPlus.html#SWIGPlus_nn28">Overloaded operators</a>
<li><a href="SWIGPlus.html#SWIGPlus_class_extension">Class extension</a>
+<ul>
+<li><a href="SWIGPlus.html#SWIGPlus_replacing_methods">Replacing class methods</a>
+</ul>
<li><a href="SWIGPlus.html#SWIGPlus_nn30">Templates</a>
<ul>
<li><a href="SWIGPlus.html#SWIGPlus_template_directive">The %template directive</a>
@@ -294,6 +297,11 @@
<li><a href="CPlusPlus11.html#CPlusPlus11_core_language_changes">Core language changes</a>
<ul>
<li><a href="CPlusPlus11.html#CPlusPlus11_rvalue_reference_and_move_semantics">Rvalue reference and move semantics</a>
+<ul>
+<li><a href="CPlusPlus11.html#CPlusPlus11_rvalue_reference_inputs">Rvalue reference inputs</a>
+<li><a href="CPlusPlus11.html#CPlusPlus11_rvalue_reference_outputs">Rvalue reference outputs</a>
+<li><a href="CPlusPlus11.html#CPlusPlus11_move_only">Movable and move-only types by value</a>
+</ul>
<li><a href="CPlusPlus11.html#CPlusPlus11_generalized_constant_expressions">Generalized constant expressions</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_extern_template">Extern template</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_initializer_lists">Initializer lists</a>
@@ -380,6 +388,10 @@
<ul>
<li><a href="CPlusPlus20.html#CPlusPlus20_introduction">Introduction</a>
<li><a href="CPlusPlus20.html#CPlusPlus20_core_language_changes">Core language changes</a>
+<ul>
+<li><a href="CPlusPlus20.html#CPlusPlus20_spaceship_operator">Spaceship operator</a>
+<li><a href="CPlusPlus20.html#CPlusPlus20_lambda_templates">Lambda templates</a>
+</ul>
<li><a href="CPlusPlus20.html#CPlusPlus20_standard_library_changes">Standard library changes</a>
</ul>
</div>
@@ -416,6 +428,7 @@
<li><a href="Library.html#Library_nn2">The %include directive and library search path</a>
<li><a href="Library.html#Library_nn3">C arrays and pointers</a>
<ul>
+<li><a href="Library.html#Library_argcargv">argcargv.i</a>
<li><a href="Library.html#Library_nn4">cpointer.i</a>
<li><a href="Library.html#Library_carrays">carrays.i</a>
<li><a href="Library.html#Library_nn6">cmalloc.i</a>
@@ -441,11 +454,16 @@
<li><a href="Library.html#Library_shared_ptr_templates">shared_ptr and templates</a>
<li><a href="Library.html#Library_shared_ptr_directors">shared_ptr and directors</a>
</ul>
+<li><a href="Library.html#Library_std_unique_ptr">unique_ptr smart pointer</a>
<li><a href="Library.html#Library_std_auto_ptr">auto_ptr smart pointer</a>
</ul>
<li><a href="Library.html#Library_nn16">Utility Libraries</a>
<ul>
<li><a href="Library.html#Library_nn17">exception.i</a>
+<li><a href="Library.html#Library_attributes">attribute.i</a>
+<ul>
+<li><a href="Library.html#Library_attribute_templates">%attribute and C++ templates</a>
+</ul>
</ul>
</ul>
</div>
@@ -516,6 +534,7 @@
<ul>
<li><a href="Typemaps.html#Typemaps_special_macro_descriptor">$descriptor(type)</a>
<li><a href="Typemaps.html#Typemaps_special_macro_typemap">$typemap(method, typepattern)</a>
+<li><a href="Typemaps.html#Typemaps_special_macro_typemap_attribute">$typemap(method:attribute, typepattern)</a>
</ul>
<li><a href="Typemaps.html#Typemaps_special_variable_attributes">Special variables and typemap attributes</a>
<li><a href="Typemaps.html#Typemaps_special_variables_and_macros">Special variables combined with special variable macros</a>
@@ -870,6 +889,8 @@
<li><a href="Go.html#Go_class_inheritance">Go Class Inheritance</a>
</ul>
<li><a href="Go.html#Go_templates">Go Templates</a>
+<li><a href="Go.html#Go_threads">Go and C/C++ Threads</a>
+<li><a href="Go.html#Go_exceptions">Go and C++ Exceptions</a>
<li><a href="Go.html#Go_director_classes">Go Director Classes</a>
<ul>
<li><a href="Go.html#Go_director_example_cpp_code">Example C++ code</a>
@@ -1330,6 +1351,7 @@
<li><a href="Php.html#Php_nn2_6_3">Static Member Variables</a>
<li><a href="Php.html#Php_nn2_6_4">Static Member Functions</a>
<li><a href="Php.html#Php_nn2_6_5">Specifying Implemented Interfaces</a>
+<li><a href="Php.html#Php_nn2_6_6">Dynamic Properties</a>
</ul>
<li><a href="Php.html#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</a>
</ul>
@@ -1455,6 +1477,7 @@
<li><a href="Python.html#Python_nn70">%feature("autodoc", "docstring")</a>
</ul>
<li><a href="Python.html#Python_nn71">%feature("docstring")</a>
+<li><a href="Python.html#Python_doxygen_docstrings">Doxygen comments</a>
</ul>
<li><a href="Python.html#Python_nn72">Python Packages</a>
<ul>
@@ -1474,7 +1497,10 @@
</ul>
<li><a href="Python.html#Python_python3support">Python 3 Support</a>
<ul>
-<li><a href="Python.html#Python_nn74">Function annotation</a>
+<li><a href="Python.html#Python_annotations">Python function annotations and variable annotations</a>
+<ul>
+<li><a href="Python.html#Python_annotations_c">C/C++ annotation types</a>
+</ul>
<li><a href="Python.html#Python_nn75">Buffer interface</a>
<li><a href="Python.html#Python_nn76">Abstract base classes</a>
<li><a href="Python.html#Python_nn77">Byte string output conversion</a>
diff --git a/Doc/Manual/Customization.html b/Doc/Manual/Customization.html
index 5fe0f5b52..aab3528ac 100644
--- a/Doc/Manual/Customization.html
+++ b/Doc/Manual/Customization.html
@@ -668,7 +668,7 @@ results. For example:
<div class="code">
<pre>
-%typemap(newfree) char * "free($1);";
+%typemap(newfree) char * "free($1);"
...
%newobject strdup;
...
diff --git a/Doc/Manual/D.html b/Doc/Manual/D.html
index f9f2d53ca..4b4e3c2c0 100644
--- a/Doc/Manual/D.html
+++ b/Doc/Manual/D.html
@@ -44,7 +44,7 @@
<H2><a name="D_introduction">24.1 Introduction</a></H2>
-<p>From the <a href="http://www.digitalmars.com/d/">D Programming Language</a> web site: <em>D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. [...] The D language is statically typed and compiles directly to machine code.</em> As such, it is not very surprising that D is able to directly <a href="http://www.digitalmars.com/d/1.0/interfaceToC.html">interface with C libraries</a>. Why would a SWIG module for D be needed then in the first place?</p>
+<p>From the <a href="https://www.digitalmars.com/d/">D Programming Language</a> web site: <em>D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. [...] The D language is statically typed and compiles directly to machine code.</em> As such, it is not very surprising that D is able to directly <a href="https://www.digitalmars.com/d/1.0/interfaceToC.html">interface with C libraries</a>. Why would a SWIG module for D be needed then in the first place?</p>
<p>Well, besides the obvious downside that the C header files have to be manually converted to D modules for this to work, there is one major inconvenience with this approach: D code usually is on a higher abstraction level than C, and many of the features that make D interesting are simply not available when dealing with C libraries, requiring you e.g. to manually convert strings between pointers to <tt>\0</tt>-terminated char arrays and D char arrays, making the algorithms from the D2 standard library unusable with C arrays and data structures, and so on.</p>
@@ -267,12 +267,18 @@ SomeClass bar() {
</pre></div>
</dd>
+ <dt><tt>$imfuncname</tt></dt>
+ <dd><p>
+This special variable expands to the name of the function in the intermediary class that will be used in $imcall.
+Like, $imcall, this special variable is only expanded in the "dout" typemap.
+ </p></dd>
+
<dt><a name="D_importtype"></a><tt>$importtype(SomeDType)</tt></dt>
<dd>
<p>This macro is used in the <tt>dimports</tt> typemap if a dependency on another D type generated by SWIG is added by a custom typemap.</p>
<p>Consider the following code snippet:</p>
<div class="code"><pre>
-%typemap(dinterfaces) SomeClass "AnInterface, AnotherInterface";
+%typemap(dinterfaces) SomeClass "AnInterface, AnotherInterface"
</pre></div>
<p>This causes SWIG to add <tt>AnInterface</tt> and <tt>AnotherInterface</tt> to the base class list of <tt>SomeClass</tt>:</p>
<div class="targetlang"><pre>
@@ -415,7 +421,7 @@ struct A {
<p>The first key difference is that C++ supports free functions as operators (along with argument-dependent lookup), while D requires operators to be member functions of the class they are operating on. SWIG can only automatically generate wrapping code for member function operators; if you want to use operators defined as free functions in D, you need to handle them manually.</p>
-<p>Another set of differences between C++ and D concerns individual operators. For example, there are quite a few operators which are overloadable in C++, but not in D, for example <tt>&amp;&amp;</tt> and <tt>||</tt>, but also <tt>!</tt>, and prefix increment/decrement operators in <a href="http://www.digitalmars.com/d/1.0/operatoroverloading.html">D1</a> resp. their postfix pendants in <a href="http://www.digitalmars.com/d/2.0/operatoroverloading.html">D2</a>.</p>
+<p>Another set of differences between C++ and D concerns individual operators. For example, there are quite a few operators which are overloadable in C++, but not in D, for example <tt>&amp;&amp;</tt> and <tt>||</tt>, but also <tt>!</tt>, and prefix increment/decrement operators in <a href="https://www.digitalmars.com/d/1.0/operatoroverloading.html">D1</a> resp. their postfix pendants in <a href="https://www.digitalmars.com/d/2.0/operatoroverloading.html">D2</a>.</p>
<p>There are also some cases where the operators can be translated to D, but the differences in the implementation details are big enough that a rather involved scheme would be required for automatic wrapping them, which has not been implemented yet. This affects, for example, the array subscript operator, <tt>[]</tt>, in combination with assignments - while <tt>operator []</tt> in C++ simply returns a reference which is then written to, D resorts to a separate <tt>opIndexAssign</tt> method -, or implicit casting (which was introduced in D2 via <tt>alias this</tt>). Despite the lack of automatic support, manually handling these cases should be perfectly possible.</p>
diff --git a/Doc/Manual/Doxygen.html b/Doc/Manual/Doxygen.html
index e7fd4c359..9f92db91a 100644
--- a/Doc/Manual/Doxygen.html
+++ b/Doc/Manual/Doxygen.html
@@ -67,7 +67,7 @@ supported.
<p>
The Doxygen Translation module of SWIG adds an extra layer of
functionality to SWIG, allowing automated translation of <a href=
-"http://www.doxygen.nl/manual/">Doxygen</a> formatted comments
+"https://www.doxygen.nl/manual/">Doxygen</a> formatted comments
from input files into a documentation language more suited for the
target language. Currently this module only translates into Javadoc
and Pydoc for the SWIG Java and Python modules.
@@ -83,14 +83,14 @@ Code</a> proposal from Summer 2008.
<p>
To make use of the comment translation system, your documentation
comments must be in properly formatted <a href=
-"http://www.doxygen.nl/manual/">Doxygen.</a> Doxygen comments can be
+"https://www.doxygen.nl/manual/">Doxygen.</a> Doxygen comments can be
present in your main SWIG interface file or any header file that it
imports. You are advised to be validate that your comments compile
properly with Doxygen before you try to translate them. Doxygen
itself is a more comprehensive tool and can provide you better feedback for
correcting any syntax errors that may be present. Please look at
Doxygen's <a href=
-"http://www.doxygen.nl/manual/docblocks.html"> Documenting the
+"https://www.doxygen.nl/manual/docblocks.html"> Documenting the
code</a> for the full comment format specifications. However, SWIG's
Doxygen parser will still report many errors and warnings found
in comments (like unterminated strings or missing ending tags).
@@ -98,7 +98,7 @@ in comments (like unterminated strings or missing ending tags).
<p>
Currently, the whole subset of Doxygen comment styles is supported
-(See <a href="http://www.doxygen.nl/manual/docblocks.html">
+(See <a href="https://www.doxygen.nl/manual/docblocks.html">
Documenting the code</a>). Here they are:
</p>
@@ -181,7 +181,7 @@ or enum element comments:
<div class="code"><pre>
enum E_NUMBERS
{
- EN_ZERO, ///&lt; The first enum item, gets zero as it's value
+ EN_ZERO, ///&lt; The first enum item, gets zero as its value
EN_ONE, ///&lt; The second, EN_ONE=1
EN_THREE
};
@@ -298,7 +298,7 @@ make much sense for the other languages without explicit ownership management.
<p>
Doxygen syntax is rather rich and, in addition to simple commands such as
<tt>@transferfull</tt>, it is also possible to define commands with arguments.
-As explained in <a href="http://www.doxygen.nl/manual/commands.html">Doxygen documentation</a>,
+As explained in <a href="https://www.doxygen.nl/manual/commands.html">Doxygen documentation</a>,
the arguments can have a range of a single word, everything until the end of
line or everything until the end of the next paragraph. Currently, only the "end
of line" case is supported using the <tt>range="line"</tt> argument of the
@@ -1079,7 +1079,7 @@ class Shape(_object):
<p>
If any parameters of a function or a method are documented in the Doxygen comment,
their description is copied into the generated output using
-<a href="http://sphinx-doc.org/">Sphinx </a> documentation conventions. For example
+<a href="https://www.sphinx-doc.org/">Sphinx </a> documentation conventions. For example
</p>
<div class="code"><pre>
/**
@@ -1114,7 +1114,7 @@ name of the type with namespace scope delimiters (<tt>::</tt>) replaced with a d
change this, you can define your own typemaps for the custom types, e.g:
</p>
<div class="code"><pre>
-%typemap(doctype) MyDate "datetime.date";
+%typemap(doctype) MyDate "datetime.date"
</pre></div>
<p>
@@ -1167,7 +1167,7 @@ completely (doxygen:notranslate feature). Then SWIG will just copy
the comments to the proxy file and reformat them if needed, but all
the comment content will be left as is. As Doxygen doesn't support
special commands in Python comments
-(see <a href="http://www.doxygen.nl/manual/docblocks.html#pythonblocks">Doxygen
+(see <a href="https://www.doxygen.nl/manual/docblocks.html#pythonblocks">Doxygen
docs</a>), you may want to use some tool like doxypy
(<a href="https://pypi.org/project/doxypy/">doxypy</a>)
to do the work.
diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html
index 5749f37ce..b13c5167e 100644
--- a/Doc/Manual/Extending.html
+++ b/Doc/Manual/Extending.html
@@ -462,187 +462,220 @@ the stage being processed.
There are a number of other parse tree display options, for example, <tt>swig -debug-module &lt;n&gt;</tt> will
avoid displaying system parse information and only display the parse tree pertaining to the user's module at
stage <tt>n</tt> of processing.
+Adding the <tt>-debug-quiet</tt> option is recommended as it removes some noise which is not usually needed,
+that is, the display of many linked list pointers and symbol table pointers.
</p>
<div class="shell">
<pre>
-$ swig -c++ -python -debug-module 4 example.i
- +++ include ----------------------------------------
- | name - "example.i"
-
- +++ module ----------------------------------------
- | name - "example"
- |
- +++ insert ----------------------------------------
- | code - "\n#include \"example.h\"\n"
- |
- +++ include ----------------------------------------
- | name - "example.h"
-
- +++ class ----------------------------------------
- | abstract - "1"
- | sym:name - "Shape"
- | name - "Shape"
- | kind - "class"
- | symtab - 0x40194140
- | sym:symtab - 0x40191078
-
- +++ access ----------------------------------------
- | kind - "public"
- |
- +++ constructor ----------------------------------------
- | sym:name - "Shape"
- | name - "Shape"
- | decl - "f()."
- | code - "{\n nshapes++;\n }"
- | sym:symtab - 0x40194140
- |
- +++ destructor ----------------------------------------
- | sym:name - "~Shape"
- | name - "~Shape"
- | storage - "virtual"
- | code - "{\n nshapes--;\n }"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "x"
- | name - "x"
- | decl - ""
- | type - "double"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "y"
- | name - "y"
- | decl - ""
- | type - "double"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "move"
- | name - "move"
- | decl - "f(double, double)."
- | parms - double, double
- | type - "void"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "area"
- | name - "area"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | value - "0"
- | type - "double"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "perimeter"
- | name - "perimeter"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | value - "0"
- | type - "double"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "nshapes"
- | name - "nshapes"
- | decl - ""
- | storage - "static"
- | type - "int"
- | sym:symtab - 0x40194140
- |
- +++ class ----------------------------------------
- | sym:name - "Circle"
- | name - "Circle"
- | kind - "class"
- | bases - 0x40194510
- | symtab - 0x40194538
- | sym:symtab - 0x40191078
-
- +++ access ----------------------------------------
- | kind - "private"
- |
- +++ cdecl ----------------------------------------
- | name - "radius"
- | decl - ""
- | type - "double"
- |
- +++ access ----------------------------------------
- | kind - "public"
- |
- +++ constructor ----------------------------------------
- | sym:name - "Circle"
- | name - "Circle"
- | parms - double
- | decl - "f(double)."
- | code - "{ }"
- | sym:symtab - 0x40194538
- |
- +++ cdecl ----------------------------------------
- | sym:name - "area"
- | name - "area"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | type - "double"
- | sym:symtab - 0x40194538
- |
- +++ cdecl ----------------------------------------
- | sym:name - "perimeter"
- | name - "perimeter"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | type - "double"
- | sym:symtab - 0x40194538
- |
- +++ class ----------------------------------------
- | sym:name - "Square"
- | name - "Square"
- | kind - "class"
- | bases - 0x40194760
- | symtab - 0x40194788
- | sym:symtab - 0x40191078
-
- +++ access ----------------------------------------
- | kind - "private"
- |
- +++ cdecl ----------------------------------------
- | name - "width"
- | decl - ""
- | type - "double"
- |
- +++ access ----------------------------------------
- | kind - "public"
- |
- +++ constructor ----------------------------------------
- | sym:name - "Square"
- | name - "Square"
- | parms - double
- | decl - "f(double)."
- | code - "{ }"
- | sym:symtab - 0x40194788
- |
- +++ cdecl ----------------------------------------
- | sym:name - "area"
- | name - "area"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | type - "double"
- | sym:symtab - 0x40194788
- |
- +++ cdecl ----------------------------------------
- | sym:name - "perimeter"
- | name - "perimeter"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | type - "double"
- | sym:symtab - 0x40194788
+$ swig -c++ -python -debug-module 1 -debug-quiet example.i
+debug-module stage 1
++++ module ----------------------------------------
+| name - "example"
+|
++++ insert ----------------------------------------
+| code - "\n#include \"example.h\"\n"
+|
++++ include ----------------------------------------
+| name - "example.h"
+
+ +++ class ----------------------------------------
+ | abstracts - 0x7f4f15182930
+ | allows_typedef - "1"
+ | kind - "class"
+ | name - "Shape"
+ | sym:name - "Shape"
+
+ +++ access ----------------------------------------
+ | kind - "public"
+ |
+ +++ constructor ----------------------------------------
+ | access - "public"
+ | code - "{\n nshapes++;\n }"
+ | decl - "f()."
+ | feature:new - "1"
+ | ismember - "1"
+ | name - "Shape"
+ | sym:name - "Shape"
+ |
+ +++ destructor ----------------------------------------
+ | access - "public"
+ | code - "{\n nshapes--;\n }"
+ | decl - "f()."
+ | ismember - "1"
+ | name - "~Shape"
+ | storage - "virtual"
+ | sym:name - "~Shape"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "x"
+ | sym:name - "x"
+ | type - "double"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "y"
+ | sym:name - "y"
+ | type - "double"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f(double,double)."
+ | ismember - "1"
+ | kind - "function"
+ | name - "move"
+ | parms - 'double dx,double dy'
+ | sym:name - "move"
+ | type - "void"
+ |
+ +++ cdecl ----------------------------------------
+ | abstract - "1"
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "area"
+ | storage - "virtual"
+ | sym:name - "area"
+ | type - "double"
+ | value - "0"
+ | valuetype - "int"
+ |
+ +++ cdecl ----------------------------------------
+ | abstract - "1"
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "perimeter"
+ | storage - "virtual"
+ | sym:name - "perimeter"
+ | type - "double"
+ | value - "0"
+ | valuetype - "int"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "nshapes"
+ | storage - "static"
+ | sym:name - "nshapes"
+ | type - "int"
+ |
+ +++ class ----------------------------------------
+ | allows_typedef - "1"
+ | baselist - 0x7f4f15182ad0
+ | kind - "class"
+ | name - "Circle"
+ | privatebaselist - 0x7f4f15182b10
+ | protectedbaselist - 0x7f4f15182af0
+ | sym:name - "Circle"
+
+ +++ access ----------------------------------------
+ | kind - "private"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "private"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "radius"
+ | type - "double"
+ |
+ +++ access ----------------------------------------
+ | kind - "public"
+ |
+ +++ constructor ----------------------------------------
+ | access - "public"
+ | code - "{ }"
+ | decl - "f(double)."
+ | feature:new - "1"
+ | ismember - "1"
+ | name - "Circle"
+ | parms - 'double r'
+ | sym:name - "Circle"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "area"
+ | storage - "virtual"
+ | sym:name - "area"
+ | type - "double"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "perimeter"
+ | storage - "virtual"
+ | sym:name - "perimeter"
+ | type - "double"
+ |
+ +++ class ----------------------------------------
+ | allows_typedef - "1"
+ | baselist - 0x7f4f15183830
+ | kind - "class"
+ | name - "Square"
+ | privatebaselist - 0x7f4f15183870
+ | protectedbaselist - 0x7f4f15183850
+ | sym:name - "Square"
+
+ +++ access ----------------------------------------
+ | kind - "private"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "private"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "width"
+ | type - "double"
+ |
+ +++ access ----------------------------------------
+ | kind - "public"
+ |
+ +++ constructor ----------------------------------------
+ | access - "public"
+ | code - "{ }"
+ | decl - "f(double)."
+ | feature:new - "1"
+ | ismember - "1"
+ | name - "Square"
+ | parms - 'double w'
+ | sym:name - "Square"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "area"
+ | storage - "virtual"
+ | sym:name - "area"
+ | type - "double"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "perimeter"
+ | storage - "virtual"
+ | sym:name - "perimeter"
+ | type - "double"
</pre>
</div>
@@ -698,31 +731,28 @@ The parse tree can be viewed after the final stage of processing by running SWIG
<div class="shell">
<pre>
-$ swig -debug-top 4 example.i
+$ swig -debug-top 1 -debug-quiet example.i
...
+++ cdecl ----------------------------------------
- | sym:name - "foo_i"
- | name - "foo"
| decl - "f(int)."
+ | name - "foo"
| parms - int
+ | sym:name - "foo_i"
| type - "void"
- | sym:symtab - 0x40165078
|
+++ cdecl ----------------------------------------
- | sym:name - "foo_d"
- | name - "foo"
| decl - "f(double)."
+ | name - "foo"
| parms - double
+ | sym:name - "foo_d"
| type - "void"
- | sym:symtab - 0x40165078
|
+++ cdecl ----------------------------------------
- | sym:name - "foo"
- | name - "foo"
| decl - "f(p.Bar)."
+ | name - "foo"
| parms - Bar *
+ | sym:name - "foo"
| type - "void"
- | sym:symtab - 0x40165078
</pre>
</div>
@@ -787,19 +817,18 @@ public:
The behavior of <tt>%feature</tt> is very easy to describe--it simply
attaches a new attribute to any parse tree node that matches the
given prototype. When a feature is added, it shows up as an attribute in the <tt>feature:</tt> namespace.
-You can see this when running with the <tt>-debug-top 4</tt> option. For example:
+You can see this when running with the <tt>-debug-top 4 -debug-quiet</tt> option. For example:
</p>
<div class="shell">
<pre>
+++ cdecl ----------------------------------------
- | sym:name - "getitem"
- | name - "getitem"
| decl - "f(int).p."
+ | feature:except - "{\n try {\n $action\n } catc..."
+ | name - "getitem"
| parms - int
+ | sym:name - "getitem"
| type - "Object"
- | feature:except - "{\n try {\n $action\n } catc..."
- | sym:symtab - 0x40168ac8
|
</pre>
</div>
@@ -1132,6 +1161,11 @@ DOH_REPLACE_FIRST - Replace first occurrence only.
Returns the number of replacements made (if any).
</p>
+<p>
+At most one of <tt>DOH_REPLACE_ANY</tt> and <tt>DOH_REPLACE_FIRST</tt> should be specified.
+<tt>DOH_REPLACE_ANY</tt> is the default if neither is specified.
+</p>
+
</div>
<H3><a name="Extending_nn16">40.5.2 Hashes</a></H3>
@@ -1210,6 +1244,14 @@ if an object was removed, 0 otherwise.
Returns the list of hash table keys.
</div>
+<p>
+<b><tt>List *SortedKeys(Hash *h, int (*cmp) (const DOH *, const DOH *))</tt></b>
+</p>
+
+<div class="indent">
+Returns the list of sorted hash table keys.
+</div>
+
<H3><a name="Extending_nn17">40.5.3 Lists</a></H3>
@@ -2802,7 +2844,7 @@ int Python::top(Node *n) {
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
@@ -2986,7 +3028,7 @@ virtual int functionWrapper(Node *n) {
/* create the wrapper object */
Wrapper *wrapper = NewWrapper();
- /* create the functions wrappered name */
+ /* create the wrapper function's name */
String *wname = Swig_name_wrapper(iname);
/* deal with overloading */
@@ -2995,7 +3037,7 @@ virtual int functionWrapper(Node *n) {
/* write the wrapper function definition */
Printv(wrapper-&gt;def, "RETURN_TYPE ", wname, "(ARGS) {", NIL);
- /* if any additional local variable needed, add them now */
+ /* if any additional local variables are needed, add them now */
...
/* write the list of locals/arguments required */
@@ -3107,7 +3149,7 @@ As you can see, most usages are direct.
<dd> This file is processed by
<p>
-<A HREF="http://www.gnu.org/software/autoconf/">autoconf</A>
+<A HREF="https://www.gnu.org/software/autoconf/">autoconf</A>
to generate the <TT>configure</TT> script. This is where you
need to add shell script fragments and autoconf macros to detect the
presence of whatever development support your language module requires,
@@ -3455,7 +3497,7 @@ Advanced usage of the test-suite facilitates running tools on some of the five s
The make variables <tt>SWIGTOOL</tt> and <tt>RUNTOOL</tt> are used to specify a tool to respectively, invoke SWIG
and the execution of the runtime test.
You are advised to view the <tt>Examples/test-suite/common.mk</tt> file for details but for a short summary,
-the classic usage is to use <a href="http://valgrind.org/">Valgrind</a> for memory checking.
+the classic usage is to use <a href="https://valgrind.org/">Valgrind</a> for memory checking.
For example, checking for memory leaks when running the runtime test in the target language interpreter:
</p>
@@ -3588,7 +3630,7 @@ A target language is given the 'Supported' status when
<li>
It passes all of the main SWIG test-suite.
The main test-suite is defined by the tests in the C_TEST_CASES, CPP_TEST_CASES and MULTI_CPP_TEST_CASES lists in Examples/test-suite/common.mk.
- The tests in CPP11_TEST_CASES will also be required in the near future.
+ All the newer C++ standard tests need to work and are grouped together, such as CPP11_TEST_CASES for C++11. These more 'modern' C++ standards are only tested though if the compiler is detected as supporting the given standard.
</li>
<li>
The test-suite must also include at least twenty wide-ranging runtime tests.
@@ -3760,6 +3802,7 @@ There are various command line options which can aid debugging a SWIG interface
-debug-symbols - Display target language symbols in the symbol tables
-debug-csymbols - Display C symbols in the symbol tables
-debug-lsymbols - Display target language layer symbols
+-debug-quiet - Display less parse tree node debug info when using other -debug options
-debug-tags - Display information about the tags found in the interface
-debug-template - Display information for debugging templates
-debug-top &lt;n&gt; - Display entire parse tree at stages 1-4, &lt;n&gt; is a csv list of stages
diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html
index 4e230c78b..5b774bc45 100644
--- a/Doc/Manual/Go.html
+++ b/Doc/Manual/Go.html
@@ -29,6 +29,8 @@
<li><a href="#Go_class_inheritance">Go Class Inheritance</a>
</ul>
<li><a href="#Go_templates">Go Templates</a>
+<li><a href="#Go_threads">Go and C/C++ Threads</a>
+<li><a href="#Go_exceptions">Go and C++ Exceptions</a>
<li><a href="#Go_director_classes">Go Director Classes</a>
<ul>
<li><a href="#Go_director_example_cpp_code">Example C++ code</a>
@@ -54,7 +56,7 @@
<p>
This chapter describes SWIG's support of Go. For more information on
the Go programming language
-see <a href="http://golang.org/">golang.org</a>.
+see <a href="https://golang.org/">golang.org</a>.
</p>
<H2><a name="Go_overview">25.1 Overview</a></H2>
@@ -176,10 +178,10 @@ swig -go -help
<td>-intgosize &lt;s&gt;</td>
<td>Set the size for the Go type <tt>int</tt>. This controls the size
that the C/C++ code expects to see. The &lt;s&gt; argument should
- be 32 or 64. This option is currently required during the
+ be 32 or 64. This option was required during the
transition from Go 1.0 to Go 1.1, as the size of <tt>int</tt> on
- 64-bit x86 systems changes between those releases (from 32 bits to
- 64 bits). In the future the option may become optional, and SWIG
+ 64-bit x86 systems changed between those releases (from 32 bits to
+ 64 bits). It was made optional in SWIG 4.1.0 and if not specified SWIG
will assume that the size of <tt>int</tt> is the size of a C
pointer.</td>
</tr>
@@ -494,10 +496,6 @@ The usage of Go finalizers is problematic with C++'s RAII idiom as it isn't
predictable when the finalizer will run and this might require a Close or Delete
method to be added the Go object that stores a C++ object to mitigate.
</li>
-<li>
-The Go finalizer function typically runs in a different OS thread which can be
-problematic with C++ code that uses thread-local storage.
-</li>
</ul>
<p>
@@ -557,8 +555,37 @@ In order to use C++ templates in Go, you must tell SWIG to create
wrappers for a particular template instantiation. To do this, use
the <tt>%template</tt> directive.
+<H3><a name="Go_threads">25.4.7 Go and C/C++ Threads</a></H3>
+
+
+<p>
+C and C++ code can use operating system threads and thread local
+storage. Go code uses goroutines, which are multiplexed onto
+operating system threads. This multiplexing means that Go code can
+change to run on a different thread at any time. C/C++ code, on the
+other hand, may assume that it runs on a single thread; this is true
+in particular if the C/C++ code uses thread local storage.
+</p>
+
+<p>
+In order to use Go code with C/C++ code that expects to run on a
+single thread, the Go code must call
+the <a href="https://pkg.go.dev/runtime#LockOSThread"><code>runtime.LockOSThread</code></a>
+function to lock the goroutine onto a single thread.
+</p>
+
+<H3><a name="Go_exceptions">25.4.8 Go and C++ Exceptions</a></H3>
+
+
+<p>
+C++ exceptions do not interoperate with Go code. Attempts to throw
+C++ exceptions through a Go caller are unreliable: in many cases the
+C++ exception handler will be unable to unwind the stack, and the
+program will crash. The only safe way to handle C++ exceptions is to
+catch them in C++ before returning to Go.
+</p>
-<H3><a name="Go_director_classes">25.4.7 Go Director Classes</a></H3>
+<H3><a name="Go_director_classes">25.4.9 Go Director Classes</a></H3>
<p>
@@ -576,7 +603,7 @@ completely to avoid common pitfalls with directors in Go.
</p>
-<H4><a name="Go_director_example_cpp_code">25.4.7.1 Example C++ code</a></H4>
+<H4><a name="Go_director_example_cpp_code">25.4.9.1 Example C++ code</a></H4>
<p>
@@ -648,7 +675,7 @@ be found in <a href="#Go_director_foobargo_class">the end of the guide</a>.
</p>
-<H4><a name="Go_director_enable">25.4.7.2 Enable director feature</a></H4>
+<H4><a name="Go_director_enable">25.4.9.2 Enable director feature</a></H4>
<p>
@@ -683,7 +710,7 @@ documentation on directors.
</p>
-<H4><a name="Go_director_ctor_dtor">25.4.7.3 Constructor and destructor</a></H4>
+<H4><a name="Go_director_ctor_dtor">25.4.9.3 Constructor and destructor</a></H4>
<p>
@@ -736,7 +763,7 @@ embedding</a>.
</p>
-<H4><a name="Go_director_overriding">25.4.7.4 Override virtual methods</a></H4>
+<H4><a name="Go_director_overriding">25.4.9.4 Override virtual methods</a></H4>
<p>
@@ -804,7 +831,7 @@ the Go methods.
</p>
-<H4><a name="Go_director_base_methods">25.4.7.5 Call base methods</a></H4>
+<H4><a name="Go_director_base_methods">25.4.9.5 Call base methods</a></H4>
<p>
@@ -841,7 +868,7 @@ be found in <a href="#Go_director_foobargo_class">the end of the guide</a>.
</p>
-<H4><a name="Go_director_subclass">25.4.7.6 Subclass via embedding</a></H4>
+<H4><a name="Go_director_subclass">25.4.9.6 Subclass via embedding</a></H4>
<p>
@@ -909,7 +936,7 @@ class.
</p>
-<H4><a name="Go_director_finalizer">25.4.7.7 Memory management with runtime.SetFinalizer</a></H4>
+<H4><a name="Go_director_finalizer">25.4.9.7 Memory management with runtime.SetFinalizer</a></H4>
<p>
@@ -974,7 +1001,7 @@ before using <tt>runtime.SetFinalizer</tt> to know all of its gotchas.
</p>
-<H4><a name="Go_director_foobargo_class">25.4.7.8 Complete FooBarGo example class</a></H4>
+<H4><a name="Go_director_foobargo_class">25.4.9.8 Complete FooBarGo example class</a></H4>
<p>
@@ -1103,7 +1130,7 @@ SWIG/Examples/go/director/</a>.
</p>
-<H3><a name="Go_primitive_type_mappings">25.4.8 Default Go primitive type mappings</a></H3>
+<H3><a name="Go_primitive_type_mappings">25.4.10 Default Go primitive type mappings</a></H3>
<p>
@@ -1210,7 +1237,7 @@ that typemap, or add new values, to control how C/C++ types are mapped
into Go types.
</p>
-<H3><a name="Go_output_arguments">25.4.9 Output arguments</a></H3>
+<H3><a name="Go_output_arguments">25.4.11 Output arguments</a></H3>
<p>Because of limitations in the way output arguments are processed in swig,
@@ -1263,7 +1290,7 @@ void f(char *output);
</pre>
</div>
-<H3><a name="Go_adding_additional_code">25.4.10 Adding additional go code</a></H3>
+<H3><a name="Go_adding_additional_code">25.4.12 Adding additional go code</a></H3>
<p>Often the APIs generated by swig are not very natural in go, especially if
@@ -1358,7 +1385,7 @@ func bar() {
</pre>
</div>
-<H3><a name="Go_typemaps">25.4.11 Go typemaps</a></H3>
+<H3><a name="Go_typemaps">25.4.13 Go typemaps</a></H3>
<p>
@@ -1397,7 +1424,7 @@ default as <a href="#Go_primitive_type_mappings">described above</a>.
<td>
An intermediate Go type used by the "goin", "goout", "godirectorin",
and "godirectorout" typemaps. If this typemap is not defined for a
-C/C++ type, the gotype typemape will be used. This is useful when
+C/C++ type, the gotype typemap will be used. This is useful when
gotype is best converted to C/C++ using Go code.
</td>
</tr>
diff --git a/Doc/Manual/Guile.html b/Doc/Manual/Guile.html
index 26679dc4b..eaf658373 100644
--- a/Doc/Manual/Guile.html
+++ b/Doc/Manual/Guile.html
@@ -52,15 +52,16 @@ This section details guile-specific support in SWIG.
<p>
-SWIG works with Guile versions 1.8.x and 2.0.x. Support for version
-1.6.x has been dropped. The last version of SWIG that still works with
-Guile version 1.6.x is SWIG 2.0.9.
+SWIG is known to work with Guile versions 2.0.x, 2.2.x and 3.0.x (these are
+all tested via CI). SWIG probably still works with Guile 1.8.x but we're no
+longer able to regularly test this either in CI or by hand. Support for Guile
+1.6.x has been dropped (SWIG 2.0.9 was the last version of SWIG to support it).
<p>
Note that starting with guile 2.0, the guile sources can be compiled for
improved performance. This is currently not tested with swig
so your mileage may vary. To be safe set environment variable
-GUILE_AUTO_COMPILE to 0 when using swig generated guile code.
+<tt>GUILE_AUTO_COMPILE</tt> to 0 when using swig generated guile code.
<H2><a name="Guile_nn2">26.2 Meaning of "Module"</a></H2>
@@ -75,7 +76,7 @@ we explicitly prefix the context, e.g., "guile-module".
<p>Guile 1.8 and older could be interfaced using two different api's, the SCM
or the GH API. The GH interface to guile is deprecated. Read more about why in the
-<a href="http://www.gnu.org/software/guile/docs/docs-1.6/guile-ref/GH.html#GH">Guile manual</a>.
+<a href="https://www.gnu.org/software/guile/docs/docs-1.6/guile-ref/GH.html#GH">Guile manual</a>.
<p>Support for the guile GH wrapper code generation has been dropped from SWIG. The last
version of SWIG that can still generate guile GH wrapper code is 2.0.9. Please
@@ -303,10 +304,12 @@ experimental; the (hobbit4d link) conventions are not well understood.
Underscores are converted to dashes in identifiers. Guile support may
grow an option to inhibit this folding in the future, but no one has
complained so far.
+</p>
-<p>You can use the SWIG directives <code>%name</code> and
-<code>%rename</code> to specify the Guile name of the wrapped
-functions and variables (see CHANGES).
+<p>You can use the <a href="SWIG.html#SWIG_rename_ignore">SWIG
+directive <code>%rename</code></a> to specify the Guile
+names of the wrapped functions and variables.
+</p>
<H2><a name="Guile_nn11">26.6 Typemaps</a></H2>
diff --git a/Doc/Manual/Introduction.html b/Doc/Manual/Introduction.html
index facfc7dd1..69e2563bd 100644
--- a/Doc/Manual/Introduction.html
+++ b/Doc/Manual/Introduction.html
@@ -453,14 +453,14 @@ Microsoft Visual Studio.
<p>
If you are using the GNU Autotools
-(<a href="http://www.gnu.org/software/autoconf/">Autoconf</a>/
-<a href="http://www.gnu.org/software/automake/">Automake</a>/
-<a href="http://www.gnu.org/software/libtool/">Libtool</a>)
+(<a href="https://www.gnu.org/software/autoconf/">Autoconf</a>/
+<a href="https://www.gnu.org/software/automake/">Automake</a>/
+<a href="https://www.gnu.org/software/libtool/">Libtool</a>)
to configure SWIG use in your project, the SWIG Autoconf macros can be used.
The primary macro is <tt>ax_pkg_swig</tt>, see
-<a href="http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig">http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig</a>.
+<a href="https://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig">http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig</a>.
The <tt>ax_python_devel</tt> macro is also helpful for generating Python extensions. See the
-<a href="http://www.gnu.org/software/autoconf-archive/">Autoconf Archive</a>
+<a href="https://www.gnu.org/software/autoconf-archive/">Autoconf Archive</a>
for further information on this and other Autoconf macros.
</p>
diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html
index 2591b27b5..d15ef2f0b 100644
--- a/Doc/Manual/Java.html
+++ b/Doc/Manual/Java.html
@@ -644,7 +644,7 @@ java::
<p>
To build the DLL and compile the java code, run NMAKE (you may need to run <tt>vcvars32</tt> first).
-This is a pretty simplistic Makefile, but hopefully its enough to get you started.
+This is a pretty simplistic Makefile, but hopefully it's enough to get you started.
Of course you may want to make changes for it to work for C++ by adding in the -c++ command line option for swig and replacing .c with .cxx.
</p>
@@ -3434,9 +3434,11 @@ Consider the following C++ code:
namespace Space {
struct Base1 {
virtual void Method1();
+ virtual Base1();
};
struct Base2 {
virtual void Method2();
+ virtual Base2();
};
struct Derived : Base1, Base2 {
};
@@ -3453,7 +3455,7 @@ SWIG generates a warning for the above code:
<div class="shell">
<pre>
-example.i:10: Warning 813: Warning for Derived, base Base2 ignored.
+example.i:12: Warning 813: Warning for Derived, base Base2 ignored.
Multiple inheritance is not supported in Java.
</pre>
</div>
@@ -3506,7 +3508,7 @@ public class Base1SwigImpl implements Base1 {
</div>
<p>
-In fact any class deriving from <tt>Base</tt> will now implement the interface instead of
+In fact any class using <tt>Base</tt> as an immediate base class will now implement the interface instead of
deriving from it (or ignoring the base in the case of multiple base classes).
Hence the <tt>Derived</tt> proxy class will now implement both bases:
</p>
@@ -3536,6 +3538,21 @@ public class Derived implements Base1, Base2 {
</div>
<p>
+The proxy class has methods added to it, from the implemented bases, so that
+the underlying C++ implementation can be called.
+In the example above, <tt>Method1</tt> and <tt>Method2</tt> have been added from the implemented bases.
+If a method is ignored in the base, such as via <tt>%ignore</tt>, then that method
+will be excluded from the interface and there will not be an additional method
+added to the proxy class implementing that interface.
+</p>
+
+<p>
+The Java interface only ever contains virtual and non-virtual instance methods from the wrapped C++ class.
+Any static methods, enums or variables in the wrapped C++ class are not supported and are not added to the interface.
+They are of course still available in the Java proxy class.
+</p>
+
+<p>
Wherever a class marked as an interface is used, such as the <tt>UseBases</tt> method in the example,
the interface name is used as the type in the Java layer:
</p>
@@ -4201,7 +4218,7 @@ You can copy the code below into an interface file and run SWIG on it and examin
%}
// Expose C++ exception as a Java Exception by changing the Java base class and providing a getMessage()
-%typemap(javabase) MyNS::MyException "java.lang.RuntimeException";
+%typemap(javabase) MyNS::MyException "java.lang.RuntimeException"
%rename(getMessage) MyNS::MyException::whatsup;
%inline %{
@@ -6440,6 +6457,12 @@ unless the jniclassname attribute is specified in the <a href="Java.html#Java_mo
</p>
<p>
+<b><tt>$imfuncname</tt></b><br>
+This special variable expands to the name of the function in the intermediary class that will be used in $jnicall.
+Like, $jnicall, this special variable is only expanded in the "javaout" typemap.
+</p>
+
+<p>
<b><tt>$javainterfacename</tt></b><br>
This special variable is only expanded when the <tt>interface</tt> feature is applied to a class.
It works much like <tt>$javaclassname</tt>, but instead of expanding to the proxy classname,
@@ -7042,7 +7065,7 @@ The corrected interface file looks like:
<pre>
// class Foo is handled in a different interface file:
%import "Foo.i"
-%typemap("javapackage") Foo, Foo *, Foo &amp; "com.wombat.foo";
+%typemap("javapackage") Foo, Foo *, Foo &amp; "com.wombat.foo"
%feature("director") Example;
%inline {
@@ -7070,11 +7093,11 @@ Note the helper macros below, <code>OTHER_PACKAGE_SPEC</code> and <code>ANOTHER_
"package.for.most.classes";
%define OTHER_PACKAGE_SPEC(TYPE...)
-%typemap("javapackage") TYPE, TYPE *, TYPE &amp; "package.for.other.classes";
+%typemap("javapackage") TYPE, TYPE *, TYPE &amp; "package.for.other.classes"
%enddef
%define ANOTHER_PACKAGE_SPEC(TYPE...)
-%typemap("javapackage") TYPE, TYPE *, TYPE &amp; "package.for.another.set";
+%typemap("javapackage") TYPE, TYPE *, TYPE &amp; "package.for.another.set"
%enddef
OTHER_PACKAGE_SPEC(Package_2_class_one)
@@ -7268,7 +7291,7 @@ The typemaps to use then are as follows:
<div class="code">
<pre>
-%typemap(javabase) FileException "java.lang.Exception";
+%typemap(javabase) FileException "java.lang.Exception"
%typemap(javacode) FileException %{
public String getMessage() {
return what();
@@ -9063,6 +9086,11 @@ Here the default typemaps work for <tt>int</tt> and <tt>char *</tt>.
</p>
<p>
+Note that if you're wanting to effectively <b>replace</b> the JNI code generated for a C/C++ function then you'll need to use <tt>%ignore</tt> as well
+to tell SWIG not to automatically generate a JNI wrapper for it.
+</p>
+
+<p>
In summary the <tt>%native</tt> directive is telling SWIG to generate the Java code to access the JNI C code, but not the JNI C function itself.
This directive is only really useful if you want to mix your own hand crafted JNI code and the SWIG generated code into one Java class or package.
</p>
diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html
index 54bd68521..c4545ecff 100644
--- a/Doc/Manual/Javascript.html
+++ b/Doc/Manual/Javascript.html
@@ -89,24 +89,10 @@ $ swig -javascript -jsc example.i</pre>
<pre>
$ swig -c++ -javascript -jsc example.i</pre>
</div>
-<p>The V8 code that SWIG generates should work with most versions from 3.11.10.
-However, the only early version that receives some testing is 3.14.5, which is
-still shipped with Ubuntu for some reason. Other than that it's probably safer
-to assume that versions earlier than 5.0 are no longer supported. Keep in mind
-that these are V8 versions, not Node.js. To give some perspective, Node.js v6.0
+<p>The V8 code that SWIG generates requires at least V8 5.0. Keep in mind
+that this is theV8 version, not Node.js. To give some perspective, Node.js v6.0
uses V8 5.0, v12.0 - 7.4, v14.0 - 8.1...</p>
-<p>The API headers for V8 &gt;= 4.3.10 define constants which SWIG can use to
-determine the V8 version it is compiling for. For versions &lt; 4.3.10, you
-need to specify the V8 version when running SWIG. This is specified as a hex
-constant, but the constant is read as pairs of decimal digits, so for V8
-3.25.30 use constant 0x032530. This scheme can't represent components &gt; 99,
-but this constant is only useful for V8 &lt; 4.3.10, and no V8 versions from
-that era had a component &gt; 99. For example:</p>
-<div class="shell">
-<pre>
-$ swig -c++ -javascript -v8 -DV8_VERSION=0x032530 example.i</pre>
-</div>
-<p>If you're targeting V8 &gt;= 4.3.10, you would just run swig like so:</p>
+<p>To generate code for V8, you would run swig like so:</p>
<div class="shell">
<pre>
$ swig -c++ -javascript -v8 example.i</pre>
@@ -293,7 +279,7 @@ extern bool example_initialize(JSGlobalContextRef context, JSObjectRef* exports)
<H4><a name="Javascript_gtk">28.3.2.2 GTK</a></H4>
-<p>There is general information about programming GTK at <a href="https://developer.gnome.org/gtk2/">GTK documentation</a> and in the <a href="https://developer.gnome.org/gtk-tutorial/">GTK tutorial</a>, and for Webkit there is a <a href="http://webkitgtk.org/reference/webkitgtk/stable/index.html">Webkit GTK+ API Reference</a>.</p>
+<p>There is general information about programming GTK at <a href="https://developer.gnome.org/gtk2/">GTK documentation</a> and in the <a href="https://developer.gnome.org/gtk-tutorial/">GTK tutorial</a>, and for Webkit there is a <a href="https://webkitgtk.org/reference/webkitgtk/stable/index.html">Webkit GTK+ API Reference</a>.</p>
<p>An integration of a native extension 'example' would look like this:</p>
<div class="code">
<pre>
@@ -324,7 +310,7 @@ int main(int argc, char* argv[])
...
// Load a web page into the browser instance
- webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/");
+ webkit_web_view_load_uri(webView, "https://www.webkitgtk.org/");
...
@@ -479,7 +465,7 @@ example.Foo = 3.1415926;</pre>
</div>
<p>First the module <code>example</code> is loaded from the previously built extension. Global methods and variables are available in the scope of the module.</p>
-<p><b>Note</b>: ECMAScript 5, the currently implemented Javascript standard, does not have modules. <code>node.js</code> and other implementations provide this mechanism defined by the <a href="http://wiki.commonjs.org/wiki/CommonJS">CommonJS</a> group. For browsers this is provided by <a href="http://browserify.org">Browserify</a>, for instance.</p>
+<p><b>Note</b>: ECMAScript 5, the currently implemented Javascript standard, does not have modules. <code>node.js</code> and other implementations provide this mechanism defined by the <a href="https://wiki.commonjs.org/wiki/CommonJS">CommonJS</a> group. For browsers this is provided by <a href="https://browserify.org">Browserify</a>, for instance.</p>
<H3><a name="Javascript_class_example">28.4.2 Class</a></H3>
diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html
index 5f72b557d..f308c31f1 100644
--- a/Doc/Manual/Library.html
+++ b/Doc/Manual/Library.html
@@ -14,6 +14,7 @@
<li><a href="#Library_nn2">The %include directive and library search path</a>
<li><a href="#Library_nn3">C arrays and pointers</a>
<ul>
+<li><a href="#Library_argcargv">argcargv.i</a>
<li><a href="#Library_nn4">cpointer.i</a>
<li><a href="#Library_carrays">carrays.i</a>
<li><a href="#Library_nn6">cmalloc.i</a>
@@ -39,11 +40,16 @@
<li><a href="#Library_shared_ptr_templates">shared_ptr and templates</a>
<li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a>
</ul>
+<li><a href="#Library_std_unique_ptr">unique_ptr smart pointer</a>
<li><a href="#Library_std_auto_ptr">auto_ptr smart pointer</a>
</ul>
<li><a href="#Library_nn16">Utility Libraries</a>
<ul>
<li><a href="#Library_nn17">exception.i</a>
+<li><a href="#Library_attributes">attribute.i</a>
+<ul>
+<li><a href="#Library_attribute_templates">%attribute and C++ templates</a>
+</ul>
</ul>
</ul>
</div>
@@ -111,7 +117,48 @@ pointers as class-like objects. Since these functions provide direct access to
memory, their use is potentially unsafe and you should exercise caution.
</p>
-<H3><a name="Library_nn4">12.2.1 cpointer.i</a></H3>
+<H3><a name="Library_argcargv">12.2.1 argcargv.i</a></H3>
+
+
+<p>
+The argcargv.i library is a simple library providing multi-argument typemaps for handling C
+argc argv command line argument C string arrays.
+The <tt>argc</tt> parameter contains the argument count and <tt>argv</tt> contains the argument vector array.
+</p>
+
+<p>
+This library provides the following multi-argument typemap:
+</p>
+
+<p>
+<b><tt>(int ARGC, char **ARGV)</tt></b>
+</p>
+
+<p>
+Apply this multi-argument typemap to your use case, for example:
+</p>
+
+<div class="code">
+<pre>
+%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+
+int mainApp(size_t argc, const char **argv);
+</pre>
+</div>
+
+<p>
+then from Ruby:
+</p>
+
+<div class="targetlang">
+<pre>
+$args = ["myarg1", "myarg2"]
+mainApp(args);
+</pre>
+</div>
+
+
+<H3><a name="Library_nn4">12.2.2 cpointer.i</a></H3>
<p>
@@ -327,7 +374,7 @@ In this example, the function <tt>int_to_uint()</tt> would be used to cast type
<b>Note:</b> When working with simple pointers, typemaps can often be used to provide more seamless operation.
</p>
-<H3><a name="Library_carrays">12.2.2 carrays.i</a></H3>
+<H3><a name="Library_carrays">12.2.3 carrays.i</a></H3>
<p>
@@ -506,7 +553,7 @@ used with types of <tt>char</tt> or <tt>char *</tt>.
SWIG's default handling of these types is to handle them as character strings and the two macros do not do enough to change this.
</p>
-<H3><a name="Library_nn6">12.2.3 cmalloc.i</a></H3>
+<H3><a name="Library_nn6">12.2.4 cmalloc.i</a></H3>
<p>
@@ -667,7 +714,7 @@ Now, in a script:
</pre>
</div>
-<H3><a name="Library_nn7">12.2.4 cdata.i</a></H3>
+<H3><a name="Library_nn7">12.2.5 cdata.i</a></H3>
<p>
@@ -1994,27 +2041,159 @@ The SWIG code below shows the required ordering:
The languages that support shared_ptr also have support for using shared_ptr with directors.
</p>
+<H3><a name="Library_std_unique_ptr">12.4.5 unique_ptr smart pointer</a></H3>
+
+
+<p>
+The <tt>std_unique_ptr.i</tt> library file provides SWIG's unique_ptr support.
+It defines typemaps and a macro, <tt>%unique_ptr(T)</tt>, to use for handling
+<tt>std::unique_ptr&lt;T&gt;</tt> for a type <tt>T</tt>.
+The type <tt>T</tt> must be non-primitive.
+This macro should be used before any code declaring or using type <tt>T</tt>.
+Ordering requirements for using this smart pointer macro are the same as the
+equivalent <tt>%shared_ptr(T)</tt> macro covered in the previous section.
+</p>
+
+<p>
+Example usage of a <tt>std::unique_ptr</tt> being returned from a function is shown below.
+</p>
+
+<div class="code">
+<pre>
+%include &lt;std_unique_ptr.i&gt;
+
+%unique_ptr(Klass)
+%inline %{
+#include &lt;memory&gt;
+class Klass {
+public:
+ // Factory function creating objects of this class:
+ static std::unique_ptr&lt;Klass&gt; Create(int value) {
+ return std::unique_ptr&lt;Klass&gt;(new Klass(value));
+ }
+
+ int getValue() const { return m_value; }
+
+private:
+ Klass(int value) : m_value(value) {}
+ int m_value;
+};
+%}
+</pre>
+</div>
+
+<p>
+The returned objects can be used naturally from the target language, e.g. from
+C#:
+</p>
+
+<div class="targetlang">
+<pre>
+Klass k = Klass.Create(17);
+int value = k.getValue();
+</pre>
+</div>
+
+<p>
+The implementation simply calls <tt>std::unique_ptr::release()</tt> to obtain
+the underlying raw pointer. The pointer is then used to create a target language
+proxy class in the same way that SWIG handles a C++ function returning a class by value.
+The target language proxy class then owns the memory pointed to by the raw pointer
+and memory handling is identical to normal SWIG proxy class handling of the underlying C++ memory.
+Note that an object returned by value is first copied/moved from the stack onto the heap in order to obtain
+a raw pointer on the heap, whereas the underlying raw pointer in <tt>std::unique_ptr</tt> already points to an object the heap.
+</p>
+
+<p>
+Note that the implementation is quite different to the <tt>std::shared_ptr</tt> smart pointer,
+where the proxy class manages the underlying C++ memory as a pointer to a shared_ptr instead of a plain raw pointer.
+</p>
+
+<p>
+A possibly less common usage of this smart pointer is as a parameter to a function.
+When used like this it indicates that memory usage of the object pointed to by the underlying pointer
+is transferred to the function being called.
+The code that SWIG generates assumes this happens.
+First, it is assumed that a proxy class already owns the underlying C++ object and is used to pass the object to the C++ function being called.
+Second, the ownership is transferred from the proxy class to the C++ function being called and
+lifetime is then controlled by the function.
+Finally, it is assumed the lifetime of the object may not last beyond returning from the C++ function
+and hence the proxy class can no longer be used.
+</p>
+
+<p>
+Consider expanding the example above with a function that takes a <tt>std::unique_ptr</tt> as follows:
+</p>
+
+<div class="code">
+<pre>
+void take(std::unique_ptr&lt;Klass&gt;);
+</pre>
+</div>
-<H3><a name="Library_std_auto_ptr">12.4.5 auto_ptr smart pointer</a></H3>
+<p>
+and use from C#:
+</p>
+
+<div class="targetlang">
+<pre>
+Klass k = Klass.Create(17); // create an instance of Klass any way you like
+int value = k.getValue(); // ok
+example.take(k); // memory ownership passes from C# layer to C++ layer
+int v = k.getValue(); // don't do this - invalid use of k
+</pre>
+</div>
+
+<p>
+Attempts to use <tt>k</tt> after the ownership has been passed into the <tt>take</tt> function
+should not be attempted.
+The implementation sets the proxy class to an invalid state by setting the class's underlying
+C++ pointer to null after the return from the <tt>take</tt> function.
+Subsequent use of an invalid proxy class instance is very much dependent on the implementation
+in the target language and ranges from a segfault to giving a nice error.
+Consider implementing additional checks via the 'check' typemap.
+</p>
+
+<p>
+Attempts to pass ownership from a proxy class to a <tt>std::unique</tt> parameter more than once will result
+in a "Cannot release ownership as memory is not owned" exception. For example, if <tt>example.take(k)</tt> in the example above is called twice.
+</p>
+
+<p>
+<b>Compatibility note:</b> Support for <tt>std::unique_ptr</tt> was added in SWIG-4.1.0.
+</p>
+
+<H3><a name="Library_std_auto_ptr">12.4.6 auto_ptr smart pointer</a></H3>
<p>
While <tt>std::auto_ptr</tt> is deprecated in C++11, some existing code may
-still be using it, so SWIG provides limited support for this class:
-<tt>std_auto_ptr.i</tt> defines the typemaps which apply to the functions
-returning objects of this type. Any other use of <tt>std_auto_ptr.i</tt> is not
-directly supported.
+still be using it. SWIG provides support for this class which is nearly identical
+to <tt>std::unique_ptr</tt>.
+</p>
+
+<p>
+The <tt>std_auto_ptr.i</tt> library file provides SWIG's auto_ptr support.
+It defines typemaps and a macro, <tt>%auto_ptr(T)</tt>, to use for handling
+<tt>std::auto_ptr&lt;T&gt;</tt> for a type <tt>T</tt>.
+The type <tt>T</tt> must be non-primitive.
+This macro should be used before any code declaring or using type <tt>T</tt>.
+Ordering requirements for using this smart pointer macro are the same as the
+equivalent <tt>%shared_ptr(T)</tt> and <tt>%unique_ptr</tt> macros covered in
+the previous two sections.
</p>
<p>
-A typical example of use would be
+Example usage of a <tt>std::auto_ptr</tt> being returned from a function is shown below.
</p>
+
<div class="code">
<pre>
%include &lt;std_auto_ptr.i&gt;
%auto_ptr(Klass)
%inline %{
+#include &lt;memory&gt;
class Klass {
public:
// Factory function creating objects of this class:
@@ -2025,7 +2204,7 @@ public:
int getValue() const { return m_value; }
private:
- DerivedIntValue(int value) : m_value(value) {}
+ Klass(int value) : m_value(value) {}
int m_value;
};
%}
@@ -2044,6 +2223,15 @@ int value = k.getValue();
</pre>
</div>
+<p>
+The implementation simply calls <tt>std::auto_ptr::release()</tt> to obtain the underlying raw pointer.
+That is, it works the same way covered in the previous section for <tt>std::unique_ptr</tt>.
+</p>
+
+<p>
+Input parameters also work the same way as <tt>std::unique_ptr</tt> covered in the previous section.
+</p>
+
<H2><a name="Library_nn16">12.5 Utility Libraries</a></H2>
@@ -2108,5 +2296,244 @@ For example:
</div>
+<H3><a name="Library_attributes">12.5.2 attribute.i</a></H3>
+
+
+<p>
+The attribute library contains a set of macros to convert a pair of set/get methods
+into a "native" attribute/property.
+</p>
+
+<p>
+Use <tt>%attribute</tt> when you have a pair of get/set methods to a
+primitive type like:
+</p>
+
+<div class="code">
+<pre>
+%include "attribute.i"
+%attribute(A, int, a, get_a, set_a);
+
+struct A {
+ int get_a() const;
+ void set_a(int aa);
+};
+</pre>
+</div>
+
+<p>
+and you want to provide that variable as an attribute in the target
+language. This example only works for primitive types, not derived
+types.
+Now you can use the attributes like so (in Python):
+</p>
+
+<div class="targetlang">
+<pre>
+x = A()
+x.a = 3 # calls A::set_a(3)
+print(x.a) # calls A::get_a() const
+</pre>
+</div>
+
+<p>
+If you don't provide a 'set' method, a 'read-only' attribute
+is generated, ie, like:
+</p>
+
+<div class="code">
+<pre>
+%attribute(A, int, c, get_c);
+</pre>
+</div>
+
+<p>
+Use <tt>%attributeref</tt> when you have const/non-const reference
+access methods for primitive types or class/structs, like:
+</p>
+
+<div class="code">
+<pre>
+%attributeref(A, int, b);
+
+struct A {
+ const int &amp; b() const;
+ int &amp; b();
+};
+
+%attributeref(B, int, c);
+
+struct B {
+ int &amp; c();
+};
+</pre>
+</div>
+
+<p>
+Use the attributes like so (in Python):
+</p>
+
+<div class="targetlang">
+<pre>
+x = A()
+x.b = 3 # calls A::b()
+print(x.b) # calls A::b() const
+</pre>
+</div>
+
+<p>
+You can also use
+</p>
+
+<div class="code">
+<pre>
+%attributeref(Class, AttributeType, AttributeName, AccessorMethod)
+</pre>
+</div>
+
+<p>
+if the internal C++ reference methods have a different name from the
+attribute you want, so
+</p>
+
+<div class="code">
+<pre>
+%attributeref(B, int, d, c);
+</pre>
+</div>
+
+<p>
+is the same as the last example, but instead of the attribute 'c' being
+called 'c', it is called 'd'.
+</p>
+
+<p>
+Use <tt>%attribute2</tt> instead of <tt>%attribute</tt> to indicate
+that reference-pointer translation is required.
+Use <tt>%attribute2</tt> instead of <tt>%attribute</tt> in cases like
+this:
+</p>
+
+<div class="code">
+<pre>
+%attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
+%inline %{
+ struct MyFoo {
+ int x;
+ };
+ class MyClass {
+ MyFoo foo;
+ public:
+ MyFoo &amp; GetFoo() { return foo; }
+ void SetFoo(const MyFoo &amp;other) { foo = other; }
+ };
+%}
+</pre>
+</div>
+
+<p>
+Here, the data type of the property is a wrapped type <tt>MyFoo</tt> and on
+the C++ side it is passed by reference. The problem is that the SWIG
+wrapper will pass around a pointer (MyFoo *) which is not compatible
+with the reference type of the accessors (MyFoo &amp;). Therefore, if you
+use <tt>%attribute</tt>, you'll get an error from your C/C++
+compiler. <tt>%attribute2</tt> translates between a pointer and a
+reference to eliminate the error. In case you're confused, let's make
+it simple: just use <tt>%attribute</tt> at first, but if the C/C++
+compiler gives an error while compiling the wrapper,
+try <tt>%attribute2</tt> instead.
+</p>
+
+<p>
+NOTE: remember that if the type contains commas, such as
+<tt>std::pair&lt;int, int&gt;</tt>, you need to use the macro like:
+</p>
+
+<div class="code">
+<pre>
+%attributeref(A, %arg(std::pair&lt;int, int&gt;), pval);
+</pre>
+</div>
+
+<p>
+where <tt>%arg()</tt> 'normalizes' the type to be understood as a single
+argument, otherwise the macro will get confused by the comma.
+</p>
+
+<p>
+The <tt>%attributeval</tt> is the same as <tt>%attribute</tt>, but
+should be used when the type is a class/struct (ie a non-primitive
+type) and when the get and set methods return/pass by value. The
+following is very similar to the above example, but note that the
+access is by value rather than reference.
+</p>
+
+<div class="code">
+<pre>
+%attributeval(MyClassVal, MyFoo, ReadWriteFoo, GetFoo, SetFoo);
+%attributeval(MyClassVal, MyFoo, ReadOnlyFoo, GetFoo);
+%inline %{
+ class MyClassVal {
+ MyFoo foo;
+ public:
+ MyFoo GetFoo() { return foo; }
+ void SetFoo(MyFoo other) { foo = other; }
+ };
+%}
+</pre>
+</div>
+
+<p>
+The <tt>%attributestring</tt> is the same as <tt>%attributeval</tt>,
+but should be used for string class types, which are unusual as they
+are a class on the C++ side, but normally an immutable/primitive type
+in the target language. Example usage for <tt>std::string</tt>:
+</p>
+
+<div class="code">
+<pre>
+%include &lt;std_string.i&gt;
+%attributestring(MyStringyClass, std::string, ReadWriteString, GetString, SetString);
+%attributestring(MyStringyClass, std::string, ReadOnlyString, GetString);
+%inline %{
+ class MyStringyClass {
+ std::string str;
+ public:
+ MyStringyClass(const std::string &amp;val) : str(val) {}
+ std::string GetString() { return str; }
+ void SetString(std::string other) { str = other; }
+ };
+%}
+</pre>
+</div>
+
+<p>
+The <tt>%attributestring</tt> also works for class types that
+have <tt>%naturalvar</tt> turned on and so is also useful for
+shared_ptr which has <tt>%naturalvar</tt> turned on in
+<tt>%shared_ptr</tt>.
+</p>
+
+<H4><a name="Library_attribute_templates">12.5.2.1 %attribute and C++ templates</a></H4>
+
+
+<p>
+ <tt>%attribute</tt> and friends have to be used on fully specified classes. For example
+</p>
+<div class="code">
+<pre>
+%attributeref(A&lt;int&gt;, int, a);
+%inline %{
+ template &lt;class T&gt; struct A {
+ T a() const;
+ void a(T &amp;);
+ };
+%}
+</pre>
+</div>
+<p>
+Note the use of a template-id (i.e., <tt>A&lt;int&gt;</tt> not <tt>A&lt;T&gt;</tt> or just <tt>A</tt>).
+This means that <tt>%attribute</tt> statements have to be repeated for any template-id that you want to use with <tt>%template</tt>.
+</p>
</body>
</html>
diff --git a/Doc/Manual/Lisp.html b/Doc/Manual/Lisp.html
deleted file mode 100644
index 6eb448a12..000000000
--- a/Doc/Manual/Lisp.html
+++ /dev/null
@@ -1,604 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<title>SWIG and Common Lisp</title>
-<link rel="stylesheet" type="text/css" href="style.css">
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-</head>
-
-<body bgcolor="#ffffff">
-<H1><a name="Lisp">29 SWIG and Common Lisp</a></H1>
-<!-- INDEX -->
-<div class="sectiontoc">
-<ul>
-<li><a href="#Lisp_nn3">Common Foreign Function Interface(CFFI)</a>
-<ul>
-<li><a href="#Lisp_nn4">Additional Commandline Options </a>
-<li><a href="#Lisp_nn5">Generating CFFI bindings</a>
-<li><a href="#Lisp_nn6">Generating CFFI bindings for C++ code</a>
-<li><a href="#Lisp_nn7">Inserting user code into generated files</a>
-</ul>
-<ul>
-<li><a href="#Lisp_nn9">Additional Commandline Options </a>
-</ul>
-</ul>
-</div>
-<!-- INDEX -->
-
-
-
-<p>
- Common Lisp is a high-level, all-purpose, object-oriented,
- dynamic, functional programming language with long history.
- Common Lisp is used in many fields, ranging from web development to
- finance, and also common in computer science education.
- There are more than 9 different implementations of common lisp which
- are available, all have different foreign function
- interfaces. SWIG currently supports the
- Common Foreign Function Interface(CFFI).
-</p>
-
-<H2><a name="Lisp_nn3">29.2 Common Foreign Function Interface(CFFI)</a></H2>
-
-
-<p>
- CFFI, the Common Foreign Function Interface, is a portable foreign
- function interface for ANSI Common Lisp systems.
- CFFI requires only a small set of
- low-level functionality from the Lisp implementation, such as
- calling a foreign function by name, allocating foreign memory,
- and dereferencing pointers.
-</p>
-
-<p>
- To run the cffi module of SWIG requires very little effort, you
- just need to run:
-</p>
-<div class="code"><pre>
-swig -cffi -module <i>module-name</i> <i>file-name</i>
-
-</pre></div>
-
-<p>
- But a better was of using all the power of SWIG is to write SWIG
- interface files. Below we will explain how to write interface
- files and the various things which you can do with them.
-</p>
-
-<H3><a name="Lisp_nn4">29.2.1 Additional Commandline Options </a></H3>
-
-
-<table summary="CFFI specific options">
-<tr>
- <th> CFFI specific options</th>
-</tr>
-
-<tr>
-<td>-generate-typedef</td>
-<td>If this option is given then defctype will be used to generate<br/>
- shortcuts according to the typedefs in the input.
-</td>
-</tr>
-
-<tr>
-<td>-[no]cwrap</td>
-<td>Turn on or turn off generation of an intermediate C file when<br/>
- creating a C interface. By default this is only done for C++ code.
-</td>
-</tr>
-
-<tr>
-<td>-[no]swig-lisp</td>
-<td>Turns on or off generation of code for helper lisp macro, functions,
- etc. which SWIG uses while generating wrappers. These macros, functions
- may still be used by generated wrapper code.
-</td>
-</tr>
-
-</table>
-
-<H3><a name="Lisp_nn5">29.2.2 Generating CFFI bindings</a></H3>
-
-
-<p>
-
-As we mentioned earlier the ideal way to use SWIG is to use interface
- files. To illustrate the use of it, let's assume that we have a
- file named <i>test.h</i> with the following C code:
-</p>
-
-<div class="code"><pre>
-#define y 5
-#define x (y &gt;&gt; 1)
-
-typedef int days;
-
-struct bar {
- short p, q;
- char a, b;
- int *z[1000];
- struct bar * n;
-};
-
-struct bar * my_struct;
-
-struct foo {
- int a;
- struct foo * b[100];
-};
-
-int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p);
-
-int func123(div_t * p, int **q[100], int r[][1000][10]);
-
-void lispsort_double (int n, double * array);
-
-enum color { RED, BLUE, GREEN};
-</pre></div>
-
-<p>
-Corresponding to this we will write a simple interface file:
-</p>
-
-<div class="code"><pre>
-%module test
-
-%include "test.h"
-
-</pre></div>
-
-<p>
-The generated SWIG Code will be:
-</p>
-
-<div class="targetlang"><pre>
-;;;SWIG wrapper code starts here
-
-(cl:defmacro defanonenum (&amp;body enums)
- "Converts anonymous enums to defconstants."
- `(cl:progn , @(cl:loop for value in enums
- for index = 0 then (cl:1+ index)
- when (cl:listp value) do (cl:setf index (cl:second value)
- value (cl:first value))
- collect `(cl:defconstant , value , index))))
-
-(cl:eval-when (:compile-toplevel :load-toplevel)
- (cl:unless (cl:fboundp 'swig-lispify)
- (cl:defun swig-lispify (name flag cl:&amp;optional (package cl:*package*))
- (cl:labels ((helper (lst last rest cl:&amp;aux (c (cl:car lst)))
- (cl:cond
- ((cl:null lst)
- rest)
- ((cl:upper-case-p c)
- (helper (cl:cdr lst) 'upper
- (cl:case last
- ((lower digit) (cl:list* c #\- rest))
- (cl:t (cl:cons c rest)))))
- ((cl:lower-case-p c)
- (helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest)))
- ((cl:digit-char-p c)
- (helper (cl:cdr lst) 'digit
- (cl:case last
- ((upper lower) (cl:list* c #\- rest))
- (cl:t (cl:cons c rest)))))
- ((cl:char-equal c #\_)
- (helper (cl:cdr lst) '_ (cl:cons #\- rest)))
- (cl:t
- (cl:error "Invalid character: ~A" c)))))
- (cl:let ((fix (cl:case flag
- ((constant enumvalue) "+")
- (variable "*")
- (cl:t ""))))
- (cl:intern
- (cl:concatenate
- 'cl:string
- fix
- (cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil))
- fix)
- package))))))
-
-;;;SWIG wrapper code ends here
-
-
-(cl:defconstant y 5)
-
-(cl:defconstant x (cl:ash 5 -1))
-
-(cffi:defcstruct bar
- (p :short)
- (q :short)
- (a :char)
- (b :char)
- (z :pointer)
- (n :pointer))
-
-(cffi:defcvar ("my_struct" my_struct)
- :pointer)
-
-(cffi:defcstruct foo
- (a :int)
- (b :pointer))
-
-(cffi:defcfun ("pointer_func" pointer_func) :int
- (ClosureFun :pointer)
- (p :int))
-
-(cffi:defcfun ("func123" func123) :int
- (p :pointer)
- (q :pointer)
- (r :pointer))
-
-(cffi:defcfun ("lispsort_double" lispsort_double) :void
- (n :int)
- (array :pointer))
-
-(cffi:defcenum color
- :RED
- :BLUE
- :GREEN)
-</pre></div>
-
-<p>
- The <i>SWIG wrapper</i> code refers to the special code which SWIG
- may need to use while wrapping C code. You can turn on/off the
- generation of this code by using the <i>-[no]swig-lisp</i>
- option. You must have noticed that SWIG goes one extra step to
- ensure that CFFI does not do automatic lispification of the C
- function names. The reason SWIG does this is because quite often
- developers want to build a nice CLOS based lispy API, and this one
- to one correspondence between C function names and lisp function
- name helps.
-</p>
-
-<p> Maybe you want to have your own convention for generating lisp
- function names for corresponding C function names, or you just
- want to lispify the names, also, before we forget you want to
- export the generated lisp names. To do this, we will use the
- SWIG <a
- href="Customization.html#Customization_features">feature directive</a>.
-Let's edit the interface file such that the C type "div_t*" is changed
- to Lisp type ":my-pointer", we lispify all names,
- export everything, and do some more stuff.
-
-</p>
-<div class="code"><pre>
-%module test
-
-%typemap(cin) div_t* ":my-pointer";
-
-%feature("intern_function", "1");
-%feature("export");
-
-%feature("inline") lispsort_double;
-%feature("intern_function", "my-lispify") lispsort_double;
-%feature("export", package="'some-other-package") lispsort_double;
-
-%rename func123 renamed_cool_func;
-
-%ignore "pointer_func";
-
-%include "test.h"
-
-</pre></div>
-
-<p>
-The <i>typemap(cin)</i> ensures that for all arguments which are input
- to C with the type "div_t*", the ":my-pointer" type be
- used. Similarly <i>typemap(cout)</i> are used for all types which
- are returned from C.
-</p>
-<p>
-The feature <i>intern_function</i> ensures that all C names are
- interned using the <b>swig-lispify</b> function. The "1" given
- to the feature is optional. The use of feature like
- <i>%feature("intern_function", "1");</i> globally enables
- interning for everything. If you want to target a single
- function, or declaration then use the targeted version of
- feature, <i>%feature("intern_function", "my-lispify")
- lispsort_double;</i>, here we are using an additional feature
- which allows us to use our lispify function.
-</p>
-<p>The <i>export</i> feature allows us to export the symbols. If
- the <i>package</i> argument is given, then the symbol will be exported to
- the specified Lisp package. The <i>inline</i> feature declaims the
- declared function as inline. The <i>rename</i> directive allows us to
- change the name(it is useful when generating C wrapper code for handling
- overloaded functions). The <i>ignore</i> directive ignores a certain
- declaration.
-</p>
-<p>There are several other things which are possible, to see some
- example of usage of SWIG look at the Lispbuilder and wxCL
- projects. The generated code with 'noswig-lisp' option is:
-</p>
-
-<div class="targetlang"><pre>
-(cl:defconstant #.(swig-lispify "y" 'constant) 5)
-
-(cl:export '#.(swig-lispify "y" 'constant))
-
-(cl:defconstant #.(swig-lispify "x" 'constant) (cl:ash 5 -1))
-
-(cl:export '#.(swig-lispify "x" 'constant))
-
-(cffi:defcstruct #.(swig-lispify "bar" 'classname)
- (#.(swig-lispify "p" 'slotname) :short)
- (#.(swig-lispify "q" 'slotname) :short)
- (#.(swig-lispify "a" 'slotname) :char)
- (#.(swig-lispify "b" 'slotname) :char)
- (#.(swig-lispify "z" 'slotname) :pointer)
- (#.(swig-lispify "n" 'slotname) :pointer))
-
-(cl:export '#.(swig-lispify "bar" 'classname))
-
-(cl:export '#.(swig-lispify "p" 'slotname))
-
-(cl:export '#.(swig-lispify "q" 'slotname))
-
-(cl:export '#.(swig-lispify "a" 'slotname))
-
-(cl:export '#.(swig-lispify "b" 'slotname))
-
-(cl:export '#.(swig-lispify "z" 'slotname))
-
-(cl:export '#.(swig-lispify "n" 'slotname))
-
-(cffi:defcvar ("my_struct" #.(swig-lispify "my_struct" 'variable))
- :pointer)
-
-(cl:export '#.(swig-lispify "my_struct" 'variable))
-
-(cffi:defcstruct #.(swig-lispify "foo" 'classname)
- (#.(swig-lispify "a" 'slotname) :int)
- (#.(swig-lispify "b" 'slotname) :pointer))
-
-(cl:export '#.(swig-lispify "foo" 'classname))
-
-(cl:export '#.(swig-lispify "a" 'slotname))
-
-(cl:export '#.(swig-lispify "b" 'slotname))
-
-(cffi:defcfun ("renamed_cool_func" #.(swig-lispify "renamed_cool_func" 'function)) :int
- (p :my-pointer)
- (q :pointer)
- (r :pointer))
-
-(cl:export '#.(swig-lispify "renamed_cool_func" 'function))
-
-(cl:declaim (cl:inline #.(my-lispify "lispsort_double" 'function)))
-
-(cffi:defcfun ("lispsort_double" #.(my-lispify "lispsort_double" 'function)) :void
- (n :int)
- (array :pointer))
-
-(cl:export '#.(my-lispify "lispsort_double" 'function) 'some-other-package)
-
-(cffi:defcenum #.(swig-lispify "color" 'enumname)
- #.(swig-lispify "RED" 'enumvalue :keyword)
- #.(swig-lispify "BLUE" 'enumvalue :keyword)
- #.(swig-lispify "GREEN" 'enumvalue :keyword))
-
-(cl:export '#.(swig-lispify "color" 'enumname))
-
-</pre></div>
-
-<H3><a name="Lisp_nn6">29.2.3 Generating CFFI bindings for C++ code</a></H3>
-
-
-<p>This feature to SWIG (for CFFI) is very new and still far from
- complete. Pitch in with your patches, bug reports and feature
- requests to improve it.
-</p>
-<p> Generating bindings for C++ code, requires <i>-c++</i> option to be
- present and it first generates C binding which will wrap the C++
- code, and then generates the
- corresponding CFFI wrapper code. In the generated C wrapper
- code, you will often want to put your own C code, such as the
- code to include various files. This can be done by making use of
- "%{" and "%}" as shown below.
-</p>
-<div class="code"><pre>
-%{
- #include "Test/test.h"
-%}
-</pre></div>
-<p>
-Also, while parsing the C++ file and generating C wrapper code SWIG
- may need to be able to understand various symbols used in other
- header files. To help SWIG in doing this while ensuring that
- wrapper code is generated for the target file, use the "import"
- directive. The "include" directive specifies the target file for
- which wrapper code will be generated.
-</p>
-<div class="code"><pre>
-
-%import "ancillary/header.h"
-
-%include "target/header.h"
-
-</pre></div>
-<p>
-Various features which were available for C headers can also be used
- here. The target header which we are going to use here is:
-</p>
-<div class="code"><pre>
-namespace OpenDemo {
- class Test
- {
- public:
- float x;
- // constructors
- Test (void) {x = 0;}
- Test (float X) {x = X;}
-
- // vector addition
- Test operator+ (const Test&amp; v) const {return Test (x+v.x);}
-
- // length squared
- float lengthSquared (void) const {return this-&gt;dot (*this);}
-
- static float distance (const Test&amp; a, const Test&amp; b){return(a-b).length();}
-
- inline Test parallelComponent (const Test&amp; unitBasis) const {
- return unitBasis * projection;
- }
-
- Test setYtoZero (void) const {return Test (this-&gt;x);}
-
- static const Test zero;
- };
-
- inline Test operator* (float s, const Test&amp; v) {return v*s;}
-
- inline std::ostream&amp; operator&lt;&lt; (std::ostream&amp; o, const Test&amp; v)
- {
- return o &lt;&lt; "(" &lt;&lt; v.x &lt;&lt; ")";
- }
-
- inline Test RandomUnitVectorOnXZPlane (void)
- {
- return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
- }
-}
-</pre></div>
-<p>The interface used is: </p>
-<div class="code"><pre>
-%module test
-%include "test.cpp"
-</pre></div>
-
-<p>
-SWIG generates 3 files, the first one is a C wrap which we don't show,
- the second is the plain CFFI wrapper which is as shown below:
-</p>
-<div class="targetlang"><pre>
-(cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void
- (self :pointer)
- (x :float))
-
-(cffi:defcfun ("_wrap_Test_x_get" Test_x_get) :float
- (self :pointer))
-
-(cffi:defcfun ("_wrap_new_Test__SWIG_0" new_Test) :pointer)
-
-(cffi:defcfun ("_wrap_new_Test__SWIG_1" new_Test) :pointer
- (X :float))
-
-(cffi:defcfun ("_wrap_Test___add__" Test___add__) :pointer
- (self :pointer)
- (v :pointer))
-
-(cffi:defcfun ("_wrap_Test_lengthSquared" Test_lengthSquared) :float
- (self :pointer))
-
-(cffi:defcfun ("_wrap_Test_distance" Test_distance) :float
- (a :pointer)
- (b :pointer))
-
-(cffi:defcfun ("_wrap_Test_parallelComponent" Test_parallelComponent) :pointer
- (self :pointer)
- (unitBasis :pointer))
-
-(cffi:defcfun ("_wrap_Test_setYtoZero" Test_setYtoZero) :pointer
- (self :pointer))
-
-(cffi:defcvar ("Test_zero" Test_zero)
- :pointer)
-
-(cffi:defcfun ("_wrap_delete_Test" delete_Test) :void
- (self :pointer))
-
-(cffi:defcfun ("_wrap___mul__" __mul__) :pointer
- (s :float)
- (v :pointer))
-
-(cffi:defcfun ("_wrap___lshift__" __lshift__) :pointer
- (o :pointer)
- (v :pointer))
-
-(cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer)
-</pre></div>
-
-<p>
-The output is pretty good but it fails in disambiguating overloaded
- functions such as the constructor, in this case. One way of
- resolving this problem is to make the interface use the rename
- directiv, but hopefully there are better solutions.
- In addition SWIG also generates, a CLOS file
-</p>
-
-
-<div class="targetlang"><pre>
-(clos:defclass test()
- ((ff :reader ff-pointer)))
-
-(clos:defmethod (cl:setf x) (arg0 (obj test))
- (Test_x_set (ff-pointer obj) arg0))
-
-(clos:defmethod x ((obj test))
- (Test_x_get (ff-pointer obj)))
-
-(cl:shadow "+")
-(clos:defmethod + ((obj test) (self test) (v test))
- (Test___add__ (ff-pointer obj) (ff-pointer self) (ff-pointer v)))
-
-(clos:defmethod length-squared ((obj test) (self test))
- (Test_lengthSquared (ff-pointer obj) (ff-pointer self)))
-
-(clos:defmethod parallel-component ((obj test) (self test) (unitBasis test))
- (Test_parallelComponent (ff-pointer obj) (ff-pointer self) (ff-pointer unitBasis)))
-
-(clos:defmethod set-yto-zero ((obj test) (self test))
- (Test_setYtoZero (ff-pointer obj) (ff-pointer self)))
-</pre></div>
-
-<p>I agree that the CFFI C++ module needs lot more work. But I hope it
- provides a starting point, on which you can base your work of
- importing C++ libraries to Lisp.
-</p>
-<p>
-If you have any questions, suggestions, patches, etc., related to CFFI
- module feel free to contact us on the SWIG mailing list, and
- also please add a "[CFFI]" tag in the subject line.
-
-<H3><a name="Lisp_nn7">29.2.4 Inserting user code into generated files</a></H3>
-
-
-<p>
-It is often necessary to <a href="SWIG.html#SWIG_nn40">include user-defined code</a>
-into the automatically generated interface files. For example, when building
-a C++ interface, example_wrap.cxx will likely not compile unless
-you add a <tt>#include "header.h"</tt> directive. This can be done
-using the SWIG <tt>%insert(section) %{ ...code... %}</tt> directive:
-</p>
-
-<div class="code">
-<pre>
-%module example
-
-%{
-#include "header.h"
-%}
-
-%include "header.h"
-
-int fact(int n);
-</pre>
-</div>
-
-<p>
-Additional sections have been added for inserting into the
-generated lisp interface file:
-</p>
-<ul>
- <li><tt>lisphead</tt> - inserts before type declarations</li>
- <li><tt>swiglisp</tt> - inserts after type declarations according to
- where it appears in the .i file</li>
-</ul>
-<p>
-Note that the block <tt>%{ ... %}</tt> is effectively a shortcut for
-<tt>%insert("header") %{ ... %}</tt>.
-</p>
-
-
-</body>
-</html>
diff --git a/Doc/Manual/Lua.html b/Doc/Manual/Lua.html
index 80807baf4..8ea385b49 100644
--- a/Doc/Manual/Lua.html
+++ b/Doc/Manual/Lua.html
@@ -77,7 +77,7 @@
<p>
-Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight configuration language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ISO C and C++). It's also a <em>really</em> tiny language, less than 6000 lines of code, which compiles to &lt;100 kilobytes of binary code. It can be found at <a href="http://www.lua.org">http://www.lua.org</a>
+Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight configuration language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ISO C and C++). It's also a <em>really</em> tiny language, less than 6000 lines of code, which compiles to &lt;100 kilobytes of binary code. It can be found at <a href="https://www.lua.org">https://www.lua.org</a>
</p>
<p>
eLua stands for Embedded Lua (can be thought of as a flavor of Lua) and offers the full implementation of the Lua programming language to the embedded world, extending it with specific features for efficient and portable software embedded development. eLua runs on smaller devices like microcontrollers and provides the full features of the regular Lua desktop version. More information on eLua can be found here: <a href="http://www.eluaproject.net">http://www.eluaproject.net</a>
@@ -566,7 +566,7 @@ If the <tt>-no-old-metatable-bindings</tt> option is used, then these old-style
</p>
<p>
It is worth mentioning, that <tt>example.Test.TEST1</tt> and <tt>example.Test_TEST1</tt> are different entities and changing one does not change the other.
-Given the fact that these are constantes and they are not supposed to be changed, it is up to you to avoid such issues.
+Given the fact that these are constants and they are not supposed to be changed, it is up to you to avoid such issues.
</p>
<H3><a name="Lua_nn12">29.3.5 Pointers</a></H3>
@@ -1520,7 +1520,7 @@ function
nil
&gt;
</pre></div>
-<p> This behaviour was changed. Now unless -squash-bases option is provided, Derived store a list of it's bases and if some symbol is not found in it's own service tables
+<p> This behaviour was changed. Now unless -squash-bases option is provided, Derived stores a list of its bases and if some symbol is not found in its own service tables
then its bases are searched for it. Option -squash-bases will effectively return old behaviour.
</p>
@@ -1638,7 +1638,7 @@ More details can be found in the <a href="Library.html#Library_carrays">carrays.
<div class="code"><pre>// using the C-array
%include &lt;carrays.i&gt;
-// this declares a batch of function for manipulating C integer arrays
+// this declares a batch of functions for manipulating C integer arrays
%array_functions(int, int)
extern void sort_int(int* arr, int len); // the function to wrap
@@ -1997,10 +1997,10 @@ So when 'p:Print()' is called, the __index looks on the object metatable for a '
In theory, you can play with this usertable &amp; add new features, but remember that it is a shared table between all instances of one class, and you could very easily corrupt the functions in all the instances.
</p>
<p>
-Note: Both the opaque structures (like the FILE*) and normal wrapped classes/structs use the same 'swig_lua_userdata' structure. Though the opaque structures has do not have a metatable attached, or any information on how to dispose of them when the interpreter has finished with them.
+Note: Both the opaque structures (like the FILE*) and normal wrapped classes/structs use the same 'swig_lua_userdata' structure. Though the opaque structures do not have a metatable attached, or any information on how to dispose of them when the interpreter has finished with them.
</p>
<p>
-Note: Operator overloads are basically done in the same way, by adding functions such as '__add' &amp; '__call' to the class' metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming its an operator overload.
+Note: Operator overloads are basically done in the same way, by adding functions such as '__add' &amp; '__call' to the class' metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming it's an operator overload.
</p>
<H3><a name="Lua_nn38">29.7.3 Memory management</a></H3>
diff --git a/Doc/Manual/Makefile b/Doc/Manual/Makefile
index 9505adb91..440b3153f 100644
--- a/Doc/Manual/Makefile
+++ b/Doc/Manual/Makefile
@@ -1,7 +1,7 @@
# Makefile for generating the SWIG documentation
#
# Note that the htmldoc package needs to be installed. wkhtmltopdf patched with qt is also required
-# and can be installed from http://wkhtmltopdf.org/downloads.html.
+# and can be installed from https://wkhtmltopdf.org/downloads.html.
#
# The .html files are first processed and updated with chapter numbering and anchor names
# are added to the HTML headings using the python scripts. The htmldoc program is then
@@ -43,7 +43,7 @@ check:
# 3) <pre> <tt> <code> elements do not always select a fixed-width font - try installing the
# Courier font to fix - these have been added to style.css.
generate: SWIGDocumentation.html
- wkhtmltopdf --version | grep "with patched qt" || (echo "wkhtmltopdf is not the patched qt version and so cannot be used - download it from http://wkhtmltopdf.org/downloads.html" && false)
+ wkhtmltopdf --version | grep "with patched qt" || (echo "wkhtmltopdf is not the patched qt version and so cannot be used - download it from https://wkhtmltopdf.org/downloads.html" && false)
wkhtmltopdf --margin-top 20mm --margin-bottom 20mm --margin-left 10mm --margin-right 10mm --header-font-size 6 --footer-font-size 6 --header-spacing 6 --footer-spacing 6 --header-center '[doctitle]' --footer-left '[subsection]' --footer-right '[page]' SWIGDocumentation.html SWIGDocumentation.pdf
SWIGDocumentation.html: swightml.book
diff --git a/Doc/Manual/Modules.html b/Doc/Manual/Modules.html
index b9b7b2b94..1e3a8e7b1 100644
--- a/Doc/Manual/Modules.html
+++ b/Doc/Manual/Modules.html
@@ -119,6 +119,10 @@ public:
// File: derived_module.i
%module derived_module
+%{
+#include "base.h"
+%}
+
%import "base_module.i"
%inline %{
@@ -156,6 +160,10 @@ The <tt>derived_module.i</tt> file shown above could be replaced with the follow
// File: derived_module.i
%module derived_module
+%{
+#include "base.h"
+%}
+
%import(module="base_module") "base.h"
%inline %{
diff --git a/Doc/Manual/Ocaml.html b/Doc/Manual/Ocaml.html
index 4ae07e969..ffb9d2cde 100644
--- a/Doc/Manual/Ocaml.html
+++ b/Doc/Manual/Ocaml.html
@@ -85,7 +85,7 @@ variants, functions, classes, etc.
<p>
If you're not familiar with the Objective Caml language, you can visit
-<a href="http://ocaml.org/">The Ocaml Website</a>.
+<a href="https://ocaml.org/">The Ocaml Website</a>.
</p>
<H2><a name="Ocaml_nn2">39.1 Preliminaries</a></H2>
@@ -720,7 +720,6 @@ Here's a simple example using Trolltech's Qt Library:
class QApplication {
public:
QApplication( int argc, char **argv );
- void setMainWidget( QWidget *widget );
void exec();
};
@@ -736,16 +735,15 @@ public:
<div class="code"><pre>
-bash-2.05a$ QTPATH=/your/qt/path
-bash-2.05a$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done
-bash-2.05a$ ocamlc -c swig.mli ; ocamlc -c swig.ml
-bash-2.05a$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
-bash-2.05a$ swig -ocaml -c++ -I$QTPATH/include qt.i
-bash-2.05a$ mv qt_wrap.cxx qt_wrap.c
-bash-2.05a$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c
-bash-2.05a$ ocamlc -c qt.mli
-bash-2.05a$ ocamlc -c qt.ml
-bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
+$ QTPATH=/your/qt/path
+$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done
+$ ocamlc -c swig.mli ; ocamlc -c swig.ml
+$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
+$ swig -ocaml -c++ -o qt_wrap.c qt.i
+$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c
+$ ocamlc -c qt.mli
+$ ocamlc -c qt.ml
+$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
camlp4o.cma swigp4.cmo qt_wrap.o qt.cmo -o qt_top -cclib \
-L$QTPATH/lib -cclib -lqt
</pre></div>
diff --git a/Doc/Manual/Octave.html b/Doc/Manual/Octave.html
index bdef5db7c..ca38b4165 100644
--- a/Doc/Manual/Octave.html
+++ b/Doc/Manual/Octave.html
@@ -52,7 +52,7 @@
<p>
Octave is a high-level language intended for numerical programming that is mostly compatible with MATLAB.
-More information can be found at <a href="http://www.gnu.org/software/octave/">Octave web site</a>.
+More information can be found at <a href="https://www.gnu.org/software/octave/">Octave web site</a>.
</p>
<p>
@@ -363,6 +363,10 @@ octave:2&gt; f=swigexample.fopen("not there", "r");
error: value on right hand side of assignment is undefined
error: evaluating assignment expression near line 2, column 2 </pre></div>
+<p>
+NULL C/C++ pointers are represented by the Octave null matrix, <tt>[]</tt>.
+</p>
+
<H3><a name="Octave_nn13">30.3.6 Structures and C++ classes</a></H3>
@@ -570,13 +574,13 @@ __mul__ a * b
__div__ a / b
__pow__ a ^ b
__ldiv__ a \ b
-__lshift__ a << b
-__rshift__ a >> b
-__lt__ a < b
-__le__ a <= b
+__lshift__ a &lt;&lt; b
+__rshift__ a &gt;&gt; b
+__lt__ a &lt; b
+__le__ a &lt;= b
__eq__ a == b
-__ge__ a >= b
-__gt__ a > b
+__ge__ a &gt;= b
+__gt__ a &gt; b
__ne__ a != b
__el_mul__ a .* b
__el_div__ a ./ b
@@ -598,16 +602,16 @@ On the C++ side, the default mappings are as follows:
%rename(__mul__) *::operator*;
%rename(__div__) *::operator/;
%rename(__mod__) *::operator%;
-%rename(__lshift__) *::operator<<;
-%rename(__rshift__) *::operator>>;
+%rename(__lshift__) *::operator&lt;&lt;;
+%rename(__rshift__) *::operator&gt;&gt;;
%rename(__el_and__) *::operator&amp;&amp;;
%rename(__el_or__) *::operator||;
%rename(__xor__) *::operator^;
%rename(__invert__) *::operator~;
-%rename(__lt__) *::operator<;
-%rename(__le__) *::operator<=;
-%rename(__gt__) *::operator>;
-%rename(__ge__) *::operator>=;
+%rename(__lt__) *::operator&lt;;
+%rename(__le__) *::operator&lt;=;
+%rename(__gt__) *::operator&gt;;
+%rename(__ge__) *::operator&gt;=;
%rename(__eq__) *::operator==;
%rename(__ne__) *::operator!=;
%rename(__not__) *::operator!;
@@ -621,6 +625,16 @@ On the C++ side, the default mappings are as follows:
Octave can also utilise friend (i.e. non-member) operators with a simple %rename: see the example in the Examples/octave/operator directory.
</p>
+<p>
+Octave has several operators for which no corresponding C++ operators exist. For example, the Octave code
+</p>
+<div class="targetlang"><pre>
+x=[a,b,c];
+</pre></div>
+<p>
+calls the Octave operator <tt>horzcat</tt> of the class of <tt>a</tt>. Hence, if <tt>a</tt> is of type <tt>swig_ref</tt> you can write an overload for this operator for your wrapped C++ class by placing a file <tt>@swig_ref/horzcat.m</tt> in the Octave load path (like for every Octave class, see <a href="https://docs.octave.org/latest/Creating-a-Class.html">Creating a Class</a>). This Octave function file is then called whenever the above Octave code is executed for a variable of type <tt>swig_ref</tt>.
+</p>
+
<H3><a name="Octave_nn19">30.3.10 Class extension with %extend</a></H3>
@@ -634,7 +648,7 @@ You can use it to define special behavior, like for example defining Octave oper
%extend A {
string __str__() {
stringstream sout;
- sout&lt;&lt;$self->value;
+ sout&lt;&lt;$self-&gt;value;
return sout.str();
}
}
diff --git a/Doc/Manual/Perl5.html b/Doc/Manual/Perl5.html
index 85c2545cf..d8f24b094 100644
--- a/Doc/Manual/Perl5.html
+++ b/Doc/Manual/Perl5.html
@@ -91,10 +91,10 @@
<p>
This chapter describes SWIG's support of Perl5. Although the Perl5
module is one of the earliest SWIG modules, it has continued to evolve
-and has been improved greatly with the help of SWIG users. For the
-best results, it is recommended that SWIG be used with Perl 5.8 or
-later. We're no longer testing regularly with older versions, but
-Perl 5.6 seems to mostly work, while older versions don't.
+and has been improved greatly with the help of SWIG users. As of SWIG
+4.1.0, the minimum version of Perl we aim to support is Perl 5.8.0.
+We can no longer easily test with older versions, and they no longer
+seem to be in active use.
</p>
<H2><a name="Perl5_nn2">31.1 Overview</a></H2>
@@ -604,7 +604,7 @@ source has a list of macros that are known to conflict with either standard head
other headers. But if you get macro type conflicts from other macros not included
in Lib/perl5/noembed.h while compiling the wrapper, you will
have to find the macro that conflicts and add an #undef into the .i file. Please report
-any conflicting macros you find to <a href="http://www.swig.org/mail.html">swig-user mailing list</a>.
+any conflicting macros you find to <a href="https://www.swig.org/mail.html">swig-user mailing list</a>.
</p>
<H3><a name="Perl5_nn10">31.2.7 Compiling for 64-bit platforms</a></H3>
@@ -680,7 +680,6 @@ files(s) field".
installation under "Additional include directories".
<li>Define the symbols WIN32 and MSWIN32 under preprocessor options.
-If using the ActiveWare port, also define the symbol PERL_OBJECT.
Note that all extensions to the ActiveWare port must be compiled with
the C++ compiler since Perl has been encapsulated in a C++ class.
@@ -1065,7 +1064,7 @@ int *Foo_x_get(Foo *self) {
<p>
If you want to set an array member, you will need to supply a "memberin" typemap
described later in this chapter. As a special case, SWIG does generate
-code to set array members of type <tt>char</tt> (allowing you to store a Python
+code to set array members of type <tt>char</tt> (allowing you to store a Perl
string in the structure).
</p>
@@ -1494,7 +1493,7 @@ as well as a special error code:
<div class="code">
<pre>
/* send message, return number of bytes sent, along with success code */
-int send_message(char *text, int len, int *success);
+int send_message(char *text, int *success);
</pre>
</div>
@@ -1736,7 +1735,7 @@ See the chapter on "<a href="Customization.html#Customization">Customization fea
<div class="code">
<pre>
-%except(python) {
+%except(perl5) {
try {
$function
}
@@ -2320,7 +2319,7 @@ typedef struct {
<p>
By default, SWIG doesn't know how to the handle the values structure
-member it's an array, not a pointer. In this case, SWIG makes the array member
+member because it's an array, not a pointer. In this case, SWIG makes the array member
read-only. Reading will simply return a pointer to the first item in the array.
To make the member writable, a "memberin" typemap can be used.
</p>
@@ -2651,8 +2650,8 @@ constructors and destructors for the package and are always named
"new" and "DESTROY". The constructor always returns a tied hash
table. This hash table is used to access the member variables of a
structure in addition to being able to invoke member functions. The
-<tt>%OWNER</tt> and <tt>%BLESSEDMEMBERS</tt> hash tables are used
-internally and described shortly.
+<tt>%OWNER</tt> and <tt>%BLESSEDMEMBERS</tt> hash tables are
+implementation details used internally and described shortly.
</p>
<p>
@@ -2740,8 +2739,15 @@ to a C function that remembers the object, and then destroy the
corresponding Perl object (this situation turns out to come up
frequently when constructing objects like linked lists and trees).
When C takes possession of an object, you can change Perl's ownership
-by simply deleting the object from the <tt>%OWNER</tt> hash. This is
-done using the <tt>DISOWN</tt> method.
+by calling the <tt>DISOWN</tt> method (which will delete the object
+from the internal <tt>%OWNER</tt> hash).
+</p>
+
+<p>
+The <tt>%OWNER</tt> hash is an implementation detail, discussed here
+only to help clarify the operation of <tt>ACQUIRE</tt> and <tt>DISOWN</tt>.
+You should not access <tt>%OWNER</tt> directly - the details of how it
+works (and possibly even its existence) may change in future SWIG versions.
</p>
<div class="targetlang"><pre>
diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html
index 5aea878b2..97a48b707 100644
--- a/Doc/Manual/Php.html
+++ b/Doc/Manual/Php.html
@@ -30,6 +30,7 @@
<li><a href="#Php_nn2_6_3">Static Member Variables</a>
<li><a href="#Php_nn2_6_4">Static Member Functions</a>
<li><a href="#Php_nn2_6_5">Specifying Implemented Interfaces</a>
+<li><a href="#Php_nn2_6_6">Dynamic Properties</a>
</ul>
<li><a href="#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</a>
</ul>
@@ -50,18 +51,19 @@
<p>
-In this chapter, we discuss SWIG's support of PHP. SWIG currently supports
-generating wrappers for PHP7 and PHP8. Support for PHP5 was removed in SWIG
-4.0.0 and support for PHP4 was removed in SWIG 1.3.37.
+In this chapter, we discuss SWIG's support of PHP. Currently any PHP7 or PHP8
+release should work.
</p>
<p>
-Currently any PHP7 or PHP8 release should work.
+Support for PHP7 was added in SWIG 3.0.11 and for PHP8 in 4.1.0.
+Support for PHP5 was removed in SWIG 4.0.0 and support for PHP4 was removed in
+SWIG 1.3.37. There never was a PHP6 release.
</p>
<p>
In order to use this module, you will need to have a copy of the PHP
-include files to compile the SWIG generated files. If you installed
+include files to compile the SWIG generated C/C++ sources. If you installed
PHP from a binary package, you may need to install a "php-dev" or "php-devel"
package for these to be installed. You can find out where these files are
by running <tt>php-config --includes</tt>. To use the built PHP module you
@@ -161,7 +163,7 @@ default extension directory, you also need to specify the path, for example:
</p>
<div class="code"><pre>
- extension=/path/to/modulename.so
+ extension=/path/to/modulename.so
</pre></div>
<p>
@@ -306,11 +308,10 @@ functions.
</p>
<p>
-SWIG honors the <tt>%immutable</tt> modifier by not generating code
-for the <tt>_set</tt> method. This provides read-only access to the
-variable from the php script. Attempting to access the <tt>_set</tt>
-method will result in a php fatal error because the function is
-undefined.
+SWIG honors the <tt>%immutable</tt> modifier by not generating a
+<tt>_set</tt> method (so attempting to call it will give a PHP fatal
+error). A <tt>_get</tt> method is still generated so this provides read-only
+access to the variable from the PHP script.
</p>
<p>
@@ -343,6 +344,80 @@ $c = bar(3.5); # Use default argument for 2nd parameter
</pre></div>
+<p>
+SWIG generates PHP type declarations for function parameters and return
+types for PHP 8 and later (we don't try to support PHP 7's more limited type
+declarations and the generated wrappers compiled for PHP 7 will not have any
+type declarations).
+</p>
+
+<p>
+You can control the generation of PHP type declarations using
+the "php:type" %feature. This has three settings:
+</p>
+
+<ul>
+ <li> <p>If unset or set to "0" then no type declarations are generated, e.g.: <tt>%feature("php:type", "0");</tt>
+ </p>
+ </li>
+ <li> <p>If set to "1" then type declarations are generated for both parameters and return types, e.g.: <tt>%feature("php:type", "1");</tt>
+ </p></li>
+ <li> <p>The default setting is "compat", which is the same as "1" except no
+ return type declarations are generated for virtual methods for which
+ directors are enabled. This provides better compatibility for PHP
+ subclasses of wrapped virtual methods in existing SWIG-generated bindings, e.g.: <tt>%feature("php:type", "compat");</tt>
+ </p></li>
+</ul>
+
+<p>
+If you have an existing PHP interface and are upgrading to SWIG &gt;= 4.1.0
+then the default "compat" setting should work well.
+</p>
+
+<p>
+If you're writing a new set of bindings and <b>only targeting PHP8 or newer</b>
+then enabling type declarations everywhere probably makes sense. It will
+only actually make a difference if you enable directors and are wrapping C++
+classes with virtual methods, but doing it anyway means you won't forget to if
+the code you are wrapping later evolves to have such classes and methods.
+</p>
+
+<p>
+The type declaration information will make the generated source code and
+compiler extension module larger, so you might want to turn off type
+declarations if keeping these small is important to you. If you find you
+need to turn off type declarations to fix a problem, please let us know
+via our github issue tracker.
+</p>
+
+<p>
+Note that being a SWIG feature this can be specified globally (like above) or
+per class, per method, etc. See the <a
+href="Customization.html#Customization_features">%feature directives</a>
+section for full details of how to control at a fine-grained level.
+</p>
+
+<p>
+The PHP type information is specified via a "phptype" attribute on "in" and
+"out" typemaps, and these have been added for all the typemaps we supply for
+PHP. We don't currently support this for "argout" templates, but probably
+will in a future version.
+</p>
+
+<p>
+If you have written custom SWIG typemaps for PHP and want to add PHP type
+declarations, then the syntax is very like how you'd specify the type in
+PHP code, e.g. <tt>%typemap(in, phptype="int|string|Foo")</tt> means the
+typemap accepts a PHP int or string or an object of class Foo,
+<tt>%typemap(in, phptype="?int")</tt> means a PHP int or NULL, etc.
+As well as the standard PHP type declaration types, SWIG also understands the
+special type "SWIGTYPE" as an entry in phptype, which means the PHP type
+corresponding to the type that this typemap matched on - for a object this
+will give you the PHP class for the object, and for a pointer to a non-class
+type it will give you the name of the PHP class SWIG created for that
+pointer type.
+</p>
+
<!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality
<p>
Because PHP is a dynamically typed language, the default typemaps
@@ -426,6 +501,7 @@ taking the integer argument.
<H3><a name="Php_nn2_5">32.2.5 Pointers and References</a></H3>
+
<p>
Since SWIG 4.1.0, SWIG wraps C/C++ classes directly with PHP objects.
Pointers to other types are also wrapped as PHP objects - mostly this is an
@@ -624,8 +700,7 @@ Member variables and methods are accessed using the <tt>-&gt;</tt> operator.
<p>
The <tt>-noproxy</tt> option flattens the object structure and
-generates collections of named functions (these are the functions
-which the PHP class wrappers call). The above example results
+generates collections of named functions. The above example results
in the following PHP functions:
</p>
@@ -742,7 +817,10 @@ class Ko {
};
</pre></div>
-would be executed in PHP as,
+<p>
+would be executed in PHP as
+</p>
+
<div class="code"><pre>
Ko::threats();
</pre></div>
@@ -759,13 +837,60 @@ so:
</p>
<div class="code"><pre>
-%typemap("phpinterfaces") MyIterator "Iterator";
+%typemap("phpinterfaces") MyIterator "Iterator"
</pre></div>
<p>
If there are multiple interfaces, just list them separated by commas.
</p>
+
+<H4><a name="Php_nn2_6_6">32.2.6.6 Dynamic Properties</a></H4>
+
+
+<p>
+Historically PHP has supported dynamic class properties and SWIG
+has implemented them too (because we implement the magic <tt>__get()</tt>,
+<tt>__set()</tt> and <tt>__isset()</tt> methods we need to include explicit
+handling).
+</p>
+
+<p>
+PHP 8.2 <a
+href="https://wiki.php.net/rfc/deprecate_dynamic_properties">deprecates
+dynamic class properties</a> - initially they'll warn, and apparently they'll
+not work by default in PHP 9.0.
+</p>
+
+<p>
+In PHP code dynamic properties can be enabled for a class by
+marking that class with the attribute <tt>#[AllowDynamicProperties]</tt>.
+</p>
+
+<p>
+To follow this PHP change, as of SWIG 4.1.0 you now need enable dynamic
+properties for any classes you want to support them. To enable for class
+<tt>Foo</tt>:
+</p>
+
+<div class="code"><pre>
+%feature("php:allowdynamicproperties", 1) Foo;
+</pre></div>
+
+<p>
+or to enable them for all wrapped classes:
+</p>
+
+<div class="code"><pre>
+%feature("php:allowdynamicproperties", 1);
+</pre></div>
+
+<p>
+Note that unknown features are ignored, so you can add use these
+unconditionally in your interface file and it'll work with older SWIG too.
+</p>
+
+
<H3><a name="Php_nn2_7">32.2.7 PHP Pragmas, Startup and Shutdown code</a></H3>
@@ -1158,7 +1283,7 @@ should suffice in most cases:
</div>
<p>
-If you only need to support SWIG >= 4.1.0, you can just use the
+If you only need to support SWIG &gt;= 4.1.0, you can just use the
<tt>($error != NULL)</tt> condition.
</p>
diff --git a/Doc/Manual/Preface.html b/Doc/Manual/Preface.html
index 36a99bd1f..50a06d688 100644
--- a/Doc/Manual/Preface.html
+++ b/Doc/Manual/Preface.html
@@ -80,7 +80,7 @@ Some target languages were disabled as part of a clean up and others were given
<p>
The LICENSE file shipped with SWIG in the top level directory contains the SWIG license.
For further insight into the license including the license of SWIG's output code, please visit
-the SWIG legal page - <a href="http://www.swig.org/legal.html">http://www.swig.org/legal.html</a>.
+the SWIG legal page - <a href="https://www.swig.org/legal.html">https://www.swig.org/legal.html</a>.
</p>
<p>
@@ -98,7 +98,7 @@ The official location of SWIG related material is
</p>
<div class="shell"><pre>
-<a href="http://www.swig.org">http://www.swig.org</a>
+<a href="https://www.swig.org">https://www.swig.org</a>
</pre></div>
<p>
@@ -111,7 +111,7 @@ You can also subscribe to the swig-user mailing list by visiting the page
</p>
<div class="shell"><pre>
-<a href="http://www.swig.org/mail.html">http://www.swig.org/mail.html</a>
+<a href="https://www.swig.org/mail.html">https://www.swig.org/mail.html</a>
</pre></div>
<p>
@@ -125,7 +125,7 @@ about this can be obtained at:
</p>
<div class="shell"><pre>
-<a href="http://www.swig.org/svn.html">SWIG Bleeding Edge</a>
+<a href="https://www.swig.org/svn.html">SWIG Bleeding Edge</a>
</pre></div>
@@ -231,7 +231,7 @@ detailed release notes for previous releases and summary release notes from SWIG
SWIG is an unfunded project that would not be possible without the
contributions of many people working in their spare time.
If you have benefitted from using SWIG, please consider
-<a href="http://www.swig.org/donate.html">Donating to SWIG</a> to keep development going.
+<a href="https://www.swig.org/donate.html">Donating to SWIG</a> to keep development going.
There have been a large varied number of people
who have made contributions at all levels over time. Contributors
are mentioned either in the COPYRIGHT file or CHANGES files shipped with SWIG or in submitted bugs.
@@ -244,8 +244,8 @@ are mentioned either in the COPYRIGHT file or CHANGES files shipped with SWIG or
Although every attempt has been made to make SWIG bug-free, we are also trying
to make feature improvements that may introduce bugs.
To report a bug, either send mail to the SWIG developer
-list at the <a href="http://www.swig.org/mail.html">swig-devel mailing list</a> or report a bug
-at the <a href="http://www.swig.org/bugs.html">SWIG bug tracker</a>. In your report, be as specific as
+list at the <a href="https://www.swig.org/mail.html">swig-devel mailing list</a> or report a bug
+at the <a href="https://www.swig.org/bugs.html">SWIG bug tracker</a>. In your report, be as specific as
possible, including (if applicable), error messages, tracebacks (if a
core dump occurred), corresponding portions of the SWIG interface file
used, and any important pieces of the SWIG generated wrapper code. We
@@ -273,20 +273,20 @@ the main SWIG distribution. There is no need to download anything else.
These installation instructions are for using the distributed tarball,
for example, <tt>swig-3.0.8.tar.gz</tt>.
If you wish to build and install from source on Github, extra steps are required.
-Please see the <a href="http://swig.org/svn.html">Bleeding Edge</a> page on the SWIG website.
+Please see the <a href="https://swig.org/svn.html">Bleeding Edge</a> page on the SWIG website.
</p>
<p>
-You must use <a href="http://www.gnu.org/software/make/">GNU make</a> to build and install SWIG.
+You must use <a href="https://www.gnu.org/software/make/">GNU make</a> to build and install SWIG.
</p>
<p>
-<a href="http://www.pcre.org/">PCRE</a>
+<a href="https://www.pcre.org/">PCRE2</a>
needs to be installed on your system to build SWIG, in particular
-pcre-config must be available. If you have PCRE headers and libraries but not
-pcre-config itself or, alternatively, wish to override the compiler or linker
-flags returned by pcre-config, you may set PCRE_LIBS and PCRE_CFLAGS variables
-to be used instead. And if you don't have PCRE at all, the configure script
+pcre2-config must be available. If you have PCRE2 headers and libraries but not
+pcre2-config itself or, alternatively, wish to override the compiler or linker
+flags returned by pcre2-config, you may set PCRE2_LIBS and PCRE2_CFLAGS variables
+to be used instead. And if you don't have PCRE2 at all, the configure script
will provide instructions for obtaining it.
</p>
@@ -357,7 +357,7 @@ Note:
If you checked the code out via Git, you will have to run <tt>./autogen.sh</tt>
before <tt>./configure</tt>. In addition, a full build of SWIG requires
a number of packages to be installed. Full instructions at
-<a href="http://www.swig.org/svn.html">SWIG bleeding edge</a>.
+<a href="https://www.swig.org/svn.html">SWIG bleeding edge</a>.
</li>
</ul>
diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html
index 7611ea40c..659cb6fa2 100644
--- a/Doc/Manual/Preprocessor.html
+++ b/Doc/Manual/Preprocessor.html
@@ -99,8 +99,23 @@ header files without generating any wrappers.
<p>
SWIG fully supports the use of <tt>#if</tt>, <tt>#ifdef</tt>,
<tt>#ifndef</tt>, <tt>#else</tt>, <tt>#endif</tt> to conditionally
-include parts of an interface. The following symbols are predefined
-by SWIG when it is parsing the interface:
+include parts of an interface.
+</p>
+
+<p>
+SWIG's preprocessor conditionals support the standard C/C++ preprocessor
+integer expressions. As a SWIG-specific extension, string equality and
+inequality tests are also supported, for example:
+</p>
+
+<div class="code">
+<pre>
+#if defined __cplusplus &amp;&amp; (#__VA_ARGS__ != "" || #TYPE == "void")
+</pre>
+</div>
+
+<p>
+The following symbols are predefined by SWIG when it is parsing the interface:
</p>
<div class="code"><pre>
@@ -133,6 +148,14 @@ SWIGXML Defined when using XML
</pre></div>
<p>
+SWIG also defines <tt>SWIG_VERSION</tt> and a target language macro in
+the generated wrapper file (since SWIG 4.1.0 - in older versions these
+were defined for some target languages but this wasn't consistent). Best
+practice is to use SWIG-time conditional checks because that results in smaller
+generated wrapper sources.
+</p>
+
+<p>
In addition, SWIG defines the following set of standard C/C++ macros:
</p>
@@ -154,7 +177,6 @@ SWIG_D_VERSION Unsigned integer target version when using D
SWIGGO_CGO Defined when using Go for cgo
SWIGGO_GCCGO Defined when using Go for gccgo
SWIGGO_INTGO_SIZE Size of the Go type int when using Go (32 or 64)
-SWIGPYTHON_PY3 Defined when using Python with -py3
SWIGPYTHON_BUILTIN Defined when using Python with -builtin
SWIG_RUBY_AUTORENAME Defined when using Ruby with -autorename
</pre></div>
@@ -175,15 +197,15 @@ is also used to try and detect constants. Therefore, if you have something like
<div class="code">
<pre>
-#ifndef _FOO_H 1
-#define _FOO_H 1
+#ifndef FOO_H 1
+#define FOO_H 1
...
#endif
</pre>
</div>
<p>
-you may get some extra constants such as <tt>_FOO_H</tt> showing up in the scripting interface.
+you may get some extra constants such as <tt>FOO_H</tt> showing up in the scripting interface.
</p>
<p>
diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html
index 1bd7b1e3c..a8c7d4c86 100644
--- a/Doc/Manual/Python.html
+++ b/Doc/Manual/Python.html
@@ -114,6 +114,7 @@
<li><a href="#Python_nn70">%feature("autodoc", "docstring")</a>
</ul>
<li><a href="#Python_nn71">%feature("docstring")</a>
+<li><a href="#Python_doxygen_docstrings">Doxygen comments</a>
</ul>
<li><a href="#Python_nn72">Python Packages</a>
<ul>
@@ -133,7 +134,10 @@
</ul>
<li><a href="#Python_python3support">Python 3 Support</a>
<ul>
-<li><a href="#Python_nn74">Function annotation</a>
+<li><a href="#Python_annotations">Python function annotations and variable annotations</a>
+<ul>
+<li><a href="#Python_annotations_c">C/C++ annotation types</a>
+</ul>
<li><a href="#Python_nn75">Buffer interface</a>
<li><a href="#Python_nn76">Abstract base classes</a>
<li><a href="#Python_nn77">Byte string output conversion</a>
@@ -151,14 +155,9 @@
<p>
-<b>Caution: This chapter is under repair!</b>
-</p>
-
-<p>
This chapter describes SWIG's support of Python. SWIG is compatible
-with all recent Python versions (Python 2.7 and Python &gt;= 3.2). If you
-still need to generate bindings which work with older versions of Python,
-you'll have to use SWIG 3.0.x.
+with all recent Python versions (Python 2.7 and Python &gt;= 3.3). SWIG 4.0.x
+supported Python 3.2. SWIG 3.0.x supported older Python 2.x and 3.x.
</p>
<p>
@@ -954,6 +953,7 @@ swig -python -help
<tr><td>-doxygen </td><td>Convert C++ doxygen comments to pydoc comments in proxy classes</td></tr>
<tr><td>-extranative </td><td>Return extra native wrappers for C++ std containers wherever possible</td></tr>
<tr><td>-fastproxy </td><td>Use fast proxy mechanism for member methods</td></tr>
+<tr><td>-flatstaticmethod </td><td>Generate additional flattened Python methods for C++ static methods</td></tr>
<tr><td>-globals &lt;name&gt; </td><td>Set &lt;name&gt; used to access C global variable (default: 'cvar')</td></tr>
<tr><td>-interface &lt;mod&gt;</td><td>Set low-level C/C++ module name to &lt;mod&gt; (default: module name prefixed by '_')</td></tr>
<tr><td>-keyword </td><td>Use keyword arguments</td></tr>
@@ -963,7 +963,6 @@ swig -python -help
<tr><td>-nortti </td><td>Disable the use of the native C++ RTTI with directors</td></tr>
<tr><td>-nothreads </td><td>Disable thread support for the entire interface</td></tr>
<tr><td>-olddefs </td><td>Keep the old method definitions when using -fastproxy</td></tr>
-<tr><td>-py3 </td><td>Generate code with Python 3 specific features and syntax</td></tr>
<tr><td>-relativeimport </td><td>Use relative Python imports</td></tr>
<tr><td>-threads </td><td>Add thread support for all the interface</td></tr>
<tr><td>-O </td><td>Enable the following optimization options: -fastdispatch -fastproxy -fvirtual</td></tr>
@@ -1613,16 +1612,17 @@ In Python, the static member can be accessed in three different ways:
<div class="targetlang">
<pre>
-&gt;&gt;&gt; example.Spam_foo() # Spam::foo()
&gt;&gt;&gt; s = example.Spam()
&gt;&gt;&gt; s.foo() # Spam::foo() via an instance
-&gt;&gt;&gt; example.Spam.foo() # Spam::foo() using Python-2.2 and later
+&gt;&gt;&gt; example.Spam.foo() # Spam::foo() using class method
+&gt;&gt;&gt; example.Spam_foo() # Spam::foo() "flattened" name
</pre>
</div>
<p>
-The first two methods of access are supported in all versions of Python. The
-last technique is only available in Python-2.2 and later versions.
+The last technique is only available when using the <tt>-flatstaticmethod</tt> option.
+This option is not recommended, it is only available for backwards compatibility
+as ancient versions of Python did not have Python class methods.
</p>
<p>
@@ -2531,6 +2531,12 @@ import A
assert(issubclass(B.Derived, A.Base))
</pre></div>
</li>
+
+
+<li><p><a href="#Python_annotations">Python annotations</a> are not supported.
+</p>
+</li>
+
</ul>
<H4><a name="Python_builtin_overloads">33.4.2.2 Operator overloads and slots -- use them!</a></H4>
@@ -3122,9 +3128,7 @@ likely cause your program to segfault.
<p>
To help ensure that no references to the Python object remain after
calling <tt>__disown__()</tt>, this method returns a weak reference to
-the Python object. Weak references are only available in Python versions
-2.1 and higher, so for older versions you must explicitly delete all
-references. Here is an example:
+the Python object. Here is an example:
</p>
<div class="code">
@@ -3498,7 +3502,7 @@ The insert code can be seen at the start of the generated <tt>.py</tt> file:
<div class="code">
<pre>
-# This file was automatically generated by SWIG (http://www.swig.org).
+# This file was automatically generated by SWIG (https://www.swig.org).
# Version 4.0.0
#
# Do not make changes to this file unless you know what you are doing--modify
@@ -3989,7 +3993,7 @@ Also included in the table for comparison is using the <tt>-builtin</tt> option
<p>
Although the <tt>-fastproxy</tt> option results in faster code over the default, the generated proxy code is not as user-friendly
-as docstring/doxygen comments and functions with default values are not visible in the generated Python proxy class.
+as docstring/doxygen comments, <a href="#Python_annotations">Python annotations</a> and functions with default values are not visible in the generated Python proxy class.
The <tt>-olddefs</tt> option can rectify this.
</p>
@@ -4166,7 +4170,7 @@ as well as a special error code:
<div class="code">
<pre>
/* send message, return number of bytes sent, along with success code */
-int send_message(char *text, int len, int *success);
+int send_message(char *text, int *success);
</pre>
</div>
@@ -4954,7 +4958,6 @@ object to be used as a <tt>char **</tt> object.
if (PyString_Check(o)) {
$1[i] = PyString_AsString(PyList_GetItem($input, i));
} else {
- free($1);
PyErr_SetString(PyExc_TypeError, "list must contain strings");
SWIG_fail;
}
@@ -5053,7 +5056,6 @@ previous example:
if (PyString_Check(o)) {
$2[i] = PyString_AsString(PyList_GetItem($input, i));
} else {
- free($2);
PyErr_SetString(PyExc_TypeError, "list must contain strings");
SWIG_fail;
}
@@ -5373,10 +5375,9 @@ int SWIG_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags)</t
Converts a Python object <tt>obj</tt> to a C pointer. The result of the conversion is placed
into the pointer located at <tt>ptr</tt>. <tt>ty</tt> is a SWIG type descriptor structure.
<tt>flags</tt> is used to handle error checking and other aspects of conversion. It is the
-bitwise-or of several flag values including <tt>SWIG_POINTER_EXCEPTION</tt> and
-<tt>SWIG_POINTER_DISOWN</tt>. The first flag makes the function raise an exception on type
-error. The second flag additionally
-steals ownership of an object. Returns 0 on success and -1 on error.
+bitwise-or of several flag values including <tt>SWIG_POINTER_DISOWN</tt> (which steals
+ownership of the object) and <tt>SWIG_POINTER_NO_NULL</tt> (which makes the conversion fail
+if the C pointer would be <tt>NULL</tt>). Returns 0 on success and -1 on error.
</div>
<p>
@@ -5895,6 +5896,28 @@ with more than one line.
</pre>
</div>
+<H3><a name="Python_doxygen_docstrings">33.10.4 Doxygen comments</a></H3>
+
+
+<p>
+Please see the separate <a href="Doxygen.html#Doxygen">Doxygen</a> chapter for information
+on making use of C++ Doxygen comments and translating them into Python docstring comments.
+</p>
+
+<p>
+Note that when generating docstrings and Doxygen comments have also been turned on,
+the <a href="#Python_nn71">docstring feature</a> will take precedence over a Doxygen comment.
+If the <a href="#Python_nn67">autodoc feature</a> is also turned on, then it will be
+used in conjunction with the docstring feature.
+However, if there is no docstring feature present and there is a Doxygen comment, then the autodoc docstring will not be generated. The Doxygen comment alone will be used.
+</p>
+
+<p>
+This way, if the autodoc feature is specified globally it will fill in any missing
+Doxygen documentation comments.
+Doxygen comments can be overridden by using the docstring feature.
+</p>
+
<H2><a name="Python_nn72">33.11 Python Packages</a></H2>
@@ -6735,13 +6758,11 @@ to do this (remember you are now the Python importer) or use dynamic linking.
<p>
SWIG is able to support Python 3.x. The wrapper code generated by
-SWIG can be compiled with both Python 2.x or 3.x. Further more, by
-passing the <tt>-py3</tt> command line option to SWIG, wrapper code
-with some Python 3 specific features can be generated (see below
-subsections for details of these features).
+SWIG can be compiled with both Python 2.x or 3.x.
+</p>
<p>
-There is a list of known-to-be-broken features in Python 3:
+The list of known-to-be-broken features around Python 3 are:
</p>
<ul>
<li>No more support for FILE* typemaps, because PyFile_AsFile has been dropped
@@ -6755,37 +6776,120 @@ The following are Python 3 new features that are currently supported by
SWIG.
</p>
-<H3><a name="Python_nn74">33.12.1 Function annotation</a></H3>
+<H3><a name="Python_annotations">33.12.1 Python function annotations and variable annotations</a></H3>
+
+
+<p>
+Python 3 supports function annotations as defined in
+<a href="https://www.python.org/dev/peps/pep-3107/">PEP 3107</a>.
+Python 3.6 and later additionally support variable annotations as defined in
+<a href="https://www.python.org/dev/peps/pep-526/">PEP 526</a>.
+Note that currently there is no annotations support in SWIG for the <tt>-builtin</tt> nor
+the <tt>-fastproxy</tt> option.
+Annotations are added via the <tt>python:annotations</tt>
+<a href="Customization.html#Customization_features">%feature directives</a>.
+SWIG currently supports one type of function annotation.
+</p>
+
+<H4><a name="Python_annotations_c">33.12.1.1 C/C++ annotation types</a></H4>
<p>
-The <tt>-py3</tt> option will enable function annotation support. When used
-SWIG is able to generate proxy method definitions like this:
+The <tt>%feature("python:annotations", "c")</tt> directive generates annotations
+containing C/C++ types. For example:
</p>
<div class="code"><pre>
- def foo(self, bar : "int"=0) -&gt; "void" : ...
+%feature("python:annotations", "c") global_ints;
+int *global_ints(int &amp;ri);
</pre></div>
<p>
-Also, even if without passing SWIG the <tt>-py3</tt> option, the parameter list
-still could be generated:
+The generated code then contains function annotations containing the C++ types:
+</p>
+
+<div class="targetlang"><pre>
+def global_ints(ri: "int &amp;") -&gt; "int *":
+ return _example.global_ints(ri)
+</pre></div>
+
+<p>
+There are some limitations with function annotations support, for example, overloaded functions use
+<tt>*args</tt> or <tt>**kwargs</tt> when keyword arguments are enabled.
+The parameter names and types are then not shown. For example, with input:
</p>
<div class="code"><pre>
- def foo(self, bar=0): ...
+int *global_overloaded(int &amp;ri);
+int *global_overloaded();
</pre></div>
<p>
-But for overloaded function or method, the parameter list would fallback to
-<tt>*args</tt> or <tt>self, *args</tt>, and <tt>**kwargs</tt> may be append
-depend on whether you enabled the keyword argument. This fallback is due to
-all overloaded functions share the same function in SWIG generated proxy class.
+The generated Python function including annotations is shown below.
+Only the return type is annotated.
</p>
+<div class="targetlang"><pre>
+def global_overloaded(*args) -&gt; "int *":
+ return _example.global_overloaded(*args)
+</pre></div>
+
<p>
-For detailed usage of function annotation, see
-<a href="https://www.python.org/dev/peps/pep-3107/">PEP 3107</a>.
+Below is an example demonstrating variable annotations.
+</p>
+
+<div class="code"><pre>
+%feature("python:annotations", "c");
+
+struct V {
+ float val;
+};
+</pre></div>
+
+<p>
+The generated code contains a variable annotation containing the C <tt>float</tt> type:
+</p>
+
+<div class="targetlang"><pre>
+class V(object):
+ val: "float" = property(_example.V_val_get, _example.V_val_set)
+ ...
+</pre></div>
+
+<p>
+Variable annotations are only supported from Python 3.6. If you need to support earlier versions of Python, you'll need to turn variable annotations off via the <tt>python:annotations:novar</tt> feature flag.
+It is quite easy to support function annotations but turn off variable annotations. The next example shows how to do this for all variables.
+</p>
+
+<div class="code"><pre>
+%feature("python:annotations", "c"); // Turn on function annotations and variable annotations globally
+%feature("python:annotations:novar"); // Turn off variable annotations globally
+
+struct V {
+ float val;
+ void vv(float *v) const;
+};
+</pre></div>
+
+<p>
+The resulting code will work with versions older than Python 3.6 as the variable annotations are turned off:
+</p>
+
+<div class="targetlang"><pre>
+class V(object):
+ val = property(_example.V_val_get, _example.V_val_set)
+
+ def vv(self, v: "float *") -&gt; "void":
+ return _example.V_vv(self, v)
+ ...
+</pre></div>
+
+
+<p>
+<b>Compatibility Note:</b> SWIG-4.1.0 changed the way that function annotations are generated.
+Prior versions required the (now removed) <tt>-py3</tt> option to generate function annotation support
+containing C/C++ types instead of supporting <tt>%feature("python:annotations", "c")</tt>.
+Variable annotations were also added in SWIG-4.1.0.
</p>
<H3><a name="Python_nn75">33.12.2 Buffer interface</a></H3>
@@ -6944,10 +7048,11 @@ modify the buffer.
<p>
-By including <tt>pyabc.i</tt> and using the <tt>-py3</tt> command
-line option when calling SWIG, the proxy classes of the STL containers
+By including <tt>pyabc.i</tt> in your interface file,
+the proxy classes of the STL containers
will automatically gain an appropriate abstract base class from the
-<tt>collections.abc</tt> module. For
+<tt>collections.abc</tt> module for Python 3.3 and later, otherwise from the
+<tt>collections</tt> module. For
example, the following SWIG interface:
</p>
@@ -6964,8 +7069,10 @@ namespace std {
<p>
will generate a Python proxy class <tt>Mapii</tt> inheriting from
-<tt>collections.abc.MutableMap</tt> and a proxy class <tt>IntList</tt>
-inheriting from <tt>collections.abc.MutableSequence</tt>.
+<tt>collections.abc.MutableMap</tt> for Python 3.3 and later, or <tt>collections.MutableMap</tt>
+for earlier versions and a proxy class <tt>IntList</tt>
+inheriting from <tt>collections.abc.MutableSequence</tt> for Python 3.3 or later,
+or <tt>collections.MutableSequence</tt> for earlier versions.
</p>
<p>
@@ -6974,7 +7081,9 @@ used to define an abstract base class for your own C++ class:
</p>
<div class="code"><pre>
-%pythonabc(MySet, collections.abc.MutableSet);
+%pythonabc(MySet, collections.abc.MutableSet); # Python 3.3 and later
+%pythonabc(MySet, collections.MutableSet); # Prior to Python 3.3
+%pythonabc(MySet, "collections.abc.MutableSet if _swig_python_version_info &gt;= (3, 3) else collections.MutableSet"); # All Python versions
</pre></div>
<p>
@@ -6988,6 +7097,8 @@ For details of abstract base class, please see
of the classes in the <tt>collections</tt> module in Python 3.7.
The <tt>collections.abc</tt> module was introduced in Python 3.3 and hence this feature
requires Python 3.3 or later.
+SWIG-4.1.0 introduced the flexibility of using
+either the <tt>collections.abc</tt> module for Python 3.3 and later or the <tt>collections</tt> module for earlier Python versions.
</p>
<H3><a name="Python_nn77">33.12.4 Byte string output conversion</a></H3>
diff --git a/Doc/Manual/R.html b/Doc/Manual/R.html
index 9b05922fd..0e9e55b8e 100644
--- a/Doc/Manual/R.html
+++ b/Doc/Manual/R.html
@@ -30,7 +30,7 @@
<p>
R is a GPL'ed open source statistical and plotting environment.
Information about R can be found at <a
-href="http://www.r-project.org/">www.r-project.org</a>.
+href="https://www.r-project.org/">www.r-project.org</a>.
</p>
<p>
@@ -39,7 +39,7 @@ compile and run an R interface to QuantLib running on Mandriva Linux
with gcc. They are also used to create the SimpleITK R package, which
runs on Linux and MacOS. SWIG is used to create all wrapper
interfaces
-to <a href="http://http://www.simpleitk.org/">SimpleITK</a>. The R
+to <a href="https://www.simpleitk.org/">SimpleITK</a>. The R
bindings also work on Microsoft Windows using Visual C++.
</p>
@@ -321,7 +321,7 @@ and forth between integers.
<p>
The details of enumeration names and contents are stored in hidden R
-environments, which are named according the the enumeration name - for
+environments, which are named according to the enumeration name - for
example, an enumeration colour:
</p>
diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html
index 5581cc458..e85faec42 100644
--- a/Doc/Manual/Ruby.html
+++ b/Doc/Manual/Ruby.html
@@ -1707,7 +1707,7 @@ For example: </p>
<div class="code">
<pre>%rename("is_it_safe?") is_it_safe();
-%typemap(out) int is_it_safe "$result = ($1 != 0) ? Qtrue : Qfalse;";
+%typemap(out) int is_it_safe "$result = ($1 != 0) ? Qtrue : Qfalse;"
int is_it_safe();</pre>
</div>
diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html
index 876c0ac17..3fb41e522 100644
--- a/Doc/Manual/SWIG.html
+++ b/Doc/Manual/SWIG.html
@@ -47,6 +47,7 @@
<li><a href="#SWIG_rename_ignore">Renaming and ignoring declarations</a>
<ul>
<li><a href="#SWIG_nn29">Simple renaming of specific identifiers</a>
+<li><a href="#SWIG_ignore">Ignoring identifiers</a>
<li><a href="#SWIG_advanced_renaming">Advanced renaming support</a>
<li><a href="#SWIG_limiting_renaming">Limiting global renaming rules</a>
<li><a href="#SWIG_chosen_unignore">Ignoring everything then wrapping a few selected symbols</a>
@@ -154,6 +155,7 @@ General Options
-debug-symbols - Display target language symbols in the symbol tables
-debug-csymbols - Display C symbols in the symbol tables
-debug-lsymbols - Display target language layer symbols
+ -debug-quiet - Display less parse tree node debug info when using other -debug options
-debug-tags - Display information about the tags found in the interface
-debug-template - Display information for debugging templates
-debug-top &lt;n&gt; - Display entire parse tree at stages 1-4, &lt;n&gt; is a csv list of stages
@@ -208,7 +210,7 @@ General Options
-oh &lt;headfile&gt; - Set name of C++ output header file for directors to &lt;headfile&gt;
-outcurrentdir - Set default output dir to current dir instead of input file's path
-outdir &lt;dir&gt; - Set language specific files output directory to &lt;dir&gt;
- -pcreversion - Display PCRE version information
+ -pcreversion - Display PCRE2 version information
-small - Compile in virtual elimination and compact mode
-swiglib - Report location of SWIG library and exit
-templatereduce - Reduce all the typedefs in templates
@@ -217,7 +219,7 @@ General Options
-Wall - Remove all warning suppression, also implies -Wextra
-Wallkw - Enable keyword warnings for all the supported languages
-Werror - Treat warnings as errors
- -Wextra - Adds the following additional warnings: 202,309,403,405,512,321,322
+ -Wextra - Adds the following additional warnings: 309,403,405,512,321,322
-w&lt;list&gt; - Suppress/add warning messages, eg -w401,+321 - see Warnings.html
-xmlout &lt;file&gt; - Write XML version of the parse tree to &lt;file&gt; after normal processing
</pre></div>
@@ -1469,14 +1471,14 @@ SWIG generates the following code:
<pre>
/* C mode */
void foo_set(char *value) {
- if (foo) free(foo);
+ free(foo);
foo = (char *) malloc(strlen(value)+1);
strcpy(foo, value);
}
/* C++ mode. When -c++ option is used */
void foo_set(char *value) {
- if (foo) delete [] foo;
+ delete [] foo;
foo = new char[strlen(value)+1];
strcpy(foo, value);
}
@@ -1842,6 +1844,25 @@ all to `output' by specifying :</p>
</pre></div>
<p>
+A new <tt>%rename</tt> for the same name will replace the current
+<tt>%rename</tt> for all uses after it in the file, and setting the
+new name to "" will remove the rename. So, for instance, if you
+wanted to rename some things in one file and not in another, you could
+do:
+</p>
+
+<div class="code">
+<pre>
+ %rename(print1) print;
+ %include "header1.h" //Anything "print" in here will become "print1"
+ %rename(print2) print;
+ %include "header2.h" //Anything "print" in here will become "print2"
+ %rename("") print;
+ %include "header3.h" //Anything "print" in here will remain "print"
+</pre>
+</div>
+
+<p>
SWIG does not normally perform any checks to see if the functions it wraps are
already defined in the target scripting language. However, if you are
careful about namespaces and your use of modules, you can usually
@@ -1857,6 +1878,9 @@ If you are using the <tt>%rename</tt> directive and C++, make sure you read the
for method overloading and default arguments.
</p>
+<H4><a name="SWIG_ignore">5.4.7.2 Ignoring identifiers</a></H4>
+
+
<p>
Closely related to <tt>%rename</tt> is the <tt>%ignore</tt> directive. <tt>%ignore</tt> instructs SWIG
to ignore declarations that match a given identifier. For example:
@@ -1896,7 +1920,7 @@ This directive is still supported, but it is deprecated and should probably be a
directive is more powerful and better supports wrapping of raw header file information.
</p>
-<H4><a name="SWIG_advanced_renaming">5.4.7.2 Advanced renaming support</a></H4>
+<H4><a name="SWIG_advanced_renaming">5.4.7.3 Advanced renaming support</a></H4>
<p>
@@ -2022,8 +2046,8 @@ and a more descriptive one, but the two functions are otherwise equivalent:
<td>String after (Perl-like) regex substitution operation. This function
allows applying arbitrary regular expressions to the identifier names. The
<i>pattern</i> part is a regular expression in Perl syntax (as supported
- by the <a href="http://www.pcre.org/">Perl Compatible Regular Expressions (PCRE)</a>)
- library and the <i>subst</i> string
+ by the <a href="https://www.pcre.org/">Perl Compatible Regular Expressions</a>)
+ (PCRE2 library) and the <i>subst</i> string
can contain back-references of the form <tt>\N</tt> where <tt>N</tt> is a digit
from 0 to 9, or one of the following escape sequences: <tt>\l</tt>, <tt>\L</tt>,
<tt>\u</tt>, <tt>\U</tt> or <tt>\E</tt>. The back-references are replaced with the
@@ -2041,23 +2065,10 @@ and a more descriptive one, but the two functions are otherwise equivalent:
<tt>%rename("regex:/(\\w+)_(.*)/\\u\\2/")</tt></td>
<td><tt>prefix_print</tt></td><td><tt>Print</tt></td>
</tr>
-<tr>
- <td><tt>command:cmd</tt></td>
- <td>Output of an external command <tt>cmd</tt> with the string passed to
- it as input. Notice that this function is extremely slow compared to all
- the other ones as it involves spawning a separate process and using it for
- many declarations is not recommended. The <i>cmd</i> is not enclosed in
- square brackets but must be terminated with a triple <tt>'&lt;'</tt> sign,
- e.g. <tt>%rename("command:tr&nbsp;-d&nbsp;aeiou &lt;&lt;&lt;")</tt>
- (nonsensical example removing all vowels)</td>
- <td><tt>Print</tt></td><td><tt>Prnt</tt></td>
-</tr>
</table>
<p>
-The most general function of all of the above ones (not counting
-<tt>command</tt> which is even more powerful in principle but which should
-generally be avoided because of performance considerations) is the
+The most general function of all of the above ones is the
<tt>regex</tt> one. Here are some more examples of its use:
</p>
@@ -2105,7 +2116,7 @@ are exactly equivalent and <tt>%rename</tt> can be used to selectively ignore
multiple declarations using the previously described matching possibilities.
</p>
-<H4><a name="SWIG_limiting_renaming">5.4.7.3 Limiting global renaming rules</a></H4>
+<H4><a name="SWIG_limiting_renaming">5.4.7.4 Limiting global renaming rules</a></H4>
<p>
@@ -2137,11 +2148,15 @@ the match to class declarations only (in C++) and <tt>match="enumitem"</tt>
restricts it to the enum elements. SWIG also provides convenience macros for
such match expressions, for example
</p>
+
<div class="code">
<pre>
%rename("%(title)s", %$isenumitem) "";
+// same as:
+%rename("%(title)s", match="enumitem") "";
</pre>
</div>
+
<p>
will capitalize the names of all the enum elements but not change the case of
the other declarations. Similarly, <tt>%$isclass</tt>, <tt>%$isfunction</tt>,
@@ -2152,6 +2167,56 @@ documentation is not exhaustive, see the "%rename predicates" section in
</p>
<p>
+A logical not is also possible by using <tt>notmatch</tt>.
+For example, <tt>notmatch="enumitem"</tt> will restrict the
+match to all items that are not enum elements.
+There is also a <tt>%$not</tt> macro which simply expands to "not".
+Be careful using this as some of the other macros in <tt>swig.swg</tt>
+are complex expressions and so it will only "notmatch" the first part
+of the expression.
+</p>
+
+<div class="code">
+<pre>
+%rename("%(title)s", %$not %$isenumitem) "";
+// same as:
+%rename("%(title)s", notmatch="enumitem") "";
+</pre>
+</div>
+
+<p>
+For a comprehensive understanding of how the matching works, the internal
+<a href="Extending.html#Extending_nn8">parse tree</a> needs to be examined using the
+command line option: <tt>-debug-module 1 -debug-quiet</tt>.
+A snippet of the resulting output might be:
+</p>
+
+<div class="shell">
+<pre>
+ +++ destructor ----------------------------------------
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | name - "~Shape"
+ | storage - "virtual"
+ | sym:name - "~Shape"
+</pre>
+</div>
+
+<p>
+Here the node type is a "destructor" and in order to match all destructor nodes, use
+<tt>match="destructor"</tt>. To match one of the listed attributes in the node,
+such as when the storage is virtual, use <tt>match$storage="virtual"</tt>.
+This will match all nodes that have a storage attribute set to "virtual".
+To match only virtual destructors, combine them and use <tt>match="destructor", match$storage="virtual"</tt>.
+</p>
+
+<p>
+While the vast majority of these internal parse tree nodes are unlikely to change from one version of
+SWIG to the next, <b>use these matching rules at your own risk</b> as there are no guarantees that they will not change.
+</p>
+
+<p>
In addition to literally matching some string with <tt>match</tt> you can
also use <tt>regexmatch</tt> or <tt>notregexmatch</tt> to match a string
against a regular expression. For example, to ignore all functions having
@@ -2203,7 +2268,7 @@ wrap C++ overloaded functions and methods or C++ methods which use default argum
</p>
-<H4><a name="SWIG_chosen_unignore">5.4.7.4 Ignoring everything then wrapping a few selected symbols</a></H4>
+<H4><a name="SWIG_chosen_unignore">5.4.7.5 Ignoring everything then wrapping a few selected symbols</a></H4>
<p>
@@ -2227,6 +2292,23 @@ the following approach could be taken:
%rename("%s") Star::shine; // named method
%include "myheader.h"
+
+%rename("%s") ""; // Undo the %ignore
+</pre>
+</div>
+
+<p>
+If <tt>Star</tt> was in the <tt>Galaxy</tt> namespace, you would need
+to unignore the namespace, too, and add the namespace to all the
+renames:
+</p>
+
+<div class="code">
+<pre>
+%rename("%s") Galaxy;
+%rename("%s") Galaxy::Star;
+%rename("%s") Galaxy::Star::Star;
+...
</pre>
</div>
@@ -2241,6 +2323,7 @@ members of the class, so when the chosen class is unignored, all of its methods
%rename($ignore, %$isclass) ""; // Only ignore all classes
%rename("%s") Star; // Unignore 'Star'
%include "myheader.h"
+%rename("%s", %$isclass) ""; // Stop ignoring all classes
</pre>
</div>
@@ -2446,6 +2529,45 @@ handle C++ are described in the next section.
</p>
<p>
+ISO C has a separate tag name space in which the names of structures,
+unions and enumerated types are put, which is separate from the
+name space for ordinary identifiers (function names, object names,
+typedef names, enumeration constants). For example, this is valid
+ISO C because <tt>Foo</tt> the struct tag and <tt>Foo</tt> the function
+name are in different name spaces:
+</p>
+
+<div class="code"><pre>
+struct Foo {
+ int bar;
+};
+
+int Foo(void) { return 42; }
+</pre></div>
+
+<p>
+SWIG doesn't currently implement this separate tag name space and
+for the above example you'll get:
+</p>
+
+<div class="code"><pre>
+foo.i:5: Warning 302: Identifier 'Foo' redefined (ignored),
+foo.i:1: Warning 302: previous definition of 'Foo'.
+</pre></div>
+
+<p>
+In practice this rarely actually causes problems, particular because
+SWIG has special handling for <tt>typedef</tt> so cases such as this
+work:
+</p>
+
+<div class="code"><pre>
+typedef struct Foo {
+ int bar;
+} Foo;
+</pre></div>
+
+<p>
If SWIG encounters the definition of a structure or union, it
creates a set of accessor functions. Although SWIG does not need
structure definitions to build an interface, providing definitions
@@ -2456,8 +2578,7 @@ to an individual member. For example, the declaration :</p>
<div class="code"><pre>
struct Vector {
double x, y, z;
-}
-
+};
</pre></div>
<p>
@@ -2594,8 +2715,7 @@ char *Foo_name_get(Foo *obj) {
}
char *Foo_name_set(Foo *obj, char *c) {
- if (obj-&gt;name)
- free(obj-&gt;name);
+ free(obj-&gt;name);
obj-&gt;name = (char *) malloc(strlen(c)+1);
strcpy(obj-&gt;name, c);
return obj-&gt;name;
@@ -2733,6 +2853,11 @@ void Foo_w_set(FOO *f, WORD value) {
</pre>
</div>
+<p>
+If you have accessor methods that you want to use as attributes in the
+target language, you can make them appear as data members using
+<a href="Library.html#Library_attributes">attributes.i</a>.
+</p>
<p>
<b>Compatibility Note:</b> SWIG-1.3.11 and earlier releases transformed all non-primitive member datatypes
@@ -2977,6 +3102,11 @@ typedef struct Vector {
</div>
<p>
+You'll also need to use these names if you want to directly call methods added
+using <tt>%extend</tt> from other C/C++ code.
+</p>
+
+<p>
The name used for %extend should be the name of the struct and not the name of any typedef to the struct.
For example:
</p>
@@ -3534,8 +3664,8 @@ In the process of building an interface, SWIG may encounter syntax errors or
other problems. The best way to deal with this is to simply copy the offending
code into a separate interface file and edit it. However, the SWIG developers
have worked very hard to improve the SWIG parser--you should report parsing errors
-to the <a href="http://www.swig.org/mail.html">swig-devel mailing list</a> or to the
-<a href="http://www.swig.org/bugs.html">SWIG bug tracker</a>.
+to the <a href="https://www.swig.org/mail.html">swig-devel mailing list</a> or to the
+<a href="https://www.swig.org/bugs.html">SWIG bug tracker</a>.
</p>
<H3><a name="SWIG_nn47">5.7.2 The SWIG interface file</a></H3>
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index 2244a0508..b4b9acb17 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -48,6 +48,9 @@
</ul>
<li><a href="#SWIGPlus_nn28">Overloaded operators</a>
<li><a href="#SWIGPlus_class_extension">Class extension</a>
+<ul>
+<li><a href="#SWIGPlus_replacing_methods">Replacing class methods</a>
+</ul>
<li><a href="#SWIGPlus_nn30">Templates</a>
<ul>
<li><a href="#SWIGPlus_template_directive">The %template directive</a>
@@ -581,7 +584,7 @@ automatically generate a wrapper for one.
<li>
If a C++ class does not declare an explicit copy constructor, SWIG will
-automatically generate a wrapper for one if the <tt>%copyctor</tt> is used.
+automatically generate a wrapper for one if <tt>%copyctor</tt> is used.
</li>
<li>
@@ -1122,7 +1125,7 @@ customization features.
<p>
SWIG wraps class members that are public following the C++
conventions, i.e., by explicit public declaration or by the use of
- the <tt>using</tt> directive. In general, anything specified in a
+ <tt>using</tt> declarations. In general, anything specified in a
private or protected section will be ignored, although the internal
code generator sometimes looks at the contents of the private and
protected sections so that it can properly generate code for default
@@ -1349,16 +1352,19 @@ following:
<div class="code">
<pre>
Vector *wrap_cross_product(Vector *a, Vector *b) {
- Vector x = *a;
- Vector y = *b;
- Vector r = cross_product(x, y);
+ Vector x;
+ Vector y;
+ Vector r;
+ x = *a;
+ y = *b;
+ r = cross_product(x, y);
return new Vector(r);
}</pre>
</div>
<p>
-In order for the wrapper code to compile, <tt>Vector</tt> must define a copy constructor and a
-default constructor.
+In order for the wrapper code to compile, <tt>Vector</tt> must define a default constructor, copy assignment operator (and/or a move assignment operator for C++11 and later).
+The <a href="CPlusPlus11.html#CPlusPlus11_move_only">Movable and move-only types</a> section should be read regarding C++11 move semantics and return by value.
</p>
<p>
@@ -1371,9 +1377,12 @@ called the "Fulton Transform". This produces a wrapper that looks like this:
<div class="code">
<pre>
Vector cross_product(Vector *a, Vector *b) {
- SwigValueWrapper&lt;Vector&gt; x = *a;
- SwigValueWrapper&lt;Vector&gt; y = *b;
- SwigValueWrapper&lt;Vector&gt; r = cross_product(x, y);
+ SwigValueWrapper&lt;Vector&gt; x;
+ SwigValueWrapper&lt;Vector&gt; y;
+ SwigValueWrapper&lt;Vector&gt; r;
+ x = *a;
+ y = *b;
+ r = cross_product(x, y);
return new Vector(r);
}
</pre>
@@ -2080,7 +2089,6 @@ or for statically typed languages like Java:
<pre>
example.i:4: Warning 516: Overloaded method foo(long) ignored,
example.i:3: Warning 516: using foo(int) instead.
-at example.i:3 used.
</pre>
</div>
@@ -2139,7 +2147,7 @@ This error means that the target language module supports overloading,
but for some reason there is no type-checking rule that can be used to
generate a working dispatch function. The resulting behavior is then
undefined. You should report this as a bug to the
-<a href="http://www.swig.org/bugs.html">SWIG bug tracking database</a>
+<a href="https://www.swig.org/bugs.html">SWIG bug tracking database</a>
if this is due to one of the typemaps supplied with SWIG.
</p>
@@ -2316,7 +2324,7 @@ members (of all classes):
Note: the <tt>*::</tt> syntax is non-standard C++, but the '*' is meant to be a
wildcard that matches any class name (we couldn't think of a better
alternative so if you have a better idea, send email to
-the <a href="http://www.swig.org/mail.html">swig-devel mailing list</a>.
+the <a href="https://www.swig.org/mail.html">swig-devel mailing list</a>.
</p>
<p>
@@ -2327,8 +2335,8 @@ also apply to <tt>%ignore</tt>. For example:
<div class="code">
<pre>
%ignore foo(double); // Ignore all foo(double)
-%ignore Spam::foo; // Ignore foo in class Spam
-%ignore Spam::foo(double); // Ignore foo(double) in class Spam
+%ignore Spam::foo; // Ignore foo in class Spam (and foo in any derived classes)
+%ignore Spam::foo(double); // Ignore foo(double) in class Spam (and foo in any derived classes)
%ignore *::foo(double); // Ignore foo(double) in all classes
</pre>
</div>
@@ -2384,6 +2392,53 @@ over a renaming of <tt>foo(int)</tt>).</p>
</li>
<li><p>
+Renaming a class member, using an unparameterized but qualified name, such as <tt>Spam::foo</tt>, also applies to members in all derived classes
+that have members with the same name.
+This can be used to simply rename a method, across an entire class hierarchy for all overloaded and non-overloaded methods.
+This also applies to methods introduced via <tt>using</tt> declarations, see
+<a href="#SWIGPlus_nn35">Using declarations and inheritance</a>.
+For example:
+</p>
+
+<div class="code">
+<pre>
+%rename(foo_new) Spam::foo;
+
+class Spam {
+public:
+ virtual void foo(int); // Renamed to foo_new
+};
+
+class Bar : public Spam {
+public:
+ virtual void foo(int); // Renamed to foo_new
+ void foo(bool, short, int); // Renamed to foo_new
+};
+
+class Grok : public Bar {
+public:
+ virtual void foo(int); // Renamed to foo_new
+ void foo(bool, int); // Renamed to foo_new
+ void foo(const char *); // Renamed to foo_new
+ void foo(Bar *); // Renamed to foo_new
+};
+
+class Spok : public Grok {
+public:
+ void foo(); // Renamed to foo_new
+};
+
+class Knock : public Spok {
+public:
+ using Grok::foo; // Introduced methods renamed to foo_new
+};
+</pre>
+</div>
+
+</li>
+
+
+<li><p>
The order in which <tt>%rename</tt> directives are defined does not matter
as long as they appear before the declarations to be renamed. Thus, there is no difference
between saying:</p>
@@ -2944,6 +2999,59 @@ be used to extend a structure with more than just methods, a more suitable
directive name has been chosen.
</p>
+<H3><a name="SWIGPlus_replacing_methods">6.17.1 Replacing class methods</a></H3>
+
+
+<p>
+Suppose there is a method in a class that you need to replace and keep the method name the same.
+This can be achieved combining the <tt>%extend</tt> and <tt>%ignore</tt> directives covered earlier.
+Here is an example to replace the <tt>MyClass::mymethod()</tt>:
+
+<div class="code">
+<pre>
+%extend MyClass {
+ void mymethod() {
+ std::cout &lt;&lt; "swig mymethod" &lt;&lt; std::endl;
+ }
+}
+
+%ignore MyClass::mymethod;
+
+%inline %{
+class MyClass {
+public:
+ void mymethod() {
+ std::cout &lt;&lt; "class mymethod" &lt;&lt; std::endl;
+ }
+};
+%}
+</pre>
+</div>
+
+<p>
+Or if your code organization makes more sense to put
+the <tt>%extend</tt> after the class definition, you would need the following:
+</p>
+
+<div class="code">
+<pre>
+%rename("") MyClass::mymethod; // unignores the method
+</pre>
+</div>
+
+<p>
+before the <tt>%extend</tt> or SWIG will continue to ignore
+<tt>mymethod()</tt>, even in an <tt>%extend</tt>.
+</p>
+
+<p>
+Note that you can call the class method from the method
+in <tt>%extend</tt>, just use <tt>self-&gt;mymethod()</tt> and it will call
+the class method, not the one in <tt>%extend</tt>.
+</p>
+
+
+
<H2><a name="SWIGPlus_nn30">6.18 Templates</a></H2>
@@ -2955,22 +3063,24 @@ is expected in an interface file. For example:
<div class="code">
<pre>
void foo(vector&lt;int&gt; *a, int n);
-void bar(list&lt;int, 100&gt; *x);
+void bar(std::array&lt;int, 100&gt; *x);
</pre>
</div>
<p>
There are some restrictions on the use of non-type arguments. Simple literals
-are supported, and so are some constant expressions. However, use of '&lt;'
-and '&gt;' within a constant expressions currently is not supported by SWIG
-('&lt;=' and '&gt;=' are though). For example:
+are supported, and so are most constant expressions. However, there are some
+limitations on the use of '&lt;' and '&gt;' in constant expressions (but note
+that '&lt;=' and '&gt;=' are fully supported). For example:
</p>
<div class="code">
<pre>
-void bar(list&lt;int, 100&gt; *x); // OK
-void bar(list&lt;int, 2*50&gt; *x); // OK
-void bar(list&lt;int, (2&gt;1 ? 100 : 50)&gt; *x) // Not supported
+void bar(std::array&lt;int, 100&gt; *x); // OK
+void bar(std::array&lt;int, 2*50&gt; *x); // OK
+void bar(std::array&lt;int, (1&lt;2 ? 100 : 50)&gt; *x) // OK
+void bar(std::array&lt;int, 1&lt;2 ? 100 : 50&gt; *x) // Not supported
+void bar(std::array&lt;int, (2&gt;1 ? 100 : 50)&gt; *x) // Not supported
</pre>
</div>
@@ -4017,23 +4127,23 @@ math::Complex c;
<p>
At this level, namespaces are relatively easy to manage. However, things start to get
very ugly when you throw in the other ways a namespace can be used. For example,
-selective symbols can be exported from a namespace with <tt>using</tt>.
+selective symbols can be exported from a namespace with a <tt>using</tt> declaration:
</p>
<div class="code">
<pre>
-using math::Complex;
+using math::Complex; // Using declaration
double magnitude(Complex *c); // Namespace prefix stripped
</pre>
</div>
<p>
-Similarly, the contents of an entire namespace can be made available like this:
+Similarly, the contents of an entire namespace can be made available via a <tt>using</tt> directive:
</p>
<div class="code">
<pre>
-using namespace math;
+using namespace math; // Using directive
double x = sin(1.0);
double magnitude(Complex *c);
</pre>
@@ -4190,9 +4300,11 @@ Similarly, <tt>%ignore</tt> can be used to ignore declarations.
</p>
<p>
-<tt>using</tt> declarations do not have any effect on the generated wrapper
-code. They are ignored by SWIG language modules and they do not result in any
-code. However, these declarations <em>are</em> used by the internal type
+C++ <tt>using</tt> directives and <tt>using</tt> declarations
+do not add any code to the generated wrapper code.
+However, there is an exception in one context, see <a href="#SWIGPlus_nn35">Using declarations and inheritance</a>
+for introducing members of a base class into a derived class definition.
+C++ <tt>using</tt> declarations and directives <em>are</em> used by the internal type
system to track type-names. Therefore, if you have code like this:
</p>
@@ -5116,7 +5228,7 @@ exit # 'a' is released, SWIG unref 'a' called in the destructor wra
<p>
-<tt>using</tt> declarations are sometimes used to adjust access to members of
+C++ <tt>using</tt> declarations are sometimes used to introduce members of
base classes. For example:
</p>
@@ -5124,7 +5236,7 @@ base classes. For example:
<pre>
class Foo {
public:
- int blah(int x);
+ int blah(int x);
};
class Bar {
@@ -5172,7 +5284,8 @@ you wrap this code in Python, the module works just like you would expect:
</div>
<p>
-<tt>using</tt> declarations can also be used to change access when applicable. For example:
+C++ <tt>using</tt> declarations can also be used to change access when applicable.
+For example, protected methods in a base class can be made public in a derived class:
</p>
<div class="code">
@@ -5205,15 +5318,15 @@ ignored in a base class, it will also be ignored by a <tt>using</tt> declaration
<p>
Because a <tt>using</tt> declaration does not provide fine-grained
-control over the declarations that get imported, it may be difficult
+control over the declarations that get imported, because a single <tt>using</tt> declaration
+may introduce multiple methods, it may be difficult
to manage such declarations in applications that make heavy use of
SWIG customization features. If you can't get <tt>using</tt> to work
-correctly, you can always change the interface to the following:
+correctly, you can always modify the C++ code to handle SWIG differently such as:
</p>
<div class="code">
<pre>
-
class FooBar : public Foo, public Bar {
public:
#ifndef SWIG
@@ -5230,12 +5343,35 @@ public:
</div>
<p>
+If the C++ code being wrapped cannot be changed, make judicious usage of <tt>%extend</tt> and <tt>%rename</tt>
+to ignore and unignore declarations. The example below is effectively the same as above:
+</p>
+
+<div class="code">
+<pre>
+%extend FooBar {
+ int blah(int x) { return $self-&gt;Foo::blah(x); }
+ double blah(double x) { return $self-&gt;Bar::blah(x); }
+}
+%ignore FooBar::blah; // ignore all FooBar::blah below
+%rename("") FooBar::blah(const char *x); // parameterized unignore
+
+class FooBar : public Foo, public Bar {
+public:
+ using Foo::blah;
+ using Bar::blah;
+ char *blah(const char *x);
+};
+</pre>
+</div>
+
+<p>
<b>Notes:</b>
</p>
<ul>
-<li><p>If a derived class redefines a method defined in a base class, then a <tt>using</tt> declaration
-won't cause a conflict. For example:</p>
+<li><p>If a derived class introduces a method defined in a base class via a <tt>using</tt> declaration,
+there won't be a conflict due to incorrect additional methods. For example:</p>
<div class="code">
<pre>
@@ -5247,14 +5383,14 @@ public:
class Bar : public Foo {
public:
- using Foo::blah; // Only imports blah(double);
+ using Foo::blah; // Only introduces blah(double);
int blah(int);
};
</pre>
</div>
-<li><p>Resolving ambiguity in overloading may prevent declarations from being
-imported by <tt>using</tt>. For example:
+<li><p>Renaming methods may prevent methods from being
+introduced into the derived class via <tt>using</tt> declarations. For example:
</p>
<div class="code">
@@ -5268,11 +5404,38 @@ public:
class Bar : public Foo {
public:
- using Foo::blah; // Only imports blah(int)
+ using Foo::blah; // Only introduces blah(int)
double blah(double x);
};
</pre>
</div>
+
+<p>
+The problem here is <tt>Foo::blah</tt> is renamed to <tt>blah_long</tt> in the target language, but
+the <tt>using</tt> declaration in Bar is not renamed in the target language and thinks all introduced methods should simply
+be called <tt>blah</tt>.
+It is not clear what target language names should be used in Bar and so the conflicting names are effectively ignored
+as they are not introduced into the derived class for the target language wrappers.
+In such situations SWIG will emit a warning:
+</p>
+
+<div class="shell">
+<pre>
+example.i:15: Warning 526: Using declaration Foo::blah, with name 'blah', is not actually using
+example.i:10: Warning 526: the method from Foo::blah(long), with name 'blah_long', as the names are different.
+</pre>
+</div>
+
+<p>
+<b>Compatibility Note:</b>
+This warning message was introduced in SWIG-4.1.0.
+Prior versions also effectively ignored the using declaration for the same reasons, but were silent about it.
+</p>
+
+<p>
+If methods really need different names, please use of combinations of <tt>%rename</tt>, <tt>%ignore</tt> and <tt>%extend</tt> to achieve the desired outcome.
+</p>
+
</ul>
<H2><a name="SWIGPlus_nested_classes">6.27 Nested classes</a></H2>
diff --git a/Doc/Manual/Scilab.html b/Doc/Manual/Scilab.html
index 5c4ef6269..95eea340f 100644
--- a/Doc/Manual/Scilab.html
+++ b/Doc/Manual/Scilab.html
@@ -80,7 +80,7 @@
<p>
-Scilab is a scientific software package for numerical computations providing a powerful open computing environment for engineering and scientific applications that is mostly compatible with MATLAB. More information can be found at <a href="http://www.scilab.org">www.scilab.org</a>.
+Scilab is a scientific software package for numerical computations providing a powerful open computing environment for engineering and scientific applications that is mostly compatible with MATLAB. More information can be found at <a href="https://www.scilab.org">www.scilab.org</a>.
</p>
<p>
@@ -304,11 +304,6 @@ The following table lists the Scilab specific command line options in addition t
<td>Generate the gateway XML with the given &lt;gateway_id&gt;</td>
</tr>
-<tr>
-<td><tt>-targetversion</tt></td>
-<td>Generate for Scilab target (major) version</td>
-</tr>
-
</table>
<p>
@@ -343,10 +338,6 @@ In Scilab 5.x, identifier names are composed of 24 characters maximum (this limi
In these cases, the <a href="SWIG.html#SWIG_rename_ignore">%rename directive</a> can be used to choose a different Scilab name.
</p>
-<p>
-Note: truncations can be disabled by specifying the target version 6 of Scilab in the <tt>targetversion</tt> argument (i.e. <tt>-targetversion 6</tt>).
-</p>
-
<H3><a name="Scilab_wrapping_functions">36.3.3 Functions</a></H3>
@@ -768,7 +759,7 @@ Pointers are supported by SWIG. A pointer can be returned from a wrapped C/C++ f
Also, thanks to the SWIG runtime which stores information about types, pointer types are tracked between exchanges Scilab and the native code. Indeed pointer types are stored alongside the pointer address.
A pointer is mapped to a Scilab structure (<a href="https://help.scilab.org/docs/5.5.2/en_US/tlist.html">tlist</a>), which contains as fields the pointer address and the pointer type (in fact a pointer to the type information structure in the SWIG runtime).
<br>
-Why a native pointer is not mapped to a Scilab pointer (type name: "pointer", type ID: 128) ? The big advantage of mapping to a <tt>tlist</tt> is that it exposes a new type for the pointer in Scilab, type which can be acessed in Scilab with the <a href="https://help.scilab.org/docs/5.5.2/en_US/typeof.html">typeof</a> function, and manipulated using the <a href="https://help.scilab.org/docs/5.5.2/en_US/overloading.html">overloading</a> mechanism.
+Why a native pointer is not mapped to a Scilab pointer (type name: "pointer", type ID: 128) ? The big advantage of mapping to a <tt>tlist</tt> is that it exposes a new type for the pointer in Scilab, type which can be accessed in Scilab with the <a href="https://help.scilab.org/docs/5.5.2/en_US/typeof.html">typeof</a> function, and manipulated using the <a href="https://help.scilab.org/docs/5.5.2/en_US/overloading.html">overloading</a> mechanism.
</p>
<p>
@@ -776,7 +767,7 @@ Notes:
</p>
<ul>
<li>type tracking needs the SWIG runtime to be first initialized with the appropriate function (see the <a href="#Scilab_module_initialization">Module initialization</a> section).</li>
-<li>for any reason, if a wrapped pointer type is unknown (or if the SWIG runtime is not initialized), SWIG maps it to a Scilab pointer. Also, a Scilab pointer is always accepted as a pointer argument of a wrapped function. The drawaback is that pointer type is lost.</li>
+<li>for any reason, if a wrapped pointer type is unknown (or if the SWIG runtime is not initialized), SWIG maps it to a Scilab pointer. Also, a Scilab pointer is always accepted as a pointer argument of a wrapped function. The drawback is that pointer type is lost.</li>
</ul>
<p>
@@ -2151,7 +2142,7 @@ clear get_file_path;
<ul>
<li>Example use cases can be found in the <tt>Examples/scilab</tt> directory.</li>
<li>The test suite in the <tt>Examples/test-suite/scilab</tt> can be another source of useful use cases.</li>
-<li>The <a href="http://help.scilab.org/docs/5.5.0/en_US/api_scilab.html">Scilab API</a> is used in the generated code and is a useful reference when examining the output.</li>
-<li>This <a href="http://wiki.scilab.org/howto/Create%20a%20toolbox">guide</a> describes the Scilab external modules structure and files, in particular the files that are generated by SWIG for Scilab.</li>
+<li>The <a href="https://help.scilab.org/docs/5.5.0/en_US/api_scilab.html">Scilab API</a> is used in the generated code and is a useful reference when examining the output.</li>
+<li>This <a href="https://wiki.scilab.org/howto/Create%20a%20toolbox">guide</a> describes the Scilab external modules structure and files, in particular the files that are generated by SWIG for Scilab.</li>
</ul>
diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html
index 0a22afb18..ab3346c70 100644
--- a/Doc/Manual/Tcl.html
+++ b/Doc/Manual/Tcl.html
@@ -79,9 +79,9 @@
</p>
<p>
-This chapter discusses SWIG's support of Tcl. SWIG currently requires
-Tcl 8.0 or a later release. Earlier releases of SWIG supported Tcl 7.x, but
-this is no longer supported.
+This chapter discusses SWIG's support of Tcl. Since SWIG 4.1.0, Tcl 8.4 or a
+later release is required. Prior to that earlier Tcl 8.x releases were also
+supported.
</p>
<H2><a name="Tcl_nn2">37.1 Preliminaries</a></H2>
@@ -636,7 +636,7 @@ tcl:
<p>
To build the extension, run NMAKE (you may need to run vcvars32
-first). This is a pretty minimal Makefile, but hopefully its enough
+first). This is a pretty minimal Makefile, but hopefully it's enough
to get you started. With a little practice, you'll be making lots of
Tcl extensions.
</p>
@@ -1227,7 +1227,15 @@ _108fea88_p_Bar
<p>
Finally, to destroy objects created from Tcl, you can either let the object
-name go out of scope or you can explicitly delete the object. For example:
+name go out of scope or you can explicitly delete the object as shown below.
+Objects won't get automatically destroyed when the Tcl program exits, so if
+it's important that the C++ destructor is called for a class you'll need to
+make sure that you explicitly do this for objects of that class before program
+exit.
+</p>
+
+<p>
+For example:
</p>
<div class="code">
@@ -2235,7 +2243,7 @@ as well as a special error code:
<div class="code">
<pre>
/* send message, return number of bytes sent, along with success code */
-int send_message(char *text, int len, int *success);
+int send_message(char *text, int *success);
</pre>
</div>
@@ -2811,9 +2819,7 @@ used as a <tt>char **</tt> object.
// This gives SWIG some cleanup code that will get called after the function call
%typemap(freearg) char ** {
- if ($1) {
- free($1);
- }
+ free($1);
}
// Now a test functions
@@ -3131,9 +3137,8 @@ For example:
<p>
-Tcl 7.4 introduced the idea of an extension package. By default, SWIG
-generates all of the code necessary to create a package. To set the package version,
-simply use the <tt>-pkgversion</tt> option. For example:
+SWIG generates all of the code necessary to create a Tcl extension package.
+To set the package version use the <tt>-pkgversion</tt> option. For example:
</p>
<div class="code">
@@ -3144,7 +3149,7 @@ simply use the <tt>-pkgversion</tt> option. For example:
<p>
After building the SWIG generated module, you need to execute
-the "<tt>pkg_mkIndex</tt>" command inside tclsh. For example :
+the <tt>pkg_mkIndex</tt> command inside tclsh. For example :
</p>
<div class="code"><pre>
@@ -3424,7 +3429,7 @@ interesting things.
<p>
For background information about the Tcl Stubs feature, see
-<a href="http://www.tcl.tk/doc/howto/stubs.html">http://www.tcl.tk/doc/howto/stubs.html</a>.
+<a href="https://www.tcl.tk/doc/howto/stubs.html">https://www.tcl.tk/doc/howto/stubs.html</a>.
</p>
<p>
@@ -3434,11 +3439,17 @@ feature if compiled with <tt>-DUSE_TCL_STUBS</tt>.
<p>
As of SWIG 1.3.40, the generated C/C++ wrapper will use the Tk Stubs
-feature if compiled with <tt>-DUSE_TK_STUBS</tt>. Also, you can override
-the minimum version to support which is passed to <tt>Tcl_InitStubs()</tt>
-and <tt>Tk_InitStubs()</tt> with <tt>-DSWIG_TCL_STUBS_VERSION="8.3"</tt>
-or the version being compiled with using
-<tt>-DSWIG_TCL_STUBS_VERSION=TCL_VERSION</tt>.
+feature if compiled with <tt>-DUSE_TK_STUBS</tt>.
+</p>
+
+<p>
+By default SWIG sets the minimum Tcl version to support to the 8.4
+as that's the minimum Tcl version we aim to support (since SWIG 4.1.0; before
+this SWIG set it to 8.1, which was the first Tcl version with the stubs
+mechanism). This minimum version is passed to <tt>Tcl_InitStubs()</tt> and
+<tt>Tk_InitStubs()</tt>. You can override with a specific version using
+<tt>-DSWIG_TCL_STUBS_VERSION="8.5"</tt> or set it to the Tcl version being
+compiled with using <tt>-DSWIG_TCL_STUBS_VERSION=TCL_VERSION</tt>.
</p>
</body>
diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html
index a12ede553..3f172d540 100644
--- a/Doc/Manual/Typemaps.html
+++ b/Doc/Manual/Typemaps.html
@@ -48,6 +48,7 @@
<ul>
<li><a href="#Typemaps_special_macro_descriptor">$descriptor(type)</a>
<li><a href="#Typemaps_special_macro_typemap">$typemap(method, typepattern)</a>
+<li><a href="#Typemaps_special_macro_typemap_attribute">$typemap(method:attribute, typepattern)</a>
</ul>
<li><a href="#Typemaps_special_variable_attributes">Special variables and typemap attributes</a>
<li><a href="#Typemaps_special_variables_and_macros">Special variables combined with special variable macros</a>
@@ -786,7 +787,7 @@ Here are some examples of valid typemap specifications:
%typemap(in) int {
$1 = PyInt_AsLong($input);
}
-%typemap(in) int "$1 = PyInt_AsLong($input);";
+%typemap(in) int "$1 = PyInt_AsLong($input);"
%typemap(in) int %{
$1 = PyInt_AsLong($input);
%}
@@ -802,7 +803,7 @@ Here are some examples of valid typemap specifications:
}
/* Typemap with modifiers */
-%typemap(in, doc="integer") int "$1 = scm_to_int($input);";
+%typemap(in, doc="integer") int "$1 = scm_to_int($input);"
/* Typemap applied to patterns of multiple arguments */
%typemap(in) (char *str, int len),
@@ -1060,9 +1061,11 @@ The matching rules can be observed in practice by using the debugging options al
<p>
-Typemaps are matched using both a type and a name (typically the name of a argument). For a given
-<tt>TYPE NAME</tt> pair, the following rules are applied, in order, to find a match. The first typemap found
-is used.
+Typemaps are matched using both a type and a name (typically the name of an
+argument, but in the case of <tt>out</tt> typemaps, the name of a function,
+qualified by the class name if it's a class method). For a given <tt>TYPE
+NAME</tt> pair, the following rules are applied, in order, to find a match.
+The first typemap found is used.
</p>
<ul>
@@ -1353,13 +1356,13 @@ const reference are written like this:
<div class="code">
<pre>
-%typemap(in) int "... convert to int ...";
-%typemap(in) short "... convert to short ...";
-%typemap(in) float "... convert to float ...";
+%typemap(in) int "... convert to int ..."
+%typemap(in) short "... convert to short ..."
+%typemap(in) float "... convert to float ..."
...
-%typemap(in) const int &amp; "... convert ...";
-%typemap(in) const short &amp; "... convert ...";
-%typemap(in) const float &amp; "... convert ...";
+%typemap(in) const int &amp; "... convert ..."
+%typemap(in) const short &amp; "... convert ..."
+%typemap(in) const float &amp; "... convert ..."
...
</pre>
</div>
@@ -1379,16 +1382,16 @@ Below is a list of the typical default types supplied by language modules, showi
<div class="code">
<pre>
-%typemap(in) SWIGTYPE &amp; { ... default reference handling ... };
-%typemap(in) SWIGTYPE * { ... default pointer handling ... };
-%typemap(in) SWIGTYPE *const { ... default pointer const handling ... };
-%typemap(in) SWIGTYPE *const&amp; { ... default pointer const reference handling ... };
-%typemap(in) SWIGTYPE[ANY] { ... 1D fixed size arrays handling ... };
-%typemap(in) SWIGTYPE [] { ... unknown sized array handling ... };
-%typemap(in) enum SWIGTYPE { ... default handling for enum values ... };
-%typemap(in) const enum SWIGTYPE &amp; { ... default handling for const enum reference values ... };
-%typemap(in) SWIGTYPE (CLASS::*) { ... default pointer member handling ... };
-%typemap(in) SWIGTYPE { ... simple default handling ... };
+%typemap(in) SWIGTYPE &amp; { ... default reference handling ... }
+%typemap(in) SWIGTYPE * { ... default pointer handling ... }
+%typemap(in) SWIGTYPE *const { ... default pointer const handling ... }
+%typemap(in) SWIGTYPE *const&amp; { ... default pointer const reference handling ... }
+%typemap(in) SWIGTYPE[ANY] { ... 1D fixed size arrays handling ... }
+%typemap(in) SWIGTYPE [] { ... unknown sized array handling ... }
+%typemap(in) enum SWIGTYPE { ... default handling for enum values ... }
+%typemap(in) const enum SWIGTYPE &amp; { ... default handling for const enum reference values ... }
+%typemap(in) SWIGTYPE (CLASS::*) { ... default pointer member handling ... }
+%typemap(in) SWIGTYPE { ... simple default handling ... }
</pre>
</div>
@@ -1940,7 +1943,7 @@ Occasionally, typemap code will be specified using a few alternative forms. For
<div class="code">
<pre>
-%typemap(in) int "$1 = PyInt_AsLong($input);";
+%typemap(in) int "$1 = PyInt_AsLong($input);"
%typemap(in) int %{
$1 = PyInt_AsLong($input);
%}
@@ -2455,6 +2458,41 @@ The result is the following expansion
</pre>
</div>
+<H4><a name="Typemaps_special_macro_typemap_attribute">14.4.4.3 $typemap(method:attribute, typepattern)</a></H4>
+
+
+<p>
+An enhanced version of <tt>$typemap</tt> provides access to typemap attributes by
+appending a colon and the attribute name after the method name. In the example below,
+"cstype" is the typemap method and "out" is the typemap attribute.
+</p>
+
+<div class="code">
+<pre>
+%typemap(cstype, out="object") XClass "XClass"
+%typemap(cscode) BarClass %{
+ $typemap(cstype:out, XClass) bar()
+ {
+ return null;
+ }
+</pre>
+</div>
+<p>
+which expands to
+</p>
+<div class="code">
+<pre>
+ object bar()
+ {
+ return null;
+ }
+</pre>
+</div>
+
+<p>
+<b>Compatibility note: </b> Support for typemap attributes in <tt>$typemap</tt>
+was introduced in SWIG-4.1.0.
+</p>
<H3><a name="Typemaps_special_variable_attributes">14.4.5 Special variables and typemap attributes</a></H3>
@@ -3103,7 +3141,7 @@ as shown. To work with heap allocated data, the following technique can be use
}
}
%typemap(freearg) float value[ANY] {
- if ($1) free($1);
+ free($1);
}
</pre>
</div>
@@ -3298,7 +3336,7 @@ The example above also shows a common approach of issuing a warning for an as ye
</p>
<p>
-<b>Compatibility note: </b> In SWIG-1.1 different languages could be distinguished with the language name being put within the <tt>%typemap</tt> directive, for example, <br>
+<b>Compatibility note: </b> In SWIG-1.1 different languages could be distinguished with the language name being put within the <tt>%typemap</tt> directive, but this was deprecated in SWIG 1.3.28 and support finally dropped completely in SWIG 4.1.0 so you'll need to update any remaining uses to use the approach above. For example, <br>
<tt>%typemap(ruby, in) int "$1 = NUM2INT($input);"</tt>.
</p>
@@ -3326,7 +3364,7 @@ Consider running the following code through SWIG:
<div class="code">
<pre>
%typemap(out) SWIGTYPE %{
- $result = new $1_ltype((const $1_ltype &amp;)$1);
+ $result = new $1_ltype($1);
%}
%inline %{
@@ -3376,7 +3414,7 @@ If the typemap code is kept the same and just the "optimal" attribute specified
<div class="code">
<pre>
%typemap(out, optimal="1") SWIGTYPE %{
- $result = new $1_ltype((const $1_ltype &amp;)$1);
+ $result = new $1_ltype($1);
%}
</pre>
</div>
@@ -3403,7 +3441,7 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() {
void * jresult ;
XX result;
result = XX::create();
- jresult = new XX((const XX &amp;)result);
+ jresult = new XX(result);
return jresult;
}
@@ -3418,7 +3456,7 @@ With the "optimal" attribute, the code is:
<pre>
SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() {
void * jresult ;
- jresult = new XX((const XX &amp;)XX::create());
+ jresult = new XX(XX::create());
return jresult;
}
</pre>
@@ -3475,7 +3513,7 @@ It should be clear that the above code cannot be used as the argument to the cop
</p>
<p>
-Secondly, if the typemaps uses <tt>$1</tt> more than once, then multiple calls to the wrapped function
+Secondly, if the typemap uses <tt>$1</tt> more than once, then multiple calls to the wrapped function
will be made. Obviously that is not very optimal.
In fact SWIG attempts to detect this and will issue a warning something like:
</p>
@@ -3556,7 +3594,7 @@ maps perform the conversion described for the above example:
}
%typemap(freearg) (int argc, char *argv[]) {
- if ($2) free($2);
+ free($2);
}
/* Required for C++ method overloading */
@@ -3835,7 +3873,7 @@ To eliminate this, define a fragment that includes the common marshalling code:
<p>
When the "in" or "varin" typemaps for MyClass are required, the
-contents of the fragment called "AsMyClass" is added to the "header" section within the generated code, and then the
+contents of the fragment called "AsMyClass" are added to the "header" section within the generated code, and then the
typemap code is emitted. Hence, the method <tt>AsMyClass</tt> will be
generated into the wrapper code before any typemap code that calls it.
</p>
@@ -3983,19 +4021,34 @@ inclusion of the other fragments.
<li>
<p>
-A typemap can also use more than one fragment, but since the
-syntax is different, you need to specify the dependent fragments in a comma separated
-list. Consider:
+A typemap can also use more than one fragment:
+</p>
+<div class="code">
+<pre>
+%typemap("in", fragment="frag1", fragment="frag2", fragment="frag3") {...}
+</pre>
+</div>
+
+<p>
+<b>Compatibility note: </b> The ability to use multiple
+<tt>fragment</tt> keys as shown above was introduced in SWIG-4.1.0.
+</p>
+
+<p>
+Multiple fragments can alternatively be specified as a comma
+separated list value in a single <tt>fragment</tt> key.
+Note that no whitespace is allowed within this comma separated list.
+The following is the equivalent to the above:
</p>
<div class="code">
<pre>
-%typemap(in, fragment="frag1, frag2, frag3") {...}
+%typemap(in, fragment="frag1,frag2,frag3") {...}
</pre>
</div>
<p>
-which is equivalent to:
+which in turn is functionally equivalent to:
</p>
<div class="code">
diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html
index 620f2e5a0..b7dd4bc67 100644
--- a/Doc/Manual/Varargs.html
+++ b/Doc/Manual/Varargs.html
@@ -512,7 +512,7 @@ like this:
<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 @@ like this:
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 @@ like this:
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)) {
@@ -609,7 +613,7 @@ you need to bring out some bigger guns.
<p>
One way to do this is to use a special purpose library such as libffi
(<a
-href="http://www.sourceware.org/libffi/">http://www.sourceware.org/libffi/</a>).
+href="https://www.sourceware.org/libffi/">https://www.sourceware.org/libffi/</a>).
libffi is a library that allows you to dynamically construct
call-stacks and invoke procedures in a relatively platform independent
manner. Details about the library can be found in the libffi
diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html
index 02197f1cb..b20b69cef 100644
--- a/Doc/Manual/Warnings.html
+++ b/Doc/Manual/Warnings.html
@@ -165,6 +165,15 @@ to provide additional diagnostics. These warnings can be turned on using the
</div>
<p>
+Preprocessor warning 202 ("Could not evaluate expression <em>expr</em>.") was
+formally off by default and enabled by <tt>-Wextra</tt>, but since SWIG 4.1.0
+this warning is on by default because suppressing it tends to hide genuine
+problems. If you really don't want to see it, you can suppress it with
+<tt>-w202</tt> or using <tt>%warnfilter</tt> as described below. Both will work
+with older versions of SWIG too.
+</p>
+
+<p>
To selectively turn on extra warning messages, you can use the directives and options in the
previous section--simply add a "+" to all warning numbers. For example:
</p>
@@ -211,7 +220,7 @@ You can of course also enable all warnings and suppress a select few, for exampl
</div>
<p>
-The warnings on the right take precedence over the warnings on the left, so in the above example <tt>-Wextra</tt> adds numerous warnings including 452, but then <tt>-w309,452</tt> overrides this and so 452 is suppressesed.
+The warnings on the right take precedence over the warnings on the left, so in the above example <tt>-Wextra</tt> adds numerous warnings including 452, but then <tt>-w309,452</tt> overrides this and so 452 is suppressed.
</p>
<p>
@@ -428,6 +437,7 @@ example.i(4) : Syntax error in input(1).
<li>324. Named nested template instantiations not supported. Processing as if no name was given to %template().
<li>325. Nested <em>kind</em> not currently supported (<em>name</em> ignored).
<li>326. Deprecated %extend name used - the <em>kind</em> name '<em>name</em>' should be used instead of the typedef name '<em>name</em>'.
+<li>327. Extern template ignored.
<li>350. operator new ignored.
<li>351. operator delete ignored.
<li>352. operator+ ignored.
@@ -536,6 +546,7 @@ example.i(4) : Syntax error in input(1).
<li>523. Use of an illegal destructor name '<em>name</em>' in %extend is deprecated, the destructor name should be '<em>name</em>'.
<li>524. Experimental target language. Target language <em>language</em> specified by <em>lang</em> is an experimental language. Please read about SWIG experimental languages, <em>htmllink</em>.
<li>525. Destructor <em>declaration</em> is final, <em>name</em> cannot be a director class.
+<li>526. Using declaration <em>declaration</em>, with name '<em>name</em>', is not actually using the method from <em>declaration</em>, with name '<em>name</em>', as the names are different.
</ul>
<H3><a name="Warnings_doxygen">19.9.6 Doxygen comments (560-599)</a></H3>
diff --git a/Doc/Manual/Windows.html b/Doc/Manual/Windows.html
index eae9ffb84..3bbfc9028 100644
--- a/Doc/Manual/Windows.html
+++ b/Doc/Manual/Windows.html
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Getting started on Windows</title>
@@ -29,17 +29,16 @@
</ul>
<li><a href="#Windows_other_compilers">Instructions for using the Examples with other compilers</a>
</ul>
-<li><a href="#Windows_cygwin_mingw">SWIG on Cygwin and MinGW</a>
-<ul>
<li><a href="#Windows_swig_exe">Building swig.exe on Windows</a>
<ul>
<li><a href="#Windows_cmake">Building swig.exe using CMake</a>
-<li><a href="#Windows_mingw_msys">Building swig.exe using MSYS2</a>
+<li><a href="#Windows_msys2">Building swig.exe using MSYS2</a>
<li><a href="#Windows_mingw_msys">Building swig.exe using MinGW and MSYS</a>
<li><a href="#Windows_cygwin">Building swig.exe using Cygwin</a>
-</ul>
+<ul>
<li><a href="#Windows_examples_cygwin">Running the examples on Windows using Cygwin</a>
</ul>
+</ul>
<li><a href="#Windows_interface_file">Microsoft extensions and other Windows quirks</a>
</ul>
</div>
@@ -61,7 +60,7 @@ Usage within the Unix like environments MinGW and Cygwin is also detailed.
SWIG does not come with the usual Windows type installation program, however it is quite easy to get started. The main steps are:
</p>
<ul>
- <li>Download the swigwin zip package from the <a href="http://www.swig.org">SWIG website</a> and unzip into a directory. This is all that needs downloading for the Windows platform.
+ <li>Download the swigwin zip package from the <a href="https://www.swig.org">SWIG website</a> and unzip into a directory. This is all that needs downloading for the Windows platform.
<li>Set environment variables as described in the <a href="#Windows_examples">SWIG Windows Examples</a> section in order to run examples using Visual C++.
</ul>
@@ -210,95 +209,102 @@ RUBY_LIB: D:\ruby\lib\mswin32-ruby16.lib<br>
If you do not have access to Visual C++ you will have to set up project files / Makefiles for your chosen compiler. There is a section in each of the language modules detailing what needs setting up using Visual C++ which may be of some guidance. Alternatively you may want to use Cygwin as described in the following section.
</p>
-<H2><a name="Windows_cygwin_mingw">3.3 SWIG on Cygwin and MinGW</a></H2>
+<H2><a name="Windows_swig_exe">3.3 Building swig.exe on Windows</a></H2>
<p>
-SWIG can also be compiled and run using <a href="http://www.cygwin.com">Cygwin</a> or <a href="http://www.mingw.org">MinGW</a> which provides a Unix like front end to Windows and comes free with gcc, an ISO C/C++ compiler. However, this is not a recommended approach as the prebuilt executable is supplied.
+The SWIG distribution provides a pre-built swig.exe and so it is not necessary for users to build the SWIG executable.
+However, this section is provided for those that want to modify the SWIG source code in a Windows environment.
+Normally this is not needed, so most people will want to ignore this section.
</p>
-<H3><a name="Windows_swig_exe">3.3.1 Building swig.exe on Windows</a></H3>
-
-
<p>
-If you want to replicate the build of swig.exe that comes with the download, follow the MinGW instructions below.
-This is not necessary to use the supplied swig.exe.
-This information is provided for those that want to modify the SWIG source code in a Windows environment.
-Normally this is not needed, so most people will want to ignore this section.
+There are various ways to build the SWIG executable including <a href="https://cmake.org/">CMake</a> which is able to generate project files for building with Visual Studio.
+SWIG can also be compiled and run using <a href="https://www.msys2.org/">MSYS2</a>, <a href="https://www.cygwin.com">Cygwin</a> or <a href="https://osdn.net/projects/mingw/">MinGW</a>, all of which provide a Unix like front end to Windows and comes free with the gcc C/C++ compiler.
</p>
-<H4><a name="Windows_cmake">3.3.1.1 Building swig.exe using CMake</a></H4>
+
+<H3><a name="Windows_cmake">3.3.1 Building swig.exe using CMake</a></H3>
<p>
-SWIG can also be built using <a href="https://cmake.org/">CMake</a> and Visual Studio rather than autotools. As with the other approaches to
+SWIG can be built using <a href="https://cmake.org/">CMake</a> and Visual Studio rather than autotools. As with the other approaches to
building SWIG the dependencies need to be installed. The steps below are one of a number of ways of installing the dependencies without requiring Cygwin or MinGW.
-For fully working build steps always check the Continuous Integration setups currently detailed in the <a href="https://github.com/swig/swig/blob/master/appveyor.yml">Appveyor YAML file</a>.
+For fully working build steps always check the Continuous Integration (CI) setups currently detailed in the <a href="https://github.com/swig/swig/tree/master/.github/workflows/nuget.yml">GitHub Actions YAML file</a>.
</p>
<ol>
<li>
- Install Nuget from <a href="https://www.nuget.org/downloads">https://www.nuget.org/downloads</a> (v5.8.1 is used in this example, and installed to C:\Tools). Nuget is the package manager
- for .NET, but allows us to easily install <a href="https://www.pcre.org/">PCRE</a> and other dependencies required by SWIG.
+ Install Nuget from <a href="https://www.nuget.org/downloads">https://www.nuget.org/downloads</a> (v6.0.0 is used in this example, and installed to <tt>C:\Tools</tt>). Nuget is the package manager
+ for .NET, but allows us to easily install <a href="https://cmake.org/">CMake</a> and other dependencies required by SWIG.
</li>
<li>
- Install CMake using the following command: <pre>C:\Tools\nuget install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake</pre>
+ Install <a href="https://www.nuget.org/packages/CMake-win64/">CMake-win64 Nuget package</a> using the following command: <pre>C:\Tools\nuget install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake</pre>
+ Using PowerShell the equivalent syntax is: <pre>&amp; "C:\Tools\nuget" install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake</pre>
Alternatively you can download CMake from <a href="https://cmake.org/download/">https://cmake.org/download/</a>.
</li>
<li>
- Install Bison using the following command: <pre>C:\Tools\nuget install bison-win32 -Version 2.4.1.1 -OutputDirectory C:\Tools\bison</pre>
- Alternatively download Bison from <a href="https://sourceforge.net/projects/gnuwin32/files/bison/">https://sourceforge.net/projects/gnuwin32/files/bison/</a> (2.4.1 is used in this example)
- and save to a folder e.g. C:\Tools\Bison
+ Install the <a href="https://www.nuget.org/packages/bison/">Bison Nuget package</a> using the following command: <pre>C:\Tools\nuget install Bison -Version 3.7.4 -OutputDirectory C:\Tools\bison</pre>
+ Alternatively download Bison from <a href="https://sourceforge.net/projects/winflexbison/files/">https://sourceforge.net/projects/winflexbison/files/</a> (Bison 3.7.4 is used in this example)
+ and save to a folder e.g. <tt>C:\Tools\Bison</tt>
</li>
<li>
- Install PCRE using Nuget using the following command: <pre>C:\Tools\nuget install pcre -Version 8.33.0.1 -OutputDirectory C:\Tools\pcre</pre>.
- Alternatively, use <tt>WITH_PCRE</tt> option to disable PCRE support if you are sure not to need it.
+ Install the <a href="https://www.nuget.org/packages/pcre2/">PCRE2 Nuget package</a> using the following command: <pre>C:\Tools\nuget install PCRE2 -Version 10.39 -OutputDirectory C:\Tools\pcre2</pre>
+ Note this is a x64 build, if this is not suitable PCRE2 can be built from source using <a href="https://github.com/PhilipHazel/pcre2/">https://github.com/PhilipHazel/pcre2/</a>.
+ Alternatively, set <tt>WITH_PCRE=OFF</tt> to disable PCRE2 support if you are sure you do not require it.
</li>
<li>
We will also need the SWIG source code. Either download a zipped archive from GitHub, or if git is installed clone the latest codebase
- using <pre>git clone https://github.com/swig/swig.git</pre>
- In this example we are assuming the source code is available at C:\swig
+ using: <pre>git clone https://github.com/swig/swig.git</pre>
+ In this example we are assuming the source code is available at <tt>C:\swig</tt>
+ </li>
+ <li>
+ <p>
+ Now we have all the required dependencies we can build SWIG using PowerShell and the commands below. We are assuming Visual Studio 2019 is installed. For other versions of Visual Studio change <tt>"Visual Studio 16 2019 -A x64"</tt> to the relevant
+ <a href="https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators">Visual Studio Generator</a> and
+ architecture. We add the required build tools to the system PATH, and then
+ build a Release version of SWIG. If all runs successfully a new swig.exe should be generated in the <tt>C:/swig/install2/bin</tt> folder.
+ </p>
</li>
</ol>
-
-<p>
- We are assuming Visual Studio 2017 is installed. For other versions of Visual Studio change <i>"Visual Studio 15 2017 Win64"</i> to the relevant
- <a href="https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators">Visual Studio Generator</a>.
- Now we have all the required dependencies we can build SWIG using the commands below. We add the required build tools to the system PATH, and then
- build a Release version of SWIG. If all runs successfully a new swig.exe should be generated in a /Release folder.
-</p>
-
-<div class="shell">
- <pre>
+<div class="shell"><pre>
cd C:\swig
-SET PATH=C:\Tools\CMake\CMake-win64.3.15.5\bin;C:\Tools\bison\bison-win32.2.4.1.1\tools\native\bin;%PATH%
-SET PCRE_ROOT=C:\Tools\pcre\pcre.8.33.0.1\build\native
-SET PCRE_PLATFORM=x64
-cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install2" -DCMAKE_C_FLAGS="/DPCRE_STATIC" ^
- -DPCRE_INCLUDE_DIR=%PCRE_ROOT%/include -DPCRE_LIBRARY=%PCRE_ROOT%/lib/v110/%PCRE_PLATFORM%/Release/static/utf8/pcre8.lib .
-cmake --build . --config Release
-
-REM to test the exe
-cd /Release
-swig.exe -help
-</pre>
-</div>
+
+$env:PATH="C:\Tools\CMake\CMake-win64.3.15.5\bin;C:\Tools\bison\Bison.3.7.4\bin;" + $env:PATH
+$PCRE_ROOT="C:\Tools\pcre2\PCRE2.10.39.0"
+$PCRE_PLATFORM="x64"
+
+cmake -G "Visual Studio 16 2019" -A "x64" `
+-DCMAKE_INSTALL_PREFIX="C:/swig/install2" `
+-DCMAKE_C_FLAGS="/DPCRE2_STATIC" `
+-DCMAKE_CXX_FLAGS="/DPCRE2_STATIC" `
+-DPCRE2_INCLUDE_DIR="$PCRE_ROOT/include" `
+-DPCRE2_LIBRARY="$PCRE_ROOT/lib/pcre2-8-static.lib" `
+-S . -B build
+
+cmake --build build --config Release
+cmake --install build --config Release
+
+# to test the exe built correctly
+cd install2/bin
+./swig.exe -version
+./swig.exe -help
+</pre></div>
<p>
In addition to Release builds you can create a Debug build using:
</p>
<div class="shell">
- <pre>cmake --build . --config Debug</pre>
+ <pre>cmake --build build --config Debug</pre>
</div>
<p>
- A Visual Studio solution file should be generated named swig.sln. This can be opened and debugged by running the swig project and setting the
- Debugging Command Arguments. For example to debug one of the test-suite .i files included with the SWIG source use the following:
+ A Visual Studio solution file should be generated named swig.sln. This can be opened and debugged by running the swig project and setting <tt>Properties &gt; Debugging &gt; Command Arguments</tt>. For example to debug one of the test-suite .i files included with the SWIG source use the following:
</p>
<div class="shell">
<pre>-python -c++ -o C:\Temp\doxygen_parsing.cpp C:\swig\Examples\test-suite\doxygen_parsing.i</pre>
</div>
-<H4><a name="Windows_mingw_msys">3.3.1.2 Building swig.exe using MSYS2</a></H4>
+<H3><a name="Windows_msys2">3.3.2 Building swig.exe using MSYS2</a></H3>
<p>
@@ -311,7 +317,7 @@ Install the packages needed to build swig:<br>
<div class="shell">
<pre>
-pacman -S git autoconf automake bison gcc make pcre-devel
+pacman -S git autoconf automake bison gcc make pcre2-devel
</pre>
</div>
@@ -350,7 +356,7 @@ make install
</pre>
</div>
-<H4><a name="Windows_mingw_msys">3.3.1.3 Building swig.exe using MinGW and MSYS</a></H4>
+<H3><a name="Windows_mingw_msys">3.3.3 Building swig.exe using MinGW and MSYS</a></H3>
<p>
@@ -358,13 +364,13 @@ The short abbreviated instructions follow...
</p>
<ul>
- <li>Install MinGW and MSYS from the <a href="http://www.mingw.org">MinGW</a> site. This provides a Unix environment on Windows.
+ <li>Install MinGW and MSYS from the <a href="https://osdn.net/projects/mingw/">MinGW</a> site. This provides a Unix environment on Windows.
<li>Follow the usual Unix instructions in the README file in the SWIG root directory to build swig.exe from the MinGW command prompt.
</ul>
<p>
The step by step instructions to download and install MinGW and MSYS, then download and build the latest version of SWIG from Github follow...
-Note that the instructions for obtaining SWIG from Github are also online at <a href="http://www.swig.org/svn.html">SWIG Bleeding Edge</a>.
+Note that the instructions for obtaining SWIG from Github are also online at <a href="https://www.swig.org/svn.html">SWIG Bleeding Edge</a>.
</p>
<p>
@@ -374,8 +380,7 @@ Execute the steps in the order shown and don't use spaces in path names. In fact
<ol>
<li>
- Download the following packages from the <a href="http://www.mingw.org/download.shtml">MinGW download page</a>
- or <a href="https://sourceforge.net/projects/mingw/files/">MinGW SourceForge download page</a>.
+ Download the following packages from the <a href="https://osdn.net/projects/mingw/releases/">MinGW download page</a>.
Note that at the time of writing, the majority of these are in the Current
release list and some are in the Snapshot or Previous release list.
<ul>
@@ -445,10 +450,10 @@ the autotools will fail miserably on those.
</li>
<li>
-The PCRE third party library needs to be built next.
-Download the latest PCRE source tarball, such as <tt>pcre-8.10.tar.bz2</tt>, from
-<a href=http://www.pcre.org>PCRE</a> and place in the <tt>/usr/src/swig</tt> directory.
-Build PCRE as a static library using the Tools/pcre-build.sh script as follows:
+The PCRE2 third party library needs to be built next.
+Download the latest PCRE2 source tarball, such as <tt>pcre2-10.39.tar.bz2</tt>, from
+<a href=https://www.pcre.org>www.pcre.org</a> and place in the <tt>/usr/src/swig</tt> directory.
+Build PCRE2 as a static library using the Tools/pcre-build.sh script as follows:
<div class="shell"><pre>
cd /usr/src/swig
@@ -468,7 +473,7 @@ make
</ol>
-<H4><a name="Windows_cygwin">3.3.1.4 Building swig.exe using Cygwin</a></H4>
+<H3><a name="Windows_cygwin">3.3.4 Building swig.exe using Cygwin</a></H3>
<p>
@@ -480,7 +485,7 @@ These files are generated using the <tt>autogen.sh</tt> script and will only nee
</p>
-<H3><a name="Windows_examples_cygwin">3.3.2 Running the examples on Windows using Cygwin</a></H3>
+<H4><a name="Windows_examples_cygwin">3.3.4.1 Running the examples on Windows using Cygwin</a></H4>
<p>
diff --git a/Doc/Manual/makechap.py b/Doc/Manual/makechap.py
index e30d14e0f..9c43f6ac5 100644
--- a/Doc/Manual/makechap.py
+++ b/Doc/Manual/makechap.py
@@ -11,10 +11,8 @@
# then change the heading link name to something that does not look like an
# autogenerated link name.
###############################################################################
-
import sys
import re
-import string
###############################################################################
# Functions
@@ -58,11 +56,11 @@ def getheadingtext(m, s):
###############################################################################
if len(sys.argv) != 3:
- print "usage: makechap.py filename num"
+ print("usage: makechap.py filename num")
sys.exit(1)
filename = sys.argv[1]
-filenamebase = string.split(filename,".")[0]
+filenamebase = filename.split(".")[0]
num = int(sys.argv[2])
section = 0
@@ -223,6 +221,6 @@ open(filename,"w").write(data)
# Print the TOC data to stdout correcting the anchor links for external referencing
index = index.replace("<li><a href=\"#","<li><a href=\"%s#" % filename)
-print """<h3><a href="%s#%s">%d %s</a></h3>\n""" % (filename,filenamebase,num,name)
-print index
+print("""<h3><a href="%s#%s">%d %s</a></h3>\n""" % (filename,filenamebase,num,name))
+print(index)
diff --git a/Doc/Manual/maketoc.py b/Doc/Manual/maketoc.py
index dc8626434..8322e3767 100644
--- a/Doc/Manual/maketoc.py
+++ b/Doc/Manual/maketoc.py
@@ -5,7 +5,7 @@ import os
chs = open("chapters").readlines()
f = open("Contents.html","w")
-print >>f, """
+f.write("""
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
@@ -17,7 +17,8 @@ print >>f, """
<H1><a name="Contents"></a>SWIG Users Manual</H1>
<p>
-"""
+
+""")
f.close()
@@ -25,15 +26,16 @@ num = 1
for c in chs:
c = c.strip()
- print "Processing %s" % c
+ print("Processing " + c)
if c:
os.system("python makechap.py %s %d >> Contents.html" % (c,num))
num += 1
-
+
f = open("Contents.html","a")
-print >>f, """
+f.write("""
</BODY>
</HTML>
-"""
+
+""")
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index eeb7a25a5..e28e48149 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -46,8 +46,8 @@ TARGET =
CC = @CC@
CXX = @CXX@
CPPFLAGS = $(SRCDIR_INCLUDE)
-CFLAGS = @PLATCFLAGS@
-CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@
+CFLAGS = @PLATCFLAGS@ $(EXTRA_CFLAGS)
+CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ $(EXTRA_CXXFLAGS)
LDFLAGS =
prefix = @prefix@
exec_prefix= @exec_prefix@
@@ -148,354 +148,373 @@ swiginvoke:
$(SWIG) $(SWIGOPT)
##################################################################
-##### Tcl/Tk ######
+##### ANDROID ######
##################################################################
-# Set these to your local copy of Tcl/Tk.
-
-TCLSH = tclsh
-TCL_INCLUDE = @TCLINCLUDE@
-TCL_LIB = @TCLLIB@
-TCL_OPTS = @LIBS@
-TK_OPTS = -ltk -ltcl @LIBS@
-
-# Extra Tcl specific dynamic linking options
-TCL_DLNK = @TCLDYNAMICLINKING@
-TCL_SO = @TCL_SO@
-TCLLDSHARED = @TCLLDSHARED@
-TCLCXXSHARED = @TCLCXXSHARED@
-TCL_SCRIPT = $(SRCDIR)$(RUNME).tcl
-TCL_LINK = @TCLLINK@
-
-# -----------------------------------------------------------
-# Build a new version of the tclsh shell
-# -----------------------------------------------------------
-
-tclsh: $(SRCDIR_SRCS)
- $(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i -o $(ISRCS) $(INTERFACEPATH)
- $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE) \
- $(TCL_LIB) $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET)
-
-tclsh_cpp: $(SRCDIR_SRCS)
- $(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE) \
- $(TCL_LIB) $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET)
+ANDROID = @ANDROID@
+ANDROID_NDK_BUILD = @NDKBUILD@
+ANDROID_ADB = @ADB@
+ANT = @ANT@
+TARGETID = 1
-# -----------------------------------------------------------
-# Build a Tcl dynamic loadable module (you might need to tweak this)
-# -----------------------------------------------------------
+# ----------------------------------------------------------------
+# Build an Android dynamically loadable module (C)
+# ----------------------------------------------------------------
-tcl: $(SRCDIR_SRCS)
- $(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE)
- $(TCLLDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO) $(TCL_LINK)
+android: $(SRCDIR_SRCS)
+ $(ANDROID) $(SILENT_OPTION) update project --target $(TARGETID) --name $(PROJECTNAME) --path .
+ $(SWIG) -java $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH)
+ +$(ANDROID_NDK_BUILD) $(SILENT_PIPE)
+ $(ANT) $(ANT_QUIET) debug
-# -----------------------------------------------------------
-# Build a Tcl7.5 dynamic loadable module for C++
-# -----------------------------------------------------------
+# ----------------------------------------------------------------
+# Build an Android dynamically loadable module (C++)
+# ----------------------------------------------------------------
-tcl_cpp: $(SRCDIR_SRCS)
- $(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE)
- $(TCLCXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO) $(TCL_LINK)
+android_cpp: $(SRCDIR_SRCS)
+ $(ANDROID) $(SILENT_OPTION) update project --target $(TARGETID) --name $(PROJECTNAME) --path .
+ $(SWIG) -java -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cpp $(INTERFACEPATH)
+ +$(ANDROID_NDK_BUILD) $(SILENT_PIPE)
+ $(ANT) $(ANT_QUIET) debug
-# -----------------------------------------------------------------
-# Run Tcl example
-# -----------------------------------------------------------------
+# ----------------------------------------------------------------
+# Android install
+# ----------------------------------------------------------------
-tcl_run:
- $(RUNTOOL) $(TCLSH) $(TCL_SCRIPT) $(RUNPIPE)
+android_install:
+ -$(ANDROID_ADB) uninstall $(PACKAGENAME)
+ $(ANDROID_ADB) install $(INSTALLOPTIONS) bin/$(PROJECTNAME)-debug.apk
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
-tcl_version:
- echo 'puts $$tcl_version;exit 0' | $(TCLSH)
+android_version:
+ $(ANDROID_ADB) version
# -----------------------------------------------------------------
-# Cleaning the Tcl examples
+# Cleaning the Android examples
# -----------------------------------------------------------------
-tcl_clean:
- rm -f *_wrap* *~ .~* mytclsh@EXEEXT@
- rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *$(TCL_SO)
+android_clean:
+ test -n "$(SRCDIR)" && cd $(SRCDIR) ; $(ANT) -q -logfile /dev/null clean
+ rm -f $(INTERFACEDIR)$(TARGET)_wrap.*
+ rm -f `find $(PACKAGEDIR) -name \*.java | grep -v $(PROJECTNAME).java`
+ rm -rf obj
##################################################################
-##### PERL 5 ######
+##### CSHARP ######
##################################################################
-# You need to set this variable to the Perl5 directory containing the
-# files "perl.h", "EXTERN.h" and "XSUB.h". With Perl5.003, it's
-# usually something like /usr/local/lib/perl5/arch-osname/5.003/CORE.
-
-PERL5_INCLUDE= @PERL5EXT@
-
-# Extra Perl specific dynamic linking options
-PERL5_DLNK = @PERL5DYNAMICLINKING@
-PERL5_CCFLAGS = @PERL5CCFLAGS@
-PERL5_CCDLFLAGS = @PERL5CCDLFLAGS@
-PERL5_CCCDLFLAGS = @PERL5CCCDLFLAGS@
-PERL5_LDFLAGS = @PERL5LDFLAGS@
-PERL = @PERL@
-PERL5_LIB = -L$(PERL5_INCLUDE) -l@PERL5LIB@ @LIBS@ $(SYSLIBS)
-PERL5_SCRIPT = $(SRCDIR)$(RUNME).pl
+# Extra CSharp specific dynamic linking options
+CSHARP_DLNK = @CSHARPDYNAMICLINKING@
+CSHARP_LIBPREFIX = @CSHARPLIBRARYPREFIX@
+CSHARPCOMPILER = @CSHARPCOMPILER@
+CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@
+CSHARPCILINTERPRETER_FLAGS = @CSHARPCILINTERPRETER_FLAGS@
+CSHARPCFLAGS = @CSHARPCFLAGS@
+CSHARPFLAGS =
+CSHARPOPTIONS =
+CSHARPSO = @CSHARPSO@
+CSHARP_RUNME = ./$(RUNME).exe
# ----------------------------------------------------------------
-# Build a Perl5 dynamically loadable module (C)
+# Build a CSharp dynamically loadable module (C)
# ----------------------------------------------------------------
-perl5: $(SRCDIR_SRCS)
- $(SWIG) -perl5 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) -c -Dbool=char $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PERL5_CCFLAGS) $(PERL5_CCCDLFLAGS) -I$(PERL5_INCLUDE)
- $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(PERL5_CCDLFLAGS) $(OBJS) $(IOBJS) $(PERL5_LDFLAGS) $(PERL5_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+csharp: $(SRCDIR_SRCS)
+ $(SWIG) -csharp $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(CSHARPCFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
+ $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(CSHARP_DLNK) $(LIBS) -o $(CSHARP_LIBPREFIX)$(TARGET)$(CSHARPSO)
# ----------------------------------------------------------------
-# Build a Perl5 dynamically loadable module (C++)
+# Build a CSharp dynamically loadable module (C++)
# ----------------------------------------------------------------
-perl5_cpp: $(SRCDIR_SRCS)
- $(SWIG) -perl5 -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PERL5_CCFLAGS) $(PERL5_CCCDLFLAGS) -I$(PERL5_INCLUDE)
- $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(PERL5_CCDLFLAGS) $(OBJS) $(IOBJS) $(PERL5_LDFLAGS) $(PERL5_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
-
-# ----------------------------------------------------------------
-# Build a module from existing XS C source code. (ie. from xsubpp).
-# ----------------------------------------------------------------
-perl5_xs: $(SRCDIR_SRCS)
- $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(INCLUDES) -I$(PERL5_INCLUDE)
- $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $(TARGET)$(SO)
+csharp_cpp: $(SRCDIR_SRCS)
+ $(SWIG) -csharp -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(CSHARPCFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
+ $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(CSHARP_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(CSHARP_LIBPREFIX)$(TARGET)$(CSHARPSO)
# ----------------------------------------------------------------
-# Build a statically linked Perl5 executable
+# Compile CSharp files
# ----------------------------------------------------------------
-perl5_static: $(SRCDIR_SRCS)
- $(SWIG) -perl5 -static -lperlmain.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Dbool=char $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET)
+ifneq (,$(SRCDIR))
+SRCDIR_CSHARPSRCS = $(addprefix $(SRCDIR),$(CSHARPSRCS))
+else
+SRCDIR_CSHARPSRCS =
+endif
-perl5_static_cpp: $(SRCDIR_SRCS)
- $(SWIG) -perl5 -c++ -static -lperlmain.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET)
+csharp_compile: $(SRCDIR_SRCS)
+ $(COMPILETOOL) $(CSHARPCOMPILER) $(CSHARPFLAGS) $(CSHARPOPTIONS) $(CSHARPSRCS) $(SRCDIR_CSHARPSRCS)
# -----------------------------------------------------------------
-# Running a Perl5 example
+# Run CSharp example
# -----------------------------------------------------------------
-perl5_run:
- $(RUNTOOL) $(PERL) -I. $(PERL5_SCRIPT) $(RUNPIPE)
+csharp_run:
+ env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(CSHARPCILINTERPRETER) $(CSHARPCILINTERPRETER_FLAGS) $(CSHARP_RUNME) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
-perl5_version:
- $(PERL) -v | grep "This is"
+# Version check below also works with MS csc.exe which does not understand --version
+csharp_version:
+ $(CSHARPCOMPILER) --version | head -n 1
+ if test -n "$(CSHARPCILINTERPRETER)" ; then "$(CSHARPCILINTERPRETER)" --version ; fi
# -----------------------------------------------------------------
-# Cleaning the Perl5 examples
+# Cleaning the CSharp examples
# -----------------------------------------------------------------
-perl5_clean:
- rm -f *_wrap* *~ .~* myperl@EXEEXT@ *.pm
+csharp_clean:
+ rm -f *_wrap* *~ .~* $(RUNME) $(RUNME).exe *.exe.mdb gc.log `find . -name \*.cs | grep -v $(RUNME).cs`
rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *@SO@
+ rm -f *.@OBJEXT@ *@CSHARPSO@
##################################################################
-##### PYTHON ######
+##### D ######
##################################################################
-PYTHON_FLAGS =
-
-# Make sure these locate your Python installation
-ifeq (,$(PY3))
- PYTHON_INCLUDE= $(DEFS) @PYINCLUDE@
- PYTHON_LIB = @PYLIB@
- PYTHON = @PYTHON@ $(PYTHON_FLAGS)
-else
- PYTHON_INCLUDE= $(DEFS) @PY3INCLUDE@
- PYTHON_LIB = @PY3LIB@
- PYTHON = @PYTHON3@ $(PYTHON_FLAGS)
-endif
+DLIBPREFIX = @DLIBPREFIX@
-# Extra Python specific linking options
-ifeq (,$(PY3))
- PYTHON_DLNK = @PYTHONDYNAMICLINKING@
- PYTHON_LINK = @PYLINK@
-else
- PYTHON_DLNK = @PYTHON3DYNAMICLINKING@
- PYTHON_LINK = @PY3LINK@
+ifeq (,$(D_VERSION))
+ D_VERSION = @DDEFAULTVERSION@
endif
-PYTHON_SO = @PYTHON_SO@
-# SWIG option for Python3
-ifeq (,$(PY3))
- SWIGOPTPY3 =
+ifeq (2,$(D_VERSION))
+ SWIGD = $(SWIG) -d -d2
+ DCOMPILER = @D2COMPILER@
else
- SWIGOPTPY3 = -py3
+ SWIGD = $(SWIG) -d
+ DCOMPILER = @D1COMPILER@
endif
-PYCODESTYLE = @PYCODESTYLE@
-PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
+D_RUNME = ./$(RUNME)
# ----------------------------------------------------------------
-# Build a C dynamically loadable module
+# Build a dynamically loadable D wrapper for a C module
# ----------------------------------------------------------------
-python: $(SRCDIR_SRCS)
- $(SWIG) -python $(SWIGOPTPY3) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE)
- $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
-
-# -----------------------------------------------------------------
-# Build a C++ dynamically loadable module
-# -----------------------------------------------------------------
-
-python_cpp: $(SRCDIR_SRCS)
- $(SWIG) -python $(SWIGOPTPY3) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE)
- $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
+d: $(SRCDIR_SRCS)
+ $(SWIGD) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
+ $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
-# -----------------------------------------------------------------
-# Build statically linked Python interpreter
-#
-# These should only be used in conjunction with the %include embed.i
-# library file
-# -----------------------------------------------------------------
+# ----------------------------------------------------------------
+# Build a dynamically loadable D wrapper for a C++ module
+# ----------------------------------------------------------------
-#TKINTER = -L/usr/X11R6.3/lib -L/usr/local/compat/lib -ltk4.0 -ltcl7.4 -lX11
-TKINTER =
-PYTHON_LIBOPTS = $(PYTHON_LINK) @LIBS@ $(TKINTER) $(SYSLIBS)
+d_cpp: $(SRCDIR_SRCS)
+ $(SWIGD) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
+ $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
-python_static: $(SRCDIR_SRCS)
- $(SWIG) -python $(SWIGOPTPY3) -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
- $(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
+# ----------------------------------------------------------------
+# Compile D files
+# ----------------------------------------------------------------
-python_static_cpp: $(SRCDIR_SRCS)
- $(SWIG) -python $(SWIGOPTPY3) -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
- $(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
+# Clear the DFLAGS environment variable for the compiler call itself
+# to work around a discrepancy in argument handling between DMD and LDC.
+d_compile: $(SRCDIR_SRCS)
+ DFLAGS="" $(COMPILETOOL) $(DCOMPILER) $(DFLAGS) $(DSRCS)
# -----------------------------------------------------------------
-# Running a Python example
+# Run D example
# -----------------------------------------------------------------
-PYSCRIPT = $(RUNME).py
-
-python_run: $(PYSCRIPT)
-ifneq (,$(PYCODESTYLE))
- $(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(PYSCRIPT)
-endif
- env PYTHONPATH=$$PWD $(RUNTOOL) $(PYTHON) $(PYSCRIPT) $(RUNPIPE)
-
-ifneq (,$(SRCDIR))
-$(RUNME).py: $(SRCDIR)$(RUNME).py
- cp $< $@
-endif
+d_run:
+ env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(D_RUNME) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
-python_version:
- $(PYTHON) -V
+d_version:
+ ($(DCOMPILER) --version 2> /dev/null || $(DCOMPILER)) | head -n 3
# -----------------------------------------------------------------
-# Cleaning the python examples
+# Clean the D examples
# -----------------------------------------------------------------
-python_clean:
- rm -rf __pycache__
- rm -f *_wrap* *~ .~* mypython@EXEEXT@ *.pyc
+d_clean:
+ rm -f *_wrap* *~ .~* $(RUNME) $(RUNME).exe `find . -name \*.d | grep -v $(RUNME).d`
rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *@SO@ *$(PYTHON_SO)
- rm -f $(TARGET).py
- case "x$(SRCDIR)" in x|x./);; *) rm -f $(RUNME).py;; esac
-
+ rm -f *.@OBJEXT@ *@SO@
##################################################################
-##### OCTAVE ######
+##### Go ######
##################################################################
-# Make sure these locate your Octave installation
-OCTAVE = @OCTAVE@
-OCTAVE_CXX = $(DEFS) @OCTAVE_CPPFLAGS@ @OCTAVE_CXXFLAGS@
+# TODO: The Go make targets need simplifying to use configure time
+# configuration or to use Make's ifeq rather than using lots of
+# runtime shell code. The output will then be a lot less verbose.
-# Extra Octave specific dynamic linking options
-OCTAVE_DLNK = @OCTAVE_LDFLAGS@
-OCTAVE_SO = @OCTAVE_SO@
+GO = @GO@
+GOGCC = @GOGCC@
+GCCGO = @GCCGO@
+GOOPT = @GOOPT@
+GCCGOOPT = @GCCGOOPT@
+GOVERSIONOPTION = @GOVERSIONOPTION@
-OCTAVE_SCRIPT = $(SRCDIR)$(RUNME).m
+GOSWIGARG = `if $(GOGCC) ; then echo -gccgo; fi`
-# ----------------------------------------------------------------
-# Pre-compile Octave headers, if supported
-# ----------------------------------------------------------------
+GOSRCS = $(INTERFACE:.i=.go)
+GOCSRCS = $(INTERFACE:.i=_gc.c)
-ifeq (yes,$(PCHSUPPORT))
+GOPACKAGE = $(notdir $(INTERFACE:.i=.a))
-octave_precompile_headers:
- echo "precompiling $(OCTHEADERS)"
- cp -f $(OCTHEADERSSRC) $(OCTHEADERS)
- if $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(OCTAVE_CXX) $(OCTHEADERS); then \
- : ; \
- else \
- rm -f $(OCTHEADERSGCH); \
- exit 1; \
- fi
+GOPATHPARENTDIR = gopath/$(GOMOD)/src
+GOPATHDIR = $(GOPATHPARENTDIR)/$(INTERFACE:.i=)
-else
+# ----------------------------------------------------------------
+# Build a Go module (C)
+# ----------------------------------------------------------------
-octave_precompile_headers:
- echo "precompiling Octave headers not supported"; exit 1
+$(GOPATHPARENTDIR)/go.mod:
+ @mkdir gopath 2>/dev/null || true
+ @mkdir gopath/$(GOMOD) 2>/dev/null || true
+ @mkdir gopath/$(GOMOD)/src 2>/dev/null || true
+ @mkdir $(GOPATHDIR) 2>/dev/null || true
+ echo "module swigtests" > $(GOPATHDIR)/go.mod
+ echo "" >> $(GOPATHDIR)/go.mod
+ echo "go 1.12" >> $(GOPATHDIR)/go.mod
+ mv -f $(GOPATHDIR)/go.mod $(GOPATHPARENTDIR)/go.mod
-endif
+go: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
+ $(SWIG) -go -import-prefix swigtests $(GOOPT) $(GOSWIGARG) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ @mkdir gopath 2>/dev/null || true
+ @mkdir gopath/$(GOMOD) 2>/dev/null || true
+ @mkdir gopath/$(GOMOD)/src 2>/dev/null || true
+ @mkdir $(GOPATHDIR) 2>/dev/null || true
+ rm -rf $(GOPATHDIR)/*
+ cp $(ISRCS) $(GOPATHDIR)/
+ if test -f $(IWRAP:.i=.h); then \
+ cp $(IWRAP:.i=.h) $(GOPATHDIR)/; \
+ fi
+ if test -n "$(SRCDIR_SRCS)"; then \
+ cp $(SRCDIR_SRCS) $(GOPATHDIR)/; \
+ fi
+ cp $(GOSRCS) $(GOPATHDIR)/
+ @if test -f $(SRCDIR)$(RUNME).go; then \
+ mkdir gopath/$(GOMOD)/src/runme 2>/dev/null || true; \
+ rm -f gopath/$(GOMOD)/src/runme/*; \
+ fi
+ if test -f $(SRCDIR)$(RUNME).go; then \
+ cp $(SRCDIR)$(RUNME).go gopath/$(GOMOD)/src/runme/; \
+ fi
+ GOPATH=`pwd`/gopath/$(GOMOD); \
+ export GOPATH; \
+ CGO_CPPFLAGS="$(CPPFLAGS) $(INCLUDES) -I `cd $(SRCDIR) && pwd` -I `pwd`"; \
+ export CGO_CPPFLAGS; \
+ CGO_CFLAGS="$(CFLAGS)"; \
+ export CGO_CFLAGS; \
+ CGO_LDFLAGS="$(LDFLAGS) -lm"; \
+ export CGO_LDFLAGS; \
+ (cd $(GOPATHDIR)/ && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
+ stat=$$?; \
+ if test $$stat != 0; then \
+ exit $$stat; \
+ fi; \
+ if $(GOGCC); then \
+ cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
+ fi; \
+ if test -f $(SRCDIR)$(RUNME).go; then \
+ mkdir gopath/$(GOMOD)/src/swigtests 2>/dev/null || true; \
+ mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
+ cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
+ (cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
+ stat=$$?; \
+ if test $$stat != 0; then \
+ exit $$stat; \
+ fi; \
+ cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
+ fi
# ----------------------------------------------------------------
-# Build a C dynamically loadable module
-# Note: Octave requires C++ compiler when compiling C wrappers
+# Build a Go module (C++)
# ----------------------------------------------------------------
-octave: $(SRCDIR_SRCS)
- $(SWIG) -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
- $(CC) -g -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CSRCS) $(INCLUDES)
- $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
-
-# -----------------------------------------------------------------
-# Build a C++ dynamically loadable module
-# -----------------------------------------------------------------
-
-octave_cpp: $(SRCDIR_SRCS)
- $(SWIG) -c++ -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
- $(CXXSHARED) -g $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
+go_cpp: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
+ $(SWIG) -go -c++ -import-prefix swigtests $(GOOPT) $(GOSWIGARG) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ @mkdir gopath 2>/dev/null || true
+ @mkdir gopath/$(GOMOD) 2>/dev/null || true
+ @mkdir gopath/$(GOMOD)/src 2>/dev/null || true
+ @mkdir $(GOPATHDIR) 2>/dev/null || true
+ rm -rf $(GOPATHDIR)/*
+ cp $(ICXXSRCS) $(GOPATHDIR)/
+ if test -f $(IWRAP:.i=.h); then \
+ cp $(IWRAP:.i=.h) $(GOPATHDIR)/; \
+ fi
+ if test -n "$(SRCDIR_CXXSRCS)"; then \
+ cp $(SRCDIR_CXXSRCS) $(GOPATHDIR)/; \
+ fi
+ if test -n "$(SRCDIR_SRCS)"; then \
+ cp $(SRCDIR_SRCS) $(GOPATHDIR)/; \
+ fi
+ cp $(GOSRCS) $(GOPATHDIR)/
+ @if test -f $(SRCDIR)$(RUNME).go; then \
+ mkdir gopath/$(GOMOD)/src/runme 2>/dev/null || true; \
+ rm -f gopath/$(GOMOD)/src/runme/*; \
+ fi
+ if test -f $(SRCDIR)$(RUNME).go; then \
+ cp $(SRCDIR)$(RUNME).go gopath/$(GOMOD)/src/runme/; \
+ fi
+ GOPATH=`pwd`/gopath/$(GOMOD); \
+ export GOPATH; \
+ CGO_CPPFLAGS="$(CPPFLAGS) $(INCLUDES) -I `cd $(SRCDIR) && pwd` -I `pwd`"; \
+ export CGO_CPPFLAGS; \
+ CGO_CFLAGS="$(CFLAGS)"; \
+ export CGO_CFLAGS; \
+ CGO_CXXFLAGS="$(CXXFLAGS)"; \
+ export CGO_CXXFLAGS; \
+ CGO_LDFLAGS="$(LDFLAGS) -lm"; \
+ export CGO_LDFLAGS; \
+ (cd $(GOPATHDIR) && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
+ stat=$$?; \
+ if test $$stat != 0; then \
+ exit $$stat; \
+ fi; \
+ if $(GOGCC); then \
+ cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
+ fi; \
+ if test -f $(SRCDIR)$(RUNME).go; then \
+ mkdir gopath/$(GOMOD)/src/swigtests 2>/dev/null || true; \
+ mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
+ cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
+ (cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
+ stat=$$?; \
+ if test $$stat != 0; then \
+ exit $$stat; \
+ fi; \
+ cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
+ fi
# -----------------------------------------------------------------
-# Running an Octave example
+# Running Go example
# -----------------------------------------------------------------
-octave_run:
- env OCTAVE_PATH= OCTAVE_HISTFILE=/dev/null $(RUNTOOL) $(OCTAVE) $(OCTAVE_SCRIPT) $(RUNPIPE)
+go_run:
+ env $(RUNTOOL) ./$(RUNME) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
-octave_version:
- $(OCTAVE) --version | head -n 1
+go_version:
+ $(GO) $(GOVERSIONOPTION)
# -----------------------------------------------------------------
-# Cleaning the Octave examples
+# Cleaning the Go examples
# -----------------------------------------------------------------
-octave_clean:
- rm -rf __pycache__
- rm -f *_wrap* *~ .~* myoctave@EXEEXT@ *.pyc
+go_clean:
+ rm -f *_wrap* *_gc* *.gox .~* $(RUNME) $(GOSRCS)
+ rm -rf gopath
rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *@SO@ *$(OCTAVE_SO)
- rm -f $(OCTHEADERS) $(OCTHEADERSGCH)
+ rm -f *.@OBJEXT@ *.[568] *.a *@SO@
##################################################################
##### GUILE ######
@@ -744,9 +763,9 @@ ifeq (node, $(ENGINE))
endif
ifeq (jsc, $(ENGINE))
@if [ "@JSCOREVERSION@" != "" ]; then \
- echo "@JSCOREVERSION@"; \
+ echo "JavaScriptCore: @JSCOREVERSION@"; \
else \
- echo "Unknown JavascriptCore version."; \
+ echo "Unknown JavaScriptCore version."; \
fi
endif
ifeq (v8, $(ENGINE))
@@ -766,59 +785,86 @@ javascript_clean:
cd $(ROOT_DIR)/Tools/javascript && $(MAKE) -s clean
##################################################################
-##### ANDROID ######
+##### LUA ######
##################################################################
-ANDROID = @ANDROID@
-ANDROID_NDK_BUILD = @NDKBUILD@
-ANDROID_ADB = @ADB@
-ANT = @ANT@
-TARGETID = 1
+# lua flags
+LUA_INCLUDE= @LUAFLAGS@
+LUA_LIB = @LUALINK@
-# ----------------------------------------------------------------
-# Build an Android dynamically loadable module (C)
-# ----------------------------------------------------------------
+# Extra specific dynamic linking options
+LUA_DLNK = @LUADYNAMICLINKING@
+LUA_SO = @LUA_SO@
-android: $(SRCDIR_SRCS)
- $(ANDROID) $(SILENT_OPTION) update project --target $(TARGETID) --name $(PROJECTNAME) --path .
- $(SWIG) -java $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH)
- +$(ANDROID_NDK_BUILD) $(SILENT_PIPE)
- $(ANT) $(ANT_QUIET) debug
+LUA = @LUABIN@
+LUA_SCRIPT = $(SRCDIR)$(RUNME).lua
+
+# Extra code for lua static link
+LUA_INTERP = ../lua.c
# ----------------------------------------------------------------
-# Build an Android dynamically loadable module (C++)
+# Build a C dynamically loadable module
# ----------------------------------------------------------------
-android_cpp: $(SRCDIR_SRCS)
- $(ANDROID) $(SILENT_OPTION) update project --target $(TARGETID) --name $(PROJECTNAME) --path .
- $(SWIG) -java -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cpp $(INTERFACEPATH)
- +$(ANDROID_NDK_BUILD) $(SILENT_PIPE)
- $(ANT) $(ANT_QUIET) debug
+lua: $(SRCDIR_SRCS)
+ $(SWIG) -lua $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(LUA_INCLUDE)
+ $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(LUA_LIB) -o $(LIBPREFIX)$(TARGET)$(LUA_SO)
-# ----------------------------------------------------------------
-# Android install
-# ----------------------------------------------------------------
+# -----------------------------------------------------------------
+# Build a C++ dynamically loadable module
+# -----------------------------------------------------------------
-android_install:
- -$(ANDROID_ADB) uninstall $(PACKAGENAME)
- $(ANDROID_ADB) install $(INSTALLOPTIONS) bin/$(PROJECTNAME)-debug.apk
+lua_cpp: $(SRCDIR_SRCS) $(GENCXXSRCS)
+ $(SWIG) -c++ -lua $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(GENCXXSRCS) $(INCLUDES) $(LUA_INCLUDE)
+ $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(LUA_LIB) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(LUA_SO)
+
+lua_externalhdr:
+ $(SWIG) -lua -external-runtime $(TARGET)
+
+lua_swig_cpp:
+ $(SWIG) -c++ -lua $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+
+# -----------------------------------------------------------------
+# Build statically linked Lua interpreter
+# -----------------------------------------------------------------
+
+lua_static: $(SRCDIR_SRCS)
+ $(SWIG) -lua -module example $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(SRCDIR)$(LUA_INTERP) $(INCLUDES) \
+ $(LUA_INCLUDE) $(LIBS) $(LUA_LIB) -o $(TARGET)
+
+lua_static_cpp: $(SRCDIR_SRCS) $(GENCXXSRCS)
+ $(SWIG) -c++ -lua -module example $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(GENCXXSRCS) $(SRCDIR)$(LUA_INTERP) $(INCLUDES) \
+ $(LUA_INCLUDE) $(LIBS) $(LUA_LIB) -o $(TARGET)
+
+# -----------------------------------------------------------------
+# Run Lua example
+# -----------------------------------------------------------------
+
+lua_run:
+ $(RUNTOOL) $(LUA) $(LUA_SCRIPT) $(RUNPIPE)
+
+lua_embed_run:
+ $(RUNTOOL) ./$(TARGET) $(LUA_SCRIPT) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
-android_version:
- $(ANDROID_ADB) version
+lua_version:
+ $(LUA) -v | head -n 1
# -----------------------------------------------------------------
-# Cleaning the Android examples
+# Cleaning the lua examples
# -----------------------------------------------------------------
-android_clean:
- test -n "$(SRCDIR)" && cd $(SRCDIR) ; $(ANT) -q -logfile /dev/null clean
- rm -f $(INTERFACEDIR)$(TARGET)_wrap.*
- rm -f `find $(PACKAGEDIR) -name \*.java | grep -v $(PROJECTNAME).java`
- rm -rf obj
+lua_clean:
+ rm -f *_wrap* *~ .~* mylua@EXEEXT@
+ rm -f core @EXTRA_CLEAN@
+ rm -f *.@OBJEXT@ *$(LUA_SO)
##################################################################
##### MZSCHEME ######
@@ -869,7 +915,7 @@ mzscheme_clean:
rm -f *.@OBJEXT@ *$(MZSCHEME_SO)
##################################################################
-##### Ocaml #####
+##### OCAML ######
##################################################################
OCC=$(COMPILETOOL) @OCAMLC@
@@ -973,77 +1019,166 @@ ocaml_clean:
rm -rf ./localtmp
##################################################################
-##### RUBY ######
+##### OCTAVE ######
##################################################################
-# Make sure these locate your Ruby installation
-RUBY_CFLAGS= @RUBYCCDLFLAGS@ $(DEFS)
-RUBY_INCLUDE= @RUBYINCLUDE@
-RUBY_LIB = @RUBYLIB@
-RUBY_DLNK = @RUBYDYNAMICLINKING@
-RUBY_LIBOPTS = @RUBYLINK@ @LIBS@ $(SYSLIBS)
-RUBY_SO = @RUBYSO@
-RUBY = @RUBY@
-RUBY_SCRIPT = $(SRCDIR)$(RUNME).rb
+# Make sure these locate your Octave installation
+OCTAVE = @OCTAVE@
+OCTAVE_CXX = $(DEFS) @OCTAVE_CPPFLAGS@ @OCTAVE_CXXFLAGS@
+
+# Extra Octave specific dynamic linking options
+OCTAVE_DLNK = @OCTAVE_LDFLAGS@
+OCTAVE_SO = @OCTAVE_SO@
+OCTAVE_SCRIPT = $(SRCDIR)$(RUNME).m
+
+# ----------------------------------------------------------------
+# Pre-compile Octave headers, if supported
+# ----------------------------------------------------------------
+
+ifeq (yes,$(PCHSUPPORT))
+
+octave_precompile_headers:
+ echo "precompiling $(OCTHEADERS)"
+ cp -f $(OCTHEADERSSRC) $(OCTHEADERS)
+ if $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(OCTAVE_CXX) $(OCTHEADERS); then \
+ : ; \
+ else \
+ rm -f $(OCTHEADERSGCH); \
+ exit 1; \
+ fi
+
+else
+
+octave_precompile_headers:
+ echo "precompiling Octave headers not supported"; exit 1
+
+endif
# ----------------------------------------------------------------
# Build a C dynamically loadable module
+# Note: Octave requires C++ compiler when compiling C wrappers
# ----------------------------------------------------------------
-ruby: $(SRCDIR_SRCS)
- $(SWIG) -ruby $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(RUBY_CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(RUBY_INCLUDE)
- $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(RUBY_SO)
+octave: $(SRCDIR_SRCS)
+ $(SWIG) -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
+ $(CC) -g -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CSRCS) $(INCLUDES)
+ $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
# -----------------------------------------------------------------
# Build a C++ dynamically loadable module
# -----------------------------------------------------------------
-ruby_cpp: $(SRCDIR_SRCS)
- $(SWIG) -c++ -ruby $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(RUBY_INCLUDE)
- $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(RUBY_SO)
+octave_cpp: $(SRCDIR_SRCS)
+ $(SWIG) -c++ -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
+ $(CXXSHARED) -g $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
# -----------------------------------------------------------------
-# Build statically linked Ruby interpreter
-#
-# These should only be used in conjunction with the %include embed.i
-# library file
+# Running an Octave example
# -----------------------------------------------------------------
-ruby_static: $(SRCDIR_SRCS)
- $(SWIG) -ruby -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(RUBY_CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
- $(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
+octave_run:
+ env OCTAVE_PATH= OCTAVE_HISTFILE=/dev/null $(RUNTOOL) $(OCTAVE) $(OCTAVE_SCRIPT) $(RUNPIPE)
-ruby_cpp_static: $(SRCDIR_SRCS)
- $(SWIG) -c++ -ruby -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
- $(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
+# -----------------------------------------------------------------
+# Version display
+# -----------------------------------------------------------------
+
+octave_version:
+ $(OCTAVE) --version | head -n 1
# -----------------------------------------------------------------
-# Run Ruby example
+# Cleaning the Octave examples
# -----------------------------------------------------------------
-ruby_run:
- $(RUNTOOL) $(RUBY) $(RUBYFLAGS) -I. $(RUBY_SCRIPT) $(RUNPIPE)
+octave_clean:
+ rm -rf __pycache__
+ rm -f *_wrap* *~ .~* myoctave@EXEEXT@ *.pyc
+ rm -f core @EXTRA_CLEAN@
+ rm -f *.@OBJEXT@ *@SO@ *$(OCTAVE_SO)
+ rm -f $(OCTHEADERS) $(OCTHEADERSGCH)
+
+##################################################################
+##### PERL 5 ######
+##################################################################
+
+# You need to set this variable to the Perl5 directory containing the
+# files "perl.h", "EXTERN.h" and "XSUB.h". With Perl5.003, it's
+# usually something like /usr/local/lib/perl5/arch-osname/5.003/CORE.
+
+PERL5_INCLUDE= @PERL5EXT@
+
+# Extra Perl specific dynamic linking options
+PERL5_DLNK = @PERL5DYNAMICLINKING@
+PERL5_CCFLAGS = @PERL5CCFLAGS@
+PERL5_CCDLFLAGS = @PERL5CCDLFLAGS@
+PERL5_CCCDLFLAGS = @PERL5CCCDLFLAGS@
+PERL5_LDFLAGS = @PERL5LDFLAGS@
+PERL = @PERL@
+PERL5_LIB = -L$(PERL5_INCLUDE) -l@PERL5LIB@ @LIBS@ $(SYSLIBS)
+PERL5_SCRIPT = $(SRCDIR)$(RUNME).pl
+
+# ----------------------------------------------------------------
+# Build a Perl5 dynamically loadable module (C)
+# ----------------------------------------------------------------
+
+perl5: $(SRCDIR_SRCS)
+ $(SWIG) -perl5 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) -c -Dbool=char $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PERL5_CCFLAGS) $(PERL5_CCCDLFLAGS) -I$(PERL5_INCLUDE)
+ $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(PERL5_CCDLFLAGS) $(OBJS) $(IOBJS) $(PERL5_LDFLAGS) $(PERL5_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+
+# ----------------------------------------------------------------
+# Build a Perl5 dynamically loadable module (C++)
+# ----------------------------------------------------------------
+
+perl5_cpp: $(SRCDIR_SRCS)
+ $(SWIG) -perl5 -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PERL5_CCFLAGS) $(PERL5_CCCDLFLAGS) -I$(PERL5_INCLUDE)
+ $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(PERL5_CCDLFLAGS) $(OBJS) $(IOBJS) $(PERL5_LDFLAGS) $(PERL5_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+
+# ----------------------------------------------------------------
+# Build a module from existing XS C source code. (ie. from xsubpp).
+# ----------------------------------------------------------------
+perl5_xs: $(SRCDIR_SRCS)
+ $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(INCLUDES) -I$(PERL5_INCLUDE)
+ $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $(TARGET)$(SO)
+
+# ----------------------------------------------------------------
+# Build a statically linked Perl5 executable
+# ----------------------------------------------------------------
+
+perl5_static: $(SRCDIR_SRCS)
+ $(SWIG) -perl5 -static -lperlmain.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Dbool=char $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET)
+
+perl5_static_cpp: $(SRCDIR_SRCS)
+ $(SWIG) -perl5 -c++ -static -lperlmain.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET)
+
+# -----------------------------------------------------------------
+# Running a Perl5 example
+# -----------------------------------------------------------------
+
+perl5_run:
+ $(RUNTOOL) $(PERL) -I. $(PERL5_SCRIPT) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
-ruby_version:
- $(RUBY) -v
+perl5_version:
+ $(PERL) -v | grep "This is"
# -----------------------------------------------------------------
-# Cleaning the Ruby examples
+# Cleaning the Perl5 examples
# -----------------------------------------------------------------
-ruby_clean:
- rm -f *_wrap* *~ .~* myruby@EXEEXT@
+perl5_clean:
+ rm -f *_wrap* *~ .~* myperl@EXEEXT@ *.pm
rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *$(RUBY_SO)
+ rm -f *.@OBJEXT@ *@SO@
##################################################################
##### PHP ######
@@ -1078,7 +1213,7 @@ php_cpp: $(SRCDIR_SRCS)
# -----------------------------------------------------------------
php_run:
- $(RUNTOOL) $(PHP) -n -d extension_dir=. -d extension=$(PHP_EXTENSION) -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});include($$argv[1]);' $(PHP_SCRIPT) $(RUNPIPE)
+ $(RUNTOOL) $(PHP) -n -d extension_dir=. -d extension=$(PHP_EXTENSION) -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});if(strlen($$argv[1]))include($$argv[1]);' '$(PHP_SCRIPT)' $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
@@ -1097,201 +1232,112 @@ php_clean:
rm -f *.@OBJEXT@ *$(PHP_SO)
##################################################################
-##### CSHARP ######
+##### PYTHON ######
##################################################################
-# Extra CSharp specific dynamic linking options
-CSHARP_DLNK = @CSHARPDYNAMICLINKING@
-CSHARP_LIBPREFIX = @CSHARPLIBRARYPREFIX@
-CSHARPCOMPILER = @CSHARPCOMPILER@
-CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@
-CSHARPCILINTERPRETER_FLAGS = @CSHARPCILINTERPRETER_FLAGS@
-CSHARPCFLAGS = @CSHARPCFLAGS@
-CSHARPFLAGS =
-CSHARPOPTIONS =
-CSHARPSO = @CSHARPSO@
-CSHARP_RUNME = ./$(RUNME).exe
-
-# ----------------------------------------------------------------
-# Build a CSharp dynamically loadable module (C)
-# ----------------------------------------------------------------
-
-csharp: $(SRCDIR_SRCS)
- $(SWIG) -csharp $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(CSHARPCFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
- $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(CSHARP_DLNK) $(LIBS) -o $(CSHARP_LIBPREFIX)$(TARGET)$(CSHARPSO)
-
-# ----------------------------------------------------------------
-# Build a CSharp dynamically loadable module (C++)
-# ----------------------------------------------------------------
-
-csharp_cpp: $(SRCDIR_SRCS)
- $(SWIG) -csharp -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(CSHARPCFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
- $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(CSHARP_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(CSHARP_LIBPREFIX)$(TARGET)$(CSHARPSO)
-
-# ----------------------------------------------------------------
-# Compile CSharp files
-# ----------------------------------------------------------------
+PYTHON_FLAGS =
-ifneq (,$(SRCDIR))
-SRCDIR_CSHARPSRCS = $(addprefix $(SRCDIR),$(CSHARPSRCS))
+# Make sure these locate your Python installation
+ifneq (,$(PY2))
+ PYTHON_INCLUDE= $(DEFS) @PYINCLUDE@
+ PYTHON_LIB = @PYLIB@
+ PYTHON = @PYTHON@ $(PYTHON_FLAGS)
else
-SRCDIR_CSHARPSRCS =
+ PYTHON_INCLUDE= $(DEFS) @PY3INCLUDE@
+ PYTHON_LIB = @PY3LIB@
+ PYTHON = @PYTHON3@ $(PYTHON_FLAGS)
endif
-csharp_compile: $(SRCDIR_SRCS)
- $(COMPILETOOL) $(CSHARPCOMPILER) $(CSHARPFLAGS) $(CSHARPOPTIONS) $(CSHARPSRCS) $(SRCDIR_CSHARPSRCS)
-
-# -----------------------------------------------------------------
-# Run CSharp example
-# -----------------------------------------------------------------
-
-csharp_run:
- env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(CSHARPCILINTERPRETER) $(CSHARPCILINTERPRETER_FLAGS) $(CSHARP_RUNME) $(RUNPIPE)
-
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
-
-# Version check below also works with MS csc.exe which does not understand --version
-csharp_version:
- $(CSHARPCOMPILER) --version | head -n 1
- if test -n "$(CSHARPCILINTERPRETER)" ; then "$(CSHARPCILINTERPRETER)" --version ; fi
-
-# -----------------------------------------------------------------
-# Cleaning the CSharp examples
-# -----------------------------------------------------------------
-
-csharp_clean:
- rm -f *_wrap* *~ .~* $(RUNME) $(RUNME).exe *.exe.mdb gc.log `find . -name \*.cs | grep -v $(RUNME).cs`
- rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *@CSHARPSO@
-
-##################################################################
-##### LUA ######
-##################################################################
-
-# lua flags
-LUA_INCLUDE= @LUAFLAGS@
-LUA_LIB = @LUALINK@
-
-# Extra specific dynamic linking options
-LUA_DLNK = @LUADYNAMICLINKING@
-LUA_SO = @LUA_SO@
-
-LUA = @LUABIN@
-LUA_SCRIPT = $(SRCDIR)$(RUNME).lua
+# Extra Python specific linking options
+ifneq (,$(PY2))
+ PYTHON_DLNK = @PYTHONDYNAMICLINKING@
+ PYTHON_LINK = @PYLINK@
+else
+ PYTHON_DLNK = @PYTHON3DYNAMICLINKING@
+ PYTHON_LINK = @PY3LINK@
+endif
+PYTHON_SO = @PYTHON_SO@
-# Extra code for lua static link
-LUA_INTERP = ../lua.c
+PYCODESTYLE = @PYCODESTYLE@
+PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
# ----------------------------------------------------------------
# Build a C dynamically loadable module
# ----------------------------------------------------------------
-lua: $(SRCDIR_SRCS)
- $(SWIG) -lua $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(LUA_INCLUDE)
- $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(LUA_LIB) -o $(LIBPREFIX)$(TARGET)$(LUA_SO)
+python: $(SRCDIR_SRCS)
+ $(SWIG) -python $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE)
+ $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
# -----------------------------------------------------------------
# Build a C++ dynamically loadable module
# -----------------------------------------------------------------
-lua_cpp: $(SRCDIR_SRCS) $(GENCXXSRCS)
- $(SWIG) -c++ -lua $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(GENCXXSRCS) $(INCLUDES) $(LUA_INCLUDE)
- $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(LUA_LIB) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(LUA_SO)
-
-lua_externalhdr:
- $(SWIG) -lua -external-runtime $(TARGET)
-
-lua_swig_cpp:
- $(SWIG) -c++ -lua $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-
-# -----------------------------------------------------------------
-# Build statically linked Lua interpreter
-# -----------------------------------------------------------------
-
-lua_static: $(SRCDIR_SRCS)
- $(SWIG) -lua -module example $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(SRCDIR)$(LUA_INTERP) $(INCLUDES) \
- $(LUA_INCLUDE) $(LIBS) $(LUA_LIB) -o $(TARGET)
-
-lua_static_cpp: $(SRCDIR_SRCS) $(GENCXXSRCS)
- $(SWIG) -c++ -lua -module example $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(GENCXXSRCS) $(SRCDIR)$(LUA_INTERP) $(INCLUDES) \
- $(LUA_INCLUDE) $(LIBS) $(LUA_LIB) -o $(TARGET)
+python_cpp: $(SRCDIR_SRCS)
+ $(SWIG) -python -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE)
+ $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
# -----------------------------------------------------------------
-# Run Lua example
+# Build statically linked Python interpreter
+#
+# These should only be used in conjunction with the %include embed.i
+# library file
# -----------------------------------------------------------------
-lua_run:
- $(RUNTOOL) $(LUA) $(LUA_SCRIPT) $(RUNPIPE)
-
-lua_embed_run:
- $(RUNTOOL) ./$(TARGET) $(LUA_SCRIPT) $(RUNPIPE)
+#TKINTER = -L/usr/X11R6.3/lib -L/usr/local/compat/lib -ltk4.0 -ltcl7.4 -lX11
+TKINTER =
+PYTHON_LIBOPTS = $(PYTHON_LINK) @LIBS@ $(TKINTER) $(SYSLIBS)
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
+python_static: $(SRCDIR_SRCS)
+ $(SWIG) -python -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
+ $(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
-lua_version:
- $(LUA) -v | head -n 1
+python_static_cpp: $(SRCDIR_SRCS)
+ $(SWIG) -python -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
+ $(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
# -----------------------------------------------------------------
-# Cleaning the lua examples
+# Running a Python example
# -----------------------------------------------------------------
-lua_clean:
- rm -f *_wrap* *~ .~* mylua@EXEEXT@
- rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *$(LUA_SO)
-
-##################################################################
-##### CFFI ######
-##################################################################
-
-CFFI = @CFFIBIN@
-CFFI_SCRIPT=$(RUNME).lisp
-
-cffi: $(SRCDIR_SRCS)
- $(SWIG) -cffi $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-# $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCDIR_SRCS)
-# $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
-
-cffi_cpp: $(SRCDIR_SRCS)
- $(SWIG) -c++ -cffi $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES)
- $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+PYSCRIPT = $(RUNME).py
-# -----------------------------------------------------------------
-# Run CFFI example
-# -----------------------------------------------------------------
+python_run: $(PYSCRIPT)
+ifneq (,$(PYCODESTYLE))
+ $(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(PYSCRIPT)
+endif
+ env PYTHONPATH=$$PWD $(RUNTOOL) $(PYTHON) $(PYSCRIPT) $(RUNPIPE)
-cffi_run:
- $(RUNTOOL) $(CFFI) -batch -s $(CFFI_SCRIPT) $(RUNPIPE)
+ifneq (,$(SRCDIR))
+$(RUNME).py: $(SRCDIR)$(RUNME).py
+ cp $< $@
+endif
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
-cffi_version:
- $(CFFI) --version
+python_version:
+ $(PYTHON) -V
# -----------------------------------------------------------------
-# Cleaning the CFFI examples
+# Cleaning the python examples
# -----------------------------------------------------------------
-cffi_clean:
- rm -f *_wrap* *~ .~*
+python_clean:
+ rm -rf __pycache__
+ rm -f *_wrap* *~ .~* mypython@EXEEXT@ *.pyc
rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *@SO@
+ rm -f *.@OBJEXT@ *@SO@ *$(PYTHON_SO)
+ rm -f $(TARGET).py
+ case "x$(SRCDIR)" in x|x./);; *) rm -f $(RUNME).py;; esac
##################################################################
-##### R ######
+##### R ######
##################################################################
R = R
@@ -1351,279 +1397,201 @@ r_clean:
rm -f $(RRSRC) $(RUNME).Rout .RData
##################################################################
-##### SCILAB ######
+##### RUBY ######
##################################################################
-SCILAB = @SCILAB@
-SCILAB_INC= @SCILABINCLUDE@
-SCILAB_OPT = @SCILABOPT@
-SCILAB_LIBPREFIX = lib
+# Make sure these locate your Ruby installation
+RUBY_CFLAGS= @RUBYCCDLFLAGS@ $(DEFS)
+RUBY_INCLUDE= @RUBYINCLUDE@
+RUBY_LIB = @RUBYLIB@
+RUBY_DLNK = @RUBYDYNAMICLINKING@
+RUBY_LIBOPTS = @RUBYLINK@ @LIBS@ $(SYSLIBS)
+RUBY_SO = @RUBYSO@
+RUBY = @RUBY@
+RUBY_SCRIPT = $(SRCDIR)$(RUNME).rb
+
# ----------------------------------------------------------------
# Build a C dynamically loadable module
# ----------------------------------------------------------------
-scilab:
- $(SWIG) -scilab $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) -g -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SCILAB_INC) $(INCLUDES) $(ISRCS) $(SRCDIR_SRCS) $(SRCDIR_CSRCS)
- $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(IOBJS) $(OBJS) $(LIBS) -o $(SCILAB_LIBPREFIX)$(TARGET)$(SO)
+ruby: $(SRCDIR_SRCS)
+ $(SWIG) -ruby $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(RUBY_CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(RUBY_INCLUDE)
+ $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(RUBY_SO)
-# ----------------------------------------------------------------
+# -----------------------------------------------------------------
# Build a C++ dynamically loadable module
-# ----------------------------------------------------------------
+# -----------------------------------------------------------------
-scilab_cpp:
- $(SWIG) -c++ -scilab $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SCILAB_INC) $(INCLUDES) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
- $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(IOBJS) $(OBJS) $(LIBS) $(CPP_DLLIBS) -o $(SCILAB_LIBPREFIX)$(TARGET)$(SO)
+ruby_cpp: $(SRCDIR_SRCS)
+ $(SWIG) -c++ -ruby $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(RUBY_INCLUDE)
+ $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(RUBY_SO)
# -----------------------------------------------------------------
-# Running a Scilab example
+# Build statically linked Ruby interpreter
+#
+# These should only be used in conjunction with the %include embed.i
+# library file
# -----------------------------------------------------------------
-scilab_run:
- env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(SCILAB) $(SCILAB_OPT) -f $(SRCDIR)$(RUNME).sci $(RUNPIPE)
+ruby_static: $(SRCDIR_SRCS)
+ $(SWIG) -ruby -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(RUBY_CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
+ $(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
+
+ruby_cpp_static: $(SRCDIR_SRCS)
+ $(SWIG) -c++ -ruby -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
+ $(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
# -----------------------------------------------------------------
-# Scilab version
+# Run Ruby example
# -----------------------------------------------------------------
-scilab_version:
- echo `$(SCILAB) -version | head -1`
+ruby_run:
+ $(RUNTOOL) $(RUBY) $(RUBYFLAGS) -I. $(RUBY_SCRIPT) $(RUNPIPE)
# -----------------------------------------------------------------
-# Cleaning the scilab examples
+# Version display
# -----------------------------------------------------------------
-scilab_clean:
- rm -f *_wrap* *~ .~*
+ruby_version:
+ $(RUBY) -v
+
+# -----------------------------------------------------------------
+# Cleaning the Ruby examples
+# -----------------------------------------------------------------
+
+ruby_clean:
+ rm -f *_wrap* *~ .~* myruby@EXEEXT@
rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *@SO@
- rm -f *.sce
+ rm -f *.@OBJEXT@ *$(RUBY_SO)
##################################################################
-##### Go ######
+##### SCILAB ######
##################################################################
-# TODO: The Go make targets need simplifying to use configure time
-# configuration or to use Make's ifeq rather than using lots of
-# runtime shell code. The output will then be a lot less verbose.
-
-GO = @GO@
-GOGCC = @GOGCC@
-GCCGO = @GCCGO@
-GOOPT = @GOOPT@
-GCCGOOPT = @GCCGOOPT@
-GOVERSIONOPTION = @GOVERSIONOPTION@
-
-GOSWIGARG = `if $(GOGCC) ; then echo -gccgo; fi`
-
-GOSRCS = $(INTERFACE:.i=.go)
-GOCSRCS = $(INTERFACE:.i=_gc.c)
-
-GOPACKAGE = $(notdir $(INTERFACE:.i=.a))
-
-GOPATHPARENTDIR = gopath/$(GOMOD)/src
-GOPATHDIR = $(GOPATHPARENTDIR)/$(INTERFACE:.i=)
+SCILAB = @SCILAB@
+SCILAB_INC= @SCILABINCLUDE@
+SCILAB_OPT = @SCILABOPT@
+SCILAB_VERSION = @SCILAB_VERSION@
+SCILAB_LIBPREFIX = lib
# ----------------------------------------------------------------
-# Build a Go module (C)
+# Build a C dynamically loadable module
# ----------------------------------------------------------------
-$(GOPATHPARENTDIR)/go.mod:
- @mkdir gopath 2>/dev/null || true
- @mkdir gopath/$(GOMOD) 2>/dev/null || true
- @mkdir gopath/$(GOMOD)/src 2>/dev/null || true
- @mkdir $(GOPATHDIR) 2>/dev/null || true
- echo "module swigtests" > $(GOPATHDIR)/go.mod
- echo "" >> $(GOPATHDIR)/go.mod
- echo "go 1.12" >> $(GOPATHDIR)/go.mod
- mv -f $(GOPATHDIR)/go.mod $(GOPATHPARENTDIR)/go.mod
-
-go: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
- $(SWIG) -go -import-prefix swigtests $(GOOPT) $(GOSWIGARG) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- @mkdir gopath 2>/dev/null || true
- @mkdir gopath/$(GOMOD) 2>/dev/null || true
- @mkdir gopath/$(GOMOD)/src 2>/dev/null || true
- @mkdir $(GOPATHDIR) 2>/dev/null || true
- rm -rf $(GOPATHDIR)/*
- cp $(ISRCS) $(GOPATHDIR)/
- if test -f $(IWRAP:.i=.h); then \
- cp $(IWRAP:.i=.h) $(GOPATHDIR)/; \
- fi
- if test -n "$(SRCDIR_SRCS)"; then \
- cp $(SRCDIR_SRCS) $(GOPATHDIR)/; \
- fi
- cp $(GOSRCS) $(GOPATHDIR)/
- @if test -f $(SRCDIR)$(RUNME).go; then \
- mkdir gopath/$(GOMOD)/src/runme 2>/dev/null || true; \
- rm -f gopath/$(GOMOD)/src/runme/*; \
- fi
- if test -f $(SRCDIR)$(RUNME).go; then \
- cp $(SRCDIR)$(RUNME).go gopath/$(GOMOD)/src/runme/; \
- fi
- GOPATH=`pwd`/gopath/$(GOMOD); \
- export GOPATH; \
- CGO_CPPFLAGS="$(CPPFLAGS) $(INCLUDES) -I `cd $(SRCDIR) && pwd` -I `pwd`"; \
- export CGO_CPPFLAGS; \
- CGO_CFLAGS="$(CFLAGS)"; \
- export CGO_CFLAGS; \
- CGO_LDFLAGS="$(LDFLAGS) -lm"; \
- export CGO_LDFLAGS; \
- (cd $(GOPATHDIR)/ && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
- if $(GOGCC); then \
- cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
- fi; \
- if test -f $(SRCDIR)$(RUNME).go; then \
- mkdir gopath/$(GOMOD)/src/swigtests 2>/dev/null || true; \
- mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
- cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
- (cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
- cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
- fi
+scilab:
+ $(SWIG) -scilab $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) -g -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SCILAB_INC) $(INCLUDES) $(ISRCS) $(SRCDIR_SRCS) $(SRCDIR_CSRCS)
+ $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(IOBJS) $(OBJS) $(LIBS) -o $(SCILAB_LIBPREFIX)$(TARGET)$(SO)
# ----------------------------------------------------------------
-# Build a Go module (C++)
+# Build a C++ dynamically loadable module
# ----------------------------------------------------------------
-go_cpp: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
- $(SWIG) -go -c++ -import-prefix swigtests $(GOOPT) $(GOSWIGARG) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- @mkdir gopath 2>/dev/null || true
- @mkdir gopath/$(GOMOD) 2>/dev/null || true
- @mkdir gopath/$(GOMOD)/src 2>/dev/null || true
- @mkdir $(GOPATHDIR) 2>/dev/null || true
- rm -rf $(GOPATHDIR)/*
- cp $(ICXXSRCS) $(GOPATHDIR)/
- if test -f $(IWRAP:.i=.h); then \
- cp $(IWRAP:.i=.h) $(GOPATHDIR)/; \
- fi
- if test -n "$(SRCDIR_CXXSRCS)"; then \
- cp $(SRCDIR_CXXSRCS) $(GOPATHDIR)/; \
- fi
- if test -n "$(SRCDIR_SRCS)"; then \
- cp $(SRCDIR_SRCS) $(GOPATHDIR)/; \
- fi
- cp $(GOSRCS) $(GOPATHDIR)/
- @if test -f $(SRCDIR)$(RUNME).go; then \
- mkdir gopath/$(GOMOD)/src/runme 2>/dev/null || true; \
- rm -f gopath/$(GOMOD)/src/runme/*; \
- fi
- if test -f $(SRCDIR)$(RUNME).go; then \
- cp $(SRCDIR)$(RUNME).go gopath/$(GOMOD)/src/runme/; \
- fi
- GOPATH=`pwd`/gopath/$(GOMOD); \
- export GOPATH; \
- CGO_CPPFLAGS="$(CPPFLAGS) $(INCLUDES) -I `cd $(SRCDIR) && pwd` -I `pwd`"; \
- export CGO_CPPFLAGS; \
- CGO_CFLAGS="$(CFLAGS)"; \
- export CGO_CFLAGS; \
- CGO_CXXFLAGS="$(CXXFLAGS)"; \
- export CGO_CXXFLAGS; \
- CGO_LDFLAGS="$(LDFLAGS) -lm"; \
- export CGO_LDFLAGS; \
- (cd $(GOPATHDIR) && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
- if $(GOGCC); then \
- cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
- fi; \
- if test -f $(SRCDIR)$(RUNME).go; then \
- mkdir gopath/$(GOMOD)/src/swigtests 2>/dev/null || true; \
- mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
- cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
- (cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
- cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
- fi
+scilab_cpp:
+ $(SWIG) -c++ -scilab $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SCILAB_INC) $(INCLUDES) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
+ $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(IOBJS) $(OBJS) $(LIBS) $(CPP_DLLIBS) -o $(SCILAB_LIBPREFIX)$(TARGET)$(SO)
# -----------------------------------------------------------------
-# Running Go example
+# Running a Scilab example
# -----------------------------------------------------------------
-go_run:
- env $(RUNTOOL) ./$(RUNME) $(RUNPIPE)
+scilab_run:
+ env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(SCILAB) $(SCILAB_OPT) -f $(SRCDIR)$(RUNME).sci $(RUNPIPE)
# -----------------------------------------------------------------
-# Version display
+# Scilab version
# -----------------------------------------------------------------
-go_version:
- $(GO) $(GOVERSIONOPTION)
+scilab_version:
+ echo `$(SCILAB) -nwni -version | head -1`
# -----------------------------------------------------------------
-# Cleaning the Go examples
+# Cleaning the scilab examples
# -----------------------------------------------------------------
-go_clean:
- rm -f *_wrap* *_gc* *.gox .~* $(RUNME) $(GOSRCS)
- rm -rf gopath
+scilab_clean:
+ rm -f *_wrap* *~ .~*
rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *.[568] *.a *@SO@
+ rm -f *.@OBJEXT@ *@SO@
+ rm -f *.sce
##################################################################
-##### D ######
+##### TCL ######
##################################################################
-DLIBPREFIX = @DLIBPREFIX@
+# Set these to your local copy of Tcl
-ifeq (,$(D_VERSION))
- D_VERSION = @DDEFAULTVERSION@
-endif
+TCLSH = tclsh
+TCL_INCLUDE = @TCLINCLUDE@
+TCL_LIB = @TCLLIB@
+TCL_OPTS = @LIBS@
+TK_OPTS = -ltk -ltcl @LIBS@
-ifeq (2,$(D_VERSION))
- SWIGD = $(SWIG) -d -d2
- DCOMPILER = @D2COMPILER@
-else
- SWIGD = $(SWIG) -d
- DCOMPILER = @D1COMPILER@
-endif
+# Extra Tcl specific dynamic linking options
+TCL_DLNK = @TCLDYNAMICLINKING@
+TCL_SO = @TCL_SO@
+TCLLDSHARED = @TCLLDSHARED@
+TCLCXXSHARED = @TCLCXXSHARED@
+TCL_SCRIPT = $(SRCDIR)$(RUNME).tcl
+TCL_LINK = @TCLLINK@
-D_RUNME = ./$(RUNME)
+# -----------------------------------------------------------
+# Build a new version of the tclsh shell
+# -----------------------------------------------------------
-# ----------------------------------------------------------------
-# Build a dynamically loadable D wrapper for a C module
-# ----------------------------------------------------------------
+tclsh: $(SRCDIR_SRCS)
+ $(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE) \
+ $(TCL_LIB) $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET)
-d: $(SRCDIR_SRCS)
- $(SWIGD) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
- $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
- $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
+tclsh_cpp: $(SRCDIR_SRCS)
+ $(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE) \
+ $(TCL_LIB) $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET)
-# ----------------------------------------------------------------
-# Build a dynamically loadable D wrapper for a C++ module
-# ----------------------------------------------------------------
+# -----------------------------------------------------------
+# Build a Tcl dynamic loadable module (you might need to tweak this)
+# -----------------------------------------------------------
-d_cpp: $(SRCDIR_SRCS)
- $(SWIGD) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
- $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
- $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
+tcl: $(SRCDIR_SRCS)
+ $(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ISRCS) $(INTERFACEPATH)
+ $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE)
+ $(TCLLDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO) $(TCL_LINK)
-# ----------------------------------------------------------------
-# Compile D files
-# ----------------------------------------------------------------
+# -----------------------------------------------------------
+# Build a Tcl dynamic loadable module for C++
+# -----------------------------------------------------------
-# Clear the DFLAGS environment variable for the compiler call itself
-# to work around a discrepancy in argument handling between DMD and LDC.
-d_compile: $(SRCDIR_SRCS)
- DFLAGS="" $(COMPILETOOL) $(DCOMPILER) $(DFLAGS) $(DSRCS)
+tcl_cpp: $(SRCDIR_SRCS)
+ $(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ICXXSRCS) $(INTERFACEPATH)
+ $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE)
+ $(TCLCXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO) $(TCL_LINK)
# -----------------------------------------------------------------
-# Run D example
+# Run Tcl example
# -----------------------------------------------------------------
-d_run:
- env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(D_RUNME) $(RUNPIPE)
+tcl_run:
+ $(RUNTOOL) $(TCLSH) $(TCL_SCRIPT) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
-d_version:
- # Needs improvement!
- echo D version guess - $(D_VERSION)
+tcl_version:
+ echo 'puts $$tcl_version;exit 0' | $(TCLSH)
# -----------------------------------------------------------------
-# Clean the D examples
+# Cleaning the Tcl examples
# -----------------------------------------------------------------
-d_clean:
- rm -f *_wrap* *~ .~* $(RUNME) $(RUNME).exe `find . -name \*.d | grep -v $(RUNME).d`
+tcl_clean:
+ rm -f *_wrap* *~ .~* mytclsh@EXEEXT@
rm -f core @EXTRA_CLEAN@
- rm -f *.@OBJEXT@ *@SO@
+ rm -f *.@OBJEXT@ *$(TCL_SO)
diff --git a/Examples/go/check.list b/Examples/go/check.list
index b3f34b306..6046c8310 100644
--- a/Examples/go/check.list
+++ b/Examples/go/check.list
@@ -12,3 +12,4 @@ reference
simple
template
variables
+goin
diff --git a/Examples/go/goin/Makefile b/Examples/go/goin/Makefile
new file mode 100644
index 000000000..f79b083cb
--- /dev/null
+++ b/Examples/go/goin/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIGEXE = $(TOP)/../swig
+SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
+CXXSRCS =
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+check: build
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
+
+build:
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean:
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean
diff --git a/Examples/go/goin/example.i b/Examples/go/goin/example.i
new file mode 100644
index 000000000..b819b8089
--- /dev/null
+++ b/Examples/go/goin/example.i
@@ -0,0 +1,106 @@
+
+%module(directors="1") example
+
+%inline %{
+// Helper functions for converting string arrays
+#include <stdlib.h>
+void *alloc_ptr_array(unsigned int len)
+{
+ return calloc(len, sizeof(void *));
+}
+void set_ptr_array(void *ain, unsigned int pos, void *val)
+{
+ void **a = (void **) ain;
+ a[pos] = val;
+}
+void *get_ptr_array(void *ain, unsigned int pos)
+{
+ void **a = (void **) ain;
+ return a[pos];
+}
+void free_ptr_array(void *ain)
+{
+ void **a = (void **) ain;
+ unsigned int i;
+
+ if (!a)
+ return;
+ for (i = 0; a[i]; i++) {
+ free(a[i]);
+ }
+ free(a);
+}
+char *uintptr_to_string(void *in)
+{
+ return (char *) in;
+}
+void *string_to_uintptr(char *in)
+{
+ return strdup(in);
+}
+%}
+
+// These typemaps convert between an array of strings in Go and a
+// const char** that is NULL terminated in C++.
+%typemap(gotype) (const char * const *) "[]string"
+%typemap(imtype) (const char * const *) "uintptr"
+%typemap(goin) (const char * const *) {
+ if $input == nil || len($input) == 0 {
+ $result = 0
+ } else {
+ $result = Alloc_ptr_array(uint(len($input) + 1))
+ defer func() {
+ Free_ptr_array($result)
+ }()
+ var i uint
+ for i = 0; i < uint(len($input)); i++ {
+ Set_ptr_array($result, i, String_to_uintptr($input[i]))
+ }
+ }
+}
+%typemap(in) (const char * const *) {
+ $1 = (char **) $input;
+}
+%typemap(godirectorin) (const char * const *) {
+ if ($input == 0) {
+ $result = nil
+ } else {
+ var i uint
+ for i = 0; ; i++ {
+ var v uintptr = Get_ptr_array($input, i)
+ if v == 0 {
+ break
+ }
+ }
+ if i == 0 {
+ $result = nil
+ } else {
+ $result = make([]string, i)
+ for i = 0; ; i++ {
+ var v uintptr = Get_ptr_array($input, i)
+ if v == 0 {
+ break
+ }
+ $result[i] = Uintptr_to_string(v)
+ }
+ }
+ }
+}
+
+%feature("director") callbacks;
+
+%inline %{
+ class callbacks {
+ public:
+ virtual bool call1(int v, const char * const *strarray);
+ virtual ~callbacks() {}
+ };
+
+ bool check1(callbacks *c, int v, const char * const *strarray) {
+ return c->call1(v, strarray);
+ }
+
+ bool callbacks::call1(int v, const char * const *strarray) {
+ return false;
+ }
+%}
diff --git a/Examples/go/goin/index.html b/Examples/go/goin/index.html
new file mode 100644
index 000000000..852b068da
--- /dev/null
+++ b/Examples/go/goin/index.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<title>SWIG:Examples:go:going</title>
+</head>
+
+<body bgcolor="#ffffff">
+
+
+<tt>SWIG/Examples/go/goin/</tt>
+<hr>
+
+<H2>Example of using goin and godirectorin</H2>
+
+<p>
+This example converts between a Go []string and a "const char * const *"
+in C/C++. It does this for a director and for a normal call.
+
+<p>
+<ul>
+<li><a href="example.i">example.i</a>. SWIG interface file.
+<li><a href="runme.go">runme.go</a>. Sample Go program.
+</ul>
+
+<hr>
+</body>
+</html>
diff --git a/Examples/go/goin/runme.go b/Examples/go/goin/runme.go
new file mode 100644
index 000000000..dfc7b0936
--- /dev/null
+++ b/Examples/go/goin/runme.go
@@ -0,0 +1,38 @@
+package main
+
+import (
+ "fmt"
+ "swigtests/example"
+)
+
+type mycallbacks struct {
+ example.Callbacks
+}
+
+var tststrs = []string{ "A", "BCD", "EFGH" }
+var tstint int = 5
+
+func (v *mycallbacks) Call1(val int, strarray []string) bool {
+ var rv bool = true
+
+ for i, s := range strarray {
+ fmt.Printf("%d: %s\n", i, s)
+ if s != tststrs[i] {
+ fmt.Printf(" ***Mismatch, expected %s\n", tststrs[i])
+ rv = false
+ }
+ }
+ if val != tstint {
+ rv = false
+ }
+ return rv
+}
+
+func main() {
+ cbs := &mycallbacks{}
+ cbs.Callbacks = example.NewDirectorCallbacks(cbs)
+ worked := example.Check1(cbs, tstint, tststrs)
+ if !worked {
+ panic("Data mismatch")
+ }
+}
diff --git a/Examples/go/index.html b/Examples/go/index.html
index 467f4ecb7..b8af100ff 100644
--- a/Examples/go/index.html
+++ b/Examples/go/index.html
@@ -24,6 +24,7 @@ certain C declarations are turned into constants.
<li><a href="callback/index.html">callback</a>. C++ callbacks using directors.
<li><a href="extend/index.html">extend</a>. Polymorphism using directors.
<li><a href="director/index.html">director</a>. Example how to utilize the director feature.
+<li><a href="goin/index.html">director</a>. Example how to use goin and godirectorin.
</ul>
<h2>Compilation Issues</h2>
@@ -93,6 +94,6 @@ All of the examples were last tested with the following configuration
</ul>
Your mileage may vary. If you experience a problem, please let us know by
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
</body>
</html>
diff --git a/Examples/guile/multimap/example.i b/Examples/guile/multimap/example.i
index c24d45ddc..776eb30c4 100644
--- a/Examples/guile/multimap/example.i
+++ b/Examples/guile/multimap/example.i
@@ -78,7 +78,7 @@ extern int count(char *bytes, int len, char c);
%typemap(argout) (char *str, int len) {
SWIG_APPEND_VALUE(scm_from_locale_stringn($1,$2));
- if ($1) SWIG_free($1);
+ SWIG_free($1);
}
extern void capitalize(char *str, int len);
diff --git a/Examples/java/index.html b/Examples/java/index.html
index 007e14dbc..bebf1b1bf 100644
--- a/Examples/java/index.html
+++ b/Examples/java/index.html
@@ -58,7 +58,7 @@ The examples have been extensively tested on the following platforms:
</ul>
Your mileage may vary. If you experience a problem, please let us know by
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
</body>
</html>
diff --git a/Examples/javascript/exception/runme.js b/Examples/javascript/exception/runme.js
index 1001a7111..646a33dbe 100644
--- a/Examples/javascript/exception/runme.js
+++ b/Examples/javascript/exception/runme.js
@@ -10,7 +10,7 @@ try{
if(error == -1) {
console.log("t.unknown() didn't throw");
} else {
- console.log("successfully caught throw in Test::unknown().");
+ console.log("successfully caught throw in Test::unknown() :" + error);
}
}
@@ -22,7 +22,7 @@ catch(error){
if(error == -1) {
console.log("t.simple() did not throw");
} else {
- console.log("successfully caught throw in Test::simple().");
+ console.log("successfully caught throw in Test::simple() :" + error);
}
}
@@ -33,7 +33,7 @@ try{
if(error == -1) {
console.log("t.message() did not throw");
} else {
- console.log("successfully caught throw in Test::message().");
+ console.log("successfully caught throw in Test::message() :" + error);
}
}
@@ -45,7 +45,7 @@ catch(error){
if(error == -1) {
console.log("t.hosed() did not throw");
} else {
- console.log("successfully caught throw in Test::hosed().");
+ console.log("successfully caught throw in Test::hosed() :" + error);
}
}
@@ -58,7 +58,7 @@ for (var i=1; i<4; i++) {
if(error == -1) {
console.log("t.multi(" + i + ") did not throw");
} else {
- console.log("successfully caught throw in Test::multi().");
+ console.log("successfully caught throw in Test::multi() :" + error);
}
}
-}
+}
diff --git a/Examples/javascript/nspace/example.h b/Examples/javascript/nspace/example.h
index 53066980a..b2e46e95c 100644
--- a/Examples/javascript/nspace/example.h
+++ b/Examples/javascript/nspace/example.h
@@ -1,5 +1,5 @@
-#ifndef _example_guardian_
-#define _example_guardian_
+#ifndef EXAMPLE_H
+#define EXAMPLE_H
int module_function() { return 7; }
int module_variable = 9;
diff --git a/Examples/lua/arrays/example.i b/Examples/lua/arrays/example.i
index eafd8ff55..54bc31bde 100644
--- a/Examples/lua/arrays/example.i
+++ b/Examples/lua/arrays/example.i
@@ -9,12 +9,12 @@ See the lua code for how they are called
%include <carrays.i> // array helpers
-// this declares a batch of function for manipulating C integer arrays
+// this declares a batch of functions for manipulating C integer arrays
%array_functions(int,int)
// this adds some lua code directly into the module
// warning: you need the example. prefix if you want it added into the module
-// admittedly this code is a bit tedious, but its a one off effort
+// admittedly this code is a bit tedious, but it's a one off effort
%luacode {
function example.sort_int2(t)
-- local len=table.maxn(t) -- the len - maxn deprecated in 5.3
diff --git a/Examples/lua/constants/runme.lua b/Examples/lua/constants/runme.lua
index ad6bd45d2..bc7ca2450 100644
--- a/Examples/lua/constants/runme.lua
+++ b/Examples/lua/constants/runme.lua
@@ -30,6 +30,6 @@ function checkfail(fn)
end
-- these should fail
--- example.EXTERN is a nil value, so concatentatin will make it fail
+-- example.EXTERN is a nil value, so concatenation will make it fail
checkfail(function() print("EXTERN = "..example.EXTERN) end)
checkfail(function() print("FOO = "..example.FOO) end)
diff --git a/Examples/lua/embed/embed.c b/Examples/lua/embed/embed.c
index 1f10cc8e8..2cb4728fb 100644
--- a/Examples/lua/embed/embed.c
+++ b/Examples/lua/embed/embed.c
@@ -23,7 +23,7 @@ We will be using the luaL_dostring()/lua_dostring() function to call into lua
#define lua_open luaL_newstate
#endif
-/* the SWIG wrappered library */
+/* the SWIG wrapped library */
extern int luaopen_example(lua_State*L);
/* a really simple way of calling lua from C
diff --git a/Examples/lua/embed2/embed2.c b/Examples/lua/embed2/embed2.c
index 0ce9f8f7f..5507877e5 100644
--- a/Examples/lua/embed2/embed2.c
+++ b/Examples/lua/embed2/embed2.c
@@ -41,7 +41,7 @@ extern int luaopen_example(lua_State*L);
/* This is an example of how to call the Lua function
int add(int,int)
- its very tedious, but gives you an idea of the issues involved.
+ it's very tedious, but gives you an idea of the issues involved.
(look below for a better idea)
*/
int call_add(lua_State *L,int a,int b,int* res) {
@@ -75,7 +75,7 @@ int call_add(lua_State *L,int a,int b,int* res) {
return 1;
}
-/* This is a variargs call function for calling from C into Lua.
+/* This is a varargs call function for calling from C into Lua.
Original Code from Programming in Lua (PIL) by Roberto Ierusalimschy
ISBN 85-903798-1-7
http://www.lua.org/pil/25.3.html
@@ -186,7 +186,7 @@ int main(int argc,char* argv[]) {
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
- printf("[C] now loading the SWIG wrappered library\n");
+ printf("[C] now loading the SWIG wrapped library\n");
luaopen_example(L);
printf("[C] all looks ok\n");
printf("\n");
@@ -226,8 +226,8 @@ int main(int argc,char* argv[]) {
printf("\n");
printf("[C] Note: no protection if you mess up the va-args, this is C\n");
printf("\n");
- printf("[C] Finally we will call the wrappered gcd function gdc(6,9):\n");
- printf("[C] This will pass the values to Lua, then call the wrappered function\n");
+ printf("[C] Finally we will call the wrapped gcd function gdc(6,9):\n");
+ printf("[C] This will pass the values to Lua, then call the wrapped function\n");
printf(" Which will get the values from Lua, call the C code \n");
printf(" and return the value to Lua and eventually back to C\n");
printf("[C] Certainly not the best way to do it :-)\n");
diff --git a/Examples/lua/embed3/embed3.cpp b/Examples/lua/embed3/embed3.cpp
index 9be49add3..c3c5d380c 100644
--- a/Examples/lua/embed3/embed3.cpp
+++ b/Examples/lua/embed3/embed3.cpp
@@ -61,7 +61,7 @@ bool push_pointer(lua_State*L, void* ptr, const char* type_name, int owned = 0)
/* This is an example of how to call the Lua function
void onEvent(Event e)
- its very tedious, but gives you an idea of the issues involed.
+ it's very tedious, but gives you an idea of the issues involved.
*/
int call_onEvent(lua_State *L, Event e) {
int top;
@@ -105,7 +105,7 @@ int main(int argc, char* argv[]) {
/* this code will pass a pointer into lua, but C++ still owns the object
this is a little tedious, to do, but let's do it
we need to pass the pointer (obviously), the type name
- and a flag which states if Lua should delete the pointer once its finished with it
+ and a flag which states if Lua should delete the pointer once it's finished with it
The type name is a class name string which is registered with SWIG
(normally, just look in the wrapper file to get this)
in this case we don't want Lua to delete the pointer so the ownership flag is 0
diff --git a/Examples/lua/nspace/example.h b/Examples/lua/nspace/example.h
index 53066980a..b2e46e95c 100644
--- a/Examples/lua/nspace/example.h
+++ b/Examples/lua/nspace/example.h
@@ -1,5 +1,5 @@
-#ifndef _example_guardian_
-#define _example_guardian_
+#ifndef EXAMPLE_H
+#define EXAMPLE_H
int module_function() { return 7; }
int module_variable = 9;
diff --git a/Examples/octave/module_load/runme.m b/Examples/octave/module_load/runme.m
index beab1213b..4e52c6ee0 100644
--- a/Examples/octave/module_load/runme.m
+++ b/Examples/octave/module_load/runme.m
@@ -19,7 +19,8 @@ clear all
# load module in a function globally before base context
clear all;
function testme_1
- assert(exist("swigexample") == 3);
+ % exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
+ assert(exist("swigexample"));
swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
@@ -32,7 +33,8 @@ assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
clear all
function testme_2
- assert(exist("swigexample") == 3);
+ % exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
+ assert(exist("swigexample"));
swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
@@ -52,7 +54,8 @@ swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
function testme_3
- assert(exist("swigexample") == 3);
+ % exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
+ assert(exist("swigexample"));
swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
@@ -65,7 +68,8 @@ swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
function testme_4
- assert(exist("swigexample") == 3);
+ % exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
+ assert(exist("swigexample"));
swigexample;
assert(isglobal("swigexample"));
assert(cvar.ivar == ifunc);
diff --git a/Examples/octave/operator/@swig_ref/horzcat.m b/Examples/octave/operator/@swig_ref/horzcat.m
new file mode 100644
index 000000000..6d4a55b20
--- /dev/null
+++ b/Examples/octave/operator/@swig_ref/horzcat.m
@@ -0,0 +1,9 @@
+% test octaves concatenation operator
+function ret=horzcat(varargin)
+ % return the concatenation of several ComplexVal values as a cell array.
+ % (not really useful but it tests the concatenation of swig_ref objects)
+ ret={};
+ for i=1:length(varargin)
+ ret{i}=varargin{i};
+ end
+end
diff --git a/Examples/octave/operator/runme.m b/Examples/octave/operator/runme.m
index e17494a84..ff8b594da 100644
--- a/Examples/octave/operator/runme.m
+++ b/Examples/octave/operator/runme.m
@@ -3,6 +3,9 @@ if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
+scriptDir = fileparts(mfilename('fullpath'));
+addpath(scriptDir);
+
# Operator overloading example
swigexample
@@ -42,3 +45,7 @@ if swig_octave_prereq(3,8,0)
printf("conj(a) = %s\n", disp(conj(a)));
printf("exp(a) = %s\n", disp(exp(a)));
endif
+
+# concatenation operator, note: calls @swig_ref/horzcat.m
+g = [a, b, c];
+printf("g = %s\n",disp(g));
diff --git a/Examples/perl5/index.html b/Examples/perl5/index.html
index 23c8ff658..2daabaaf9 100644
--- a/Examples/perl5/index.html
+++ b/Examples/perl5/index.html
@@ -72,7 +72,7 @@ Please see the <a href="../../Doc/Manual/Windows.html">Windows</a> page in the m
Due to wide variations in the Perl C API and differences between versions such as the ActivePerl release for Windows,
the code generated by SWIG is extremely messy.
If the code doesn't compile or work with your version of Perl, please let us know by
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
Better yet, send us a patch.
</body>
diff --git a/Examples/perl5/multimap/example.i b/Examples/perl5/multimap/example.i
index 64eb6a7f7..f2dff2418 100644
--- a/Examples/perl5/multimap/example.i
+++ b/Examples/perl5/multimap/example.i
@@ -15,7 +15,7 @@ extern int squareCubed (int n, int *OUTPUT);
extern int gcd(int x, int y);
-%typemap(arginit) (int argc, char *argv[]) "$2 = 0;";
+%typemap(arginit) (int argc, char *argv[]) "$2 = 0;"
%typemap(in) (int argc, char *argv[]) {
AV *tempav;
diff --git a/Examples/php/disown/example.cxx b/Examples/php/disown/example.cxx
index 6393735e9..247eb6a27 100644
--- a/Examples/php/disown/example.cxx
+++ b/Examples/php/disown/example.cxx
@@ -39,7 +39,6 @@ double Square::perimeter(void) {
}
ShapeContainer::~ShapeContainer() {
- iterator i=shapes.begin();
for( iterator i = shapes.begin(); i != shapes.end(); ++i ) {
delete *i;
}
diff --git a/Examples/php/extend/runme.php b/Examples/php/extend/runme.php
index 93eedee99..b770e5ce4 100644
--- a/Examples/php/extend/runme.php
+++ b/Examples/php/extend/runme.php
@@ -25,7 +25,7 @@ print "----------------------\n";
$list = new EmployeeList();
# EmployeeList owns its items, so we must surrender ownership of objects
-# we add. This involves first clearing the ->disown member to tell the
+# we add. This involves first clearing the ->thisown member to tell the
# C++ director to start reference counting.
$e->thisown = 0;
diff --git a/Examples/python/import/runme.py b/Examples/python/import/runme.py
index afa21a2b3..7970dec26 100644
--- a/Examples/python/import/runme.py
+++ b/Examples/python/import/runme.py
@@ -84,14 +84,14 @@ x.B()
print("\nTesting some dynamic casts\n")
x = d.toBase()
-y = foo.Foo_fromBase(x)
+y = foo.Foo.fromBase(x)
print(" Spam -> Base -> Foo : {} swig".format("bad" if y else "good"))
-y = bar.Bar_fromBase(x)
+y = bar.Bar.fromBase(x)
print(" Spam -> Base -> Bar : {} swig".format("good" if y else "bad"))
-y = spam.Spam_fromBase(x)
+y = spam.Spam.fromBase(x)
print(" Spam -> Base -> Spam : {} swig".format("good" if y else "bad"))
-y = spam.Spam_fromBase(b)
+y = spam.Spam.fromBase(b)
print(" Foo -> Spam : {} swig".format("bad" if y else "good"))
diff --git a/Examples/python/import_packages/from_init1/Makefile b/Examples/python/import_packages/from_init1/Makefile
index 90c92ab1c..f08c3344b 100644
--- a/Examples/python/import_packages/from_init1/Makefile
+++ b/Examples/python/import_packages/from_init1/Makefile
@@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
-ifeq (,$(PY3))
+ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"
diff --git a/Examples/python/import_packages/from_init1/runme.py b/Examples/python/import_packages/from_init1/runme.py
index c76716f16..1ed8898e4 100644
--- a/Examples/python/import_packages/from_init1/runme.py
+++ b/Examples/python/import_packages/from_init1/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/from_init2/Makefile b/Examples/python/import_packages/from_init2/Makefile
index 90c92ab1c..f08c3344b 100644
--- a/Examples/python/import_packages/from_init2/Makefile
+++ b/Examples/python/import_packages/from_init2/Makefile
@@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
-ifeq (,$(PY3))
+ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"
diff --git a/Examples/python/import_packages/from_init2/runme.py b/Examples/python/import_packages/from_init2/runme.py
index c9c46a4da..100c97b9e 100644
--- a/Examples/python/import_packages/from_init2/runme.py
+++ b/Examples/python/import_packages/from_init2/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/from_init3/Makefile b/Examples/python/import_packages/from_init3/Makefile
index 90c92ab1c..f08c3344b 100644
--- a/Examples/python/import_packages/from_init3/Makefile
+++ b/Examples/python/import_packages/from_init3/Makefile
@@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
-ifeq (,$(PY3))
+ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"
diff --git a/Examples/python/import_packages/from_init3/runme.py b/Examples/python/import_packages/from_init3/runme.py
index c9c46a4da..100c97b9e 100644
--- a/Examples/python/import_packages/from_init3/runme.py
+++ b/Examples/python/import_packages/from_init3/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/module_is_init/runme.py b/Examples/python/import_packages/module_is_init/runme.py
index c4806cdf8..42d48995e 100644
--- a/Examples/python/import_packages/module_is_init/runme.py
+++ b/Examples/python/import_packages/module_is_init/runme.py
@@ -5,14 +5,6 @@ import sys
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print("Testing " + testname + " - module renamed as __init__.py")
-if sys.version_info >= (3, 0, 0) and sys.version_info < (3, 3, 0):
- print(" Not importing as Python version is >= 3.0 and < 3.3")
- # Package detection does not work in these versions.
- # Can be fixed by using this in the interface file:
- # %module(moduleimport="from . import $module") foo # without -builtin
- # %module(moduleimport="from .$module import *") foo # with -builtin
- sys.exit(0)
-
import pkg1
print(" Finished importing pkg1")
diff --git a/Examples/python/import_packages/namespace_pkg/nonpkg.py b/Examples/python/import_packages/namespace_pkg/nonpkg.py
index 52be74db4..e87289089 100644
--- a/Examples/python/import_packages/namespace_pkg/nonpkg.py
+++ b/Examples/python/import_packages/namespace_pkg/nonpkg.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/namespace_pkg/normal.py b/Examples/python/import_packages/namespace_pkg/normal.py
index 0eb8f517c..f8fb025ad 100644
--- a/Examples/python/import_packages/namespace_pkg/normal.py
+++ b/Examples/python/import_packages/namespace_pkg/normal.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/namespace_pkg/nstest.py b/Examples/python/import_packages/namespace_pkg/nstest.py
index 4d618a6ad..0cd2a997d 100644
--- a/Examples/python/import_packages/namespace_pkg/nstest.py
+++ b/Examples/python/import_packages/namespace_pkg/nstest.py
@@ -6,7 +6,7 @@ import zipfile
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/namespace_pkg/split.py b/Examples/python/import_packages/namespace_pkg/split.py
index 9d786dc07..ed259b618 100644
--- a/Examples/python/import_packages/namespace_pkg/split.py
+++ b/Examples/python/import_packages/namespace_pkg/split.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/namespace_pkg/zipsplit.py b/Examples/python/import_packages/namespace_pkg/zipsplit.py
index 30434f9c0..474f2c742 100644
--- a/Examples/python/import_packages/namespace_pkg/zipsplit.py
+++ b/Examples/python/import_packages/namespace_pkg/zipsplit.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/relativeimport1/Makefile b/Examples/python/import_packages/relativeimport1/Makefile
index 90c92ab1c..f08c3344b 100644
--- a/Examples/python/import_packages/relativeimport1/Makefile
+++ b/Examples/python/import_packages/relativeimport1/Makefile
@@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
-ifeq (,$(PY3))
+ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"
diff --git a/Examples/python/import_packages/relativeimport1/runme.py b/Examples/python/import_packages/relativeimport1/runme.py
index 3073cb5a7..ff8ca0427 100644
--- a/Examples/python/import_packages/relativeimport1/runme.py
+++ b/Examples/python/import_packages/relativeimport1/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/relativeimport2/Makefile b/Examples/python/import_packages/relativeimport2/Makefile
index 90c92ab1c..f08c3344b 100644
--- a/Examples/python/import_packages/relativeimport2/Makefile
+++ b/Examples/python/import_packages/relativeimport2/Makefile
@@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
-ifeq (,$(PY3))
+ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"
diff --git a/Examples/python/import_packages/relativeimport2/runme.py b/Examples/python/import_packages/relativeimport2/runme.py
index 9ab8d9471..35c57e10b 100644
--- a/Examples/python/import_packages/relativeimport2/runme.py
+++ b/Examples/python/import_packages/relativeimport2/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/relativeimport3/Makefile b/Examples/python/import_packages/relativeimport3/Makefile
index 90c92ab1c..f08c3344b 100644
--- a/Examples/python/import_packages/relativeimport3/Makefile
+++ b/Examples/python/import_packages/relativeimport3/Makefile
@@ -1,7 +1,7 @@
TOP = ../../..
LIBS =
-ifeq (,$(PY3))
+ifneq (,$(PY2))
PKG1DIR = "py2"
else
PKG1DIR = "py3"
diff --git a/Examples/python/import_packages/relativeimport3/runme.py b/Examples/python/import_packages/relativeimport3/runme.py
index 3073cb5a7..ff8ca0427 100644
--- a/Examples/python/import_packages/relativeimport3/runme.py
+++ b/Examples/python/import_packages/relativeimport3/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/same_modnames1/runme.py b/Examples/python/import_packages/same_modnames1/runme.py
index 05846ed9d..41d84aa3d 100644
--- a/Examples/python/import_packages/same_modnames1/runme.py
+++ b/Examples/python/import_packages/same_modnames1/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/same_modnames2/runme.py b/Examples/python/import_packages/same_modnames2/runme.py
index 190dadc77..48c209b86 100644
--- a/Examples/python/import_packages/same_modnames2/runme.py
+++ b/Examples/python/import_packages/same_modnames2/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/split_modules/README b/Examples/python/import_packages/split_modules/README
index d2ca15e7a..41de834c1 100644
--- a/Examples/python/import_packages/split_modules/README
+++ b/Examples/python/import_packages/split_modules/README
@@ -4,7 +4,7 @@ and the C/C++ part is not in any package at all. Historically SWIG has
supported this sort of thing.
From SWIG 4.0.0 onwards, split modules are not supported by default.
The %module directive needs to be customised with the moduleimport attribute
-in order to import the a global C/C++ module.
+in order to import a global C/C++ module.
vanilla # "plane Jane" module both halves in pkg1
vanilla_split # python 1/2 in pkg1 C 1/2 in global namespace
diff --git a/Examples/python/import_packages/split_modules/vanilla/runme.py b/Examples/python/import_packages/split_modules/vanilla/runme.py
index 0f7b8806b..963adca79 100644
--- a/Examples/python/import_packages/split_modules/vanilla/runme.py
+++ b/Examples/python/import_packages/split_modules/vanilla/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
@@ -15,7 +15,7 @@ import pkg1.foo
print(" Finished importing pkg1.foo")
-if not(pkg1.foo.count() == 3):
+if not pkg1.foo.count() == 3:
raise RuntimeError("test failed")
commandline = sys.executable + " -m pkg1.foo"
diff --git a/Examples/python/import_packages/split_modules/vanilla_split/runme.py b/Examples/python/import_packages/split_modules/vanilla_split/runme.py
index 0f7b8806b..963adca79 100644
--- a/Examples/python/import_packages/split_modules/vanilla_split/runme.py
+++ b/Examples/python/import_packages/split_modules/vanilla_split/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
@@ -15,7 +15,7 @@ import pkg1.foo
print(" Finished importing pkg1.foo")
-if not(pkg1.foo.count() == 3):
+if not pkg1.foo.count() == 3:
raise RuntimeError("test failed")
commandline = sys.executable + " -m pkg1.foo"
diff --git a/Examples/python/import_template/runme.py b/Examples/python/import_template/runme.py
index b14f8d35e..74a918426 100644
--- a/Examples/python/import_template/runme.py
+++ b/Examples/python/import_template/runme.py
@@ -84,14 +84,14 @@ x.B()
print("\nTesting some dynamic casts\n")
x = d.toBase()
-y = foo.intFoo_fromBase(x)
+y = foo.intFoo.fromBase(x)
print(" Spam -> Base -> Foo : {} swig".format("bad" if y else "good"))
-y = bar.intBar_fromBase(x)
+y = bar.intBar.fromBase(x)
print(" Spam -> Base -> Bar : {} swig".format("good" if y else "bad"))
-y = spam.intSpam_fromBase(x)
+y = spam.intSpam.fromBase(x)
print(" Spam -> Base -> Spam : {} swig".format("good" if y else "bad"))
-y = spam.intSpam_fromBase(b)
+y = spam.intSpam.fromBase(b)
print(" Foo -> Spam : {} swig".format("bad" if y else "good"))
diff --git a/Examples/python/index.html b/Examples/python/index.html
index 750c0f04a..fcb7eace8 100644
--- a/Examples/python/index.html
+++ b/Examples/python/index.html
@@ -88,11 +88,11 @@ to look at the <a href="http://www.python.org/sigs/distutils-sig/">distutils</a>
<h2>Compatibility</h2>
-For Python 3, set the environment variable <tt>PY3=1</tt>.
+For Python 2, set the environment variable <tt>PY2=1</tt>.
<p>
Your mileage may vary. If you experience a problem, please let us know by
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
</body>
</html>
diff --git a/Examples/python/multimap/example.i b/Examples/python/multimap/example.i
index 3ff5d52c0..7087d426b 100644
--- a/Examples/python/multimap/example.i
+++ b/Examples/python/multimap/example.i
@@ -39,12 +39,14 @@ extern int gcd(int x, int y);
%#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/python/variables/runme.py b/Examples/python/variables/runme.py
index d59e0aa3e..f305fbe25 100644
--- a/Examples/python/variables/runme.py
+++ b/Examples/python/variables/runme.py
@@ -2,6 +2,8 @@
import example
+print("Variables = " + str(example.cvar))
+
# Try to set the values of some global variables
example.cvar.ivar = 42
@@ -22,7 +24,7 @@ example.cvar.name = "Bill"
# Now print out the values of the variables
-print("Variables (values printed from Python)")
+print("\nVariables (values printed from Python)")
print("ivar = %s" % example.cvar.ivar)
print("svar = %s" % example.cvar.svar)
diff --git a/Examples/ruby/exceptproxy/example.i b/Examples/ruby/exceptproxy/example.i
index ad0c23acb..3a3077f8a 100644
--- a/Examples/ruby/exceptproxy/example.i
+++ b/Examples/ruby/exceptproxy/example.i
@@ -16,7 +16,7 @@
/* The EmptyError doesn't appear in a throw declaration, and hence
we need to tell SWIG that the dequeue method throws it. This can
- now be done via the %catchs feature. */
+ now be done via the %catches feature. */
%catches(FullError) *::enqueue;
%catches(EmptyError) *::dequeue();
diff --git a/Examples/ruby/free_function/example.h b/Examples/ruby/free_function/example.h
index 933bb3645..c709cdec1 100644
--- a/Examples/ruby/free_function/example.h
+++ b/Examples/ruby/free_function/example.h
@@ -1,5 +1,5 @@
-#ifndef _EXAMPLE_H_
-#define _EXAMPLE_H_
+#ifndef EXAMPLE_H
+#define EXAMPLE_H
#include <vector>
#include <string>
@@ -46,4 +46,4 @@ public:
Animal* get_animal(size_t i) const;
};
-#endif /*_EXAMPLE_H_*/
+#endif /* EXAMPLE_H */
diff --git a/Examples/ruby/index.html b/Examples/ruby/index.html
index 4f4aa0ad2..ceb6c925d 100644
--- a/Examples/ruby/index.html
+++ b/Examples/ruby/index.html
@@ -87,7 +87,7 @@ The examples have been extensively tested on the following platforms:
</ul>
Your mileage may vary. If you experience a problem, please let us know by
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
</body>
</html>
diff --git a/Examples/ruby/mark_function/example.h b/Examples/ruby/mark_function/example.h
index 933bb3645..c709cdec1 100644
--- a/Examples/ruby/mark_function/example.h
+++ b/Examples/ruby/mark_function/example.h
@@ -1,5 +1,5 @@
-#ifndef _EXAMPLE_H_
-#define _EXAMPLE_H_
+#ifndef EXAMPLE_H
+#define EXAMPLE_H
#include <vector>
#include <string>
@@ -46,4 +46,4 @@ public:
Animal* get_animal(size_t i) const;
};
-#endif /*_EXAMPLE_H_*/
+#endif /* EXAMPLE_H */
diff --git a/Examples/tcl/index.html b/Examples/tcl/index.html
index b32726002..acd90029f 100644
--- a/Examples/tcl/index.html
+++ b/Examples/tcl/index.html
@@ -63,7 +63,7 @@ The examples have been extensively tested on the following platforms:
</ul>
Your mileage may vary. If you experience a problem, please let us know by
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
</body>
</html>
diff --git a/Examples/tcl/multimap/example.i b/Examples/tcl/multimap/example.i
index 9a141b65a..42d00225d 100644
--- a/Examples/tcl/multimap/example.i
+++ b/Examples/tcl/multimap/example.i
@@ -14,7 +14,7 @@ extern int squareCubed (int n, int *OUTPUT);
extern int gcd(int x, int y);
-%typemap(arginit) (int argc, char *argv[]) "$2 = 0;";
+%typemap(arginit) (int argc, char *argv[]) "$2 = 0;"
%typemap(in) (int argc, char *argv[]) {
Tcl_Obj **listobjv = 0;
diff --git a/Examples/test-suite/abstract_basecast.i b/Examples/test-suite/abstract_basecast.i
new file mode 100644
index 000000000..b6a21aa64
--- /dev/null
+++ b/Examples/test-suite/abstract_basecast.i
@@ -0,0 +1,20 @@
+%module abstract_basecast
+
+%inline %{
+class BaseClass {
+public:
+ virtual ~BaseClass() { }
+
+ virtual void g() = 0;
+};
+
+class DerivedClass : public BaseClass {
+public:
+
+ virtual void g() { }
+
+ BaseClass& f() {
+ return *this;
+ }
+};
+%}
diff --git a/Examples/test-suite/abstract_signature.i b/Examples/test-suite/abstract_signature.i
index 5d68fd0a9..8d4199844 100644
--- a/Examples/test-suite/abstract_signature.i
+++ b/Examples/test-suite/abstract_signature.i
@@ -7,8 +7,8 @@
class abstract_foo
{
public:
- abstract_foo() { };
- virtual ~abstract_foo() { };
+ abstract_foo() { }
+ virtual ~abstract_foo() { }
virtual int meth(int meth_param) = 0;
};
@@ -16,9 +16,9 @@ public:
class abstract_bar : public abstract_foo
{
public:
- abstract_bar() { };
+ abstract_bar() { }
- virtual ~abstract_bar() { };
+ virtual ~abstract_bar() { }
virtual int meth(int meth_param) = 0;
int meth(int meth_param_1, int meth_param_2) { return 0; }
};
diff --git a/Examples/test-suite/aggregate.i b/Examples/test-suite/aggregate.i
index dc00f0605..8ac31ece7 100644
--- a/Examples/test-suite/aggregate.i
+++ b/Examples/test-suite/aggregate.i
@@ -6,7 +6,7 @@
To support contracts, you need to add a macro to the runtime.
For Python, it looks like this:
-#define SWIG_contract_assert(expr, msg) if (!(expr)) { PyErr_SetString(PyExc_RuntimeError, (char *) msg #expr ); goto fail; } else
+#define SWIG_contract_assert(expr, msg) do { if (!(expr)) { PyErr_SetString(PyExc_RuntimeError, (char *) msg #expr ); goto fail; } } while (0)
Note: It is used like this:
SWIG_contract_assert(x == 1, "Some kind of error message");
diff --git a/Examples/test-suite/apply_signed_char.i b/Examples/test-suite/apply_signed_char.i
index d3116f024..a33b285a3 100644
--- a/Examples/test-suite/apply_signed_char.i
+++ b/Examples/test-suite/apply_signed_char.i
@@ -35,7 +35,5 @@
const char memberconstchar;
virtual ~DirectorTest() {}
- private:
- DirectorTest& operator=(const DirectorTest &);
};
%}
diff --git a/Examples/test-suite/argcargvtest.i b/Examples/test-suite/argcargvtest.i
index ed5aa0985..5711441d9 100644
--- a/Examples/test-suite/argcargvtest.i
+++ b/Examples/test-suite/argcargvtest.i
@@ -1,8 +1,10 @@
%module argcargvtest
+#if !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGGO) && !defined(SWIGGUILE) && !defined(SWIGJAVA) && !defined(SWIGJAVASCRIPT) && !defined(SWIGMZSCHEME) && !defined(SWIGOCAML) && !defined(SWIGR) && !defined(SWIGSCILAB)
%include <argcargv.i>
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+#endif
%inline %{
diff --git a/Examples/test-suite/autodoc.i b/Examples/test-suite/autodoc.i
index efc720155..0716ea631 100644
--- a/Examples/test-suite/autodoc.i
+++ b/Examples/test-suite/autodoc.i
@@ -5,8 +5,8 @@
%feature("autodoc");
// special typemap and its docs
-%typemap(in) (int c, int d) "$1 = 0; $2 = 0;";
-%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]";
+%typemap(in) (int c, int d) "$1 = 0; $2 = 0;"
+%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]"
// testing for different documentation levels
%feature("autodoc","0") A::func0; // names
@@ -69,8 +69,8 @@
%typemap(doc) (int c, int d);
// docs for some parameters
-%typemap(doc) int a "a: special comment for parameter a";
-%typemap(doc) int b "b: another special comment for parameter b";
+%typemap(doc) int a "a: special comment for parameter a"
+%typemap(doc) int b "b: another special comment for parameter b"
%feature("autodoc","0") C::C(int a, int b, Hola h); // names
%feature("autodoc","1") D::D(int a, int b, Hola h); // names + types
diff --git a/Examples/test-suite/bools.i b/Examples/test-suite/bools.i
index 2ef3d93a6..0c4f9d661 100644
--- a/Examples/test-suite/bools.i
+++ b/Examples/test-suite/bools.i
@@ -62,8 +62,6 @@ struct BoolStructure {
m_rbool(m_bool2),
m_const_pbool(m_pbool),
m_const_rbool(m_rbool) {}
-private:
- BoolStructure& operator=(const BoolStructure &);
};
%}
diff --git a/Examples/test-suite/callback.i b/Examples/test-suite/callback.i
index 4db63353b..e406615bb 100644
--- a/Examples/test-suite/callback.i
+++ b/Examples/test-suite/callback.i
@@ -13,6 +13,7 @@
%callback("%s") A::foom;
#endif
%callback("%(uppercase)s_Cb_Ptr") foo_T; // this works in Python too
+%callback("%s_cb") identity_finger;
%inline %{
@@ -85,6 +86,15 @@
const T& ident(const T& x) {
return x;
}
+
+ // Test callbacks for enum types
+ typedef enum {One, Two, Three, Four, Five} finger;
+ typedef finger (*finger_finger)(finger);
+ finger identity_finger(finger f) { return f; }
+ finger apply_finger_cb(finger f, finger_finger cb) {
+ return cb(f);
+ }
+
%}
%template(foo_i) foo_T<int>;
diff --git a/Examples/test-suite/catches_strings.i b/Examples/test-suite/catches_strings.i
new file mode 100644
index 000000000..818a62285
--- /dev/null
+++ b/Examples/test-suite/catches_strings.i
@@ -0,0 +1,17 @@
+%module catches_strings
+
+%include <std_string.i>
+
+%catches(const char *) StringsThrower::charstring;
+%catches(std::string) StringsThrower::stdstring;
+
+%inline %{
+struct StringsThrower {
+ static void charstring() {
+ throw "charstring message";
+ }
+ static void stdstring() {
+ throw std::string("stdstring message");
+ }
+};
+%}
diff --git a/Examples/test-suite/cffi/Makefile.in b/Examples/test-suite/cffi/Makefile.in
deleted file mode 100644
index 6eebaa07c..000000000
--- a/Examples/test-suite/cffi/Makefile.in
+++ /dev/null
@@ -1,51 +0,0 @@
-#######################################################################
-# Makefile for cffi test-suite
-#######################################################################
-
-LANGUAGE = cffi
-CFFI = @CFFIBIN@
-SCRIPTSUFFIX = _runme.lisp
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-top_builddir = @top_builddir@
-
-include $(srcdir)/../common.mk
-
-# Overridden variables here
-# no C++ tests for now
-CPP_TEST_CASES =
-#C_TEST_CASES +=
-
-# Custom tests - tests with additional commandline options
-# none!
-
-# Rules for the different types of tests
-%.cpptest:
- $(setup)
- +$(swig_and_compile_cpp)
- $(run_testcase)
-
-%.ctest:
- $(setup)
- +$(swig_and_compile_c)
- $(run_testcase)
-
-%.multicpptest:
- $(setup)
- +$(swig_and_compile_multi_cpp)
- $(run_testcase)
-
-# Runs the testcase. A testcase is only run if
-# a file is found which has _runme.lisp appended after the testcase name.
-run_testcase = \
- if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
- env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CFFI) -batch -s $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
- fi
-
-# Clean: (does nothing, we dont generate extra cffi code)
-%.clean:
- @exit 0
-
-clean:
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' cffi_clean
diff --git a/Examples/test-suite/char_strings.i b/Examples/test-suite/char_strings.i
index 9a87df4e3..aa3b125ce 100644
--- a/Examples/test-suite/char_strings.i
+++ b/Examples/test-suite/char_strings.i
@@ -11,6 +11,7 @@ below.
%{
#include <stdio.h>
+#include <string.h>
#define OTHERLAND_MSG "Little message from the safe world."
#define CPLUSPLUS_MSG "A message from the deep dark world of C++, where anything is possible."
@@ -150,11 +151,11 @@ const char global_const_char_array2[sizeof(CPLUSPLUS_MSG)+1] = CPLUSPLUS_MSG;
%inline {
struct Formatpos;
struct OBFormat;
-
+
static int GetNextFormat(Formatpos& itr, const char*& str,OBFormat*& pFormat) {
return 0;
}
-
+
}
diff --git a/Examples/test-suite/class_case.i b/Examples/test-suite/class_case.i
new file mode 100644
index 000000000..e9438d80b
--- /dev/null
+++ b/Examples/test-suite/class_case.i
@@ -0,0 +1,18 @@
+%module class_case
+
+// Regression test for SWIG/Go bug #676
+
+%inline %{
+
+class ClassA {};
+
+class classB {};
+class classB2 : public classB {};
+
+int Test1(ClassA* a) { return 1; }
+int Test1(int i) { return 0; }
+
+int Test2(classB* a) { return 1; }
+int Test2(int i) { return 0; }
+
+%}
diff --git a/Examples/test-suite/class_scope_namespace.i b/Examples/test-suite/class_scope_namespace.i
index 47d918157..a24932a6e 100644
--- a/Examples/test-suite/class_scope_namespace.i
+++ b/Examples/test-suite/class_scope_namespace.i
@@ -15,6 +15,7 @@ namespace Space1 {
void aaa(Space1::SubSpace1::A, SubSpace1::A, A) {}
}
}
+void global_namespace_a(A*) {}
namespace Space2 {
struct B;
diff --git a/Examples/test-suite/clientdata_prop_a.h b/Examples/test-suite/clientdata_prop_a.h
index 5f82e98bc..52c54066d 100644
--- a/Examples/test-suite/clientdata_prop_a.h
+++ b/Examples/test-suite/clientdata_prop_a.h
@@ -6,7 +6,7 @@ class A {
typedef A tA;
-void test_A(A *a) {}
-void test_tA(tA *a) {}
+inline void test_A(A *a) {}
+inline void test_tA(tA *a) {}
-tA *new_tA() { return new tA(); }
+inline tA *new_tA() { return new tA(); }
diff --git a/Examples/test-suite/command_line_define.i b/Examples/test-suite/command_line_define.i
new file mode 100644
index 000000000..842add7fd
--- /dev/null
+++ b/Examples/test-suite/command_line_define.i
@@ -0,0 +1,7 @@
+%module command_line_define
+
+// Test handling of -D without a value specified.
+
+#if FOO-0 != 1
+# error "-DFOO didn't set FOO to 1"
+#endif
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 5a44980cc..1c70ece4c 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -88,11 +88,13 @@ CPP_TEST_BROKEN += \
extend_variable \
li_boost_shared_ptr_template \
nested_private \
- rename_camel \
template_default_pointer \
template_private_assignment \
template_expr \
- $(CPP11_TEST_BROKEN)
+ $(CPP11_TEST_BROKEN) \
+ $(CPP14_TEST_BROKEN) \
+ $(CPP17_TEST_BROKEN) \
+ $(CPP20_TEST_BROKEN)
# Broken C test cases. (Can be run individually using: make testcase.ctest)
@@ -102,6 +104,7 @@ C_TEST_BROKEN += \
# C++ test cases. (Can be run individually using: make testcase.cpptest)
CPP_TEST_CASES += \
abstract_access \
+ abstract_basecast \
abstract_inherit \
abstract_inherit_ok \
abstract_signature \
@@ -117,6 +120,7 @@ CPP_TEST_CASES += \
anonymous_bitfield \
apply_signed_char \
apply_strings \
+ argcargvtest \
argout \
array_member \
array_typedef_memberin \
@@ -129,11 +133,13 @@ CPP_TEST_CASES += \
bloody_hell \
bools \
catches \
+ catches_strings \
cast_operator \
casts \
char_binary \
char_strings \
chartest \
+ class_case \
class_scope_namespace \
class_forward \
class_ignore \
@@ -141,6 +147,7 @@ CPP_TEST_CASES += \
compactdefaultargs \
const_const_2 \
constant_directive \
+ constant_expr \
constant_pointers \
constover \
constructor_copy \
@@ -162,11 +169,6 @@ CPP_TEST_CASES += \
cpp_parameters \
cpp_static \
cpp_typedef \
- cpp14_binary_integer_literals \
- cpp17_hex_floating_literals \
- cpp17_nested_namespaces \
- cpp17_nspace_nested_namespaces \
- cpp17_u8_char_literals \
curiously_recurring_template_pattern \
default_args \
default_arg_expressions \
@@ -197,6 +199,7 @@ CPP_TEST_CASES += \
director_frob \
director_ignore \
director_keywords \
+ director_multiple_inheritance \
director_namespace_clash \
director_nested \
director_nspace \
@@ -211,13 +214,18 @@ CPP_TEST_CASES += \
director_protected_overloaded \
director_redefined \
director_ref \
+ director_simple \
director_smartptr \
+ director_template \
director_thread \
director_unroll \
+ director_unwrap_result \
director_using \
+ director_using_member_scopes \
director_void \
director_wombat \
disown \
+ duplicate_class_name_in_ns \
dynamic_cast \
empty \
enum_ignore \
@@ -232,6 +240,7 @@ CPP_TEST_CASES += \
evil_diamond_ns \
evil_diamond_prop \
exception_classname \
+ exception_memory_leak \
exception_order \
extend \
extend_constructor_destructor \
@@ -303,6 +312,7 @@ CPP_TEST_CASES += \
multiple_inheritance_abstract \
multiple_inheritance_interfaces \
multiple_inheritance_nspace \
+ multiple_inheritance_overload \
multiple_inheritance_shared_ptr \
name_cxx \
name_warnings \
@@ -313,6 +323,7 @@ CPP_TEST_CASES += \
namespace_forward_declaration \
namespace_nested \
namespace_spaces \
+ namespace_struct \
namespace_template \
namespace_typedef_class \
namespace_typemap \
@@ -371,6 +382,7 @@ CPP_TEST_CASES += \
rename2 \
rename3 \
rename4 \
+ rename_camel \
rename_rstrip_encoder \
rename_scope \
rename_simple \
@@ -547,6 +559,8 @@ CPP_TEST_CASES += \
using_directive_and_declaration_forward \
using_extend \
using_inherit \
+ using_member \
+ using_member_scopes \
using_namespace \
using_namespace_loop \
using_pointers \
@@ -572,6 +586,7 @@ CPP11_TEST_CASES += \
cpp11_alias_nested_template_scoping \
cpp11_alignment \
cpp11_alternate_function_syntax \
+ cpp11_attribute_specifiers \
cpp11_constexpr \
cpp11_decltype \
cpp11_default_delete \
@@ -579,6 +594,7 @@ CPP11_TEST_CASES += \
cpp11_director_enums \
cpp11_directors \
cpp11_explicit_conversion_operators \
+ cpp11_final_class \
cpp11_final_directors \
cpp11_final_override \
cpp11_function_objects \
@@ -586,6 +602,9 @@ CPP11_TEST_CASES += \
cpp11_initializer_list \
cpp11_initializer_list_extend \
cpp11_lambda_functions \
+ cpp11_move_only \
+ cpp11_move_typemaps \
+ cpp11_move_only_valuewrapper \
cpp11_noexcept \
cpp11_null_pointer_constant \
cpp11_raw_string_literals \
@@ -596,9 +615,11 @@ CPP11_TEST_CASES += \
cpp11_rvalue_reference \
cpp11_rvalue_reference2 \
cpp11_rvalue_reference3 \
+ cpp11_rvalue_reference_move \
cpp11_sizeof_object \
cpp11_static_assert \
cpp11_std_array \
+ cpp11_std_unique_ptr \
cpp11_strongly_typed_enumerations \
cpp11_thread_local \
cpp11_template_double_brackets \
@@ -615,6 +636,31 @@ CPP11_TEST_BROKEN = \
# cpp11_variadic_templates \ # Broken for some languages (such as Java)
# cpp11_reference_wrapper \ # No typemaps
+# C++14 test cases.
+CPP14_TEST_CASES += \
+ cpp14_binary_integer_literals \
+
+# Broken C++14 test cases.
+CPP14_TEST_BROKEN = \
+
+# C++17 test cases.
+CPP17_TEST_CASES += \
+ cpp17_hex_floating_literals \
+ cpp17_nested_namespaces \
+ cpp17_nspace_nested_namespaces \
+ cpp17_u8_char_literals \
+
+# Broken C++17 test cases.
+CPP17_TEST_BROKEN = \
+
+# C++20 test cases.
+CPP20_TEST_CASES += \
+ cpp20_lambda_template \
+ cpp20_spaceship_operator \
+
+# Broken C++20 test cases.
+CPP20_TEST_BROKEN = \
+
# Doxygen support test cases: can only be used with languages supporting
# Doxygen comment translation (currently Python and Java) and only if not
# disabled by configure via SKIP_DOXYGEN_TEST_CASES.
@@ -628,6 +674,7 @@ endif
ifdef HAS_DOXYGEN
DOXYGEN_TEST_CASES += \
doxygen_alias \
+ doxygen_autodoc_docstring \
doxygen_basic_notranslate \
doxygen_basic_translate \
doxygen_basic_translate_style2 \
@@ -681,6 +728,18 @@ ifeq (1,$(HAVE_CXX11))
CPP_TEST_CASES += $(CPP11_TEST_CASES)
endif
+ifeq (1,$(HAVE_CXX14))
+CPP_TEST_CASES += $(CPP14_TEST_CASES)
+endif
+
+ifeq (1,$(HAVE_CXX17))
+CPP_TEST_CASES += $(CPP17_TEST_CASES)
+endif
+
+ifeq (1,$(HAVE_CXX20))
+CPP_TEST_CASES += $(CPP20_TEST_CASES)
+endif
+
# C test cases. (Can be run individually using: make testcase.ctest)
C_TEST_CASES += \
arrays \
@@ -688,8 +747,10 @@ C_TEST_CASES += \
c_delete \
c_delete_function \
char_constant \
+ command_line_define \
const_const \
- constant_expr \
+ constant_expr_c \
+ contract_c \
default_args_c \
empty_c \
enums \
@@ -697,6 +758,7 @@ C_TEST_CASES += \
enum_macro \
enum_missing \
extern_declaration \
+ final_c \
funcptr \
function_typedef \
global_functions \
@@ -726,9 +788,11 @@ C_TEST_CASES += \
preproc \
preproc_constants_c \
preproc_defined \
+ preproc_expr \
preproc_gcc_output \
preproc_include \
preproc_line_file \
+ preproc_predefined \
register_par \
ret_by_value \
simple_array \
@@ -757,10 +821,15 @@ MULTI_CPP_TEST_CASES += \
# Custom tests - tests with additional commandline options
wallkw.cpptest: SWIGOPT += -Wallkw
preproc_include.ctest: SWIGOPT += -includeall
+command_line_define.ctest: SWIGOPT += -DFOO
# Allow modules to define temporarily failing tests.
C_TEST_CASES := $(filter-out $(FAILING_C_TESTS),$(C_TEST_CASES))
CPP_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP_TEST_CASES))
+CPP11_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP11_TEST_CASES))
+CPP14_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP14_TEST_CASES))
+CPP17_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP17_TEST_CASES))
+CPP20_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP20_TEST_CASES))
MULTI_CPP_TEST_CASES := $(filter-out $(FAILING_MULTI_CPP_TESTS),$(MULTI_CPP_TEST_CASES))
@@ -773,6 +842,10 @@ BROKEN_TEST_CASES = $(CPP_TEST_BROKEN:=.cpptest) \
$(C_TEST_BROKEN:=.ctest)
ALL_CLEAN = $(CPP_TEST_CASES:=.clean) \
+ $(CPP11_TEST_CASES:=.clean) \
+ $(CPP14_TEST_CASES:=.clean) \
+ $(CPP17_TEST_CASES:=.clean) \
+ $(CPP20_TEST_CASES:=.clean) \
$(C_TEST_CASES:=.clean) \
$(MULTI_CPP_TEST_CASES:=.clean) \
$(CPP_TEST_BROKEN:=.clean) \
@@ -801,6 +874,14 @@ check-cpp: $(CPP_TEST_CASES:=.cpptest)
check-cpp11: $(CPP11_TEST_CASES:=.cpptest)
+check-cpp14: $(CPP14_TEST_CASES:=.cpptest)
+
+check-cpp17: $(CPP17_TEST_CASES:=.cpptest)
+
+check-cpp20: $(CPP20_TEST_CASES:=.cpptest)
+
+check-multicpp: $(MULTI_CPP_TEST_CASES:=.multicpptest)
+
ifdef HAS_DOXYGEN
check-doxygen: $(DOXYGEN_TEST_CASES:=.cpptest)
endif
@@ -818,6 +899,13 @@ endif
partialcheck:
$(MAKE) check CC=true CXX=true LDSHARED=true CXXSHARED=true RUNTOOL=true COMPILETOOL=true
+swig_and_compile_cpp_helper = \
+ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+ LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT=$(2) NOLINK=true \
+ TARGET="$(TARGETPREFIX)$(1)$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$(1).i" \
+ $(LANGUAGE)$(VARIANT)_cpp
+
swig_and_compile_cpp = \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
@@ -834,11 +922,7 @@ swig_and_compile_c = \
swig_and_compile_multi_cpp = \
for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
- SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
- LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
- TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
- $(LANGUAGE)$(VARIANT)_cpp; \
+ $(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)'); \
done
swig_and_compile_external = \
diff --git a/Examples/test-suite/constant_expr.i b/Examples/test-suite/constant_expr.i
index 8e5c8aee6..a5ba5c6dd 100644
--- a/Examples/test-suite/constant_expr.i
+++ b/Examples/test-suite/constant_expr.i
@@ -1,11 +1,37 @@
%module constant_expr;
-/* Tests of constant expressions. */
+/* Tests of constant expressions (C++ version). */
+
+%include "constant_expr_c.i"
%inline %{
-/* % didn't work in SWIG 1.3.40 and earlier. */
-const int X = 123%7;
-#define FOO 12 % 9
-double d_array[12 % 9];
+// Testcase from https://sourceforge.net/p/swig/bugs/1139/
+template<typename Tp>
+struct SizeInfo {
+enum {
+isLarge = (sizeof(Tp)>sizeof(void*)),
+isPointer = false
+};
+};
+
+/* Regression test for #300, fixed in 4.1.0.
+ *
+ * Now `a%b` without a space after the `%` is handled as a modulus operator,
+ * but it gave a cryptic `Syntax error in input(1)` before SWIG 3.0.4, and from
+ * SWIG 3.0.4 until 4.1.0, `Unknown directive '%a'`.
+ */
+int a;
+int test2(int b = 9%a) { return b; }
+
+/* Example from manual, adapted to avoid C++11 requirement. */
+namespace fakestd {
+ template<typename T, unsigned N>
+ class array {
+ T a[N];
+ public:
+ array() {}
+ };
+}
+void bar(fakestd::array<int, (1<2? 100 : 50)> *x) { }
%}
diff --git a/Examples/test-suite/constant_expr_c.i b/Examples/test-suite/constant_expr_c.i
new file mode 100644
index 000000000..aae0b953c
--- /dev/null
+++ b/Examples/test-suite/constant_expr_c.i
@@ -0,0 +1,56 @@
+%module constant_expr_c;
+/* Tests of constant expressions (C version). */
+
+%inline %{
+
+/* % didn't work in SWIG 1.3.40 and earlier. */
+const int X = 123%7;
+#define FOO 12 % 9
+double d_array[12 % 9];
+
+/* `<` and `>` in constant expressions caused parse errors before SWIG 4.1.0.
+ * They're now supported if inside parentheses (and with some restrictions
+ * on the LHS of `<`.
+ */
+
+// Testcase from https://github.com/swig/swig/issues/635
+#define TEST_A 1
+#define TEST_B 2
+#define TEST_C (TEST_A < TEST_B)
+#define TEST_D (TEST_A > TEST_B)
+// These have been supported since 1.3.41.
+#define TEST_E (TEST_A <= TEST_B)
+#define TEST_F (TEST_A >= TEST_B)
+// For completeness
+#define TEST_G (TEST_A == TEST_B)
+#define TEST_H (TEST_A != TEST_B)
+
+// No warning
+#if (TEST_A < TEST_B)
+#define TEST_I 1
+#else
+#define TEST_I 0
+#endif
+
+/* sizeof didn't work on an expression before SWIG 4.1.0 except for cases where
+ * the expression was in parentheses and looked syntactically like a type (so
+ * sizeof(X) worked because X could be a type syntactically).
+ */
+const int s1a = sizeof(X); /* worked before 4.1.0 */
+//const int s1b = sizeof X; /* not currently supported */
+const int s2a = sizeof("a string" );
+const int s2b = sizeof "a string";
+const int s3a = sizeof('c');
+const int s3b = sizeof('c');
+const int s4a = sizeof(L"a wstring");
+const int s4b = sizeof L"a wstring";
+const int s5a = sizeof(L'C');
+const int s5b = sizeof L'C';
+const int s6a = sizeof(sizeof(X));
+const int s6b = sizeof sizeof(X);
+const int s7a = sizeof(3.14);
+const int s7b = sizeof 3.14;
+const int s8a = sizeof(2.1e-6);
+const int s8b = sizeof 2.1e-6;
+
+%}
diff --git a/Examples/test-suite/constant_pointers.i b/Examples/test-suite/constant_pointers.i
index 9094e9dea..1e03b29ca 100644
--- a/Examples/test-suite/constant_pointers.i
+++ b/Examples/test-suite/constant_pointers.i
@@ -53,8 +53,6 @@ public:
int* array_member1[ARRAY_SIZE];
ParametersTest* array_member2[ARRAY_SIZE];
MemberVariablesTest() : member3(NULL), member4(NULL) {}
-private:
- MemberVariablesTest& operator=(const MemberVariablesTest&);
};
void foofunction(const int *const i) {}
@@ -80,8 +78,6 @@ public:
void ret8(int*const& a) {}
int*const& ret9() {return GlobalIntPtr;}
ReturnValuesTest() : int3(NULL) {}
-private:
- ReturnValuesTest& operator=(const ReturnValuesTest&);
};
const int* globalRet1() {return &GlobalInt;}
@@ -113,8 +109,6 @@ int* const globalRet2() {return &GlobalInt;}
A* ap;
const A* cap;
Acptr acptr;
- private:
- B& operator=(const B&);
};
const B* bar(const B* b) {
diff --git a/Examples/test-suite/contract.i b/Examples/test-suite/contract.i
index 0ad7e8e7c..de662c108 100644
--- a/Examples/test-suite/contract.i
+++ b/Examples/test-suite/contract.i
@@ -48,6 +48,7 @@ int test_prepost(int x, int y) {
}
%}
+#ifdef __cplusplus
/* Class tests */
%contract Foo::test_preassert(int x, int y) {
@@ -235,4 +236,4 @@ class myClass
};
}
-
+#endif
diff --git a/Examples/test-suite/contract_c.i b/Examples/test-suite/contract_c.i
new file mode 100644
index 000000000..465a7ded6
--- /dev/null
+++ b/Examples/test-suite/contract_c.i
@@ -0,0 +1,5 @@
+%module contract_c;
+
+%include <exception.i>
+
+%include "contract.i"
diff --git a/Examples/test-suite/cpp11_alternate_function_syntax.i b/Examples/test-suite/cpp11_alternate_function_syntax.i
index b3ecabc8c..2f5aaa41a 100644
--- a/Examples/test-suite/cpp11_alternate_function_syntax.i
+++ b/Examples/test-suite/cpp11_alternate_function_syntax.i
@@ -3,6 +3,8 @@
%module cpp11_alternate_function_syntax
%inline %{
+struct Hello {};
+
struct SomeStruct {
int addNormal(int x, int y);
auto addAlternate(int x, int y) -> int;
@@ -12,6 +14,9 @@ struct SomeStruct {
auto addAlternateMemberPtrParm(int x, int (SomeStruct::*mp)(int, int)) -> int;
auto addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int;
+ // Returning a reference didn't parse in SWIG < 4.1.0 (#231)
+ auto output() -> Hello&;
+
virtual auto addFinal(int x, int y) const noexcept -> int final { return x + y; }
virtual ~SomeStruct() = default;
};
@@ -27,5 +32,6 @@ auto SomeStruct::addAlternateMemberPtrParm(int x, int (SomeStruct::*mp)(int, int
auto SomeStruct::addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int {
return 1000*x + (this->*mp)(x, x);
}
+auto SomeStruct::output() -> Hello& { static Hello h; return h; }
%}
diff --git a/Examples/test-suite/cpp11_attribute_specifiers.i b/Examples/test-suite/cpp11_attribute_specifiers.i
new file mode 100644
index 000000000..b822d2ae9
--- /dev/null
+++ b/Examples/test-suite/cpp11_attribute_specifiers.i
@@ -0,0 +1,54 @@
+%module cpp11_attribute_specifiers
+
+%inline %{
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // We're using a deprecated attribute here...
+#pragma GCC diagnostic ignored "-Wattributes" // likely is C++20
+#pragma GCC diagnostic ignored "-Wunused-variable" // We are using an unused variable on purpose here
+#pragma GCC diagnostic ignored "-Wunused-parameter" // We are using an unused param on purpose here
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#pragma clang diagnostic ignored "-Wattributes"
+#pragma clang diagnostic ignored "-Wunused-variable"
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4996) // For the deprecated attributes in this testcase
+#endif
+
+
+[[noreturn]] void noReturn() { throw; }
+[[nodiscard]] bool noDiscard() { return true; }
+[[nodiscard, deprecated("This has been replaced")]] bool noDiscardDeprecated() { return true; }
+void maybeUnused1([[maybe_unused]] bool b) { }
+bool maybeUnused2(bool a, [[maybe_unused]] bool b) { return a; }
+
+[[deprecated, nodiscard]] bool likely([[maybe_unused]] bool a, bool b) {
+ [[maybe_unused]] bool c = b;
+ if (b) [[likely]] {
+ return true;
+ } else [[unlikely]] {
+ if(a) {
+ return true;
+ }
+ }
+ return false;
+}
+
+struct [[nodiscard]] S { };
+
+const char *test_string_literal() { return "Test [[ and ]] in string literal"; }
+
+#if 0
+// Check that SWIG doesn't choke on ]] when it's not part of an attribute.
+// FIXME: SWIG's parser doesn't handle this case currently.
+int *a;
+int b = a[a[0]];
+#endif
+
+%}
diff --git a/Examples/test-suite/cpp11_constexpr.i b/Examples/test-suite/cpp11_constexpr.i
index 420db4f83..5ba9ff243 100644
--- a/Examples/test-suite/cpp11_constexpr.i
+++ b/Examples/test-suite/cpp11_constexpr.i
@@ -53,3 +53,12 @@ int Array300[ConstExpressions::LLL];
//int Array400[ConstExpressions::MMM()];
//int Array500[ConstExpressions::NNN()];
%}
+
+%{
+// Test handling of ID PERIOD ID in constant expressions (supported since 4.1.0).
+struct A {
+ int i;
+};
+constexpr A a{42};
+constexpr int N = a.i;
+%}
diff --git a/Examples/test-suite/cpp11_final_class.i b/Examples/test-suite/cpp11_final_class.i
new file mode 100644
index 000000000..4f2429320
--- /dev/null
+++ b/Examples/test-suite/cpp11_final_class.i
@@ -0,0 +1,141 @@
+%module cpp11_final_class
+
+%warnfilter(SWIGWARN_PARSE_KEYWORD) final; // 'final' is a java keyword, renaming to '_final'
+%warnfilter(SWIGWARN_PARSE_KEYWORD) override; // 'override' is a C# keyword, renaming to '_override'
+
+%ignore Space1::final::operator=;
+#if defined(SWIGPHP)
+%rename(Space1_final) Space1::final::final;
+#endif
+#if defined(SWIGOCAML)
+%rename(finale) BrokenSpace::FinalEnum1::final;
+#endif
+
+%inline %{
+struct FinalBase {
+ virtual ~FinalBase() {}
+};
+
+struct FinalClass1 final : FinalBase {
+ void method1() {}
+};
+
+class FinalClass2 final : public FinalBase {
+public:
+ void method2() {}
+};
+
+struct FinalClass3 final {
+ void method3() {}
+};
+
+struct FinalClass4 {
+ void method4() {}
+} final;
+
+struct override final {
+ void omethod() {}
+};
+%}
+
+%rename(Space1_final) Space1::final;
+
+%inline %{
+namespace Space1 {
+struct final final {
+ void finalmethod() {}
+ final() {}
+ final(const final &other) = default;
+ final& operator=(const final &other) = default;
+};
+struct FinalClass5 final {
+ void method5() {}
+ final final_member_var;
+ final get_final_member() { return final_member_var; }
+ Space1::final get_final_member2() { return final_member_var; }
+};
+struct FinalClass6 {
+ void method6() {}
+ virtual void final() final {}
+ virtual ~FinalClass6() = default;
+};
+typedef final Space1_final_typedef1;
+typedef struct final Space1_final_typedef2;
+}
+typedef Space1::final Space1_final_typedef3;
+typedef struct Space1::final Space1_final_typedef4;
+%}
+
+%inline %{
+namespace Space2 {
+class Y {
+public:
+ Y(int i=0) {}
+};
+
+struct FinalVar1 {
+ class Y notfinal;
+// class Y final; // SWIG (C++ only) fails to parse (same for struct and union)
+};
+struct FinalVar2 {
+ class Y notfinal = {};
+// class Y final = {}; // SWIG (C++ only) fails to parse (same for struct and union)
+};
+struct FinalVar3 {
+ class Y notfinal = Y();
+// class Y final = Y(); // SWIG (C++ only) fails to parse (same for struct and union)
+};
+struct FinalVar4 {
+ class Y* final;
+ FinalVar4() : final() {}
+};
+struct FinalVar5 {
+ Y final;
+};
+struct FinalVar6 {
+ Y final = {};
+};
+struct FinalVar7 {
+ Y final = Y();
+};
+struct FinalVar8 {
+ Y final{};
+};
+struct FinalVar9 {
+ Y final{9};
+};
+struct FinalVar10 {
+ void b10(Y final) {}
+};
+}
+%}
+
+// Unfortunately the use of final in BrokenSpace does not work with Visual C++
+// so we limit testing to parsing these by SWIG and then ignoring it all.
+%ignore BrokenSpace::FinalVar11;
+%ignore BrokenSpace::FinalEnum1;
+%ignore BrokenSpace::FinalEnum2;
+
+namespace BrokenSpace {
+using Space2::Y;
+struct FinalVar11 {
+ void a11(class Y final) {}
+};
+struct FinalEnum1 {
+ enum Enum1 { one, two, final };
+ void enum_in(Enum1 e) {}
+};
+struct FinalEnum2 {
+ enum Enum2 { one, two, three, four };
+ enum Enum2 final;
+};
+}
+
+%rename(Space3_final) Space3::final;
+%inline %{
+namespace Space3 {
+ typedef struct final {
+ void fmethod() {}
+ } final;
+}
+%}
diff --git a/Examples/test-suite/cpp11_final_override.i b/Examples/test-suite/cpp11_final_override.i
index 849655b16..ac14326e5 100644
--- a/Examples/test-suite/cpp11_final_override.i
+++ b/Examples/test-suite/cpp11_final_override.i
@@ -27,7 +27,7 @@ struct Base {
virtual ~Base() {}
};
-struct Derived /*final*/ : Base {
+struct Derived final : Base {
virtual void stuff() const noexcept override final {}
virtual void override1() const noexcept override;
virtual void override2() const noexcept override;
diff --git a/Examples/test-suite/cpp11_initializer_list.i b/Examples/test-suite/cpp11_initializer_list.i
index b309576c1..c1646248c 100644
--- a/Examples/test-suite/cpp11_initializer_list.i
+++ b/Examples/test-suite/cpp11_initializer_list.i
@@ -10,7 +10,7 @@
$1 = {"Ab", "Fab"};
%}
-%begin %{
+%runtime %{
#if __GNUC__ >= 9
/* warning: ‘new’ of initializer_list does not extend the lifetime of the underlying array [-Winit-list-lifetime] */
/* incorrect warning for C::C(std::initializer_list<const char *>) */
diff --git a/Examples/test-suite/cpp11_move_only.i b/Examples/test-suite/cpp11_move_only.i
new file mode 100644
index 000000000..b7db92b3b
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_only.i
@@ -0,0 +1,61 @@
+%module cpp11_move_only
+
+%include "cpp11_move_only_helper.i"
+
+#if defined(SWIGOCAML)
+%rename(valu) val;
+#endif
+
+%ignore MoveOnly::operator=;
+//%valuewrapper MoveOnly; // SWIG sets %valuewrapper by default for move-only types
+
+%inline %{
+#include <iostream>
+using namespace std;
+
+bool trace = false;
+
+struct MoveOnly {
+ int val;
+ MoveOnly(int i = 0) : val(i) { if (trace) cout << "MoveOnly(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+ MoveOnly(const MoveOnly &other) = delete;
+ MoveOnly & operator=(const MoveOnly &other) = delete;
+
+ MoveOnly(MoveOnly &&other) noexcept : val(std::move(other.val)) { if (trace) cout << "MoveOnly(MoveOnly &&)" << " " << this << endl; Counter::move_constructor++; }
+ MoveOnly & operator=(MoveOnly &&other) noexcept { if (trace) cout << "operator=(MoveOnly &&)" << " " << this << endl; Counter::move_assignment++; if (this != &other) { val = std::move(other.val); } return *this; }
+ ~MoveOnly() { if (trace) cout << "~MoveOnly()" << " " << this << endl; Counter::destructor++; }
+
+ static MoveOnly create() { return MoveOnly(111); }
+ // static const MoveOnly createConst() { return MoveOnly(111); } // not supported by default
+
+ // compile error by default, see cpp11_move_typemaps.i
+ #if defined(WRAP_TAKE_METHOD)
+ static void take(MoveOnly mo) { if (trace) cout << "take(MoveOnly)" << " " << &mo << endl; }
+ #endif
+};
+%}
+
+%ignore MovableCopyable::operator=;
+%ignore MovableCopyable::MovableCopyable(MovableCopyable &&);
+// %valuewrapper MovableCopyable; // SWIG does not use valuewrapper by default for copyable types with a default constructor
+
+%inline %{
+// Movable and Copyable
+struct MovableCopyable {
+ int val;
+ MovableCopyable(int i = 0) : val(i) { if (trace) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+ MovableCopyable(const MovableCopyable &other) : val(other.val) { if (trace) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+ MovableCopyable & operator=(const MovableCopyable &other) { if (trace) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; if (this != &other) { val = other.val; } return *this; }
+
+ MovableCopyable(MovableCopyable &&other) noexcept : val(std::move(other.val)) { if (trace) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
+ MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (trace) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; if (this != &other) { val = std::move(other.val); } return *this; }
+ ~MovableCopyable() { if (trace) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
+
+ static MovableCopyable create() { return MovableCopyable(111); }
+ static const MovableCopyable createConst() { return MovableCopyable(111); }
+
+ static void take(MovableCopyable mc) { if (trace) cout << "take(MovableCopyable)" << " " << &mc << endl; }
+};
+%}
diff --git a/Examples/test-suite/cpp11_move_only_helper.i b/Examples/test-suite/cpp11_move_only_helper.i
new file mode 100644
index 000000000..89fc1509b
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_only_helper.i
@@ -0,0 +1,71 @@
+// Helper interface for cpp11_move_only.i and others
+
+%include <std_string.i>
+%catches(std::string) Counter::check_counts;
+
+%inline %{
+#include <sstream>
+using namespace std;
+
+
+struct Counter {
+ static int normal_constructor;
+ static int copy_constructor;
+ static int copy_assignment;
+ static int move_constructor;
+ static int move_assignment;
+ static int destructor;
+ static void reset_counts() {
+ normal_constructor = 0;
+ copy_constructor = 0;
+ copy_assignment = 0;
+ move_constructor = 0;
+ move_assignment = 0;
+ destructor = 0;
+ }
+ // Check against expected counts of constructor, assignment operators etc.
+ // Not observed during development, but compiler optimisation could change the expected values.
+ // Throws exception if not correct (use %catches to catch them)
+ static void check_counts(
+ int normal_constructor,
+ int copy_constructor,
+ int copy_assignment,
+ int move_constructor,
+ int move_assignment,
+ int destructor) {
+ bool match = (
+ normal_constructor == Counter::normal_constructor &&
+ copy_constructor == Counter::copy_constructor &&
+ copy_assignment == Counter::copy_assignment &&
+ move_constructor == Counter::move_constructor &&
+ move_assignment == Counter::move_assignment &&
+ destructor == Counter::destructor);
+ if (!match) {
+ std::stringstream ss;
+ ss << "check_counts failed" << std::endl <<
+ Counter::normal_constructor << " " <<
+ Counter::copy_constructor << " " <<
+ Counter::copy_assignment << " " <<
+ Counter::move_constructor << " " <<
+ Counter::move_assignment << " " <<
+ Counter::destructor << " " <<
+ " (actual)" << std::endl <<
+ normal_constructor << " " <<
+ copy_constructor << " " <<
+ copy_assignment << " " <<
+ move_constructor << " " <<
+ move_assignment << " " <<
+ destructor << " " <<
+ " (expected)" << std::endl;
+ throw ss.str();
+ }
+ }
+};
+
+int Counter::normal_constructor = 0;
+int Counter::copy_constructor = 0;
+int Counter::copy_assignment = 0;
+int Counter::move_constructor = 0;
+int Counter::move_assignment = 0;
+int Counter::destructor = 0;
+%}
diff --git a/Examples/test-suite/cpp11_move_only_valuewrapper.i b/Examples/test-suite/cpp11_move_only_valuewrapper.i
new file mode 100644
index 000000000..d9162bf3e
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_only_valuewrapper.i
@@ -0,0 +1,180 @@
+%module cpp11_move_only_valuewrapper
+
+/*
+ * This test case checks SwigValueWrapper and move assignment.
+ * Although not necessary, the test case was developed testing with C++98 compatibility for comparing improvements.
+ * C++11 and later is of course required for the move assignment support.
+ * C++98 is not actually necessary now as the test-suite only runs this test with compilers that support C++11 and later.
+*/
+
+%{
+#include <iostream>
+#include <sstream>
+using std::cout;
+using std::endl;
+
+#if __cplusplus >= 201103L
+#include <memory>
+#else
+namespace std {
+ // just something that will compile and vaguely work for when c++11 is not supported
+ template <class T> class unique_ptr {
+ T *ptr;
+ public:
+ unique_ptr(T *ptr = 0) : ptr(ptr) {}
+ unique_ptr(const unique_ptr &a) : ptr(a.ptr) { /*please look away*/ const_cast<unique_ptr &>(a).ptr = 0;}
+ ~unique_ptr() { delete ptr; }
+ unique_ptr& operator=(const unique_ptr &a) {
+ if (&a != this) {
+ delete ptr;
+ ptr = a.ptr;
+ /*please look away*/ const_cast<unique_ptr &>(a).ptr = 0;
+ }
+ return *this;
+ }
+ };
+}
+#endif
+%}
+
+%include "cpp11_move_only_helper.i"
+
+%valuewrapper XXX;
+%ignore XXX::operator=;
+
+%inline %{
+bool trace = false;
+struct XXX {
+ XXX(int i = 0) { if (trace) cout << "XXX(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+ XXX(const XXX &other) { if (trace) cout << "XXX(const XXX &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+ XXX & operator=(const XXX &other) { if (trace) cout << "operator=(const XXX &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
+#if defined(__cplusplus) && __cplusplus >= 201103L
+ XXX(XXX &&other) noexcept { if (trace) cout << "XXX(XXX &&)" << " " << this << endl; Counter::move_constructor++; }
+ XXX & operator=(XXX &&other) noexcept { if (trace) cout << "operator=(XXX &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
+#endif
+ ~XXX() { if (trace) cout << "~XXX()" << " " << this << endl; Counter::destructor++; }
+};
+
+bool has_cplusplus11() {
+#if __cplusplus >= 201103L
+ return true;
+#else
+ return false;
+#endif
+}
+%}
+
+std::unique_ptr<XXX> makeUniqueXXX();
+void cleanup(std::unique_ptr<XXX>* p);
+
+%{
+std::unique_ptr<XXX> makeUniqueXXX() {
+ if (trace) cout << "makeUniqueXXX()" << endl;
+ return std::unique_ptr<XXX>(new XXX(11));
+}
+void cleanup(std::unique_ptr<XXX>* p) {
+ delete p;
+}
+typedef XXX UUU;
+%}
+
+%inline %{
+XXX createXXX() {
+ if (trace) cout << "createXXX()" << endl;
+ return XXX(111);
+}
+XXX createXXX2() {
+ if (trace) cout << "createXXX2()" << endl;
+ return XXX(222);
+}
+UUU createUnknownType() {
+ if (trace) cout << "createXXX2()" << endl;
+ return XXX(222);
+}
+struct YYY {};
+void inputByValue(UUU uuu, XXX xxx, YYY yyy) {}
+%}
+
+
+%catches(std::string) test1;
+%catches(std::string) test2;
+%catches(std::string) test3;
+%catches(std::string) test4;
+%catches(std::string) test5;
+%catches(std::string) test6;
+
+%inline %{
+// 'unit tests' for SwigValueWrapper
+void test1() {
+ Counter::reset_counts();
+ {
+ SwigValueWrapper<XXX> x;
+ x = XXX();
+ }
+#if __cplusplus >= 201103L
+ Counter::check_counts(1, 0, 0, 1, 0, 2); // was same as < c++11 counts below before move assignment operator added to SwigValueWrapper
+#else
+ Counter::check_counts(1, 1, 0, 0, 0, 2);
+#endif
+}
+void test2() {
+ Counter::reset_counts();
+ {
+ SwigValueWrapper<XXX> x;
+ x = XXX();
+ x = XXX();
+ }
+#if __cplusplus >= 201103L
+ Counter::check_counts(2, 0, 0, 2, 0, 4);
+#else
+ Counter::check_counts(2, 2, 0, 0, 0, 4);
+#endif
+}
+void test3() {
+ Counter::reset_counts();
+ {
+ SwigValueWrapper<XXX> x;
+ XXX a(999);
+#if __cplusplus >= 201103L
+ x = std::move(a);
+#endif
+ }
+#if __cplusplus >= 201103L
+ Counter::check_counts(1, 0, 0, 1, 0, 2);
+#endif
+}
+void test4() {
+ Counter::reset_counts();
+ {
+ SwigValueWrapper<std::unique_ptr<XXX> > x;
+ x = std::unique_ptr<XXX>(new XXX(444));
+ }
+ Counter::check_counts(1, 0, 0, 0, 0, 1);
+}
+void test5() {
+#if __cplusplus >= 201103L
+ Counter::reset_counts();
+ {
+ SwigValueWrapper<std::unique_ptr<XXX> > x;
+ x = std::unique_ptr<XXX>(new XXX(550));
+ std::unique_ptr<XXX> x2(new XXX(555));
+ x = std::move(x2);
+ }
+ Counter::check_counts(2, 0, 0, 0, 0, 2);
+#endif
+}
+void test6() {
+#if __cplusplus >= 201103L
+ Counter::reset_counts();
+ {
+ // emulates how std::unique_ptr typemaps could be wrapped with SwigValueWrapper
+ void *ptr = 0;
+ SwigValueWrapper<std::unique_ptr<XXX> > x; // SWIG generated if std::unique_ptr<> definition not parsed
+ x = makeUniqueXXX(); // SWIG generated code wrapping function returning std::unique_ptr
+ ptr = new std::unique_ptr<XXX>(x); // 'out' typemap (move std::unique_ptr from stack to the heap)
+ delete (std::unique_ptr<XXX> *)ptr; // Final cleanup (user needs to call this)
+ }
+ Counter::check_counts(1, 0, 0, 0, 0, 1);
+#endif
+}
+%}
diff --git a/Examples/test-suite/cpp11_move_typemaps.i b/Examples/test-suite/cpp11_move_typemaps.i
new file mode 100644
index 000000000..706780ad4
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_typemaps.i
@@ -0,0 +1,12 @@
+%module cpp11_move_typemaps
+
+%include <swigmove.i>
+%apply SWIGTYPE MOVE { MoveOnly mo }
+%valuewrapper MovableCopyable;
+%apply SWIGTYPE MOVE { MovableCopyable mc }
+
+%inline %{
+#define WRAP_TAKE_METHOD
+%}
+
+%include "cpp11_move_only.i"
diff --git a/Examples/test-suite/cpp11_raw_string_literals.i b/Examples/test-suite/cpp11_raw_string_literals.i
index 813374928..fb861377e 100644
--- a/Examples/test-suite/cpp11_raw_string_literals.i
+++ b/Examples/test-suite/cpp11_raw_string_literals.i
@@ -1,7 +1,7 @@
/* This module tests whether SWIG correctly parses:
- - ordinary strings (char_t)
+ - ordinary strings (char)
- L wide strings (wchar_t)
- - u8 unicode8 strings (char_t)
+ - u8 unicode8 strings (char / char8_t since C++20)
- u unicode16 strings (char16_t)
- U unicode32 strings (char32_t)
@@ -49,7 +49,8 @@ struct URStruct {
// New string literals
wstring aa = L"Wide string";
-const char *bb = u8"UTF-8 string";
+// u8"" is const char8_t[N] in C++20; const char[N] from C++11 until then.
+const char *bb = reinterpret_cast<const char*>(u8"UTF-8 string");
const char16_t *cc = u"UTF-16 string";
const char32_t *dd = U"UTF-32 string";
// New char literals
@@ -62,7 +63,7 @@ char32_t char32_t_char = U'b';
const char *xx = ")I'm an \"ascii\" \\ string.";
const char *ee = R"XXX()I'm an "ascii" \ string.)XXX";
wstring ff = LR"XXX(I'm a "raw wide" \ string.)XXX";
-const char *gg = u8R"XXX(I'm a "raw UTF-8" \ string.)XXX";
+const char *gg = reinterpret_cast<const char*>(u8R"XXX(I'm a "raw UTF-8" \ string.)XXX");
const char16_t *hh = uR"XXX(I'm a "raw UTF-16" \ string.)XXX";
const char32_t *ii = UR"XXX(I'm a "raw UTF-32" \ string.)XXX";
%}
diff --git a/Examples/test-suite/cpp11_result_of.i b/Examples/test-suite/cpp11_result_of.i
index 8a26c5f24..f37705415 100644
--- a/Examples/test-suite/cpp11_result_of.i
+++ b/Examples/test-suite/cpp11_result_of.i
@@ -2,11 +2,28 @@
and its templating capabilities introduced in C++11. */
%module cpp11_result_of
+// std::result_of is deprecated in C++17
+// Replace std implementation with a simple implementation in order to continue testing with C++17 compilers and later
+
%inline %{
-#include <functional>
typedef double(*fn_ptr)(double);
%}
+%{
+#if __cplusplus >= 201703L
+namespace std {
+ // Forward declaration of result_of
+ template<typename Func> struct result_of;
+ // Add in the required partial specialization of result_of
+ template<> struct result_of< fn_ptr(double) > {
+ typedef double type;
+ };
+}
+#else
+#include <functional>
+#endif
+%}
+
namespace std {
// Forward declaration of result_of
template<typename Func> struct result_of;
@@ -34,22 +51,14 @@ std::result_of< fn_ptr(double) >::type test_result_alternative1(double(*fun)(dou
}
%}
-%{
-// Another alternative approach using decltype (not very SWIG friendly)
-std::result_of< decltype(square)&(double) >::type test_result_alternative2(double(*fun)(double), double arg) {
- return fun(arg);
-}
-%}
-
%inline %{
#include <iostream>
void cpp_testing() {
- std::cout << "result: " << test_result_impl(square, 3) << std::endl;
- std::cout << "result: " << test_result_impl<double(*)(double), double>(square, 4) << std::endl;
- std::cout << "result: " << test_result_impl< fn_ptr, double >(square, 5) << std::endl;
- std::cout << "result: " << test_result_alternative1(square, 6) << std::endl;
- std::cout << "result: " << test_result_alternative2(square, 7) << std::endl;
+ std::cout << "result: " << test_result_impl(square, 3.0) << std::endl;
+ std::cout << "result: " << test_result_impl<double(*)(double), double>(square, 4.0) << std::endl;
+ std::cout << "result: " << test_result_impl< fn_ptr, double >(square, 5.0) << std::endl;
+ std::cout << "result: " << test_result_alternative1(square, 6.0) << std::endl;
}
%}
diff --git a/Examples/test-suite/cpp11_rvalue_reference2.i b/Examples/test-suite/cpp11_rvalue_reference2.i
index a2a0020f5..a3af6daf8 100644
--- a/Examples/test-suite/cpp11_rvalue_reference2.i
+++ b/Examples/test-suite/cpp11_rvalue_reference2.i
@@ -20,10 +20,10 @@ static const bool PublicGlobalTrue = true;
static const UserDef PublicUserDef = UserDef();
struct Thingy {
typedef int Integer;
- int val;
+ int valval;
int &lvalref;
int &&rvalref;
- Thingy(int v, int &&rvalv) : val(v), lvalref(val), rvalref(std::move(rvalv)) {}
+ Thingy(int v, int &&rvalv) : valval(v), lvalref(valval), rvalref(std::move(rvalv)) {}
void refIn(long &i) {}
void rvalueIn(long &&i) {}
short && rvalueInOut(short &&i) { return std::move(i); }
@@ -31,10 +31,10 @@ struct Thingy {
// test both primitive and user defined rvalue reference default arguments and compactdefaultargs
void compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u = (const UserDef &&)PublicUserDef) {}
void privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue) {}
- operator int &&() { return std::move(val); }
- Thingy(const Thingy& rhs) : val(rhs.val), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {}
+ operator int &&() { return std::move(valval); }
+ Thingy(const Thingy& rhs) : valval(rhs.valval), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {}
Thingy& operator=(const Thingy& rhs) {
- val = rhs.val;
+ valval = rhs.valval;
lvalref = rhs.lvalref;
rvalref = rhs.rvalref;
return *this;
diff --git a/Examples/test-suite/cpp11_rvalue_reference_move.i b/Examples/test-suite/cpp11_rvalue_reference_move.i
new file mode 100644
index 000000000..04cd2b869
--- /dev/null
+++ b/Examples/test-suite/cpp11_rvalue_reference_move.i
@@ -0,0 +1,52 @@
+%module cpp11_rvalue_reference_move
+
+// Testcase for testing rvalue reference input typemaps which assume the object is moved during a function call
+
+%include "cpp11_move_only_helper.i"
+
+%catches(std::string) MovableCopyable::check_numbers_match;
+
+%rename(MoveAssign) MovableCopyable::operator=(MovableCopyable &&);
+%ignore MovableCopyable::operator=(const MovableCopyable &); // ignore copy assignment operator, keep move assignment operator
+%ignore MovableCopyable::MovableCopyable(const MovableCopyable &); // ignore copy constructor, keep the move constructor
+
+%inline %{
+#include <iostream>
+using namespace std;
+
+bool trace = false;
+
+class MovableCopyable {
+ int num;
+public:
+ MovableCopyable(int i = 0) : num(i) { if (trace) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+ MovableCopyable(const MovableCopyable &other) : num(other.num) { if (trace) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+ MovableCopyable & operator=(const MovableCopyable &other) { if (trace) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; num = other.num; return *this; }
+
+ MovableCopyable(MovableCopyable &&other) noexcept : num(std::move(other.num)) { if (trace) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
+ MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (trace) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; num = std::move(other.num); return *this; }
+ ~MovableCopyable() { if (trace) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
+
+ int getNum() { return num; }
+
+ static void movein(MovableCopyable &&mcin) {
+ MovableCopyable mc = std::move(mcin);
+ }
+
+ static MovableCopyable && moveout(int i) {
+ static MovableCopyable instance;
+ instance = MovableCopyable(i);
+ return std::move(instance);
+ }
+
+ static bool is_nullptr(MovableCopyable *p) {
+ return p == nullptr;
+ }
+
+ static void check_numbers_match(MovableCopyable *p, int expected_num) {
+ if (p->num != expected_num)
+ throw std::string("Numbers don't match");
+ }
+};
+%}
diff --git a/Examples/test-suite/cpp11_std_array.i b/Examples/test-suite/cpp11_std_array.i
index 3d4771551..9dc11ce9e 100644
--- a/Examples/test-suite/cpp11_std_array.i
+++ b/Examples/test-suite/cpp11_std_array.i
@@ -1,6 +1,6 @@
%module cpp11_std_array
-#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGJAVA) || defined(SWIGCSHARP)
+#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGGO)
%{
#include <array>
diff --git a/Examples/test-suite/cpp11_std_unique_ptr.i b/Examples/test-suite/cpp11_std_unique_ptr.i
new file mode 100644
index 000000000..f360d8cf3
--- /dev/null
+++ b/Examples/test-suite/cpp11_std_unique_ptr.i
@@ -0,0 +1,107 @@
+%module cpp11_std_unique_ptr
+
+#if !(defined(SWIGGO) || defined(SWIGOCAML) || defined(SWIGR) || defined(SWIGSCILAB))
+
+%warnfilter(509, 516) overloadTest(Klass);
+
+%include "std_string.i"
+%include "std_unique_ptr.i"
+
+%unique_ptr(Klass)
+
+%inline %{
+#include <memory>
+#include <string>
+//#include <iostream>
+#include "swig_examples_lock.h"
+
+class Klass {
+public:
+ explicit Klass(const char* label) :
+ m_label(label)
+ {
+ SwigExamples::Lock lock(critical_section);
+ total_count++;
+ }
+
+ const char* getLabel() const { return m_label.c_str(); }
+
+ virtual ~Klass()
+ {
+ SwigExamples::Lock lock(critical_section);
+ total_count--;
+ }
+
+ static int getTotal_count() { return total_count; }
+
+private:
+ static SwigExamples::CriticalSection critical_section;
+ static int total_count;
+
+ std::string m_label;
+};
+
+SwigExamples::CriticalSection Klass::critical_section;
+int Klass::total_count = 0;
+
+%}
+
+%inline %{
+
+// Virtual inheritance used as this usually results in different values for Klass* and KlassInheritance*
+// for testing class inheritance and unique_ptr
+struct KlassInheritance : virtual Klass {
+ KlassInheritance(const char* label) : Klass(label) {
+ // std::cout << "ptrs.... " << std::hex << (Klass*)this << " " << (KlassInheritance*)this << std::endl;
+ }
+};
+
+std::string useKlassRawPtr(Klass* k) {
+// std::cout << "useKlassRawPtr " << std::hex << (Klass*)k << std::endl;
+ std::string s(k->getLabel());
+// std::cout << "useKlassRawPtr string: " << s << std::endl;
+ return s;
+}
+
+std::string takeKlassUniquePtr(std::unique_ptr<Klass> k) {
+// std::cout << "takeKlassUniquePtr " << std::hex << (Klass*)k.get() << std::endl;
+ std::string s(k ? k->getLabel() : "null smart pointer");
+// std::cout << "takeKlassUniquePtr string: " << s << std::endl;
+ return s;
+}
+
+Klass *make_null() {
+ return nullptr;
+}
+
+bool is_nullptr(Klass *p) {
+ return p == nullptr;
+}
+
+Klass *get_not_owned_ptr(Klass *p) {
+ return p;
+}
+
+std::unique_ptr<Klass> makeKlassUniquePtr(const char* label) {
+ return std::unique_ptr<Klass>(new Klass(label));
+}
+
+std::unique_ptr<Klass> makeNullUniquePtr() {
+ return std::unique_ptr<Klass>();
+}
+
+int overloadTest() {
+ return 0;
+}
+
+int overloadTest(std::unique_ptr<Klass> kover) {
+ return 1;
+}
+
+int overloadTest(Klass k) {
+ return 2;
+}
+
+%}
+
+#endif
diff --git a/Examples/test-suite/cpp11_template_explicit.i b/Examples/test-suite/cpp11_template_explicit.i
index 71752f822..950f1d265 100644
--- a/Examples/test-suite/cpp11_template_explicit.i
+++ b/Examples/test-suite/cpp11_template_explicit.i
@@ -4,13 +4,15 @@
*/
%module cpp11_template_explicit
+/* Suppress SWIG warnings related to explicit template instantiation and extern templates */
#pragma SWIG nowarn=SWIGWARN_PARSE_EXPLICIT_TEMPLATE
+#pragma SWIG nowarn=SWIGWARN_PARSE_EXTERN_TEMPLATE
%inline %{
template<typename T> class Temper {
public:
- T val;
+ T valu;
};
class A {
@@ -33,6 +35,30 @@ extern template class Temper<B*>;
template class Temper<int>;
extern template class Temper<short>;
+
+/* Templated function to check support for extern template functions */
+template <typename T>
+T my_templated_function(int a, double b)
+{
+ return T();
+}
+
+/* Explicit extern function template instantiation with simple type */
+extern template int my_templated_function<int>(int, double);
+template int my_templated_function<int>(int, double);
+
+/* Explicit extern function template instantiation with more complex types */
+extern template A my_templated_function<A>(int, double);
+template A my_templated_function<A>(int, double);
+
+extern template Temper<int> my_templated_function<Temper<int>>(int, double);
+template Temper<int> my_templated_function<Temper<int>>(int, double);
+
%}
%template(TemperInt) Temper<int>;
+
+/* Enable several versions of the templated function */
+%template(my_templated_function_int ) my_templated_function<int>;
+%template(my_templated_function_A ) my_templated_function<A>;
+%template(my_templated_function_TemperInt) my_templated_function<Temper<int>>;
diff --git a/Examples/test-suite/cpp11_thread_local.i b/Examples/test-suite/cpp11_thread_local.i
index 21f21859b..a85289149 100644
--- a/Examples/test-suite/cpp11_thread_local.i
+++ b/Examples/test-suite/cpp11_thread_local.i
@@ -16,7 +16,9 @@ thread_local static int tsval;
extern thread_local int etval;
thread_local extern int teval;
extern "C" thread_local int ectval;
+extern "C" { thread_local int ectval2 = 56; }
extern "C++" thread_local int ecpptval;
+extern "C++" { thread_local int ecpptval2 = 67; }
thread_local int ThreadLocals::stval = 11;
thread_local int ThreadLocals::tsval = 22;
@@ -30,6 +32,10 @@ thread_local const int ThreadLocals::tscval99;
// externs
thread_local int etval = 33;
thread_local int teval = 44;
+extern "C" {
thread_local int ectval = 55;
+}
+extern "C++" {
thread_local int ecpptval = 66;
+}
%}
diff --git a/Examples/test-suite/cpp11_type_traits.i b/Examples/test-suite/cpp11_type_traits.i
index 715ce99fa..45077f728 100644
--- a/Examples/test-suite/cpp11_type_traits.i
+++ b/Examples/test-suite/cpp11_type_traits.i
@@ -4,6 +4,8 @@
// This doesn't really directly test functionality in type_traits as it doesn't provide
// much for use by target languages, rather it tests usage of it.
+%warnfilter(509) elaborate;
+
%inline %{
#include <type_traits>
diff --git a/Examples/test-suite/cpp11_userdefined_literals.i b/Examples/test-suite/cpp11_userdefined_literals.i
index 43103cc8c..37dc6c5ff 100644
--- a/Examples/test-suite/cpp11_userdefined_literals.i
+++ b/Examples/test-suite/cpp11_userdefined_literals.i
@@ -17,8 +17,8 @@
#include <iostream>
struct OutputType {
- int val;
- OutputType(int v) : val(v) {}
+ int valu;
+ OutputType(int v) : valu(v) {}
};
// Raw literal
@@ -30,6 +30,9 @@ OutputType operator "" _mySuffixFloat(long double) { return OutputType(30); }
// Cooked string literals
OutputType operator "" _mySuffix1(const char * string_values, size_t num_chars) { return OutputType(100); }
+#ifdef __cpp_lib_char8_t // For C++20
+OutputType operator "" _mySuffix1(const char8_t * string_values, size_t num_chars) { return OutputType(100); }
+#endif
OutputType operator "" _mySuffix2(const wchar_t * string_values, size_t num_chars) { return OutputType(200); }
OutputType operator "" _mySuffix3(const char16_t * string_values, size_t num_chars) { return OutputType(300); }
OutputType operator "" _mySuffix4(const char32_t * string_values, size_t num_chars) { return OutputType(400); }
diff --git a/Examples/test-suite/cpp14_binary_integer_literals.i b/Examples/test-suite/cpp14_binary_integer_literals.i
index 9c696b5a5..0cabb1c74 100644
--- a/Examples/test-suite/cpp14_binary_integer_literals.i
+++ b/Examples/test-suite/cpp14_binary_integer_literals.i
@@ -1,31 +1,17 @@
%module cpp14_binary_integer_literals
-// Tests are designed so that code compiles with C++98 compilers
-
-%{
-#if __cplusplus >= 201402L
-#define CPP14 1
+#if 0b100 < 4
+# error binary constant in preprocessor expression failed
#endif
-%}
-
-int b1 = 0b1;
-int b2 = 0b10;
-long b3 = 0b11l;
-unsigned long b4 = 0b100ul;
-unsigned long b5 = 0B101UL;
-%{
-#if defined(CPP14)
+%inline %{
int b1 = 0b1;
int b2 = 0b10;
long b3 = 0b11l;
unsigned long b4 = 0b100ul;
unsigned long b5 = 0B101UL;
-#else
-int b1 = 1;
-int b2 = 2;
-long b3 = 3;
-unsigned long b4 = 4;
-unsigned long b5 = 5;
-#endif
+#define b6 0b110
+const int b7 = 0b111;
%}
+
+%constant int b8 = 0b1000;
diff --git a/Examples/test-suite/cpp17_hex_floating_literals.i b/Examples/test-suite/cpp17_hex_floating_literals.i
index dfc1dc0cf..dd8e09936 100644
--- a/Examples/test-suite/cpp17_hex_floating_literals.i
+++ b/Examples/test-suite/cpp17_hex_floating_literals.i
@@ -1,25 +1,6 @@
%module cpp17_hex_floating_literals
-// Tests are designed so that code compiles with C++98 compilers
-
-%{
-#if __cplusplus >= 201703L
-#define CPP17 1
-#endif
-%}
-
-double f1 = 0x.0p1;
-double f2 = 0x0.p1;
-double f3 = 0x0.0p-1;
-double f4 = 0xf.p-1;
-double f5 = 0xA.0p1;
-double f6 = 0x0.10P+10;
-double f7 = 0xb2F.p2;
-float f8 = 0x1234AP1F;
-float f9 = 0x45A1.D1A2p+10f;
-
-%{
-#if defined(CPP17)
+%inline %{
double f1 = 0x.0p1;
double f2 = 0x0.p1;
double f3 = 0x0.0p-1;
@@ -29,15 +10,4 @@ double f6 = 0x0.10P+10;
double f7 = 0xb2F.p2;
float f8 = 0x1234AP1F;
float f9 = 0x45A1.D1A2p+10f;
-#else
-double f1 = 0.;
-double f2 = 0.;
-double f3 = 0.;
-double f4 = 7.5;
-double f5 = 20.;
-double f6 = 64.;
-double f7 = 11452.;
-float f8 = 149140.f;
-float f9 = 18253638.f;
-#endif
%}
diff --git a/Examples/test-suite/cpp17_nested_namespaces.i b/Examples/test-suite/cpp17_nested_namespaces.i
index b9ec9bd5a..fcbf24c9a 100644
--- a/Examples/test-suite/cpp17_nested_namespaces.i
+++ b/Examples/test-suite/cpp17_nested_namespaces.i
@@ -1,13 +1,5 @@
%module cpp17_nested_namespaces
// Tests c++17 style nested namespaces
-// Tests are designed so that code compiles with C++98 compilers
-
-#define CPP17 1
-%{
-#if __cplusplus >= 201703L
-#define CPP17 1
-#endif
-%}
%inline %{
// Tests with namespaces already defined using C++98 style (non-nested) namespaces
@@ -21,20 +13,10 @@ namespace A1 {
};
}
}
-#if defined(CPP17)
namespace A1::B1 {
-#else
-namespace A1 {
- namespace B1 {
-#endif
A1Struct createA1Struct() { return ::A1::A1Struct(); }
B1Struct createB1Struct() { return ::A1::B1::B1Struct(); }
-#if !defined(CPP17)
- }
}
-#else
-}
-#endif
namespace A1 {
namespace B1 {
@@ -46,154 +28,54 @@ namespace A1 {
}
}
-#if defined(CPP17)
namespace A1::B1::C1 {
-#else
-namespace A1 {
- namespace B1 {
- namespace C1 {
-#endif
C1Struct createC1Struct() { return ::A1::B1::C1::C1Struct(); }
-#if !defined(CPP17)
- }
- }
-}
-#else
}
-#endif
%}
%inline %{
// Tests with namespaces already defined using C++17 style (nested) namespaces
-#if defined(CPP17)
namespace A2::B2 {
-#else
-namespace A2 {
- namespace B2 {
-#endif
struct B2Struct {
void B2Method() {}
};
-#if !defined(CPP17)
- }
-}
-#else
}
-#endif
-#if defined(CPP17)
namespace A2::B2 {
-#else
-namespace A2 {
- namespace B2 {
-#endif
B2Struct createB2Struct() { return ::A2::B2::B2Struct(); }
-#if !defined(CPP17)
- }
}
-#else
-}
-#endif
-#if defined(CPP17)
namespace A2::B2::C2 {
-#else
-namespace A2 {
- namespace B2 {
- namespace C2 {
-#endif
struct C2Struct {
void C2Method() {}
};
-#if !defined(CPP17)
- }
- }
}
-#else
-}
-#endif
-#if defined(CPP17)
namespace A2::B2::C2 {
-#else
-namespace A2 {
- namespace B2 {
- namespace C2 {
-#endif
C2Struct createC2Struct() { return ::A2::B2::C2::C2Struct(); }
-#if !defined(CPP17)
- }
- }
-}
-#else
}
-#endif
%}
%inline %{
// Tests with namespaces already defined using C++17 style (nested) namespaces to 3 levels
-#if defined(CPP17)
namespace A3::B3::C3 {
-#else
-namespace A3 {
- namespace B3 {
- namespace C3 {
-#endif
struct C3Struct {
void C3Method() {}
};
-#if !defined(CPP17)
- }
- }
-}
-#else
}
-#endif
-#if defined(CPP17)
namespace A3::B3::C3 {
-#else
-namespace A3 {
- namespace B3 {
- namespace C3 {
-#endif
C3Struct createC3Struct() { return ::A3::B3::C3::C3Struct(); }
-#if !defined(CPP17)
- }
- }
-}
-#else
}
-#endif
-#if defined(CPP17)
namespace A3::B3 {
-#else
-namespace A3 {
- namespace B3 {
-#endif
struct B3Struct {
void B3Method() {}
};
-#if !defined(CPP17)
- }
}
-#else
-}
-#endif
-#if defined(CPP17)
namespace A3::B3 {
-#else
-namespace A3 {
- namespace B3 {
-#endif
B3Struct createB3Struct() { return ::A3::B3::B3Struct(); }
-#if !defined(CPP17)
- }
-}
-#else
}
-#endif
%}
diff --git a/Examples/test-suite/cpp17_u8_char_literals.i b/Examples/test-suite/cpp17_u8_char_literals.i
index 1aae1b231..e2e8e0d31 100644
--- a/Examples/test-suite/cpp17_u8_char_literals.i
+++ b/Examples/test-suite/cpp17_u8_char_literals.i
@@ -1,26 +1,9 @@
%module cpp17_u8_char_literals
-// Tests are designed so that code compiles with C++98 compilers
-
-%{
-#if __cplusplus >= 201703L
-#define CPP17 1
-#endif
-%}
-
-// UTF-8 character literals will (apparently) have type char8_t in C++20.
-char a = u8'a';
-char u = u8'u';
-char u8 = u8'8';
-
-%{
-#if defined(CPP17)
+// UTF-8 character literals are type `char` in C++17 but `char8_t` in C++20,
+// but the latter can be assigned to `char`.
+%inline %{
char a = u8'a';
char u = u8'u';
char u8 = u8'8';
-#else
-char a = 'a';
-char u = 'u';
-char u8 = '8';
-#endif
%}
diff --git a/Examples/test-suite/cpp20_lambda_template.i b/Examples/test-suite/cpp20_lambda_template.i
new file mode 100644
index 000000000..5672bd1b7
--- /dev/null
+++ b/Examples/test-suite/cpp20_lambda_template.i
@@ -0,0 +1,12 @@
+%module cpp20_lambda_template
+
+// We just want to test that SWIG doesn't choke parsing this so suppress:
+// Warning 340: Lambda expressions and closures are not fully supported yet.
+%warnfilter(SWIGWARN_CPP11_LAMBDA);
+
+%include <std_vector.i>
+
+%inline %{
+#include <vector>
+auto templated_lambda = []<typename T>(std::vector<T> t){};
+%}
diff --git a/Examples/test-suite/cpp20_spaceship_operator.i b/Examples/test-suite/cpp20_spaceship_operator.i
new file mode 100644
index 000000000..ddece13a0
--- /dev/null
+++ b/Examples/test-suite/cpp20_spaceship_operator.i
@@ -0,0 +1,28 @@
+%module cpp20_spaceship_operator
+
+%rename(spaceship) operator<=>;
+
+%inline %{
+#include <compare>
+
+int v = (-1 <=> 1 > 0) ? 7 : 42;
+
+// We use !(a >= b) here due to limited support for (a < b) in SWIG's parser.
+#define ALIEN !(0 <=> 1 >= 0)
+
+const int SPACE = 3 <=> 3 == 0;
+
+struct A {
+ int v;
+
+ explicit A(int v_) : v(v_) { }
+};
+
+int operator<=>(const A& a, const A& b) {
+ return a.v - b.v;
+}
+
+int f(int v = (-1 <=> 1 > 0) ? 7 : 42) { return v; }
+%}
+
+%constant int COMET = (4 <=> 2 > 0);
diff --git a/Examples/test-suite/cpp_basic.i b/Examples/test-suite/cpp_basic.i
index f2537e109..8c31a9cf0 100644
--- a/Examples/test-suite/cpp_basic.i
+++ b/Examples/test-suite/cpp_basic.i
@@ -4,6 +4,8 @@
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) global_cint; /* Ruby, wrong constant name */
+%feature("php:allowdynamicproperties", 1) Foo; /* Allow PHP-specific custom property testing in _runme.php */
+
%module cpp_basic
%newobject Bar::testFoo;
@@ -45,6 +47,9 @@ class FooSubSub : public FooSub {
const char* __str__() const { return "FooSubSub"; }
};
+Foo& get_reference(Foo& other) { return other; }
+const Foo& get_const_reference(const Foo& other) { return other; }
+
%}
%{
@@ -74,8 +79,16 @@ class Bar {
Foo *testFoo(int a, Foo *f) {
return new Foo(2 * a + (f ? f->num : 0) + fval.num);
}
+/* Const member data and references mean this class can't be assigned.
private:
Bar& operator=(const Bar&);
+*/
+};
+
+// This class is valid C++ but cannot be assigned to because it has const member data.
+struct JustConst {
+explicit JustConst(int i_inp) : i(i_inp) {}
+const int i;
};
%}
diff --git a/Examples/test-suite/cpp_typedef.i b/Examples/test-suite/cpp_typedef.i
index d77485c77..140df34ae 100644
--- a/Examples/test-suite/cpp_typedef.i
+++ b/Examples/test-suite/cpp_typedef.i
@@ -3,7 +3,7 @@
%module cpp_typedef
%{
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && _MSC_VER >= 1900
#pragma warning( disable : 5208) // warning C5208: unnamed class used in typedef name cannot declare members other than non-static data members, member enumerations, or member classes
#endif
@@ -30,7 +30,6 @@ public:
// Test that the correct types are used for typedef struct declarations
typedef struct {
int something;
- void m() {}
} UnnamedStruct;
typedef struct NamedStruct {
diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in
index 02dcaafb0..0d2664681 100644
--- a/Examples/test-suite/csharp/Makefile.in
+++ b/Examples/test-suite/csharp/Makefile.in
@@ -8,6 +8,10 @@ CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@
CSHARPCILINTERPRETER_FLAGS = @CSHARPCILINTERPRETER_FLAGS@
CSHARPCONVERTPATH = @top_srcdir@/@CSHARPCONVERTPATH@
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@
@@ -24,6 +28,7 @@ CPP_TEST_CASES = \
csharp_namespace_system_collision \
csharp_prepost \
csharp_typemaps \
+ director_wstring \
enum_thorough_simple \
enum_thorough_typesafe \
exception_partial_info \
diff --git a/Examples/test-suite/csharp/catches_strings_runme.cs b/Examples/test-suite/csharp/catches_strings_runme.cs
new file mode 100644
index 000000000..e2e336443
--- /dev/null
+++ b/Examples/test-suite/csharp/catches_strings_runme.cs
@@ -0,0 +1,32 @@
+using System;
+using catches_stringsNamespace;
+
+public class catches_strings_runme {
+ public static void Main()
+ {
+ {
+ bool exception_thrown = false;
+ try {
+ StringsThrower.charstring();
+ } catch (ApplicationException e) {
+ if (!e.Message.Contains("charstring message"))
+ throw new ApplicationException("incorrect exception message:" + e);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new ApplicationException("Should have thrown an exception");
+ }
+ {
+ bool exception_thrown = false;
+ try {
+ StringsThrower.stdstring();
+ } catch (ApplicationException e) {
+ if (!e.Message.Contains("stdstring message"))
+ throw new ApplicationException("incorrect exception message:" + e);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new ApplicationException("Should have thrown an exception");
+ }
+ }
+}
diff --git a/Examples/test-suite/csharp/cpp11_move_only_runme.cs b/Examples/test-suite/csharp/cpp11_move_only_runme.cs
new file mode 100644
index 000000000..f2d1c4cb5
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_move_only_runme.cs
@@ -0,0 +1,34 @@
+using System;
+using cpp11_move_onlyNamespace;
+
+public class cpp11_move_only_runme {
+
+ public static void Main() {
+
+ // Output
+ Counter.reset_counts();
+ using (MoveOnly mo = MoveOnly.create()) {
+ }
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+
+ Counter.reset_counts();
+ using (MovableCopyable mo = MovableCopyable.create()) {
+ }
+ Counter.check_counts(2, 1, 0, 0, 1, 3);
+
+ // Move semantics not used
+ Counter.reset_counts();
+ using (MovableCopyable mo = MovableCopyable.createConst()) {
+ }
+ Counter.check_counts(2, 1, 1, 0, 0, 3);
+
+ // Input
+ Counter.reset_counts();
+ using (MovableCopyable mo = new MovableCopyable(222)) {
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.take(mo);
+ Counter.check_counts(2, 0, 1, 1, 0, 2);
+ }
+ Counter.check_counts(2, 0, 1, 1, 0, 3);
+ }
+}
diff --git a/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs b/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
new file mode 100644
index 000000000..d6a42a3f7
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
@@ -0,0 +1,33 @@
+using System;
+using cpp11_move_only_valuewrapperNamespace;
+
+public class cpp11_move_only_valuewrapper_runme {
+
+ public static void Main() {
+ Counter.reset_counts();
+ using (XXX xxx = cpp11_move_only_valuewrapper.createXXX()) {
+ }
+ if (cpp11_move_only_valuewrapper.has_cplusplus11())
+ // Was (1, 2, 0, 0, 0, 3) before SwigValueWrapper::operator=(T &&) was added.
+ // Was (1, 1, 0, 1, 0, 3) before SwigValueWrapper::operator T&&() was added with new "out" typemaps
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+ Counter.reset_counts();
+ using (XXX xxx = cpp11_move_only_valuewrapper.createXXX2()) {
+ }
+ if (cpp11_move_only_valuewrapper.has_cplusplus11())
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+ cpp11_move_only_valuewrapper.test1();
+ cpp11_move_only_valuewrapper.test2();
+ cpp11_move_only_valuewrapper.test3();
+ cpp11_move_only_valuewrapper.test4();
+ cpp11_move_only_valuewrapper.test5();
+ cpp11_move_only_valuewrapper.test6();
+
+ // Tests SwigValueWrapper, std::unique_ptr (SWIG not parsing a type that is move-only)
+ Counter.reset_counts();
+ SWIGTYPE_p_std__unique_ptrT_XXX_t ptr = cpp11_move_only_valuewrapper.makeUniqueXXX();
+ cpp11_move_only_valuewrapper.cleanup(ptr);
+ Counter.check_counts(1, 0, 0, 0, 0, 1);
+ }
+
+}
diff --git a/Examples/test-suite/csharp/cpp11_move_typemaps_runme.cs b/Examples/test-suite/csharp/cpp11_move_typemaps_runme.cs
new file mode 100644
index 000000000..96849c4d3
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_move_typemaps_runme.cs
@@ -0,0 +1,37 @@
+using System;
+using cpp11_move_typemapsNamespace;
+
+public class cpp11_move_typemaps_runme {
+
+ public static void Main() {
+ Counter.reset_counts();
+ using (MoveOnly mo = new MoveOnly(111)) {
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MoveOnly.take(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+ Counter.reset_counts();
+ using (MovableCopyable mo = new MovableCopyable(111)) {
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.take(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+ using (MoveOnly mo = new MoveOnly(222)) {
+ MoveOnly.take(mo);
+ bool exception_thrown = false;
+ try {
+ MoveOnly.take(mo);
+ } catch (ApplicationException e) {
+ if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+ throw new ApplicationException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new ApplicationException("double usage of take should have been an error");
+ }
+ }
+}
diff --git a/Examples/test-suite/csharp/cpp11_rvalue_reference_move_runme.cs b/Examples/test-suite/csharp/cpp11_rvalue_reference_move_runme.cs
new file mode 100644
index 000000000..9b2660662
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_rvalue_reference_move_runme.cs
@@ -0,0 +1,86 @@
+using System;
+using cpp11_rvalue_reference_moveNamespace;
+
+public class cpp11_rvalue_reference_move_runme {
+ public static void Main() {
+ {
+ // Function containing rvalue reference parameter
+ Counter.reset_counts();
+ MovableCopyable mo = new MovableCopyable(222);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.movein(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ if (!MovableCopyable.is_nullptr(mo))
+ throw new ApplicationException("is_nullptr failed");
+ mo.Dispose();
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+
+ {
+ // Move constructor test
+ Counter.reset_counts();
+ MovableCopyable mo = new MovableCopyable(222);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable mo_moved = new MovableCopyable(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 1);
+ if (!MovableCopyable.is_nullptr(mo))
+ throw new ApplicationException("is_nullptr failed");
+ mo.Dispose();
+ Counter.check_counts(1, 0, 0, 1, 0, 1);
+ mo_moved.Dispose();
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+
+ {
+ // Move assignment operator test
+ Counter.reset_counts();
+ MovableCopyable mo111 = new MovableCopyable(111);
+ MovableCopyable mo222 = new MovableCopyable(222);
+ Counter.check_counts(2, 0, 0, 0, 0, 0);
+ mo111.MoveAssign(mo222);
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ if (!MovableCopyable.is_nullptr(mo222))
+ throw new ApplicationException("is_nullptr failed");
+ mo222.Dispose();
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ mo111.Dispose();
+ Counter.check_counts(2, 0, 0, 0, 1, 2);
+ }
+
+ {
+ // null check
+ Counter.reset_counts();
+ bool exception_thrown = false;
+ try {
+ MovableCopyable.movein(null);
+ } catch (ArgumentNullException e) {
+ if (!e.Message.Contains("MovableCopyable && is null"))
+ throw new ApplicationException("incorrect exception message:" + e);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new ApplicationException("Should have thrown null error");
+ Counter.check_counts(0, 0, 0, 0, 0, 0);
+ }
+
+ {
+ // output
+ Counter.reset_counts();
+ MovableCopyable mc = MovableCopyable.moveout(1234);
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ MovableCopyable.check_numbers_match(mc, 1234);
+
+ bool exception_thrown = false;
+ try {
+ MovableCopyable.movein(mc);
+ } catch (ApplicationException e) {
+ if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+ throw new ApplicationException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ }
+ }
+}
diff --git a/Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs b/Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs
new file mode 100644
index 000000000..7d905e08b
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs
@@ -0,0 +1,131 @@
+using System;
+using cpp11_std_unique_ptrNamespace;
+
+public class cpp11_std_unique_ptr_runme {
+ private static void WaitForGC()
+ {
+ System.GC.Collect();
+ System.GC.WaitForPendingFinalizers();
+ System.Threading.Thread.Sleep(10);
+ }
+
+ private static void checkCount(int expected_count)
+ {
+ int actual_count = Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new ApplicationException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+ }
+
+ public static void Main()
+ {
+ // Test raw pointer handling involving virtual inheritance
+ using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
+ checkCount(1);
+ string s = cpp11_std_unique_ptr.useKlassRawPtr(kini);
+ if (s != "KlassInheritanceInput")
+ throw new ApplicationException("Incorrect string: " + s);
+ }
+ checkCount(0);
+
+ // unique_ptr as input
+ using (Klass kin = new Klass("KlassInput")) {
+ checkCount(1);
+ string s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new ApplicationException("Incorrect string: " + s);
+ if (!cpp11_std_unique_ptr.is_nullptr(kin))
+ throw new ApplicationException("is_nullptr failed");
+ } // Dispose should not fail, even though already deleted
+ checkCount(0);
+
+ using (Klass kin = new Klass("KlassInput")) {
+ checkCount(1);
+ string s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new ApplicationException("Incorrect string: " + s);
+ if (!cpp11_std_unique_ptr.is_nullptr(kin))
+ throw new ApplicationException("is_nullptr failed");
+ bool exception_thrown = false;
+ try {
+ cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ } catch (ApplicationException e) {
+ if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+ throw new ApplicationException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new ApplicationException("double usage of takeKlassUniquePtr should have been an error");
+ } // Dispose should not fail, even though already deleted
+ checkCount(0);
+
+ using (Klass kin = new Klass("KlassInput")) {
+ bool exception_thrown = false;
+ Klass notowned = cpp11_std_unique_ptr.get_not_owned_ptr(kin);
+ try {
+ cpp11_std_unique_ptr.takeKlassUniquePtr(notowned);
+ } catch (ApplicationException e) {
+ if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+ throw new ApplicationException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ }
+ checkCount(0);
+
+ using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
+ checkCount(1);
+ string s = cpp11_std_unique_ptr.takeKlassUniquePtr(kini);
+ checkCount(0);
+ if (s != "KlassInheritanceInput")
+ throw new ApplicationException("Incorrect string: " + s);
+ if (!cpp11_std_unique_ptr.is_nullptr(kini))
+ throw new ApplicationException("is_nullptr failed");
+ } // Dispose should not fail, even though already deleted
+ checkCount(0);
+
+ cpp11_std_unique_ptr.takeKlassUniquePtr(null);
+ cpp11_std_unique_ptr.takeKlassUniquePtr(cpp11_std_unique_ptr.make_null());
+ checkCount(0);
+
+ // overloaded parameters
+ if (cpp11_std_unique_ptr.overloadTest() != 0)
+ throw new ApplicationException("overloadTest failed");
+ if (cpp11_std_unique_ptr.overloadTest(null) != 1)
+ throw new ApplicationException("overloadTest failed");
+ if (cpp11_std_unique_ptr.overloadTest(new Klass("over")) != 1)
+ throw new ApplicationException("overloadTest failed");
+ checkCount(0);
+
+
+ // unique_ptr as output
+ Klass k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first");
+ if (k1.getLabel() != "first")
+ throw new Exception("wrong object label");
+
+ Klass k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second");
+ checkCount(2);
+
+ using (Klass k3 = cpp11_std_unique_ptr.makeKlassUniquePtr("second")) {
+ checkCount(3);
+ }
+ checkCount(2);
+
+ k1.Dispose();
+ k1 = null;
+ checkCount(1);
+
+ if (k2.getLabel() != "second")
+ throw new Exception("wrong object label");
+
+ k2.Dispose();
+ k2 = null;
+ checkCount(0);
+
+ if (cpp11_std_unique_ptr.makeNullUniquePtr() != null)
+ throw new Exception("null failure");
+ }
+}
diff --git a/Examples/test-suite/csharp/csharp_typemaps_runme.cs b/Examples/test-suite/csharp/csharp_typemaps_runme.cs
index 846644f09..a9119a0c3 100644
--- a/Examples/test-suite/csharp/csharp_typemaps_runme.cs
+++ b/Examples/test-suite/csharp/csharp_typemaps_runme.cs
@@ -107,6 +107,22 @@ public class TestThread {
Console.Error.WriteLine("Test failed (thread " + threadId + "): " + e.Message);
Failed = true;
}
+
+ // $imfuncname substitution
+ ProxyA pa = new ProxyA();
+ if (pa.imfuncname_test() != 123)
+ throw new ApplicationException("imfuncname_test is not 123");
+ if (ProxyA.imfuncname_static_test() != 234)
+ throw new ApplicationException("imfuncname_test is not 234");
+ if (csharp_typemaps.imfuncname_global_test() != 345)
+ throw new ApplicationException("imfuncname_test is not 345");
+
+ pa.variab = 1000;
+ if (pa.variab != 1000 + 111 + 222)
+ throw new ApplicationException("pa.variab is not 1333");
+ csharp_typemaps.global_variab = 1000;
+ if (csharp_typemaps.global_variab != 1000 + 333 + 444)
+ throw new ApplicationException("csharp_typemaps.variab is not 1777");
}
}
diff --git a/Examples/test-suite/csharp/director_basic_runme.cs b/Examples/test-suite/csharp/director_basic_runme.cs
index de299b145..a81f27ef3 100644
--- a/Examples/test-suite/csharp/director_basic_runme.cs
+++ b/Examples/test-suite/csharp/director_basic_runme.cs
@@ -50,7 +50,7 @@ public class runme
myNewBar.x = 10;
// Low level implementation check
-// my.testSwigDerivedClassHasMethod();
+ my.testSwigDerivedClassHasMethod();
// These should not call the C# implementations as they are not overridden
int v;
diff --git a/Examples/test-suite/csharp/director_classes_runme.cs b/Examples/test-suite/csharp/director_classes_runme.cs
index 700492fb1..cea4949c6 100644
--- a/Examples/test-suite/csharp/director_classes_runme.cs
+++ b/Examples/test-suite/csharp/director_classes_runme.cs
@@ -177,7 +177,7 @@ public class CSharpDerived : Base
// Note the following method can never be called from unmanaged code.
// It is here only for code that calls it directly from managed code.
// But should always be defined to ensure behaviour is consistent
- // independent of where DefaultParsms is called from (managed or unmanaged code).
+ // independent of where DefaultParams is called from (managed or unmanaged code).
// Note this method can never be called from unmanaged code
public override String DefaultParms(int x)
{
diff --git a/Examples/test-suite/csharp/director_default_runme.cs b/Examples/test-suite/csharp/director_default_runme.cs
new file mode 100644
index 000000000..af14c1eb4
--- /dev/null
+++ b/Examples/test-suite/csharp/director_default_runme.cs
@@ -0,0 +1,58 @@
+using System;
+
+namespace director_defaultNamespace {
+
+public class runme
+{
+ static void Main()
+ {
+ {
+ MyFoo a = new MyFoo();
+ a = new MyFoo(10);
+ a.Dispose();
+ }
+
+ {
+ MyFoo a = new MyFoo();
+ if (a.GetMsg() != "MyFoo-default") {
+ throw new Exception( "Test 1 failed" );
+ }
+ if (a.GetMsg("boo") != "MyFoo-boo") {
+ throw new Exception( "Test 2 failed" );
+ }
+ a.Dispose();
+ }
+
+ {
+ Foo b = new Foo();
+ if (b.GetMsg() != "Foo-default") {
+ throw new Exception( "Test 1 failed" );
+ }
+ if (b.GetMsg("boo") != "Foo-boo") {
+ throw new Exception( "Test 2 failed" );
+ }
+ b.Dispose();
+ }
+ }
+}
+
+public class MyFoo : Foo
+{
+ public MyFoo()
+ : base()
+ {
+ }
+
+ public MyFoo(int i)
+ : base(i)
+ {
+ }
+
+ public override string Msg(string msg)
+ {
+ return "MyFoo-" + msg;
+ }
+}
+
+}
+
diff --git a/Examples/test-suite/csharp/director_pass_by_value_runme.cs b/Examples/test-suite/csharp/director_pass_by_value_runme.cs
index ba6371590..1f64f6d7e 100644
--- a/Examples/test-suite/csharp/director_pass_by_value_runme.cs
+++ b/Examples/test-suite/csharp/director_pass_by_value_runme.cs
@@ -28,6 +28,8 @@ public class runme
break;
};
}
+ if (director_pass_by_value.has_cplusplus11())
+ Counter.check_counts(1, 0, 0, 1, 0, 1); // check move constructor called and just one destructor
// bug was the passByVal 'global' object was destroyed after the call to virtualMethod had finished.
int ret = runme.passByVal.getVal();
if (ret != 0x12345678)
diff --git a/Examples/test-suite/csharp/director_property_runme.cs b/Examples/test-suite/csharp/director_property_runme.cs
new file mode 100644
index 000000000..b93e8e29d
--- /dev/null
+++ b/Examples/test-suite/csharp/director_property_runme.cs
@@ -0,0 +1,64 @@
+using System;
+
+namespace director_propertyNamespace {
+
+public class runme
+{
+ static void Main()
+ {
+ {
+ Foo a = new MyFoo();
+ if (a.getA() != "") {
+ throw new Exception( "Test failed" );
+ }
+ a.setA("Hello");
+ if (a.getA() != "Hello set from MyFoo") {
+ throw new Exception( "Test failed" );
+ }
+ a.setAByRef("Hello");
+ if (a.getA() != "Hello setAByRef from MyFoo") {
+ throw new Exception( "Test failed" );
+ }
+ a.Dispose();
+ }
+
+ {
+ Foo a_original = new MyFoo();
+ Foo a = Foo.get_self(a_original);
+ if (a.getA() != "") {
+ throw new Exception( "Test failed" );
+ }
+ a.setA("Hello");
+ if (a.getA() != "Hello set from MyFoo") {
+ throw new Exception( "Test failed" );
+ }
+ a.setAByRef("Hello");
+ if (a.getA() != "Hello setAByRef from MyFoo") {
+ throw new Exception( "Test failed" );
+ }
+ a.Dispose();
+ }
+ }
+}
+
+public class MyFoo : Foo
+{
+ public MyFoo()
+ : base()
+ {
+ }
+
+ public override void setA(string a)
+ {
+ base.setA(a + " set from MyFoo");
+ }
+
+ public override void setAByRef(string a)
+ {
+ base.setA(a + " setAByRef from MyFoo");
+ }
+}
+
+}
+
+
diff --git a/Examples/test-suite/csharp/director_using_member_scopes_runme.cs b/Examples/test-suite/csharp/director_using_member_scopes_runme.cs
new file mode 100644
index 000000000..8b979907f
--- /dev/null
+++ b/Examples/test-suite/csharp/director_using_member_scopes_runme.cs
@@ -0,0 +1,70 @@
+using System;
+
+namespace director_using_member_scopesNamespace {
+
+public class runme
+{
+ static void Main()
+ {
+ runme r = new runme();
+ r.run();
+ }
+
+ void run()
+ {
+ NativeWindowType nwt = new NativeWindowType();
+ {
+ MyApplicationContextSDL a = new MyApplicationContextSDL();
+
+ if (ApplicationContextBase.call_setWindowGrab(a, nwt, true) != 100)
+ throw new Exception("failed");
+
+ if (ApplicationContextSDL.call_setWindowGrab(a, nwt, true) != 100)
+ throw new Exception("failed");
+ }
+
+ {
+ MyACSDL a = new MyACSDL();
+
+ if (ACB.call_setWindowGrab(a, nwt, true) != 100)
+ throw new Exception("failed");
+ if (ACB.call_setWindowGrab(a, "hi", 0) != 200)
+ throw new Exception("failed");
+
+ if (ACSDL.call_setWindowGrab(a, nwt, true) != 100)
+ throw new Exception("failed");
+ if (ACSDL.call_setWindowGrab(a, "hi", 0) != 200)
+ throw new Exception("failed");
+ }
+ }
+}
+
+class MyApplicationContextSDL: ApplicationContextSDL
+{
+ public MyApplicationContextSDL() : base()
+ {
+ }
+
+ public override int setWindowGrab(NativeWindowType win, bool grab)
+ {
+ return 100;
+ }
+}
+
+class MyACSDL: ACSDL
+{
+ public MyACSDL() : base()
+ {
+ }
+
+ public override int setWindowGrab(NativeWindowType win, bool grab)
+ {
+ return 100;
+ }
+ public override int setWindowGrab(string s, int val)
+ {
+ return 200;
+ }
+}
+
+}
diff --git a/Examples/test-suite/csharp/director_wstring_runme.cs b/Examples/test-suite/csharp/director_wstring_runme.cs
new file mode 100644
index 000000000..7258e7f94
--- /dev/null
+++ b/Examples/test-suite/csharp/director_wstring_runme.cs
@@ -0,0 +1,56 @@
+using System;
+using director_wstringNamespace;
+
+public class runme
+{
+ static void Main()
+ {
+ runme r = new runme();
+ r.run();
+ }
+
+ void run()
+ {
+ director_wstring_B b = new director_wstring_B("hello");
+
+ b.get(0);
+ if (b.get_first() != "hello world!")
+ throw new ApplicationException("Incorrect get_first:" + b.get_first());
+
+ b.call_process_func();
+ if (b.smem != "hello")
+ throw new ApplicationException("Incorrect smem:" + b.smem);
+
+ b.call_process_wstring_func();
+ if (b.smem != "hello (wstring)")
+ throw new ApplicationException("Incorrect smem:" + b.smem);
+
+ b.call_process_wstring_ref_func();
+ if (b.smem != "hello (wstring ref)")
+ throw new ApplicationException("Incorrect smem:" + b.smem);
+ }
+}
+
+class director_wstring_B : A
+{
+ public String smem;
+ public director_wstring_B(String first) : base(first)
+ {
+ }
+ public override String get_first()
+ {
+ return base.get_first() + " world!";
+ }
+ public override void process_text(String s)
+ {
+ this.smem = s;
+ }
+ public override void process_wstring_text(String s)
+ {
+ this.smem = s + " (wstring)";
+ }
+ public override void process_wstring_ref_text(String s)
+ {
+ this.smem = s + " (wstring ref)";
+ }
+}
diff --git a/Examples/test-suite/csharp/friends_runme.cs b/Examples/test-suite/csharp/friends_runme.cs
index ae3ffb64f..9dfd9ba09 100644
--- a/Examples/test-suite/csharp/friends_runme.cs
+++ b/Examples/test-suite/csharp/friends_runme.cs
@@ -22,7 +22,7 @@ public class friends_runme {
if (friends.mix(a,b) != 5)
throw new Exception("failed");
- D_d di = new D_d(2);
+ D_i di = new D_i(2);
D_d dd = new D_d(3.3);
// incredible template overloading working just fine
diff --git a/Examples/test-suite/csharp/li_std_auto_ptr_runme.cs b/Examples/test-suite/csharp/li_std_auto_ptr_runme.cs
index 863b86701..bc5c77608 100644
--- a/Examples/test-suite/csharp/li_std_auto_ptr_runme.cs
+++ b/Examples/test-suite/csharp/li_std_auto_ptr_runme.cs
@@ -9,56 +9,123 @@ public class li_std_auto_ptr_runme {
System.Threading.Thread.Sleep(10);
}
+ private static void checkCount(int expected_count)
+ {
+ int actual_count = Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new ApplicationException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+ }
+
public static void Main()
{
+ // Test raw pointer handling involving virtual inheritance
+ using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
+ checkCount(1);
+ string s = li_std_auto_ptr.useKlassRawPtr(kini);
+ if (s != "KlassInheritanceInput")
+ throw new ApplicationException("Incorrect string: " + s);
+ }
+ checkCount(0);
+
+ // auto_ptr as input
+ using (Klass kin = new Klass("KlassInput")) {
+ checkCount(1);
+ string s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new ApplicationException("Incorrect string: " + s);
+ if (!li_std_auto_ptr.is_nullptr(kin))
+ throw new ApplicationException("is_nullptr failed");
+ } // Dispose should not fail, even though already deleted
+ checkCount(0);
+
+ using (Klass kin = new Klass("KlassInput")) {
+ checkCount(1);
+ string s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new ApplicationException("Incorrect string: " + s);
+ if (!li_std_auto_ptr.is_nullptr(kin))
+ throw new ApplicationException("is_nullptr failed");
+ bool exception_thrown = false;
+ try {
+ li_std_auto_ptr.takeKlassAutoPtr(kin);
+ } catch (ApplicationException e) {
+ if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+ throw new ApplicationException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new ApplicationException("double usage of takeKlassAutoPtr should have been an error");
+ } // Dispose should not fail, even though already deleted
+ checkCount(0);
+
+ using (Klass kin = new Klass("KlassInput")) {
+ bool exception_thrown = false;
+ Klass notowned = li_std_auto_ptr.get_not_owned_ptr(kin);
+ try {
+ li_std_auto_ptr.takeKlassAutoPtr(notowned);
+ } catch (ApplicationException e) {
+ if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+ throw new ApplicationException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ }
+ checkCount(0);
+
+ using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
+ checkCount(1);
+ string s = li_std_auto_ptr.takeKlassAutoPtr(kini);
+ checkCount(0);
+ if (s != "KlassInheritanceInput")
+ throw new ApplicationException("Incorrect string: " + s);
+ if (!li_std_auto_ptr.is_nullptr(kini))
+ throw new ApplicationException("is_nullptr failed");
+ } // Dispose should not fail, even though already deleted
+ checkCount(0);
+
+ li_std_auto_ptr.takeKlassAutoPtr(null);
+ li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
+ checkCount(0);
+
+ // overloaded parameters
+ if (li_std_auto_ptr.overloadTest() != 0)
+ throw new ApplicationException("overloadTest failed");
+ if (li_std_auto_ptr.overloadTest(null) != 1)
+ throw new ApplicationException("overloadTest failed");
+ if (li_std_auto_ptr.overloadTest(new Klass("over")) != 1)
+ throw new ApplicationException("overloadTest failed");
+ checkCount(0);
+
+
+ // auto_ptr as output
Klass k1 = li_std_auto_ptr.makeKlassAutoPtr("first");
if (k1.getLabel() != "first")
throw new Exception("wrong object label");
Klass k2 = li_std_auto_ptr.makeKlassAutoPtr("second");
- if (Klass.getTotal_count() != 2)
- throw new Exception("number of objects should be 2");
+ checkCount(2);
using (Klass k3 = li_std_auto_ptr.makeKlassAutoPtr("second")) {
- if (Klass.getTotal_count() != 3)
- throw new Exception("number of objects should be 3");
+ checkCount(3);
}
- if (Klass.getTotal_count() != 2)
- throw new Exception("number of objects should be 2");
+ checkCount(2);
+ k1.Dispose();
k1 = null;
- {
- int countdown = 500;
- int expectedCount = 1;
- while (true) {
- WaitForGC();
- if (--countdown == 0)
- break;
- if (Klass.getTotal_count() == expectedCount)
- break;
- };
- int actualCount = Klass.getTotal_count();
- if (actualCount != expectedCount)
- Console.Error.WriteLine("Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
- }
+ checkCount(1);
if (k2.getLabel() != "second")
throw new Exception("wrong object label");
+ k2.Dispose();
k2 = null;
- {
- int countdown = 500;
- int expectedCount = 0;
- while (true) {
- WaitForGC();
- if (--countdown == 0)
- break;
- if (Klass.getTotal_count() == expectedCount)
- break;
- }
- int actualCount = Klass.getTotal_count();
- if (actualCount != expectedCount)
- Console.Error.WriteLine("Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
- }
+ checkCount(0);
+
+ if (li_std_auto_ptr.makeNullAutoPtr() != null)
+ throw new Exception("null failure");
}
}
diff --git a/Examples/test-suite/csharp/li_std_wstring_runme.cs b/Examples/test-suite/csharp/li_std_wstring_runme.cs
index d2927287f..97dfedbf0 100644
--- a/Examples/test-suite/csharp/li_std_wstring_runme.cs
+++ b/Examples/test-suite/csharp/li_std_wstring_runme.cs
@@ -1,3 +1,6 @@
+// This file has a BOM for UTF-8
+// Notes for displaying UTF-8 properly in Windows: https://stackoverflow.com/questions/49476326/displaying-unicode-in-powershell
+
using System;
using li_std_wstringNamespace;
@@ -5,17 +8,38 @@ public class runme
{
static private void check_equal(char a, char b)
{
- if (a != b)
- throw new Exception("char failed '" + a + "' != '" + b + "'");
+ if (a != b)
+ throw new Exception("char failed '" + a + "' != '" + b + "'");
+ }
+
+ static private void display_bytes(string s)
+ {
+ Console.Write("[");
+ if (s != null)
+ {
+ foreach (char x in s)
+ {
+ int n = Convert.ToInt32(x);
+ Console.Write(n.ToString("X") + " ");
+ }
+ }
+ else
+ Console.Write("null");
+ Console.WriteLine("]");
}
static private void check_equal(string a, string b)
{
- if (a != b)
- throw new Exception("string failed '" + a + "' != '" + b + "'");
+ if (li_std_wstring.trace) {
+ Console.WriteLine("check_equal {0} {1}", a, b);
+ display_bytes(a);
+ display_bytes(b);
+ }
+ if (a != b)
+ throw new Exception("string failed '" + a + "' != '" + b + "'");
}
- static void Main()
+ static void Main()
{
char h = 'h';
check_equal(li_std_wstring.test_wcvalue(h), h);
@@ -30,6 +54,8 @@ public class runme
li_std_wstring.test_pointer(null);
li_std_wstring.test_const_pointer(null);
+ check_equal(li_std_wstring.test_ccvalue(null), null);
+
try {
li_std_wstring.test_value(null);
throw new Exception("NULL check failed");
@@ -37,10 +63,10 @@ public class runme
}
try {
- li_std_wstring.test_reference(null);
- throw new Exception("NULL check failed");
+ li_std_wstring.test_reference(null);
+ throw new Exception("NULL check failed");
} catch (ArgumentNullException e) {
- if (!e.Message.Contains("type is null"))
+ if (!e.Message.Contains("is null"))
throw new Exception("Missing text " + e);
}
try {
@@ -54,13 +80,24 @@ public class runme
x = "hello";
check_equal(li_std_wstring.test_const_reference(x), x);
- /* Postpone, tricky, std::wstring portability problem.
+ /* Tricky, std::wstring portability problem.
* std::wstring is 2 bytes on Windows, 4 bytes on Linux, LPWSTR is 2 bytes.
- * .NET marshalling should work on Windows but not Linux.
- string s = "abc";
- if (!li_std_wstring.test_equal_abc(s))
- throw new Exception("Not equal " + s);
- */
+ */
+ string ss = "abc";
+ if (!li_std_wstring.test_equal_abc(ss))
+ throw new Exception("Not equal " + ss);
+
+ ss = "JP: 日本語";
+ if (!li_std_wstring.test_equal_jp(ss))
+ throw new Exception("Not equal " + ss);
+
+ ss = "DE: Kröpeliner Straße";
+ if (!li_std_wstring.test_equal_de(ss))
+ throw new Exception("Not equal " + ss);
+
+ ss = "RU: Война и мир";
+ if (!li_std_wstring.test_equal_ru(ss))
+ throw new Exception("Not equal " + ss);
try {
li_std_wstring.test_throw();
@@ -68,6 +105,24 @@ public class runme
check_equal(e.Message, "throwing test_throw");
}
+ try {
+ li_std_wstring.test_throw_jp();
+ } catch (Exception e) {
+ check_equal(e.Message, "JP: 日本語");
+ }
+
+ try {
+ li_std_wstring.test_throw_ref_jp();
+ } catch (Exception e) {
+ check_equal(e.Message, "JP: 日本語");
+ }
+
+ try {
+ li_std_wstring.test_throw_wchar_t_ptr();
+ } catch (Exception e) {
+ check_equal(e.Message, "JP: 日本語");
+ }
+
x = "abc\0def";
// Unlike other languages, embedded NULL in std::string not supported
// check_equal(li_std_wstring.test_value(x), x);
@@ -81,15 +136,22 @@ public class runme
check_equal(s.wchar_t_member, h);
s.wchar_t_ptr_member = x;
check_equal(s.wchar_t_ptr_member, "abc");
+ s.wchar_t_ptr_member = ss;
+ check_equal(s.wchar_t_ptr_member, ss);
{
// Unicode strings
+ // Strings below are UTF8 in this file, but .NET holds them internally as UTF16
+ // DE: https://www.utf8-chartable.de/
+ // RU: https://www.utf8-chartable.de/unicode-utf8-table.pl?start=1024
string[] test_strings = {
"JP: 日本語", "DE: Kröpeliner Straße" , "RU: Война и мир", "EN: War and Peace"
};
foreach (string expected in test_strings)
{
+ if (li_std_wstring.trace)
+ Console.WriteLine("expected (C#): " + expected);
string received = li_std_wstring.test_value(expected);
check_equal(received, expected);
}
diff --git a/Examples/test-suite/csharp/multiple_inheritance_interfaces_runme.cs b/Examples/test-suite/csharp/multiple_inheritance_interfaces_runme.cs
index c786ff9b3..96b74bc5c 100644
--- a/Examples/test-suite/csharp/multiple_inheritance_interfaces_runme.cs
+++ b/Examples/test-suite/csharp/multiple_inheritance_interfaces_runme.cs
@@ -83,5 +83,7 @@ public class multiple_inheritance_interfaces_runme {
d.ia(10);
d.ia("bye");
d.ia("bye", false);
+
+ UndesirablesSwigImpl.UndesiredStaticMethod(UndesirablesSwigImpl.UndesiredEnum.UndesiredEnum1);
}
}
diff --git a/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs b/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs
new file mode 100644
index 000000000..24a284931
--- /dev/null
+++ b/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using multiple_inheritance_overloadNamespace;
+
+public class multiple_inheritance_overload_runme {
+
+ public static void check(bool fail, String msg) {
+ if (fail)
+ throw new Exception(msg);
+ }
+
+ public static void Main() {
+ int i = 0;
+ Base b1 = new Derived();
+ check(b1.Method(i) != 0, "b1.Method failed");
+ check(b1.MethodForRenaming(i) != 0, "b1.MethodForRenaming failed");
+ check(b1.MethodForRenamingConst(i) != 1, "b1.MethodForRenamingConst failed");
+ check(b1.MethodWarningSuppressed(i) != 0, "b1.MethodWarningSuppressed failed");
+ check(b1.NotVirtualMethod(i) != 0, "b1.NotVirtualMethod failed");
+ check(b1.SimilarOverloadedMethod(i) != 0, "b1.NotVirtualMethod failed");
+
+ Derived d1 = new Derived();
+ check(d1.Method(i) != 0, "d1.Method failed");
+ check(d1.MethodForRenaming(i) != 0, "d1.MethodForRenaming failed");
+ check(d1.MethodForRenamingConst(i) != 1, "d1.MethodForRenamingConst failed");
+ check(d1.MethodWarningSuppressed(i) != 0, "d1.MethodWarningSuppressed failed");
+ check(d1.NotVirtualMethod(i) != 0, "d1.NotVirtualMethod failed");
+ check(d1.SimilarOverloadedMethod(i) != 0, "d1.NotVirtualMethod failed");
+
+ check(d1.AnotherMethod(i) != 0, "d1.AnotherMethod failed");
+
+ Base db1 = BaseSwigImpl.in_out(d1);
+ check(db1.Method(i) != 0, "db1.Method failed");
+ check(db1.MethodForRenaming(i) != 0, "db1.MethodForRenaming failed");
+ check(db1.MethodForRenamingConst(i) != 1, "db1.MethodForRenamingConst failed");
+ check(db1.MethodWarningSuppressed(i) != 0, "db1.MethodWarningSuppressed failed");
+ check(db1.NotVirtualMethod(i) != 0, "db1.NotVirtualMethod failed");
+ check(db1.SimilarOverloadedMethod(i) != 0, "db1.NotVirtualMethod failed");
+
+ MoreDerived m1 = new MoreDerived();
+ check(m1.Method(i) != 0, "m1.Method failed");
+ check(m1.MethodForRenaming(i) != 0, "m1.MethodForRenaming failed");
+ check(m1.MethodForRenamingConst(i) != 1, "m1.MethodForRenamingConst failed");
+ check(m1.MethodWarningSuppressed(i) != 0, "m1.MethodWarningSuppressed failed");
+ check(m1.NotVirtualMethod(i) != 0, "m1.NotVirtualMethod failed");
+ check(m1.SimilarOverloadedMethod(i) != 0, "m1.NotVirtualMethod failed");
+
+ check(m1.AnotherMethod(i) != 0, "m1.AnotherMethod failed");
+
+ Base mb2 = BaseSwigImpl.in_out(m1);
+ check(mb2.Method(i) != 0, "mb2.Method failed");
+ check(mb2.MethodForRenaming(i) != 0, "mb2.MethodForRenaming failed");
+ check(mb2.MethodForRenamingConst(i) != 1, "mb2.MethodForRenamingConst failed");
+ check(mb2.MethodWarningSuppressed(i) != 0, "mb2.MethodWarningSuppressed failed");
+ check(mb2.NotVirtualMethod(i) != 0, "mb2.NotVirtualMethod failed");
+ check(mb2.SimilarOverloadedMethod(i) != 0, "mb2.NotVirtualMethod failed");
+ }
+}
diff --git a/Examples/test-suite/csharp/preproc_constants_c_runme.cs b/Examples/test-suite/csharp/preproc_constants_c_runme.cs
index 5966d5266..8cdb705c9 100644
--- a/Examples/test-suite/csharp/preproc_constants_c_runme.cs
+++ b/Examples/test-suite/csharp/preproc_constants_c_runme.cs
@@ -51,6 +51,8 @@ public class runme {
assert( typeof(int) == preproc_constants_c.EXPR_MINUS.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_LSHIFT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_RSHIFT.GetType() );
+ assert( typeof(int) == preproc_constants_c.EXPR_LT.GetType() );
+ assert( typeof(int) == preproc_constants_c.EXPR_GT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_LTE.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_GTE.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_INEQUALITY.GetType() );
diff --git a/Examples/test-suite/csharp/preproc_constants_runme.cs b/Examples/test-suite/csharp/preproc_constants_runme.cs
index 6af8f20a4..d79e2c302 100644
--- a/Examples/test-suite/csharp/preproc_constants_runme.cs
+++ b/Examples/test-suite/csharp/preproc_constants_runme.cs
@@ -50,6 +50,8 @@ public class runme {
assert( typeof(int) == preproc_constants.EXPR_MINUS.GetType() );
assert( typeof(int) == preproc_constants.EXPR_LSHIFT.GetType() );
assert( typeof(int) == preproc_constants.EXPR_RSHIFT.GetType() );
+ assert( typeof(bool) == preproc_constants.EXPR_LT.GetType() );
+ assert( typeof(bool) == preproc_constants.EXPR_GT.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_LTE.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_GTE.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_INEQUALITY.GetType() );
diff --git a/Examples/test-suite/csharp/typemap_out_optimal_runme.cs b/Examples/test-suite/csharp/typemap_out_optimal_runme.cs
index 5bc1d14be..0d4254eef 100644
--- a/Examples/test-suite/csharp/typemap_out_optimal_runme.cs
+++ b/Examples/test-suite/csharp/typemap_out_optimal_runme.cs
@@ -3,10 +3,14 @@ using typemap_out_optimalNamespace;
public class typemap_out_optimal_runme {
- public static XX x = null;
public static void Main() {
- XX.debug = false;
- x = XX.create();
+ XX.trace = false;
+ if (XX.trace)
+ Console.WriteLine("calling create()");
+ using (XX x = XX.create()) { }
+ if (XX.trace)
+ Console.WriteLine("calling createConst()");
+ using (XX x = XX.createConst()) { }
}
}
diff --git a/Examples/test-suite/csharp_typemaps.i b/Examples/test-suite/csharp_typemaps.i
index dc5b40c02..a73f01c44 100644
--- a/Examples/test-suite/csharp_typemaps.i
+++ b/Examples/test-suite/csharp_typemaps.i
@@ -136,3 +136,42 @@ namespace Glob {
bool MVar::svar = false;
%}
+// $imfuncname substitution
+%typemap(csout) int imfuncname_test {
+ return $modulePINVOKE.$imfuncname(swigCPtr) + 123;
+ }
+%typemap(csout) int imfuncname_static_test {
+ return $modulePINVOKE.$imfuncname() + 234;
+ }
+%typemap(csout) int imfuncname_global_test {
+ return $modulePINVOKE.$imfuncname() + 345;
+ }
+
+%typemap(csvarout, excode=SWIGEXCODE2) int variab %{
+ get {
+ int ret = $modulePINVOKE.$imfuncname(swigCPtr) + 222;$excode
+ return ret;
+ } %}
+%typemap(csvarin, excode=SWIGEXCODE2) int variab %{
+ set {
+ $modulePINVOKE.$imfuncname(swigCPtr, value + 111);$excode
+ } %}
+
+%typemap(csvarout, excode=SWIGEXCODE2) int global_variab %{
+ get {
+ int ret = $modulePINVOKE.$imfuncname() + 333;$excode
+ return ret;
+ } %}
+%typemap(csvarin, excode=SWIGEXCODE2) int global_variab %{
+ set {
+ $modulePINVOKE.$imfuncname(value + 444);$excode
+ } %}
+%inline %{
+struct ProxyA {
+ int imfuncname_test() { return 0; }
+ static int imfuncname_static_test() { return 0; }
+ int variab;
+};
+int imfuncname_global_test() { return 0; }
+int global_variab;
+%}
diff --git a/Examples/test-suite/d/Makefile.in b/Examples/test-suite/d/Makefile.in
index a20cfb4e3..d6486845c 100644
--- a/Examples/test-suite/d/Makefile.in
+++ b/Examples/test-suite/d/Makefile.in
@@ -4,6 +4,10 @@
LANGUAGE = d
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@
diff --git a/Examples/test-suite/d/catches_strings_runme.1.d b/Examples/test-suite/d/catches_strings_runme.1.d
new file mode 100644
index 000000000..89108355b
--- /dev/null
+++ b/Examples/test-suite/d/catches_strings_runme.1.d
@@ -0,0 +1,32 @@
+module catches_strings_runme;
+
+import catches_strings.catches_strings;
+import catches_strings.StringsThrower;
+import std.algorithm;
+
+void main() {
+ {
+ bool exception_thrown = false;
+ try {
+ StringsThrower.charstring();
+ } catch (Exception e) {
+ if (!canFind(e.msg, "charstring message"))
+ throw new Exception("incorrect exception message:" ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown an exception");
+ }
+ {
+ bool exception_thrown = false;
+ try {
+ StringsThrower.stdstring();
+ } catch (Exception e) {
+ if (!canFind(e.msg, "stdstring message"))
+ throw new Exception("incorrect exception message:" ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown an exception");
+ }
+}
diff --git a/Examples/test-suite/d/catches_strings_runme.2.d b/Examples/test-suite/d/catches_strings_runme.2.d
new file mode 100644
index 000000000..89108355b
--- /dev/null
+++ b/Examples/test-suite/d/catches_strings_runme.2.d
@@ -0,0 +1,32 @@
+module catches_strings_runme;
+
+import catches_strings.catches_strings;
+import catches_strings.StringsThrower;
+import std.algorithm;
+
+void main() {
+ {
+ bool exception_thrown = false;
+ try {
+ StringsThrower.charstring();
+ } catch (Exception e) {
+ if (!canFind(e.msg, "charstring message"))
+ throw new Exception("incorrect exception message:" ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown an exception");
+ }
+ {
+ bool exception_thrown = false;
+ try {
+ StringsThrower.stdstring();
+ } catch (Exception e) {
+ if (!canFind(e.msg, "stdstring message"))
+ throw new Exception("incorrect exception message:" ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown an exception");
+ }
+}
diff --git a/Examples/test-suite/d/cpp11_move_typemaps_runme.1.d b/Examples/test-suite/d/cpp11_move_typemaps_runme.1.d
new file mode 100644
index 000000000..29561cde3
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_move_typemaps_runme.1.d
@@ -0,0 +1,42 @@
+module cpp11_move_typemaps_runme;
+
+import cpp11_move_typemaps.Counter;
+import cpp11_move_typemaps.MoveOnly;
+import cpp11_move_typemaps.MovableCopyable;
+import std.conv;
+import std.algorithm;
+
+void main() {
+ {
+ Counter.reset_counts();
+ scope MoveOnly mo = new MoveOnly(111);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MoveOnly.take(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+ {
+ Counter.reset_counts();
+ scope MovableCopyable mo = new MovableCopyable(111);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.take(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+ {
+ scope MoveOnly mo = new MoveOnly(222);
+ MoveOnly.take(mo);
+ bool exception_thrown = false;
+ try {
+ MoveOnly.take(mo);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("double usage of take should have been an error");
+ }
+}
diff --git a/Examples/test-suite/d/cpp11_move_typemaps_runme.2.d b/Examples/test-suite/d/cpp11_move_typemaps_runme.2.d
new file mode 100644
index 000000000..29561cde3
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_move_typemaps_runme.2.d
@@ -0,0 +1,42 @@
+module cpp11_move_typemaps_runme;
+
+import cpp11_move_typemaps.Counter;
+import cpp11_move_typemaps.MoveOnly;
+import cpp11_move_typemaps.MovableCopyable;
+import std.conv;
+import std.algorithm;
+
+void main() {
+ {
+ Counter.reset_counts();
+ scope MoveOnly mo = new MoveOnly(111);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MoveOnly.take(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+ {
+ Counter.reset_counts();
+ scope MovableCopyable mo = new MovableCopyable(111);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.take(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+ {
+ scope MoveOnly mo = new MoveOnly(222);
+ MoveOnly.take(mo);
+ bool exception_thrown = false;
+ try {
+ MoveOnly.take(mo);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("double usage of take should have been an error");
+ }
+}
diff --git a/Examples/test-suite/d/cpp11_rvalue_reference_move_runme.1.d b/Examples/test-suite/d/cpp11_rvalue_reference_move_runme.1.d
new file mode 100644
index 000000000..da1d0da32
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_rvalue_reference_move_runme.1.d
@@ -0,0 +1,86 @@
+module cpp11_rvalue_reference_move_runme;
+
+import cpp11_rvalue_reference_move.Counter;
+import cpp11_rvalue_reference_move.MovableCopyable;
+
+void main() {
+ {
+ // Function containing rvalue reference parameter
+ Counter.reset_counts();
+ scope MovableCopyable mo = new MovableCopyable(222);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.movein(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ if (!MovableCopyable.is_nullptr(mo))
+ throw new Exception("is_nullptr failed");
+ mo.dispose();
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+
+ {
+ // Move constructor test
+ Counter.reset_counts();
+ scope MovableCopyable mo = new MovableCopyable(222);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable mo_moved = new MovableCopyable(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 1);
+ if (!MovableCopyable.is_nullptr(mo))
+ throw new Exception("is_nullptr failed");
+ mo.dispose();
+ Counter.check_counts(1, 0, 0, 1, 0, 1);
+ mo_moved.dispose();
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+
+ {
+ // Move assignment operator test
+ Counter.reset_counts();
+ scope MovableCopyable mo111 = new MovableCopyable(111);
+ scope MovableCopyable mo222 = new MovableCopyable(222);
+ Counter.check_counts(2, 0, 0, 0, 0, 0);
+ mo111.MoveAssign(mo222);
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ if (!MovableCopyable.is_nullptr(mo222))
+ throw new Exception("is_nullptr failed");
+ mo222.dispose();
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ mo111.dispose();
+ Counter.check_counts(2, 0, 0, 0, 1, 2);
+ }
+
+ {
+ // null check
+ Counter.reset_counts();
+ bool exception_thrown = false;
+ try {
+ MovableCopyable.movein(null);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "MovableCopyable && is null"))
+ throw new Exception("incorrect exception message:" ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown null error");
+ Counter.check_counts(0, 0, 0, 0, 0, 0);
+ }
+
+ {
+ // output
+ Counter.reset_counts();
+ MovableCopyable mc = MovableCopyable.moveout(1234);
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ MovableCopyable.check_numbers_match(mc, 1234);
+
+ bool exception_thrown = false;
+ try {
+ MovableCopyable.movein(mc);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ }
+}
diff --git a/Examples/test-suite/d/cpp11_rvalue_reference_move_runme.2.d b/Examples/test-suite/d/cpp11_rvalue_reference_move_runme.2.d
new file mode 100644
index 000000000..342f34f94
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_rvalue_reference_move_runme.2.d
@@ -0,0 +1,87 @@
+module cpp11_rvalue_reference_move_runme;
+
+import cpp11_rvalue_reference_move.Counter;
+import cpp11_rvalue_reference_move.MovableCopyable;
+import std.algorithm;
+
+void main() {
+ {
+ // Function containing rvalue reference parameter
+ Counter.reset_counts();
+ scope MovableCopyable mo = new MovableCopyable(222);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.movein(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ if (!MovableCopyable.is_nullptr(mo))
+ throw new Exception("is_nullptr failed");
+ mo.dispose();
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+
+ {
+ // Move constructor test
+ Counter.reset_counts();
+ scope MovableCopyable mo = new MovableCopyable(222);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable mo_moved = new MovableCopyable(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 1);
+ if (!MovableCopyable.is_nullptr(mo))
+ throw new Exception("is_nullptr failed");
+ mo.dispose();
+ Counter.check_counts(1, 0, 0, 1, 0, 1);
+ mo_moved.dispose();
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+
+ {
+ // Move assignment operator test
+ Counter.reset_counts();
+ scope MovableCopyable mo111 = new MovableCopyable(111);
+ scope MovableCopyable mo222 = new MovableCopyable(222);
+ Counter.check_counts(2, 0, 0, 0, 0, 0);
+ mo111.MoveAssign(mo222);
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ if (!MovableCopyable.is_nullptr(mo222))
+ throw new Exception("is_nullptr failed");
+ mo222.dispose();
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ mo111.dispose();
+ Counter.check_counts(2, 0, 0, 0, 1, 2);
+ }
+
+ {
+ // null check
+ Counter.reset_counts();
+ bool exception_thrown = false;
+ try {
+ MovableCopyable.movein(null);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "MovableCopyable && is null"))
+ throw new Exception("incorrect exception message:" ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown null error");
+ Counter.check_counts(0, 0, 0, 0, 0, 0);
+ }
+
+ {
+ // output
+ Counter.reset_counts();
+ MovableCopyable mc = MovableCopyable.moveout(1234);
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ MovableCopyable.check_numbers_match(mc, 1234);
+
+ bool exception_thrown = false;
+ try {
+ MovableCopyable.movein(mc);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ }
+}
diff --git a/Examples/test-suite/d/cpp11_std_unique_ptr_runme.1.d b/Examples/test-suite/d/cpp11_std_unique_ptr_runme.1.d
new file mode 100644
index 000000000..b8e466414
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_std_unique_ptr_runme.1.d
@@ -0,0 +1,123 @@
+module cpp11_std_unique_ptr_runme;
+
+import cpp11_std_unique_ptr.cpp11_std_unique_ptr;
+import cpp11_std_unique_ptr.Klass;
+import cpp11_std_unique_ptr.KlassInheritance;
+import std.conv;
+import std.algorithm;
+
+void checkCount(int expected_count) {
+ int actual_count = Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
+}
+
+void main() {
+ // Test raw pointer handling involving virtual inheritance
+ {
+ scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ string s = useKlassRawPtr(kini);
+ if (s != "KlassInheritanceInput")
+ throw new Exception("Incorrect string: " ~ s);
+ }
+ checkCount(0);
+
+ // unique_ptr as input
+ {
+ scope Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ string s = takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kin))
+ throw new Exception("is_nullptr failed");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ {
+ scope Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ string s = takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kin))
+ throw new Exception("is_nullptr failed");
+ bool exception_thrown = false;
+ try {
+ takeKlassUniquePtr(kin);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("double usage of takeKlassUniquePtr should have been an error");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ {
+ scope Klass kin = new Klass("KlassInput");
+ bool exception_thrown = false;
+ Klass notowned = get_not_owned_ptr(kin);
+ try {
+ takeKlassUniquePtr(notowned);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ }
+ checkCount(0);
+
+ {
+ scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ string s = takeKlassUniquePtr(kini);
+ checkCount(0);
+ if (s != "KlassInheritanceInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kini))
+ throw new Exception("is_nullptr failed");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ takeKlassUniquePtr(null);
+ takeKlassUniquePtr(make_null());
+ checkCount(0);
+
+ // overloaded parameters
+ if (overloadTest() != 0)
+ throw new Exception("overloadTest failed");
+ if (overloadTest(null) != 1)
+ throw new Exception("overloadTest failed");
+ if (overloadTest(new Klass("over")) != 1)
+ throw new Exception("overloadTest failed");
+ checkCount(0);
+
+
+ // unique_ptr as output
+ Klass k1 = makeKlassUniquePtr("first");
+ if (k1.getLabel() != "first")
+ throw new Exception("wrong object label");
+
+ Klass k2 = makeKlassUniquePtr("second");
+ checkCount(2);
+
+ k1.dispose();
+ checkCount(1);
+
+ if (k2.getLabel() != "second")
+ throw new Exception("wrong object label");
+
+ k2.dispose();
+ checkCount(0);
+
+ if (makeNullUniquePtr() !is null)
+ throw new Exception("null failure");
+}
diff --git a/Examples/test-suite/d/cpp11_std_unique_ptr_runme.2.d b/Examples/test-suite/d/cpp11_std_unique_ptr_runme.2.d
new file mode 100644
index 000000000..b8e466414
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_std_unique_ptr_runme.2.d
@@ -0,0 +1,123 @@
+module cpp11_std_unique_ptr_runme;
+
+import cpp11_std_unique_ptr.cpp11_std_unique_ptr;
+import cpp11_std_unique_ptr.Klass;
+import cpp11_std_unique_ptr.KlassInheritance;
+import std.conv;
+import std.algorithm;
+
+void checkCount(int expected_count) {
+ int actual_count = Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
+}
+
+void main() {
+ // Test raw pointer handling involving virtual inheritance
+ {
+ scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ string s = useKlassRawPtr(kini);
+ if (s != "KlassInheritanceInput")
+ throw new Exception("Incorrect string: " ~ s);
+ }
+ checkCount(0);
+
+ // unique_ptr as input
+ {
+ scope Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ string s = takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kin))
+ throw new Exception("is_nullptr failed");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ {
+ scope Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ string s = takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kin))
+ throw new Exception("is_nullptr failed");
+ bool exception_thrown = false;
+ try {
+ takeKlassUniquePtr(kin);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("double usage of takeKlassUniquePtr should have been an error");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ {
+ scope Klass kin = new Klass("KlassInput");
+ bool exception_thrown = false;
+ Klass notowned = get_not_owned_ptr(kin);
+ try {
+ takeKlassUniquePtr(notowned);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ }
+ checkCount(0);
+
+ {
+ scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ string s = takeKlassUniquePtr(kini);
+ checkCount(0);
+ if (s != "KlassInheritanceInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kini))
+ throw new Exception("is_nullptr failed");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ takeKlassUniquePtr(null);
+ takeKlassUniquePtr(make_null());
+ checkCount(0);
+
+ // overloaded parameters
+ if (overloadTest() != 0)
+ throw new Exception("overloadTest failed");
+ if (overloadTest(null) != 1)
+ throw new Exception("overloadTest failed");
+ if (overloadTest(new Klass("over")) != 1)
+ throw new Exception("overloadTest failed");
+ checkCount(0);
+
+
+ // unique_ptr as output
+ Klass k1 = makeKlassUniquePtr("first");
+ if (k1.getLabel() != "first")
+ throw new Exception("wrong object label");
+
+ Klass k2 = makeKlassUniquePtr("second");
+ checkCount(2);
+
+ k1.dispose();
+ checkCount(1);
+
+ if (k2.getLabel() != "second")
+ throw new Exception("wrong object label");
+
+ k2.dispose();
+ checkCount(0);
+
+ if (makeNullUniquePtr() !is null)
+ throw new Exception("null failure");
+}
diff --git a/Examples/test-suite/d/li_std_auto_ptr_runme.1.d b/Examples/test-suite/d/li_std_auto_ptr_runme.1.d
new file mode 100644
index 000000000..86fac68b5
--- /dev/null
+++ b/Examples/test-suite/d/li_std_auto_ptr_runme.1.d
@@ -0,0 +1,123 @@
+module li_std_auto_ptr_runme;
+
+import li_std_auto_ptr.li_std_auto_ptr;
+import li_std_auto_ptr.Klass;
+import li_std_auto_ptr.KlassInheritance;
+import std.conv;
+import std.algorithm;
+
+void checkCount(int expected_count) {
+ int actual_count = Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
+}
+
+void main() {
+ // Test raw pointer handling involving virtual inheritance
+ {
+ scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ string s = useKlassRawPtr(kini);
+ if (s != "KlassInheritanceInput")
+ throw new Exception("Incorrect string: " ~ s);
+ }
+ checkCount(0);
+
+ // auto_ptr as input
+ {
+ scope Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ string s = takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kin))
+ throw new Exception("is_nullptr failed");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ {
+ scope Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ string s = takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kin))
+ throw new Exception("is_nullptr failed");
+ bool exception_thrown = false;
+ try {
+ takeKlassAutoPtr(kin);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("double usage of takeKlassAutoPtr should have been an error");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ {
+ scope Klass kin = new Klass("KlassInput");
+ bool exception_thrown = false;
+ Klass notowned = get_not_owned_ptr(kin);
+ try {
+ takeKlassAutoPtr(notowned);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ }
+ checkCount(0);
+
+ {
+ scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ string s = takeKlassAutoPtr(kini);
+ checkCount(0);
+ if (s != "KlassInheritanceInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kini))
+ throw new Exception("is_nullptr failed");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ takeKlassAutoPtr(null);
+ takeKlassAutoPtr(make_null());
+ checkCount(0);
+
+ // overloaded parameters
+ if (overloadTest() != 0)
+ throw new Exception("overloadTest failed");
+ if (overloadTest(null) != 1)
+ throw new Exception("overloadTest failed");
+ if (overloadTest(new Klass("over")) != 1)
+ throw new Exception("overloadTest failed");
+ checkCount(0);
+
+
+ // auto_ptr as output
+ Klass k1 = makeKlassAutoPtr("first");
+ if (k1.getLabel() != "first")
+ throw new Exception("wrong object label");
+
+ Klass k2 = makeKlassAutoPtr("second");
+ checkCount(2);
+
+ k1.dispose();
+ checkCount(1);
+
+ if (k2.getLabel() != "second")
+ throw new Exception("wrong object label");
+
+ k2.dispose();
+ checkCount(0);
+
+ if (makeNullAutoPtr() !is null)
+ throw new Exception("null failure");
+}
diff --git a/Examples/test-suite/d/li_std_auto_ptr_runme.2.d b/Examples/test-suite/d/li_std_auto_ptr_runme.2.d
new file mode 100644
index 000000000..86fac68b5
--- /dev/null
+++ b/Examples/test-suite/d/li_std_auto_ptr_runme.2.d
@@ -0,0 +1,123 @@
+module li_std_auto_ptr_runme;
+
+import li_std_auto_ptr.li_std_auto_ptr;
+import li_std_auto_ptr.Klass;
+import li_std_auto_ptr.KlassInheritance;
+import std.conv;
+import std.algorithm;
+
+void checkCount(int expected_count) {
+ int actual_count = Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
+}
+
+void main() {
+ // Test raw pointer handling involving virtual inheritance
+ {
+ scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ string s = useKlassRawPtr(kini);
+ if (s != "KlassInheritanceInput")
+ throw new Exception("Incorrect string: " ~ s);
+ }
+ checkCount(0);
+
+ // auto_ptr as input
+ {
+ scope Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ string s = takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kin))
+ throw new Exception("is_nullptr failed");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ {
+ scope Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ string s = takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (s != "KlassInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kin))
+ throw new Exception("is_nullptr failed");
+ bool exception_thrown = false;
+ try {
+ takeKlassAutoPtr(kin);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("double usage of takeKlassAutoPtr should have been an error");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ {
+ scope Klass kin = new Klass("KlassInput");
+ bool exception_thrown = false;
+ Klass notowned = get_not_owned_ptr(kin);
+ try {
+ takeKlassAutoPtr(notowned);
+ } catch (Exception e) {
+ if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+ throw new Exception("incorrect exception message: " ~ e.msg);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ }
+ checkCount(0);
+
+ {
+ scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ string s = takeKlassAutoPtr(kini);
+ checkCount(0);
+ if (s != "KlassInheritanceInput")
+ throw new Exception("Incorrect string: " ~ s);
+ if (!is_nullptr(kini))
+ throw new Exception("is_nullptr failed");
+ } // dispose should not fail, even though already deleted
+ checkCount(0);
+
+ takeKlassAutoPtr(null);
+ takeKlassAutoPtr(make_null());
+ checkCount(0);
+
+ // overloaded parameters
+ if (overloadTest() != 0)
+ throw new Exception("overloadTest failed");
+ if (overloadTest(null) != 1)
+ throw new Exception("overloadTest failed");
+ if (overloadTest(new Klass("over")) != 1)
+ throw new Exception("overloadTest failed");
+ checkCount(0);
+
+
+ // auto_ptr as output
+ Klass k1 = makeKlassAutoPtr("first");
+ if (k1.getLabel() != "first")
+ throw new Exception("wrong object label");
+
+ Klass k2 = makeKlassAutoPtr("second");
+ checkCount(2);
+
+ k1.dispose();
+ checkCount(1);
+
+ if (k2.getLabel() != "second")
+ throw new Exception("wrong object label");
+
+ k2.dispose();
+ checkCount(0);
+
+ if (makeNullAutoPtr() !is null)
+ throw new Exception("null failure");
+}
diff --git a/Examples/test-suite/d/preproc_constants_c_runme.1.d b/Examples/test-suite/d/preproc_constants_c_runme.1.d
index a6c2f3d10..f98f37b5f 100644
--- a/Examples/test-suite/d/preproc_constants_c_runme.1.d
+++ b/Examples/test-suite/d/preproc_constants_c_runme.1.d
@@ -51,6 +51,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
+ static assert(is(int == typeof(EXPR_LT())));
+ static assert(is(int == typeof(EXPR_GT())));
static assert(is(int == typeof(EXPR_LTE())));
static assert(is(int == typeof(EXPR_GTE())));
static assert(is(int == typeof(EXPR_INEQUALITY())));
diff --git a/Examples/test-suite/d/preproc_constants_c_runme.2.d b/Examples/test-suite/d/preproc_constants_c_runme.2.d
index 786cb48cc..caf3029b2 100644
--- a/Examples/test-suite/d/preproc_constants_c_runme.2.d
+++ b/Examples/test-suite/d/preproc_constants_c_runme.2.d
@@ -51,6 +51,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
+ static assert(is(int == typeof(EXPR_LT())));
+ static assert(is(int == typeof(EXPR_GT())));
static assert(is(int == typeof(EXPR_LTE())));
static assert(is(int == typeof(EXPR_GTE())));
static assert(is(int == typeof(EXPR_INEQUALITY())));
diff --git a/Examples/test-suite/d/preproc_constants_runme.1.d b/Examples/test-suite/d/preproc_constants_runme.1.d
index 85fa918e4..95f3c4757 100644
--- a/Examples/test-suite/d/preproc_constants_runme.1.d
+++ b/Examples/test-suite/d/preproc_constants_runme.1.d
@@ -50,6 +50,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
+ static assert(is(int == typeof(EXPR_LT())));
+ static assert(is(int == typeof(EXPR_GT())));
static assert(is(bool == typeof(EXPR_LTE())));
static assert(is(bool == typeof(EXPR_GTE())));
static assert(is(bool == typeof(EXPR_INEQUALITY())));
diff --git a/Examples/test-suite/d/preproc_constants_runme.2.d b/Examples/test-suite/d/preproc_constants_runme.2.d
index c81e53160..416384a11 100644
--- a/Examples/test-suite/d/preproc_constants_runme.2.d
+++ b/Examples/test-suite/d/preproc_constants_runme.2.d
@@ -50,6 +50,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
+ static assert(is(bool == typeof(EXPR_LT())));
+ static assert(is(bool == typeof(EXPR_GT())));
static assert(is(bool == typeof(EXPR_LTE())));
static assert(is(bool == typeof(EXPR_GTE())));
static assert(is(bool == typeof(EXPR_INEQUALITY())));
diff --git a/Examples/test-suite/d/typemap_out_optimal_runme.1.d b/Examples/test-suite/d/typemap_out_optimal_runme.1.d
index 16aab3cff..1267197e2 100644
--- a/Examples/test-suite/d/typemap_out_optimal_runme.1.d
+++ b/Examples/test-suite/d/typemap_out_optimal_runme.1.d
@@ -6,4 +6,5 @@ void main() {
XX x;
XX.trace = false;
x = XX.create();
+ x = XX.createConst();
}
diff --git a/Examples/test-suite/d/typemap_out_optimal_runme.2.d b/Examples/test-suite/d/typemap_out_optimal_runme.2.d
index 16aab3cff..1267197e2 100644
--- a/Examples/test-suite/d/typemap_out_optimal_runme.2.d
+++ b/Examples/test-suite/d/typemap_out_optimal_runme.2.d
@@ -6,4 +6,5 @@ void main() {
XX x;
XX.trace = false;
x = XX.create();
+ x = XX.createConst();
}
diff --git a/Examples/test-suite/default_arg_expressions.i b/Examples/test-suite/default_arg_expressions.i
index d83dc05bc..99d54c3b9 100644
--- a/Examples/test-suite/default_arg_expressions.i
+++ b/Examples/test-suite/default_arg_expressions.i
@@ -8,20 +8,29 @@
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) UsdGeomTokensPtr;
%immutable UsdGeomTokens;
+// Don't call our getters get_xxx() as that collides with generated getters in
+// some languages (e.g. csharp).
+
%inline %{
struct Numbers {
int val;
int *ptr;
+ const int& g_val() const { return val; }
+ const int* g_ptr() const { return ptr; }
Numbers() : val(), ptr(&val) {}
};
struct TfToken {
Numbers val;
Numbers *ptr;
+ const Numbers& g_val() const { return val; }
+ const Numbers* g_ptr() const { return ptr; }
TfToken() : val(), ptr(&val) {}
};
struct Tokens {
const TfToken face;
const TfToken *pface;
+ const TfToken& g_face() const { return face; }
+ const TfToken* g_pface() const { return pface; }
Tokens() : face(), pface(&face) {}
};
static Tokens UsdGeomTokens;
@@ -30,5 +39,33 @@ void CreateMaterialBindSubset1(const Tokens &elementType = UsdGeomTokens) {}
void CreateMaterialBindSubset2(int num = UsdGeomTokensPtr->pface->val.val) {}
void CreateMaterialBindSubset3(int num = UsdGeomTokensPtr->pface->ptr->val) {}
void CreateMaterialBindSubset4(int num = UsdGeomTokensPtr->face.val.val) {}
-//void CreateMaterialBindSubset5(int num = UsdGeomTokens.face.val.val) {}
+void CreateMaterialBindSubset5(int num = UsdGeomTokens.face.val.val) {}
+void CreateMaterialBindSubset6(int num = UsdGeomTokensPtr->pface->val.g_val()) {}
+void CreateMaterialBindSubset7(int num = UsdGeomTokensPtr->pface->ptr->g_val()) {}
+void CreateMaterialBindSubset8(int num = UsdGeomTokensPtr->face.val.g_val()) {}
+void CreateMaterialBindSubset9(int num = UsdGeomTokens.face.val.g_val()) {}
+void CreateMaterialBindSubseta(int num = UsdGeomTokensPtr->pface->g_val().val) {}
+void CreateMaterialBindSubsetb(int num = UsdGeomTokensPtr->pface->g_ptr()->val) {}
+void CreateMaterialBindSubsetc(int num = UsdGeomTokensPtr->face.g_val().val) {}
+void CreateMaterialBindSubsetd(int num = UsdGeomTokens.face.g_val().val) {}
+void CreateMaterialBindSubsete(int num = UsdGeomTokensPtr->pface->g_val().g_val()) {}
+void CreateMaterialBindSubsetf(int num = UsdGeomTokensPtr->pface->g_ptr()->g_val()) {}
+void CreateMaterialBindSubsetg(int num = UsdGeomTokensPtr->face.g_val().g_val()) {}
+void CreateMaterialBindSubseth(int num = UsdGeomTokens.face.g_val().g_val()) {}
+void CreateMaterialBindSubseti(int num = UsdGeomTokensPtr->g_pface()->val.val) {}
+void CreateMaterialBindSubsetj(int num = UsdGeomTokensPtr->g_pface()->ptr->val) {}
+void CreateMaterialBindSubsetk(int num = UsdGeomTokensPtr->g_face().val.val) {}
+void CreateMaterialBindSubsetl(int num = UsdGeomTokens.g_face().val.val) {}
+void CreateMaterialBindSubsetm(int num = UsdGeomTokensPtr->g_pface()->val.g_val()) {}
+void CreateMaterialBindSubsetn(int num = UsdGeomTokensPtr->g_pface()->ptr->g_val()) {}
+void CreateMaterialBindSubseto(int num = UsdGeomTokensPtr->g_face().val.g_val()) {}
+void CreateMaterialBindSubsetp(int num = UsdGeomTokens.g_face().val.g_val()) {}
+void CreateMaterialBindSubsetq(int num = UsdGeomTokensPtr->g_pface()->g_val().val) {}
+void CreateMaterialBindSubsetr(int num = UsdGeomTokensPtr->g_pface()->g_ptr()->val) {}
+void CreateMaterialBindSubsets(int num = UsdGeomTokensPtr->g_face().g_val().val) {}
+void CreateMaterialBindSubsett(int num = UsdGeomTokens.g_face().g_val().val) {}
+void CreateMaterialBindSubsetu(int num = UsdGeomTokensPtr->g_pface()->g_val().g_val()) {}
+void CreateMaterialBindSubsetv(int num = UsdGeomTokensPtr->g_pface()->g_ptr()->g_val()) {}
+void CreateMaterialBindSubsetw(int num = UsdGeomTokensPtr->g_face().g_val().g_val()) {}
+void CreateMaterialBindSubsetx(int num = UsdGeomTokens.g_face().g_val().g_val()) {}
%}
diff --git a/Examples/test-suite/default_args.i b/Examples/test-suite/default_args.i
index 6b680f561..fda88f63d 100644
--- a/Examples/test-suite/default_args.i
+++ b/Examples/test-suite/default_args.i
@@ -18,6 +18,7 @@
%{
#define TESTCASE_THROW1(T1)
#define TESTCASE_THROW2(T1, T2)
+#include <string.h>
%}
%include <std_string.i>
@@ -71,7 +72,7 @@
class EnumClass {
public:
enum speed { FAST, SLOW };
- // Note: default values should be EnumClass::FAST and SWEET
+ // Note: default values should be EnumClass::FAST and SWEET
bool blah(speed s = FAST, flavor f = SWEET) { return (s == FAST && f == SWEET); };
};
@@ -83,16 +84,16 @@
// casts
const char * casts1(const char *m = (const char *) NULL) {
- char *ret = NULL;
- if (m) {
+ char *ret = NULL;
+ if (m) {
ret = new char[strlen(m)+1];
strcpy(ret, m);
}
return ret;
}
const char * casts2(const char *m = (const char *) "Hello") {
- char *ret = NULL;
- if (m) {
+ char *ret = NULL;
+ if (m) {
ret = new char[strlen(m)+1];
strcpy(ret, m);
}
@@ -108,16 +109,16 @@
char chartest6(char c = '\x43') { return c; } // 'C'
// namespaces
- namespace AType {
- enum AType { NoType };
- }
+ namespace AType {
+ enum AType { NoType };
+ }
void dummy(AType::AType aType = AType::NoType) {}
- namespace A {
- namespace B {
- int CONST_NUM = 10;
- }
+ namespace A {
+ namespace B {
+ int CONST_NUM = 10;
+ }
int afunction(int i = B::CONST_NUM) { return i; }
- }
+ }
// references
int reftest1(const int &x = 42) { return x; }
@@ -131,7 +132,7 @@
void test(int x = Oak + Fir + Cedar) {}
};
enum Tree::types chops(enum Tree::types type) { return type; }
-
+
%}
// Rename a class member
@@ -143,7 +144,7 @@
%rename(renamed2arg) Foo::renameme(int x) const;
%rename(renamed1arg) Foo::renameme() const;
-%typemap(default) double* null_by_default "$1=0;";
+%typemap(default) double* null_by_default "$1=0;"
%inline %{
typedef void* MyHandle;
@@ -155,11 +156,11 @@
static int spam;
Foo(){}
-
+
Foo(int x, int y = 0, int z = 0){}
void meth(int x, int y = 0, int z = 0){}
-
+
// Use a renamed member as a default argument. SWIG has to resolve
// bar to Foo::bar and not Foo::spam. SWIG-1.3.11 got this wrong.
// (Different default parameter wrapping in SWIG-1.3.23 ensures SWIG doesn't have to resolve these symbols).
@@ -189,20 +190,20 @@
// tests valuewrapper
%feature("compactdefaultargs") MyClass2::set;
%inline %{
- enum MyType { Val1, Val2 };
+ enum MyType { Val1, Val2 };
- class MyClass1
- {
- public:
+ class MyClass1
+ {
+ public:
MyClass1(MyType myType) {}
- };
+ };
- class MyClass2
- {
- public :
+ class MyClass2
+ {
+ public :
void set(MyClass1 cl1 = Val1) {}
- // This could have been written : set(MyClass1 cl1 = MyClass1(Val1))
- // But it works in C++ since there is a "conversion" constructor in MyClass1.
+ // This could have been written : set(MyClass1 cl1 = MyClass1(Val1))
+ // But it works in C++ since there is a "conversion" constructor in MyClass1.
void set2(MyClass1 cl1 = Val1) {}
};
%}
@@ -281,7 +282,7 @@ struct ConstMethods {
};
%}
-// const methods
+// const methods
// runtime test needed to check that the const method is called
struct ConstMethods {
int coo(double d = 0.0) const;
@@ -305,8 +306,8 @@ struct ConstMethods {
return(x+p);
}
- typedef struct Pointf {
- double x,y;
+ typedef struct Pointf {
+ double x,y;
} Pointf;
}
%}
diff --git a/Examples/test-suite/derived_byvalue.i b/Examples/test-suite/derived_byvalue.i
index 21de809a5..34aedaa64 100644
--- a/Examples/test-suite/derived_byvalue.i
+++ b/Examples/test-suite/derived_byvalue.i
@@ -83,7 +83,7 @@ Hash {
and by checking the typemaps.
The typemap code also calls SwigType_remember(), if your typemaps
defined an object type, it will be added into the SwigType table.
- its normally a
+ it's normally a
SWIG_ConvertPtr(....$descriptor...)
when it should have been a $&descriptor or $*descriptor
diff --git a/Examples/test-suite/director_basic.i b/Examples/test-suite/director_basic.i
index 23d910324..abb1a3d13 100644
--- a/Examples/test-suite/director_basic.i
+++ b/Examples/test-suite/director_basic.i
@@ -71,11 +71,12 @@
%}
%typemap(cscode) MyClass %{
+ // low level implementation check for checking MyOverriddenClass
public void testSwigDerivedClassHasMethod() {
if (SwigDerivedClassHasMethod("nonVirtual", swigMethodTypes3))
- throw new global::System.Exception("non-overriding non-virtual method would be when connecting director");
+ throw new global::System.Exception("SwigDerivedClassHasMethod failed checking a non-overriding non-virtual method (nonVirtual)");
if (SwigDerivedClassHasMethod("nonOverride", swigMethodTypes4))
- throw new global::System.Exception("non-overriding virtual method would be when connecting director");
+ throw new global::System.Exception("SwigDerivedClassHasMethod failed checking a non-overriding method (nonOverride)");
}
%}
diff --git a/Examples/test-suite/director_binary_string.i b/Examples/test-suite/director_binary_string.i
index 17bdc1b64..40d899fe1 100644
--- a/Examples/test-suite/director_binary_string.i
+++ b/Examples/test-suite/director_binary_string.i
@@ -8,6 +8,7 @@
%inline %{
#include <stdlib.h>
+#include <string.h>
#define BUFFER_SIZE_AA 8
#define BUFFER_SIZE_BB 5
diff --git a/Examples/test-suite/director_exception.i b/Examples/test-suite/director_exception.i
index 9ff7f3842..8e76c0781 100644
--- a/Examples/test-suite/director_exception.i
+++ b/Examples/test-suite/director_exception.i
@@ -48,7 +48,7 @@ namespace Swig {
%feature("director:except") {
jthrowable $error = jenv->ExceptionOccurred();
if ($error) {
- // Dont clear exception, still be active when return to java execution
+ // Don't clear exception, still be active when return to java execution
// Essentially ignore exception occurred -- old behavior.
return $null;
}
diff --git a/Examples/test-suite/director_multiple_inheritance.i b/Examples/test-suite/director_multiple_inheritance.i
new file mode 100644
index 000000000..ff50cfeba
--- /dev/null
+++ b/Examples/test-suite/director_multiple_inheritance.i
@@ -0,0 +1,71 @@
+//%module(ruby_minherit="1") multiple_inheritance
+%module(directors="1") director_multiple_inheritance
+
+%feature("director") A;
+%feature("director") B;
+%feature("director") C;
+%feature("director") D;
+
+%inline %{
+
+class A {
+public:
+ virtual ~A() { }
+ virtual int testA();
+};
+
+class B: virtual public A {
+public:
+ virtual ~B() { }
+ virtual int testB();
+};
+
+class C: virtual public A {
+public:
+ virtual ~C() { }
+ virtual int testC();
+};
+
+class D: virtual public A {
+public:
+ virtual ~D() { }
+ virtual int testD();
+};
+
+class E {
+public:
+ virtual ~E() { }
+ virtual int testE(B*);
+};
+
+class F {
+public:
+ virtual ~F() { }
+ virtual int testF(C*);
+};
+
+class T {
+public:
+ virtual ~T() { }
+ virtual int testT(D*);
+};
+
+%}
+
+%{
+
+int A::testA() { return 1; }
+
+int B::testB() { return 2; }
+
+int C::testC() { return 3; }
+
+int D::testD() { return 4; }
+
+int E::testE(B*) { return 5; }
+
+int F::testF(C*) { return 6; }
+
+int T::testT(D*) { return 20; }
+
+%}
diff --git a/Examples/test-suite/director_overload2.i b/Examples/test-suite/director_overload2.i
index ddfa65bb4..9d020e1d1 100644
--- a/Examples/test-suite/director_overload2.i
+++ b/Examples/test-suite/director_overload2.i
@@ -14,17 +14,12 @@ struct OverloadDerived1 : OverloadBase {
virtual void nnn(int vvv) {}
#if defined(__SUNPRO_CC)
virtual void nnn() {}
-#elif defined(SWIGPHP) // FIXME: Hack to stop director_overload2 failing for PHP8
- virtual void nnn() {}
#endif
};
struct OverloadDerived2 : OverloadBase {
#if defined(__SUNPRO_CC)
virtual void nnn(int vvv) {}
-#elif defined(SWIGPHP) // FIXME: Hack to stop director_overload2 failing for PHP8
- virtual void nnn(int vvv) {}
#endif
virtual void nnn() {}
};
%}
-
diff --git a/Examples/test-suite/director_pass_by_value.i b/Examples/test-suite/director_pass_by_value.i
index 31d8ce2d2..6eb62f035 100644
--- a/Examples/test-suite/director_pass_by_value.i
+++ b/Examples/test-suite/director_pass_by_value.i
@@ -1,14 +1,34 @@
%module(directors="1") director_pass_by_value
+
%director DirectorPassByValueAbstractBase;
+%include "cpp11_move_only_helper.i"
+
+%ignore PassedByValue::operator=;
+%ignore PassedByValue::PassedByValue(PassedByValue &&);
+
%inline %{
-class PassedByValue {
- int val;
-public:
- PassedByValue() { val = 0x12345678; }
+#include <iostream>
+using namespace std;
+int trace = false;
+struct PassedByValue {
+ PassedByValue(int v = 0x12345678) { val = v; if (trace) cout << "PassedByValue(0x" << hex << val << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+ PassedByValue(const PassedByValue &other) { val = other.val; if (trace) cout << "PassedByValue(const PassedByValue &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+ PassedByValue & operator=(const PassedByValue &other) { val = other.val; if (trace) cout << "operator=(const PassedByValue &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
+
+#if __cplusplus >= 201103L
+ PassedByValue(PassedByValue &&other) noexcept { val = other.val; if (trace) cout << "PassedByValue(PassedByValue &&)" << " " << this << endl; Counter::move_constructor++; }
+ PassedByValue & operator=(PassedByValue &&other) noexcept { val = other.val; if (trace) cout << "operator=(PassedByValue &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
+ ~PassedByValue() { if (trace) cout << "~PassedByValue()" << " " << this << endl; Counter::destructor++; }
+#endif
+
int getVal() { return val; }
+private:
+ int val;
};
+
int doSomething(int x) {
int yy[256];
yy[0] =0x9876;
@@ -18,6 +38,7 @@ int doSomething(int x) {
class DirectorPassByValueAbstractBase {
public:
virtual void virtualMethod(PassedByValue pbv) = 0;
+ virtual void virtualConstMethod(const PassedByValue pbv) {}
virtual ~DirectorPassByValueAbstractBase () {}
};
@@ -27,4 +48,12 @@ public:
f.virtualMethod(PassedByValue());
}
};
+
+bool has_cplusplus11() {
+#if __cplusplus >= 201103L
+ return true;
+#else
+ return false;
+#endif
+}
%}
diff --git a/Examples/test-suite/director_property.i b/Examples/test-suite/director_property.i
index d64e0c439..3f4f57aaa 100644
--- a/Examples/test-suite/director_property.i
+++ b/Examples/test-suite/director_property.i
@@ -18,9 +18,9 @@
virtual std::string pong() { return "Foo::pong();" + ping(); }
virtual std::string getA() { return this->a_; }
virtual void setA(std::string a) { this->a_ = a; }
+ virtual void setAByRef(const std::string &a) { this->a_ = a; }
static Foo* get_self(Foo *slf) {return slf;}
-
};
%}
@@ -37,9 +37,9 @@
virtual std::string pong();
virtual std::string getA();
virtual void setA(std::string a);
+ virtual void setAByRef(const std::string &a);
static Foo* get_self(Foo *slf);
-
};
%{
diff --git a/Examples/test-suite/director_simple.i b/Examples/test-suite/director_simple.i
new file mode 100644
index 000000000..0883cae12
--- /dev/null
+++ b/Examples/test-suite/director_simple.i
@@ -0,0 +1,42 @@
+%module(directors="1") director_simple
+
+%feature("director") IntBase;
+%feature("director") BoolBase;
+
+%inline %{
+class IntBase {
+ public:
+ virtual ~IntBase() {}
+ IntBase(int i = 3) { (void)i; }
+ virtual int apply(int x) const { return x * 2; }
+};
+
+class IntDerived : public IntBase {
+ public:
+ virtual int apply(int x) const { return x * 3; }
+};
+
+int apply(const IntBase& b, int x)
+{
+ return b.apply(x);
+}
+
+class BoolBase {
+ public:
+ virtual ~BoolBase() {}
+ BoolBase() {}
+ virtual bool apply(bool a, bool b) const = 0;
+};
+
+class BoolDerived : public BoolBase {
+ public:
+ virtual bool apply(bool a, bool b) const { return a != b; }
+};
+
+bool apply(const BoolBase& base, bool a, bool b)
+{
+ return base.apply(a, b);
+}
+
+%}
+
diff --git a/Examples/test-suite/director_template.i b/Examples/test-suite/director_template.i
new file mode 100644
index 000000000..fdc5bfbd1
--- /dev/null
+++ b/Examples/test-suite/director_template.i
@@ -0,0 +1,28 @@
+%module(directors="1") director_template
+
+%{
+#include <vector>
+%}
+
+%include <std_vector.i>
+
+%feature("director") HandleBytes;
+
+%inline %{
+ template <typename X, typename Y> class TwoTemplateParms {};
+%}
+
+%template(TT_int_double) TwoTemplateParms<int, double>;
+
+%inline %{
+ class HandleBytes {
+ public:
+ virtual void handle(const std::vector<unsigned char> data) = 0; // Note: not instantiated with %template
+ virtual void handle2(TwoTemplateParms<int, double> data) = 0;
+ virtual ~HandleBytes() {}
+ };
+
+ void bytes_wrapper(const std::vector<unsigned char> data, HandleBytes *handler) {
+ handler->handle(data);
+ }
+%}
diff --git a/Examples/test-suite/director_thread.i b/Examples/test-suite/director_thread.i
index c4564737f..ac48060ed 100644
--- a/Examples/test-suite/director_thread.i
+++ b/Examples/test-suite/director_thread.i
@@ -20,7 +20,6 @@
#ifdef _WIN32
#include <windows.h>
#include <process.h>
-#include <stdio.h>
#else
#include <pthread.h>
#include <errno.h>
@@ -30,6 +29,7 @@
#endif
#include <assert.h>
+#include <stdio.h>
#include "swig_examples_lock.h"
class Foo;
@@ -42,15 +42,15 @@ extern "C" {
static pthread_t thread;
#endif
- static int thread_terminate = 0;
+ static int swig_thread_terminate = 0;
static SwigExamples::CriticalSection critical_section;
int get_thread_terminate() {
SwigExamples::Lock lock(critical_section);
- return thread_terminate;
+ return swig_thread_terminate;
}
void set_thread_terminate(int value) {
SwigExamples::Lock lock(critical_section);
- thread_terminate = value;
+ swig_thread_terminate = value;
}
}
%}
diff --git a/Examples/test-suite/director_unwrap_result.i b/Examples/test-suite/director_unwrap_result.i
new file mode 100644
index 000000000..1acc6146f
--- /dev/null
+++ b/Examples/test-suite/director_unwrap_result.i
@@ -0,0 +1,93 @@
+%module(directors="1") director_unwrap_result
+
+%warnfilter(SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Storage;
+%warnfilter(SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) StorageTmpl;
+
+%feature("director") Element;
+%feature("director") Storage;
+%feature("director") StorageTmpl;
+
+%inline %{
+
+class Element {
+ Element* self;
+ Element** selfptr;
+ public:
+ Element() {
+ self = this;
+ selfptr = &self;
+ }
+ virtual ~Element() {}
+ Element **getPtrPtr() {
+ return &self;
+ }
+ Element ***getPtrPtrPtr() {
+ return &selfptr;
+ }
+};
+typedef Element * element_ptr_t;
+typedef Element & element_ref_t;
+
+class Storage {
+ public:
+ virtual ~Storage() {}
+ virtual Element **getIt() = 0;
+ Element getElement() {
+ return **getIt();
+ }
+ Element* const getElementPtr() {
+ return *getIt();
+ }
+ Element& getElementRef() {
+ return **getIt();
+ }
+ Element* const *getElementPtrPtr() {
+ return getIt();
+ }
+ Element *&getElementPtrRef() {
+ return *getIt();
+ }
+ element_ref_t getElementRefTypedef() {
+ return **getIt();
+ }
+ element_ptr_t getElementPtrTypedef() {
+ return *getIt();
+ }
+ element_ptr_t &getElementPtrRefTypedef() {
+ return *getIt();
+ }
+};
+
+template<class T> class StorageTmpl {
+ public:
+ virtual ~StorageTmpl() {}
+ virtual T &getIt() = 0;
+ T getVal() {
+ return getIt();
+ }
+ T *getPtr() {
+ return &getIt();
+ }
+ T &getRef() {
+ return getIt();
+ }
+};
+
+%}
+
+%template(ElementStorage) StorageTmpl<Element>;
+%template(ElementPtrStorage) StorageTmpl<Element *>;
+%template(ElementPtrPtrStorage) StorageTmpl<Element *const *>;
+
+%inline %{
+
+template<class T> T getParam(T t) {
+ return t;
+}
+
+%}
+
+%template(getIntParam) getParam<int>;
+%template(getIntPtrParam) getParam<int*>;
+%template(getElementPtrParam) getParam<Element *>;
+
diff --git a/Examples/test-suite/director_using_member_scopes.i b/Examples/test-suite/director_using_member_scopes.i
new file mode 100644
index 000000000..d2776ea1e
--- /dev/null
+++ b/Examples/test-suite/director_using_member_scopes.i
@@ -0,0 +1,55 @@
+%module(directors="1") director_using_member_scopes
+
+// Similar to using_member_scopes but for directors
+
+#if !defined(SWIGGO) // TODO: fix Go crash
+
+%feature("director");
+// Python,Java,C# no diffs in generated code when adding in nodirector. Go not happy even without %nodirector.
+// Fully qualifying parameter types in a method declared after the using declaration caused
+// a method being incorrectly added by the using declaration even though the declaration already existed
+
+// Github issue #1441 - segfault in Go and C#
+
+%inline %{
+namespace OgreBites
+{
+ struct NativeWindowType {};
+ class ApplicationContextBase {
+ public:
+ virtual ~ApplicationContextBase() {}
+ virtual int setWindowGrab(NativeWindowType* win, bool grab = true) { return 0; }
+ int setWindowGrab(bool grab = true) { return 5; }
+
+ static int call_setWindowGrab(ApplicationContextBase* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+ };
+ class ApplicationContextSDL : public ApplicationContextBase {
+ public:
+ using ApplicationContextBase::setWindowGrab;
+ int setWindowGrab(NativeWindowType* win, bool grab = true) { return 10; } // This should not be added again as it exists in base class
+
+ static int call_setWindowGrab(ApplicationContextSDL* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+ };
+
+ class ACB {
+ public:
+ virtual ~ACB() {}
+ virtual int setWindowGrab(NativeWindowType* win, bool grab = true) { return 0; }
+ virtual int setWindowGrab(const char *s, int val) { return 1; } // Additional method compared to ApplicationContextBase
+ int setWindowGrab(bool grab = true) { return 5; }
+
+ static int call_setWindowGrab(ACB* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+ static int call_setWindowGrab(ACB* ptr, const char *s, int val) { return ptr->setWindowGrab(s, val); }
+ };
+ class ACSDL : public ACB {
+ public:
+ using ACB::setWindowGrab; // This introduces two methods, not one method like ApplicationContextSDL
+ int setWindowGrab(NativeWindowType* win, bool grab = true) { return 10; } // This should not be added again as it exists in base class
+
+ static int call_setWindowGrab(ACSDL* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+ static int call_setWindowGrab(ACSDL* ptr, const char *s, int val) { return ptr->setWindowGrab(s, val); }
+ };
+}
+%}
+
+#endif
diff --git a/Examples/test-suite/director_wstring.i b/Examples/test-suite/director_wstring.i
index 17761ea59..02df9d64c 100644
--- a/Examples/test-suite/director_wstring.i
+++ b/Examples/test-suite/director_wstring.i
@@ -39,10 +39,11 @@ struct A
std::vector<std::wstring> m_strings;
+ virtual const wchar_t * wchar_out() { return L"ciao"; }
- virtual void process_text(const wchar_t *text)
- {
- }
+ virtual void process_text(const wchar_t *text) {}
+ virtual void process_wstring_text(std::wstring text) {}
+ virtual void process_wstring_ref_text(const std::wstring& text) {}
virtual std::wstring multiple_params_val(const std::wstring& p1, const std::wstring& p2, std::wstring p3, std::wstring p4) const
{ return get_first(); }
@@ -51,6 +52,8 @@ struct A
{ return get_first(); }
void call_process_func() { process_text(L"hello"); }
+ void call_process_wstring_func() { process_wstring_text(L"hello"); }
+ void call_process_wstring_ref_func() { process_wstring_ref_text(L"hello"); }
};
%}
diff --git a/Examples/test-suite/doxygen_autodoc_docstring.i b/Examples/test-suite/doxygen_autodoc_docstring.i
new file mode 100644
index 000000000..e590d7f94
--- /dev/null
+++ b/Examples/test-suite/doxygen_autodoc_docstring.i
@@ -0,0 +1,75 @@
+%module doxygen_autodoc_docstring
+
+%feature("autodoc", 1);
+
+%feature("docstring") ClassWithDocString "Class doc from docstring";
+%feature("docstring") functionWithDocString "Function doc from docstring";
+%feature("docstring") ClassWithDocStringAndDoxygenComment "Class doc from docstring overriding doxycomment";
+%feature("docstring") functionWithDocStringAndDoxygenComment "Function doc from docstring overriding doxycomment";
+
+%inline %{
+class ClassWithoutDoxygenComment {};
+
+void functionWithoutDoxygenComment(int number) {}
+
+/**
+ * Class doxygen comment
+ */
+class ClassWithDoxygenComment {};
+
+/**
+ * Function doxygen comment
+ */
+void functionWithDoxygenComment(int number) {}
+
+class ClassWithDocString {};
+
+void functionWithDocString(int number) {}
+
+/**
+ * Class doxygen comment
+ */
+class ClassWithDocStringAndDoxygenComment {};
+
+/**
+ * Function doxygen comment
+ */
+void functionWithDocStringAndDoxygenComment(int number) {}
+%}
+
+
+%feature("autodoc", ""); // clear autodoc
+
+%feature("docstring") ClassWithDocStringAndDoxygenCommentNoAutodoc "Class doc from docstring overriding doxycomment (no autodoc)";
+%feature("docstring") functionWithDocStringAndDoxygenCommentNoAutodoc "Function doc from docstring overriding doxycomment (no autodoc)";
+
+%inline %{
+/**
+ * Class doxygen comment
+ */
+class ClassWithDocStringAndDoxygenCommentNoAutodoc {};
+
+/**
+ * Function doxygen comment
+ */
+void functionWithDocStringAndDoxygenCommentNoAutodoc(int number) {}
+
+/**
+ * Class doxygen comment 2
+ */
+class ClassWithDoxygenComment2 {};
+
+/**
+ * Function doxygen comment 2
+ */
+void functionWithDoxygenComment2(int number) {}
+%}
+
+%inline %{
+#ifdef SWIGPYTHON_BUILTIN
+bool is_python_builtin() { return true; }
+#else
+bool is_python_builtin() { return false; }
+#endif
+%}
+
diff --git a/Examples/test-suite/doxygen_parsing.i b/Examples/test-suite/doxygen_parsing.i
index 3a559053d..9df0097ec 100644
--- a/Examples/test-suite/doxygen_parsing.i
+++ b/Examples/test-suite/doxygen_parsing.i
@@ -133,6 +133,15 @@ struct SomeAnotherStruct
}
};
+struct Foo1750
+{
+ /// @name Group name
+ /// @{
+ int a;
+ /// @}
+ int b;
+};
+
#ifdef SWIGPYTHON_BUILTIN
bool is_python_builtin() { return true; }
#else
diff --git a/Examples/test-suite/doxygen_translate.i b/Examples/test-suite/doxygen_translate.i
index bb0af1c14..0d11a21d0 100644
--- a/Examples/test-suite/doxygen_translate.i
+++ b/Examples/test-suite/doxygen_translate.i
@@ -59,6 +59,7 @@
* \endif
*
* \image html testImage.bmp "Hello, world!" width=10cm
+ * \image html "test image.jpg" "Test jpeg" width=10cm
*
* <ul>
*
diff --git a/Examples/test-suite/duplicate_class_name_in_ns.i b/Examples/test-suite/duplicate_class_name_in_ns.i
new file mode 100644
index 000000000..8071f08b7
--- /dev/null
+++ b/Examples/test-suite/duplicate_class_name_in_ns.i
@@ -0,0 +1,88 @@
+%module duplicate_class_name_in_ns
+
+%rename(XA) A::X;
+%rename(XB) B::X;
+
+%inline %{
+
+namespace A
+{
+ class X
+ {
+ public:
+ X(){};
+ };
+
+ template<typename T>
+ class Foo
+ {
+ public:
+ Foo(){};
+ };
+
+ class Bar
+ {
+ public:
+ Bar(){};
+ };
+
+ template<typename T>
+ class Baz
+ {
+ public:
+ Baz(){};
+ };
+}
+
+namespace B
+{
+ // non-template derived from non-template
+ class X : public A::X
+ {
+ public:
+ X(){};
+ A::X do_x(){return A::X();}
+ };
+
+ // template derived from template with different template args
+ template<typename T, typename U>
+ class Foo : public A::Foo<U>
+ {
+ public:
+ Foo(){};
+ A::Foo<U> do_foo(){return A::Foo<U>();}
+ };
+
+ // template derived from non-template
+ template<typename T, typename U>
+ class Bar : public A::Bar
+ {
+ public:
+ Bar(){};
+ A::Bar do_bar(){return A::Bar();}
+ };
+
+ // template derived from template with same template args
+ template<typename T>
+ class Baz : public A::Baz<T>
+ {
+ public:
+ Baz(){};
+ A::Baz<T> do_baz(){return A::Baz<T>();}
+ };
+}
+
+%}
+
+%template(AFoo) A::Foo<double>;
+%template(ABaz) A::Baz<double>;
+%template(BFoo) B::Foo<int, double>;
+%template(BBar) B::Bar<int, double>;
+%template(BBaz) B::Baz<double>;
+
+%inline %{
+ A::X get_a_x() {B::X x; return x.do_x();}
+ A::Foo<double> get_a_foo() {B::Foo<int, double> x; return x.do_foo();}
+ A::Bar get_a_bar() {B::Bar<int, double> x; return x.do_bar();}
+ A::Baz<double> get_a_baz() {B::Baz<double> x; return x.do_baz();}
+%}
diff --git a/Examples/test-suite/enum_thorough.i b/Examples/test-suite/enum_thorough.i
index 3beefccc0..b8eb3df0d 100644
--- a/Examples/test-suite/enum_thorough.i
+++ b/Examples/test-suite/enum_thorough.i
@@ -89,8 +89,6 @@ struct SpeedClass {
const colour myColour2;
speedtd1 mySpeedtd1;
SpeedClass() : myColour2(red), mySpeedtd1(slow) { }
-private:
- SpeedClass& operator=(const SpeedClass&);
};
int speedTest0(int s) { return s; }
diff --git a/Examples/test-suite/equality.i b/Examples/test-suite/equality.i
index cdabc4892..344cb9f8c 100644
--- a/Examples/test-suite/equality.i
+++ b/Examples/test-suite/equality.i
@@ -57,8 +57,7 @@ inline bool operator==( const EqualOpWrong& first, const EqualOpWrong& second )
%}
/*
- in order to wrapper this correctly
- we need to extend the class
+ in order to wrap this correctly we need to extend the class
to make the friends & non members part of the class
*/
%extend EqualOpDefined {
diff --git a/Examples/test-suite/errors/Makefile.in b/Examples/test-suite/errors/Makefile.in
index 7137a6862..347bf3858 100644
--- a/Examples/test-suite/errors/Makefile.in
+++ b/Examples/test-suite/errors/Makefile.in
@@ -16,6 +16,10 @@
LANGUAGE = errors
ERROR_EXT = newerr
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/errors/c_extra_rbrace.stderr b/Examples/test-suite/errors/c_extra_rbrace.stderr
index 23bd41f3c..a7b19389d 100644
--- a/Examples/test-suite/errors/c_extra_rbrace.stderr
+++ b/Examples/test-suite/errors/c_extra_rbrace.stderr
@@ -1 +1 @@
-c_extra_rbrace.i:5: Error: Syntax error. Extraneous '}'
+c_extra_rbrace.i:5: Error: Syntax error. Extraneous closing brace ('}')
diff --git a/Examples/test-suite/errors/c_missing_semi.stderr b/Examples/test-suite/errors/c_missing_semi.stderr
index 18befaa1b..9b35037ae 100644
--- a/Examples/test-suite/errors/c_missing_semi.stderr
+++ b/Examples/test-suite/errors/c_missing_semi.stderr
@@ -1 +1 @@
-c_missing_semi.i:3: Error: Syntax error - possibly a missing semicolon.
+c_missing_semi.i:3: Error: Syntax error - possibly a missing semicolon (';').
diff --git a/Examples/test-suite/errors/c_spaceship.i b/Examples/test-suite/errors/c_spaceship.i
new file mode 100644
index 000000000..9be490c54
--- /dev/null
+++ b/Examples/test-suite/errors/c_spaceship.i
@@ -0,0 +1,3 @@
+%module xxx
+
+int a[(1<=>2>1)];
diff --git a/Examples/test-suite/errors/c_spaceship.stderr b/Examples/test-suite/errors/c_spaceship.stderr
new file mode 100644
index 000000000..bc18d45ed
--- /dev/null
+++ b/Examples/test-suite/errors/c_spaceship.stderr
@@ -0,0 +1 @@
+c_spaceship.i:3: Error: Syntax error in input(1).
diff --git a/Examples/test-suite/errors/cpp_extra_brackets.stderr b/Examples/test-suite/errors/cpp_extra_brackets.stderr
index f1fabc78d..901bed6a9 100644
--- a/Examples/test-suite/errors/cpp_extra_brackets.stderr
+++ b/Examples/test-suite/errors/cpp_extra_brackets.stderr
@@ -1 +1 @@
-cpp_extra_brackets.i:5: Error: Unexpected ')'.
+cpp_extra_brackets.i:5: Error: Unexpected closing parenthesis (')').
diff --git a/Examples/test-suite/errors/cpp_namewarn.i b/Examples/test-suite/errors/cpp_namewarn.i
index c0edc4b4e..5c62cebeb 100644
--- a/Examples/test-suite/errors/cpp_namewarn.i
+++ b/Examples/test-suite/errors/cpp_namewarn.i
@@ -1,10 +1,10 @@
%module xxx
-%namewarn("314:'key1' is a keyword, renaming to '_key1'", rename="_%s") "key1";
-%namewarn("314:'key2' is a keyword, renaming to '_key2'", rename="_%s") "key2";
-%namewarn("314:'key3' is a keyword, renaming to '_key3'", rename="_%s") "key3";
-%namewarn("314:'key4' is a keyword, renaming to '_key4'", rename="_%s") "key4";
-%namewarn("314:'key5' is a keyword, renaming to '_key5'", rename="_%s") "key5";
+%namewarn("314:'key1' is a keyword", rename="_%s") "key1";
+%namewarn("314:'key2' is a keyword", rename="_%s") "key2";
+%namewarn("314:'key3' is a keyword", rename="_%s") "key3";
+%namewarn("314:'key4' is a keyword", rename="_%s") "key4";
+%namewarn("314:'key5' is a keyword", rename="_%s") "key5";
// Non-templated
%ignore KlassA::key1;
diff --git a/Examples/test-suite/errors/cpp_namewarn.stderr b/Examples/test-suite/errors/cpp_namewarn.stderr
index e5b893268..7cc640e28 100644
--- a/Examples/test-suite/errors/cpp_namewarn.stderr
+++ b/Examples/test-suite/errors/cpp_namewarn.stderr
@@ -7,4 +7,4 @@ cpp_namewarn.i:67: Warning 314: 'key3' is a keyword, renaming to '_key3'
cpp_namewarn.i:72: Warning 314: 'key1' is a keyword, renaming to '_key1'
cpp_namewarn.i:73: Warning 314: 'key2' is a keyword, renaming to '_key2'
cpp_namewarn.i:74: Warning 314: 'key3' is a keyword, renaming to '_key3'
-cpp_namewarn.i:80: Warning 314: 'key5' is a keyword, renaming to '_key5'
+cpp_namewarn.i:80: Warning 314: 'key5' is a keyword
diff --git a/Examples/test-suite/errors/cpp_pp_expressions_bad.i b/Examples/test-suite/errors/cpp_pp_expressions_bad.i
new file mode 100644
index 000000000..2f71232fe
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_pp_expressions_bad.i
@@ -0,0 +1,6 @@
+%module xxx
+
+
+/* Spaceship operator doesn't seem to be allowed in preprocessor expressions. */
+#if (4 <=> 2) < 0
+#endif
diff --git a/Examples/test-suite/errors/cpp_pp_expressions_bad.stderr b/Examples/test-suite/errors/cpp_pp_expressions_bad.stderr
new file mode 100644
index 000000000..d95d416f5
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_pp_expressions_bad.stderr
@@ -0,0 +1,2 @@
+cpp_pp_expressions_bad.i:5: Warning 202: Could not evaluate expression '(4 <=> 2) < 0'
+cpp_pp_expressions_bad.i:5: Warning 202: Spaceship operator (<=>) not allowed in preprocessor expression
diff --git a/Examples/test-suite/errors/cpp_template_explicit_instantiation.i b/Examples/test-suite/errors/cpp_template_explicit_instantiation.i
new file mode 100644
index 000000000..97513724b
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_explicit_instantiation.i
@@ -0,0 +1,24 @@
+%module xxx
+
+%inline %{
+namespace std {
+ template<typename T> class vector {};
+}
+template<typename T> void Func() {}
+%}
+
+%inline %{
+// Class template
+template class std::vector<int>; // C++03 template explicit instantiation definition in C++
+extern template class std::vector<int>; // C++11 template explicit instantiation declaration (extern template)
+%}
+%template(VectorInt) std::vector<int>; // SWIG template instantiation
+
+%inline %{
+// Function template
+template void Func<int>(); // C++03 template explicit instantiation definition in C++
+extern template void Func<int>(); // C++11 template explicit instantiation declaration (extern template)
+%}
+%template(FuncInt) Func<int>; // SWIG template instantiation
+
+
diff --git a/Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr b/Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr
new file mode 100644
index 000000000..052d3de27
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr
@@ -0,0 +1,4 @@
+cpp_template_explicit_instantiation.i:12: Warning 320: Explicit template instantiation ignored.
+cpp_template_explicit_instantiation.i:13: Warning 327: Extern template ignored.
+cpp_template_explicit_instantiation.i:19: Warning 320: Explicit template instantiation ignored.
+cpp_template_explicit_instantiation.i:20: Warning 327: Extern template ignored.
diff --git a/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.i b/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.i
new file mode 100644
index 000000000..e8168ec46
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.i
@@ -0,0 +1,45 @@
+%module x
+
+// Just the following languages tested
+#if defined (SWIGCSHARP) || defined (SWIGD)
+%typemap(out, optimal="1") SWIGTYPE %{
+ $result = new $1_ltype((const $1_ltype &)$1);
+%}
+#elif defined (SWIGJAVA)
+%typemap(out, optimal="1") SWIGTYPE %{
+ *($&1_ltype*)&$result = new $1_ltype((const $1_ltype &)$1);
+%}
+#elif defined (SWIGUTL)
+%typemap(out,noblock="1", optimal="1") SWIGTYPE {
+ %set_output(SWIG_NewPointerObj(%new_copy($1, $ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+}
+#endif
+
+// This results in an action which SWIG should disable "optimal" for, but
+// it was failing to. Fixed in SWIG 4.1.0.
+%exception XX::create() "$action\n{while(sleep(1)){}}"
+
+%ignore XX::operator=;
+
+#ifdef SWIGD
+%rename(trace) XX::debug;
+#endif
+
+%inline %{
+#include <iostream>
+using namespace std;
+
+struct XX {
+ XX() { if (debug) cout << "XX()" << endl; }
+ XX(int i) { if (debug) cout << "XX(" << i << ")" << endl; }
+ XX(const XX &other) { if (debug) cout << "XX(const XX &)" << endl; }
+ XX& operator =(const XX &other) { if (debug) cout << "operator=(const XX &)" << endl; return *this; }
+ ~XX() { if (debug) cout << "~XX()" << endl; }
+ static XX create() {
+ return XX(123);
+ }
+ static bool debug;
+};
+bool XX::debug = true;
+%}
+
diff --git a/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.stderr b/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.stderr
new file mode 100644
index 000000000..15bf64f46
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.stderr
@@ -0,0 +1,4 @@
+cpp_typemap_out_optimal_bug.i:40: Warning 474: Method XX::create() usage of the optimal attribute ignored
+cpp_typemap_out_optimal_bug.i:15: Warning 474: in the out typemap as the following cannot be used to generate optimal code: result = XX::create();
+{while(sleep(1)){}}
+
diff --git a/Examples/test-suite/errors/cpp_using_declaration_overload.i b/Examples/test-suite/errors/cpp_using_declaration_overload.i
new file mode 100644
index 000000000..9ec633f3f
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_declaration_overload.i
@@ -0,0 +1,9 @@
+%module xxx
+
+struct Base {
+ void m(bool) {}
+};
+struct Derived : Base {
+ void m(bool) const {}
+ using Base::m;
+};
diff --git a/Examples/test-suite/errors/cpp_using_declaration_overload.stderr b/Examples/test-suite/errors/cpp_using_declaration_overload.stderr
new file mode 100644
index 000000000..a5118a739
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_declaration_overload.stderr
@@ -0,0 +1,2 @@
+cpp_using_declaration_overload.i:7: Warning 512: Overloaded method Derived::m(bool) const ignored,
+cpp_using_declaration_overload.i:8: Warning 512: using non-const method Derived::m(bool) instead.
diff --git a/Examples/test-suite/errors/cpp_using_rename.i b/Examples/test-suite/errors/cpp_using_rename.i
new file mode 100644
index 000000000..4b6453ca0
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_rename.i
@@ -0,0 +1,22 @@
+%module xxx
+
+%rename(UseMe) use_me(int i);
+%rename(UseMeToo) Derived::use_me_too;
+
+class Base
+{
+public:
+ void use_me(Base *);
+ void use_me(int i);
+ bool use_me_too(double d) const;
+ bool use_me_too(bool b) const;
+};
+
+class Derived : public Base
+{
+public:
+ using Base::use_me;
+ using Base::use_me_too;
+ using Base::does_not_exist;
+};
+
diff --git a/Examples/test-suite/errors/cpp_using_rename.stderr b/Examples/test-suite/errors/cpp_using_rename.stderr
new file mode 100644
index 000000000..546489655
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_rename.stderr
@@ -0,0 +1,7 @@
+cpp_using_rename.i:18: Warning 526: Using declaration Base::use_me, with name 'use_me', is not actually using
+cpp_using_rename.i:10: Warning 526: the method from Base::use_me(int), with name 'UseMe', as the names are different.
+cpp_using_rename.i:19: Warning 526: Using declaration Base::use_me_too, with name 'UseMeToo', is not actually using
+cpp_using_rename.i:11: Warning 526: the method from Base::use_me_too(double) const, with name 'use_me_too', as the names are different.
+cpp_using_rename.i:19: Warning 526: Using declaration Base::use_me_too, with name 'UseMeToo', is not actually using
+cpp_using_rename.i:12: Warning 526: the method from Base::use_me_too(bool) const, with name 'use_me_too', as the names are different.
+cpp_using_rename.i:20: Warning 315: Nothing known about 'Base::does_not_exist'.
diff --git a/Examples/test-suite/errors/doxygen_unclosed_tag.i b/Examples/test-suite/errors/doxygen_unclosed_tag.i
new file mode 100644
index 000000000..fbc359627
--- /dev/null
+++ b/Examples/test-suite/errors/doxygen_unclosed_tag.i
@@ -0,0 +1,6 @@
+%module xxx
+
+/**
+ * Return a random variate with uniform distribution in the range [a,b), where a<b
+ */
+double uniform(double a, double b);
diff --git a/Examples/test-suite/errors/doxygen_unclosed_tag.stderr b/Examples/test-suite/errors/doxygen_unclosed_tag.stderr
new file mode 100644
index 000000000..9fcdbbbe8
--- /dev/null
+++ b/Examples/test-suite/errors/doxygen_unclosed_tag.stderr
@@ -0,0 +1 @@
+doxygen_unclosed_tag.i:4: Warning 563: Doxygen HTML error for tag b: HTML tag without greater-than ('>') found.
diff --git a/Examples/test-suite/errors/pp_badeval.stderr b/Examples/test-suite/errors/pp_badeval.stderr
index 80f5037ea..bfaa17f59 100644
--- a/Examples/test-suite/errors/pp_badeval.stderr
+++ b/Examples/test-suite/errors/pp_badeval.stderr
@@ -1,2 +1,2 @@
pp_badeval.i:4: Warning 202: Could not evaluate expression 'FOO==4+'
-pp_badeval.i:4: Warning 202: Error: 'Expected an expression'
+pp_badeval.i:4: Warning 202: Expected an expression
diff --git a/Examples/test-suite/errors/pp_expressions_bad.i b/Examples/test-suite/errors/pp_expressions_bad.i
index 454437f95..eea178388 100644
--- a/Examples/test-suite/errors/pp_expressions_bad.i
+++ b/Examples/test-suite/errors/pp_expressions_bad.i
@@ -1,5 +1,5 @@
%module xxx
-/* Note: needs -Wextra to see these warnings */
+
/* Divide by zero */
#define ZERO 0
@@ -41,3 +41,34 @@
#if(1)
#warning Warning okay: #if(1)
#endif
+
+/* The SWIG preprocessor support strings with equality/inequality tests.
+ * Check error cases.
+ */
+#if "TWO" == 1
+#endif
+
+/* This didn't fail prior with SWIG < 4.1. Github #1384. */
+#if 1 == ("TWO")
+#endif
+
+/* These should all give errors. */
+#if "1"
+#endif
+#if -"1"
+#endif
+#if "1" == -"-1"
+#endif
+#if "1" == !"-1"
+#endif
+#if "1" == ~"1"
+#endif
+/* Unary + was a no-op and so this didn't give an error in SWIG < 4.1.0. */
+#if "1" == +"1"
+#endif
+
+/* Spaceship operator doesn't seem to be allowed in preprocessor expressions,
+ * and isn't valid in C at all.
+ */
+#if (4 <=> 2) < 0
+#endif
diff --git a/Examples/test-suite/errors/pp_expressions_bad.stderr b/Examples/test-suite/errors/pp_expressions_bad.stderr
index 84104c6a8..e8d187cb5 100644
--- a/Examples/test-suite/errors/pp_expressions_bad.stderr
+++ b/Examples/test-suite/errors/pp_expressions_bad.stderr
@@ -1,19 +1,35 @@
pp_expressions_bad.i:7: Warning 202: Could not evaluate expression '1%ZERO'
-pp_expressions_bad.i:7: Warning 202: Error: 'Modulo by zero in expression'
+pp_expressions_bad.i:7: Warning 202: Modulo by zero in expression
pp_expressions_bad.i:9: Warning 202: Could not evaluate expression '2/ZERO'
-pp_expressions_bad.i:9: Warning 202: Error: 'Division by zero in expression'
+pp_expressions_bad.i:9: Warning 202: Division by zero in expression
pp_expressions_bad.i:12: Warning 202: Could not evaluate expression '1%(5-5)'
-pp_expressions_bad.i:12: Warning 202: Error: 'Modulo by zero in expression'
+pp_expressions_bad.i:12: Warning 202: Modulo by zero in expression
pp_expressions_bad.i:14: Warning 202: Could not evaluate expression '2/(55-55)'
-pp_expressions_bad.i:14: Warning 202: Error: 'Division by zero in expression'
+pp_expressions_bad.i:14: Warning 202: Division by zero in expression
pp_expressions_bad.i:18: Warning 202: Could not evaluate expression '1.2'
-pp_expressions_bad.i:18: Warning 202: Error: 'Floating point constant in preprocessor expression'
+pp_expressions_bad.i:18: Warning 202: Floating point constant in preprocessor expression
pp_expressions_bad.i:21: Warning 202: Could not evaluate expression '2e3'
-pp_expressions_bad.i:21: Warning 202: Error: 'Floating point constant in preprocessor expression'
+pp_expressions_bad.i:21: Warning 202: Floating point constant in preprocessor expression
pp_expressions_bad.i:25: Warning 202: Could not evaluate expression '8.8'
-pp_expressions_bad.i:25: Warning 202: Error: 'Floating point constant in preprocessor expression'
+pp_expressions_bad.i:25: Warning 202: Floating point constant in preprocessor expression
pp_expressions_bad.i:29: Error: Unknown SWIG preprocessor directive: if123 (if this is a block of target language code, delimit it with %{ and %})
pp_expressions_bad.i:30: Error: Extraneous #endif.
pp_expressions_bad.i:32: Error: Unknown SWIG preprocessor directive: if456e (if this is a block of target language code, delimit it with %{ and %})
pp_expressions_bad.i:33: Error: Extraneous #endif.
pp_expressions_bad.i:42: Warning 204: CPP #warning, "Warning okay: #if(1)".
+pp_expressions_bad.i:48: Warning 202: Could not evaluate expression '"TWO" == 1'
+pp_expressions_bad.i:48: Warning 202: Can't mix strings and integers in expression
+pp_expressions_bad.i:52: Warning 202: Could not evaluate expression '1 == ("TWO")'
+pp_expressions_bad.i:52: Warning 202: Can't mix strings and integers in expression
+pp_expressions_bad.i:58: Warning 202: Could not evaluate expression '-"1"'
+pp_expressions_bad.i:58: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:60: Warning 202: Could not evaluate expression '"1" == -"-1"'
+pp_expressions_bad.i:60: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:62: Warning 202: Could not evaluate expression '"1" == !"-1"'
+pp_expressions_bad.i:62: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:64: Warning 202: Could not evaluate expression '"1" == ~"1"'
+pp_expressions_bad.i:64: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:67: Warning 202: Could not evaluate expression '"1" == +"1"'
+pp_expressions_bad.i:67: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:73: Warning 202: Could not evaluate expression '(4 <=> 2) < 0'
+pp_expressions_bad.i:73: Warning 202: Syntax error
diff --git a/Examples/test-suite/errors/pp_invalid_exponents.stderr b/Examples/test-suite/errors/pp_invalid_exponents.stderr
index 735a31ceb..2ad1b5c6b 100644
--- a/Examples/test-suite/errors/pp_invalid_exponents.stderr
+++ b/Examples/test-suite/errors/pp_invalid_exponents.stderr
@@ -1,6 +1,6 @@
:EOF: Error: Exponent does not have any digits
pp_invalid_exponents.i:3: Warning 202: Could not evaluate expression '123e'
-pp_invalid_exponents.i:3: Warning 202: Error: 'Syntax error'
+pp_invalid_exponents.i:3: Warning 202: Syntax error
:EOF: Error: Exponent does not have any digits
pp_invalid_exponents.i:6: Warning 202: Could not evaluate expression '456.e'
-pp_invalid_exponents.i:6: Warning 202: Error: 'Syntax error'
+pp_invalid_exponents.i:6: Warning 202: Syntax error
diff --git a/Examples/test-suite/errors/pp_unknowndirective.i b/Examples/test-suite/errors/pp_unknowndirective.i
index b4e608b34..659a997d3 100644
--- a/Examples/test-suite/errors/pp_unknowndirective.i
+++ b/Examples/test-suite/errors/pp_unknowndirective.i
@@ -1,10 +1,5 @@
%module xxx
-/* Regression test for bug introduced in 3.0.4 and fixed in 3.0.6 - the '%std'
- * here led to SWIG calling abort().
- */
-%typemap(jstype) std::vector<std::string>, const %std::vector<std::string>&, std::vector<std::string>& "List<String>"
-
/* This used to give the rather cryptic "Syntax error in input(1)." prior to
* SWIG 3.0.4. This testcase checks that the improved message is actually
* issued.
diff --git a/Examples/test-suite/errors/pp_unknowndirective.stderr b/Examples/test-suite/errors/pp_unknowndirective.stderr
index 2cc2377c7..d0d5e249f 100644
--- a/Examples/test-suite/errors/pp_unknowndirective.stderr
+++ b/Examples/test-suite/errors/pp_unknowndirective.stderr
@@ -1 +1 @@
-pp_unknowndirective.i:12: Error: Unknown directive '%remane'.
+pp_unknowndirective.i:7: Error: Unknown directive '%remane'.
diff --git a/Examples/test-suite/errors/pp_unknowndirective4.i b/Examples/test-suite/errors/pp_unknowndirective4.i
new file mode 100644
index 000000000..c9d95e1f0
--- /dev/null
+++ b/Examples/test-suite/errors/pp_unknowndirective4.i
@@ -0,0 +1,7 @@
+%module xxx
+
+/* Regression test for bug #368 introduced in 3.0.4 and fully fixed in 4.1.0.
+ * The `%std` here led to SWIG calling abort() before 3.0.6, and was quietly
+ * ignored in from 3.0.6 until 4.1.0.
+ */
+%typemap(jstype) std::vector<std::string>, const %std::vector<std::string>&, std::vector<std::string>& "List<String>"
diff --git a/Examples/test-suite/errors/pp_unknowndirective4.stderr b/Examples/test-suite/errors/pp_unknowndirective4.stderr
new file mode 100644
index 000000000..efb6afe6e
--- /dev/null
+++ b/Examples/test-suite/errors/pp_unknowndirective4.stderr
@@ -0,0 +1 @@
+pp_unknowndirective4.i:7: Error: Unknown directive '%std'.
diff --git a/Examples/test-suite/errors/pp_unknowndirective5.i b/Examples/test-suite/errors/pp_unknowndirective5.i
new file mode 100644
index 000000000..f5fb0f5e7
--- /dev/null
+++ b/Examples/test-suite/errors/pp_unknowndirective5.i
@@ -0,0 +1,20 @@
+%module xxx
+
+/* Before SWIG 4.1.0 the `9%a` expression triggered:
+ *
+ * Error: Unknown directive '%a'
+ *
+ * The fix for that works by handling an apparent directive that isn't a
+ * recognised directive by noting down its name, emitting MODULO and then
+ * rescanning what follows, and if the parser then gives a syntax error we
+ * report it as an unknown directive.
+ *
+ * However the initial version of this failed to reset the noted down apparent
+ * directive often enough, so a later syntax error could get incorrectly
+ * reported. Here the syntax error in the declaration of `c` was confusingly
+ * reported as `Error: Unknown directive '%a'`. This was found and fixed prior
+ * to 4.1.0.
+ */
+int a;
+int test2(int b = 9%a) { return b; }
+void int c;
diff --git a/Examples/test-suite/errors/pp_unknowndirective5.stderr b/Examples/test-suite/errors/pp_unknowndirective5.stderr
new file mode 100644
index 000000000..b61c3addb
--- /dev/null
+++ b/Examples/test-suite/errors/pp_unknowndirective5.stderr
@@ -0,0 +1 @@
+pp_unknowndirective5.i:20: Error: Syntax error in input(1).
diff --git a/Examples/test-suite/errors/swig_command_encoder.i b/Examples/test-suite/errors/swig_command_encoder.i
new file mode 100644
index 000000000..aaae82bb5
--- /dev/null
+++ b/Examples/test-suite/errors/swig_command_encoder.i
@@ -0,0 +1,6 @@
+%module xxx
+
+// This feature was removed in SWIG 4.1.0 so check it gives an error.
+%define SedCmd "%(command:sed -e 's/\([a-z]\)/\U\\1/' -e 's/\(_\)\([a-z]\)/\U\\2/g' <<<)s" %enddef
+%rename(SedCmd) "";
+int x;
diff --git a/Examples/test-suite/errors/swig_command_encoder.stderr b/Examples/test-suite/errors/swig_command_encoder.stderr
new file mode 100644
index 000000000..0fcf2dfb8
--- /dev/null
+++ b/Examples/test-suite/errors/swig_command_encoder.stderr
@@ -0,0 +1 @@
+SWIG:1: Error: Command encoder no longer supported - use regex encoder instead.
diff --git a/Examples/test-suite/errors/swig_constant_missing_semi.i b/Examples/test-suite/errors/swig_constant_missing_semi.i
new file mode 100644
index 000000000..3fa1f3bd2
--- /dev/null
+++ b/Examples/test-suite/errors/swig_constant_missing_semi.i
@@ -0,0 +1,3 @@
+%module xxx
+%constant int BAR=0
+int foo(int);
diff --git a/Examples/test-suite/errors/swig_constant_missing_semi.stderr b/Examples/test-suite/errors/swig_constant_missing_semi.stderr
new file mode 100644
index 000000000..f86d37356
--- /dev/null
+++ b/Examples/test-suite/errors/swig_constant_missing_semi.stderr
@@ -0,0 +1 @@
+swig_constant_missing_semi.i:3: Warning 305: Bad constant value (ignored).
diff --git a/Examples/test-suite/errors/swig_typemap_missing_value.i b/Examples/test-suite/errors/swig_typemap_missing_value.i
new file mode 100644
index 000000000..b9937af1a
--- /dev/null
+++ b/Examples/test-suite/errors/swig_typemap_missing_value.i
@@ -0,0 +1,7 @@
+%module xxx
+
+%typemap(in, numinputs=1, foo) int ""
+%typemap(argout=123) char* ""
+
+/* SWIG segfaulted trying to use the above in typemap in SWIG < 4.1.0. */
+void func(int arg);
diff --git a/Examples/test-suite/errors/swig_typemap_missing_value.stderr b/Examples/test-suite/errors/swig_typemap_missing_value.stderr
new file mode 100644
index 000000000..26bc8cdb9
--- /dev/null
+++ b/Examples/test-suite/errors/swig_typemap_missing_value.stderr
@@ -0,0 +1,2 @@
+swig_typemap_missing_value.i:3: Error: %typemap attribute 'foo' is missing its value. If this is specifying the target language, that's no longer supported: use #ifdef SWIG<LANG> instead.
+swig_typemap_missing_value.i:4: Error: %typemap method shouldn't have a value specified.
diff --git a/Examples/test-suite/exception_memory_leak.i b/Examples/test-suite/exception_memory_leak.i
new file mode 100644
index 000000000..27d199c9f
--- /dev/null
+++ b/Examples/test-suite/exception_memory_leak.i
@@ -0,0 +1,62 @@
+%module exception_memory_leak
+
+%include <std_string.i>
+%include <exception.i>
+
+%typemap(in) Foo* foo
+{
+ $1 = new Foo;
+}
+%typemap(freearg) Foo* foo
+{
+ Foo::inc_freearg_count();
+ delete $1;
+}
+%typemap(out) Foo* trigger_internal_swig_exception
+{
+ if ($1 == NULL) {
+ SWIG_exception(SWIG_RuntimeError, "Let's see how the bindings manage this exception!");
+#ifdef SWIG_fail
+ SWIG_fail;
+#endif
+ }
+ $1 = NULL;
+}
+%typemap(out) Foo trigger_internal_swig_exception
+{
+ SWIG_exception(SWIG_RuntimeError, "Let's see how the bindings manage this exception!");
+#ifdef SWIG_fail
+ SWIG_fail;
+#endif
+}
+
+%inline %{
+ #include <string>
+
+ class Foo {
+ static unsigned count;
+ static unsigned freearg_count;
+ public:
+ Foo() { ++count; }
+ ~Foo() { --count; }
+ static unsigned get_count() { return count; }
+ static unsigned get_freearg_count() { return freearg_count; }
+#ifndef SWIG
+ static void inc_freearg_count() { ++freearg_count; }
+#endif
+ };
+
+ unsigned Foo::count = 0;
+ unsigned Foo::freearg_count = 0;
+
+ static Foo* trigger_internal_swig_exception(const std::string& message, Foo* foo)
+ {
+ return (message == "null") ? NULL : foo;
+ }
+
+ static Foo trigger_internal_swig_exception(const std::string& message)
+ {
+ return Foo();
+ }
+
+%}
diff --git a/Examples/test-suite/extern_c.i b/Examples/test-suite/extern_c.i
index e56d9f128..78c9d1061 100644
--- a/Examples/test-suite/extern_c.i
+++ b/Examples/test-suite/extern_c.i
@@ -5,6 +5,7 @@ extern "C" {
void RealFunction(int value);
typedef void Function1(int value); // Fails
typedef int Integer1;
+int Integer3;
}
typedef void Function2(int value); // Works
typedef int Integer2;
@@ -27,5 +28,14 @@ Hook2_t hook2;
extern "C" typedef int Integer;
Integer int1;
+extern "C" int int2;
+extern "C" { extern int int3; }
+extern "C" { int int4 = 789; }
%}
+%{
+extern "C" {
+ int int2 = 123;
+ int int3 = 456;
+}
+%}
diff --git a/Examples/test-suite/final_c.i b/Examples/test-suite/final_c.i
new file mode 100644
index 000000000..42cac11f1
--- /dev/null
+++ b/Examples/test-suite/final_c.i
@@ -0,0 +1,13 @@
+%module final_c
+
+%warnfilter(SWIGWARN_PARSE_KEYWORD) final; // 'final' is a java keyword, renaming to '_final'
+
+%inline %{
+struct Y {
+ int yval;
+};
+struct Y final;
+void init() {
+ final.yval = 123;
+}
+%}
diff --git a/Examples/test-suite/fragments.i b/Examples/test-suite/fragments.i
index 4bf399a21..e7bcae2a0 100644
--- a/Examples/test-suite/fragments.i
+++ b/Examples/test-suite/fragments.i
@@ -21,7 +21,7 @@ int bar(int a)
}
%}
-%typemap(in,fragment="Hi") int hola "$1 = 123;";
+%typemap(in,fragment="Hi") int hola "$1 = 123;"
%inline %{
@@ -34,3 +34,107 @@ int foo(int hola)
}
%}
+
+/* Instantiate multiple fragments at once using fragments in comma separated list */
+typedef int comma_frag3;
+
+%fragment("comma_frag1","header", noblock=1) {
+typedef int comma_frag1;
+}
+
+%fragment("comma_frag2","header", noblock=1, noblock=1) {
+typedef comma_frag1 comma_frag2;
+}
+
+%fragment("comma_frag3","header",
+ fragment="comma_frag1,comma_frag2")
+%{typedef comma_frag2 comma_frag3;%}
+
+%fragment("comma_frag3");
+%inline %{
+comma_frag3 my_comma_frag_int = 0;
+%}
+
+
+/* Instantiate multiple fragments at once using multiple keywords */
+typedef int explicit_frag3;
+
+%fragment("explicit_frag1","header", noblock=1) {
+typedef int explicit_frag1;
+}
+
+%fragment("explicit_frag2","header", noblock=1) {
+typedef explicit_frag1 explicit_frag2;
+}
+
+%fragment("explicit_frag3","header",
+ fragment="explicit_frag1", fragment="explicit_frag2")
+%{typedef explicit_frag2 explicit_frag3;%}
+
+%fragment("explicit_frag3");
+%inline %{
+explicit_frag3 my_int = 0;
+%}
+
+/* Test typemap's ability to instantiate multiple fragments on demand */
+typedef int int_infrag1;
+typedef int int_infrag2;
+typedef int int_outfrag1;
+typedef int int_outfrag2;
+typedef int int_outfrag3;
+
+%fragment("infrag2","runtime") %{
+typedef int_infrag1 int_infrag2;
+%}
+
+%fragment("infrag1","runtime") %{
+typedef int int_infrag1;
+%}
+%fragment("infrag2","runtime") %{
+__second_infrag2_fragment_is_ignored_this_will_not_compile_if_emitted_
+typedef int_infrag1 int_infrag2;
+%}
+
+%fragment("outfrag1","runtime") %{
+typedef int int_outfrag1;
+%}
+%fragment("outfrag2","runtime") %{
+typedef int_outfrag1 int_outfrag2;
+%}
+
+%fragment("tcfrag1","runtime") %{
+typedef int int_tcfrag1;
+%}
+%fragment("tcfrag2","runtime") %{
+typedef int_tcfrag1 int_tcfrag2;
+%}
+
+%fragment("outspecial"{bool},"runtime") %{
+typedef int int_outfrag3_temp;
+%}
+%fragment("outfrag3","runtime") %{
+typedef int_outfrag3_temp int_outfrag3;
+%}
+
+%typemap(in, fragment="infrag1", fragment="infrag2") int_infrag2
+%{$typemap(in,int)%}
+
+%typemap(check, fragment="tcfrag1", noblock=1, fragment="tcfrag2") int_infrag2
+{(void)sizeof(int_tcfrag2);}
+
+%typemap(out, fragment="outfrag1", fragment="outfrag2", noblock=1) int_outfrag2
+{$typemap(out,int)}
+
+/* Test another permutation of keyword order */
+%typemap(out, noblock=1, fragment="outfrag1", fragment="outfrag2") int_outfrag1
+{$typemap(out,int)}
+
+/* Test fragment specialization */
+%typemap(out, noblock=1, fragment="outspecial"{bool}, fragment="outfrag3") int_outfrag3
+{$typemap(out,int)}
+
+%inline %{
+int identity_in(int_infrag2 inp) { return inp; }
+int_outfrag2 identity_out(int inp) { return inp; }
+int_outfrag3 identity_out_2(int inp) { return inp; }
+%}
diff --git a/Examples/test-suite/global_immutable_vars.i b/Examples/test-suite/global_immutable_vars.i
index ab0d4f7a8..9545b297a 100644
--- a/Examples/test-suite/global_immutable_vars.i
+++ b/Examples/test-suite/global_immutable_vars.i
@@ -1,7 +1,7 @@
%module global_immutable_vars
// Test immutable and mutable global variables,
-// see http://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables
+// see https://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables
%inline %{
int default_mutable_var = 40;
diff --git a/Examples/test-suite/global_immutable_vars_cpp.i b/Examples/test-suite/global_immutable_vars_cpp.i
index 40cc08e54..b5d5e0fd3 100644
--- a/Examples/test-suite/global_immutable_vars_cpp.i
+++ b/Examples/test-suite/global_immutable_vars_cpp.i
@@ -1,7 +1,7 @@
%module global_immutable_vars_cpp
// Test immutable and mutable global variables,
-// see http://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables
+// see https://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables
%inline %{
int default_mutable_var = 40;
diff --git a/Examples/test-suite/go/Makefile.in b/Examples/test-suite/go/Makefile.in
index 75debc538..d4c27c7b5 100644
--- a/Examples/test-suite/go/Makefile.in
+++ b/Examples/test-suite/go/Makefile.in
@@ -12,6 +12,10 @@ SCRIPTSUFFIX = _runme.go
SO = @SO@
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
@@ -43,17 +47,9 @@ INCLUDES = -I$(abs_top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)
%.multicpptest:
$(setup)
- mkdir -p gopath/$*/src 2>/dev/null || true
- if ! test -d gopath/$*/src/swigtests; then \
- (cd gopath/$*/src && ln -s . swigtests); \
- fi
+ $(go_multicpp_setup)
+for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
- SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
- LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
- TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
- GOMOD="$*" \
- $(LANGUAGE)$(VARIANT)_cpp; \
+ $(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)') GOMOD="$*"; \
done
$(run_multi_testcase)
@@ -61,28 +57,9 @@ li_windows.cpptest:
# Does not work because go build won't build li_windows.go,
# because file names with "windows" are only built on Windows.
-multi_import.multicpptest:
- $(setup)
- mkdir -p gopath/multi_import/src 2>/dev/null || true
- if ! test -d gopath/multi_import/src/swigtests; then \
- (cd gopath/multi_import/src && ln -s . swigtests); \
- fi
- for f in multi_import_b multi_import_a; do \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
- SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
- LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
- TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
- GOMOD="multi_import" \
- $(LANGUAGE)$(VARIANT)_cpp; \
- done
- $(run_multi_testcase)
-
go_subdir_import.multicpptest:
$(setup)
- mkdir -p gopath/go_subdir_import/src 2>/dev/null || true
- if ! test -d gopath/go_subdir_import/src/swigtests; then \
- (cd gopath/go_subdir_import/src && ln -s . swigtests); \
- fi
+ $(go_multicpp_setup)
mkdir -p testdir/go_subdir_import 2>/dev/null || true
mkdir -p gopath/go_subdir_import/src/testdir/go_subdir_import 2>/dev/null || true
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
@@ -93,16 +70,17 @@ go_subdir_import.multicpptest:
INTERFACE='testdir/go_subdir_import/go_subdir_import_b.i' \
GOMOD="go_subdir_import" \
$(LANGUAGE)$(VARIANT)_cpp;
- for f in testdir/go_subdir_import/go_subdir_import_c go_subdir_import_a ; do \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
- SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
- LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
- TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
- GOMOD="go_subdir_import" \
- $(LANGUAGE)$(VARIANT)_cpp; \
+ +for f in testdir/go_subdir_import/go_subdir_import_c go_subdir_import_a ; do \
+ $(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)') GOMOD="go_subdir_import"; \
done
$(run_multi_testcase)
+go_multicpp_setup = \
+ mkdir -p gopath/$*/src 2>/dev/null || true; \
+ if ! test -d gopath/$*/src/swigtests; then \
+ (cd gopath/$*/src && ln -s . swigtests); \
+ fi
+
# Runs the testcase.
run_testcase = \
if test -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); then \
@@ -181,6 +159,7 @@ clean:
rm -f mod_a.go mod_a.gox mod_b.go mod_b.gox
rm -f multi_import_a.go multi_import_a.gox
rm -f multi_import_b.go multi_import_b.gox
+ rm -f multi_import_d.go multi_import_d.gox
rm -f packageoption_a.go packageoption_a.gox
rm -f packageoption_b.go packageoption_b.gox
rm -f packageoption_c.go packageoption_c.gox
diff --git a/Examples/test-suite/go/catches_strings_runme.go b/Examples/test-suite/go/catches_strings_runme.go
new file mode 100644
index 000000000..b31565c24
--- /dev/null
+++ b/Examples/test-suite/go/catches_strings_runme.go
@@ -0,0 +1,32 @@
+package main
+
+import "strings"
+import . "swigtests/catches_strings"
+
+func main() {
+ {
+ exception_thrown := false
+ func() {
+ defer func() {
+ exception_thrown = strings.Index(recover().(string), "charstring message") == 0
+ }()
+ StringsThrowerCharstring()
+ }()
+ if !exception_thrown {
+ panic(0)
+ }
+ }
+
+ {
+ exception_thrown := false
+ func() {
+ defer func() {
+ exception_thrown = strings.Index(recover().(string), "stdstring message") == 0
+ }()
+ StringsThrowerStdstring()
+ }()
+ if !exception_thrown {
+ panic(0)
+ }
+ }
+}
diff --git a/Examples/test-suite/go/class_case_runme.go b/Examples/test-suite/go/class_case_runme.go
new file mode 100644
index 000000000..7d0870b47
--- /dev/null
+++ b/Examples/test-suite/go/class_case_runme.go
@@ -0,0 +1,12 @@
+package main
+
+import . "swigtests/class_case"
+
+func main() {
+ b2 := NewClassB2()
+ // This used to fail with:
+ // panic: interface conversion: interface {} is class_case.SwigcptrClassB2, not int
+ if Test2(b2) != 1 {
+ panic("Unexpected overload used")
+ }
+}
diff --git a/Examples/test-suite/go/cpp11_std_array_runme.go b/Examples/test-suite/go/cpp11_std_array_runme.go
new file mode 100644
index 000000000..97b5df2ec
--- /dev/null
+++ b/Examples/test-suite/go/cpp11_std_array_runme.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+ "fmt"
+ "swigtests/cpp11_std_array"
+)
+
+func CompareContainers(actual cpp11_std_array.ArrayInt6, expected [6]int) error {
+ if int(actual.Size()) != len(expected) {
+ return fmt.Errorf("Sizes are different: %d %d", actual.Size(), len(expected))
+ }
+ for i := 0; i < int(actual.Size()); i++ {
+ actualValue := actual.Get(i)
+ expectedValue := expected[i]
+ if actualValue != expectedValue {
+ return fmt.Errorf("Value is wrong for element %d. Expected %d got: %d", i, expectedValue, actualValue)
+ }
+ }
+ if actual.IsEmpty() {
+ return fmt.Errorf("ai should not be empty")
+ }
+ return nil
+}
+
+func main() {
+ ai := cpp11_std_array.NewArrayInt6()
+ ps := [6]int{0, 0, 0, 0, 0, 0}
+ CompareContainers(ai, ps)
+
+ vals := [6]int{10, 20, 30, 40, 50, 60}
+ for i := 0; i < len(vals); i++ {
+ ai.Set(i, vals[i])
+ }
+ CompareContainers(ai, vals);
+
+ // Check return
+ vals = [6]int{-2, -1, 0, 0, 1, 2}
+ CompareContainers(cpp11_std_array.ArrayOutVal(), vals);
+ CompareContainers(cpp11_std_array.ArrayOutConstRef(), vals);
+ CompareContainers(cpp11_std_array.ArrayOutRef(), vals);
+ CompareContainers(cpp11_std_array.ArrayOutPtr(), vals);
+
+ // Check passing arguments
+ vals = [6]int{9, 8, 7, 6, 5, 4}
+ valsArrayInt6 := cpp11_std_array.NewArrayInt6()
+ for i := 0; i < len(vals); i++ {
+ valsArrayInt6.Set(i, vals[i])
+ }
+
+ ai = cpp11_std_array.ArrayInVal(valsArrayInt6);
+ CompareContainers(ai, vals);
+
+ ai = cpp11_std_array.ArrayInConstRef(valsArrayInt6);
+ CompareContainers(ai, vals);
+
+ ai = cpp11_std_array.NewArrayInt6(valsArrayInt6);
+ cpp11_std_array.ArrayInRef(ai);
+ CompareContainers(ai, vals);
+
+ ai = cpp11_std_array.NewArrayInt6(valsArrayInt6);
+ cpp11_std_array.ArrayInPtr(ai);
+ CompareContainers(ai, vals);
+
+ // Fill
+ ai.Fill(111)
+ vals = [6]int{111, 111, 111, 111, 111, 111}
+ CompareContainers(ai, vals);
+}
diff --git a/Examples/test-suite/go/friends_runme.go b/Examples/test-suite/go/friends_runme.go
index b6b9e93f3..f7836ad2f 100644
--- a/Examples/test-suite/go/friends_runme.go
+++ b/Examples/test-suite/go/friends_runme.go
@@ -27,21 +27,21 @@ func main() {
panic(0)
}
- di := friends.NewD_d(2)
+ di := friends.NewD_i(2)
dd := friends.NewD_d(3.3)
// incredible template overloading working just fine
- if friends.Get_val1(di).(float64) != 2 {
+ if friends.Get_val1(di).(int) != 2 {
panic(0)
}
if friends.Get_val1(dd).(float64) != 3.3 {
panic(0)
}
- friends.Set(di, 4.0)
+ friends.Set(di, 4)
friends.Set(dd, 1.3)
- if friends.Get_val1(di).(float64) != 4 {
+ if friends.Get_val1(di).(int) != 4 {
panic(0)
}
if friends.Get_val1(dd).(float64) != 1.3 {
diff --git a/Examples/test-suite/go/go_director_inout_runme.go b/Examples/test-suite/go/go_director_inout_runme.go
index 171b3c223..6b68543a2 100644
--- a/Examples/test-suite/go/go_director_inout_runme.go
+++ b/Examples/test-suite/go/go_director_inout_runme.go
@@ -14,6 +14,35 @@ func (p *GoMyClass) Adjust(m map[string]interface{}) wrap.GoRetStruct {
return wrap.GoRetStruct{s}
}
+func (p *GoMyClass) S1(s string) {
+ if s != "S1" {
+ panic(s)
+ }
+}
+
+func (p *GoMyClass) S2(s *string) {
+ if *s != "S2" {
+ panic(s)
+ }
+ *s = "R2"
+}
+
+func (p *GoMyClass) S3(s *string) {
+ if *s != "S3" {
+ panic(s)
+ }
+ *s = "R3"
+}
+
+func (p *GoMyClass) S4(s []string) {
+ if s[0] != "T1" {
+ panic(s)
+ }
+ if s[1] != "T2" {
+ panic(s)
+ }
+}
+
func main() {
a := wrap.NewDirectorMyClass(&GoMyClass{})
m := map[string]interface{}{
@@ -24,6 +53,23 @@ func main() {
panic(s)
}
+ a.S1("S1")
+ str := "S2"
+ a.S2(&str)
+ if str != "R2" {
+ panic(str)
+ }
+ str = "S3"
+ a.S3(&str)
+ if str != "R3" {
+ panic(str)
+ }
+
+ a.CallS4([]string{ "T1", "T2" })
+
+ a.S5(&str)
+ a.S5(nil)
+
a = wrap.NewDirectorMyClass(nil)
s = a.Adjust(m)
if s.Str != `{"first":"second"}` {
diff --git a/Examples/test-suite/go/go_inout_runme.go b/Examples/test-suite/go/go_inout_runme.go
index 2dc5b9908..981b7f2b3 100644
--- a/Examples/test-suite/go/go_inout_runme.go
+++ b/Examples/test-suite/go/go_inout_runme.go
@@ -50,4 +50,12 @@ func main() {
fmt.Println("for c2.M got", pm, "want", want)
panic(pm)
}
+
+ c1 := go_inout.NewC1()
+ c2.M2(c1)
+ c2.M2(nil)
+
+ if !go_inout.Strings([]string{"1", "2"}) {
+ panic("Strings failed")
+ }
}
diff --git a/Examples/test-suite/go/smart_pointer_extend_runme.go b/Examples/test-suite/go/smart_pointer_extend_runme.go
index f91c9ac99..e349be18a 100644
--- a/Examples/test-suite/go/smart_pointer_extend_runme.go
+++ b/Examples/test-suite/go/smart_pointer_extend_runme.go
@@ -22,6 +22,10 @@ func main() {
panic(0)
}
+ if d.Bar() != p.Bar() {
+ panic(0)
+ }
+
if CBaseHello() != p.Hello() {
panic(0)
}
diff --git a/Examples/test-suite/go/typemap_out_optimal_runme.go b/Examples/test-suite/go/typemap_out_optimal_runme.go
index 0cccd97a6..646aa8ece 100644
--- a/Examples/test-suite/go/typemap_out_optimal_runme.go
+++ b/Examples/test-suite/go/typemap_out_optimal_runme.go
@@ -3,6 +3,7 @@ package main
import . "swigtests/typemap_out_optimal"
func main() {
- SetXXDebug(false)
+ SetXXTrace(false)
_ = XXCreate()
+ _ = XXCreateConst()
}
diff --git a/Examples/test-suite/go_director_inout.i b/Examples/test-suite/go_director_inout.i
index 5a7fbdf89..0be3ca1f7 100644
--- a/Examples/test-suite/go_director_inout.i
+++ b/Examples/test-suite/go_director_inout.i
@@ -2,6 +2,8 @@
%module(directors="1") go_director_inout
+%include <std_string.i>
+
%{
#include <string>
%}
@@ -108,6 +110,102 @@ type GoRetStruct struct {
$1.str.assign($input.p, $input.n);
%}
+%typemap(directorin) std::string & (_gostring_ temp) {
+ $input = &temp;
+ temp.p = (char *) $1.data();
+ temp.n = $1.size();
+}
+%typemap(directorargout) std::string & {
+ _gostring_ *tmp = $input;
+ $1.assign(tmp->p, tmp->p + tmp->n);
+}
+
+%inline %{
+// Helper functions for converting string arrays
+#include <stdlib.h>
+void *alloc_ptr_array(unsigned int len)
+{
+ return calloc(len, sizeof(void *));
+}
+void set_ptr_array(void *ain, unsigned int pos, void *val)
+{
+ void **a = (void **) ain;
+ a[pos] = val;
+}
+void *get_ptr_array(void *ain, unsigned int pos)
+{
+ void **a = (void **) ain;
+ return a[pos];
+}
+void free_ptr_array(void *ain)
+{
+ void **a = (void **) ain;
+ unsigned int i;
+
+ if (!a)
+ return;
+ for (i = 0; a[i]; i++) {
+ free(a[i]);
+ }
+ free(a);
+}
+char *uintptr_to_string(void *in)
+{
+ return (char *) in;
+}
+void *string_to_uintptr(char *in)
+{
+ return strdup(in);
+}
+%}
+
+// These typemaps convert between an array of strings in Go and a
+// const char** that is NULL terminated in C++.
+%typemap(gotype) (const char * const *) "[]string"
+%typemap(imtype) (const char * const *) "uintptr"
+%typemap(goin) (const char * const *) {
+ if $input == nil || len($input) == 0 {
+ $result = 0
+ } else {
+ $result = Alloc_ptr_array(uint(len($input) + 1))
+ defer func() {
+ Free_ptr_array($result)
+ }()
+ var i uint
+ for i = 0; i < uint(len($input)); i++ {
+ Set_ptr_array($result, i, String_to_uintptr($input[i]))
+ }
+ }
+}
+%typemap(in) (const char * const *) {
+ $1 = (char **) $input;
+}
+%typemap(godirectorin) (const char * const *) {
+ if ($input == 0) {
+ $result = nil
+ } else {
+ var i uint
+ for i = 0; ; i++ {
+ var v uintptr = Get_ptr_array($input, i)
+ if v == 0 {
+ break
+ }
+ }
+ if i == 0 {
+ $result = nil
+ } else {
+ $result = make([]string, i)
+ for i = 0; ; i++ {
+ var v uintptr = Get_ptr_array($input, i)
+ if v == 0 {
+ break
+ }
+ $result[i] = Uintptr_to_string(v)
+ }
+ }
+ }
+}
+
%feature("director") MyClass;
%inline
@@ -121,6 +219,33 @@ class MyClass {
r.str = s.str;
return r;
}
+
+ void CallS4(const char * const *strarray);
+ virtual void S1(std::string s);
+ virtual void S2(std::string& s) = 0;
+ virtual void S3(std::string* s) = 0;
+ virtual void S4(const char * const *strarray);
+ virtual int S5(const std::string* s);
};
+void MyClass::S1(std::string s) {
+ throw "Base S1 called!";
+}
+
+void MyClass::S4(const char * const *strarray) {
+ throw "Base S4 called!";
+}
+
+void MyClass::CallS4(const char * const *strarray) {
+ this->S4(strarray);
+}
+
+int MyClass::S5(const std::string* s) {
+ if (s) {
+ return (*s)[0];
+ } else {
+ return 0;
+ }
+}
+
%}
diff --git a/Examples/test-suite/go_inout.i b/Examples/test-suite/go_inout.i
index 0bcb979ef..ae68178a0 100644
--- a/Examples/test-suite/go_inout.i
+++ b/Examples/test-suite/go_inout.i
@@ -239,5 +239,47 @@ class C1 {
};
class C2 : public C1 {
+ public:
+ void M2(C1*) {}
};
%}
+
+%typemap(gotype) (char *ps[], int cs) "[]string"
+
+%typemap(in) (char *ps[], int cs)
+%{
+ {
+ int i;
+ _gostring_* a;
+
+ $2 = $input.len;
+ a = (_gostring_*) $input.array;
+ $1 = (char **) malloc (($2 + 1) * sizeof (char *));
+ for (i = 0; i < $2; i++) {
+ _gostring_ *ps = &a[i];
+ $1[i] = (char *) malloc(ps->n + 1);
+ memcpy($1[i], ps->p, ps->n);
+ $1[i][ps->n] = '\0';
+ }
+ $1[i] = NULL;
+ }
+%}
+
+%typemap(freearg) (char *ps[], int cs)
+%{
+ {
+ int i;
+
+ for (i = 0; i < $2; i++) {
+ free($1[i]);
+ }
+ free($1);
+ }
+%}
+
+%inline
+%{
+bool Strings(char *ps[], int cs) {
+ return cs == 2 && strcmp(ps[0], "1") == 0 && strcmp(ps[1], "2") == 0 & ps[2] == NULL;
+}
+%}
diff --git a/Examples/test-suite/go_subdir_import_a.i b/Examples/test-suite/go_subdir_import_a.i
index 3fc36e6f9..5a35c8f51 100644
--- a/Examples/test-suite/go_subdir_import_a.i
+++ b/Examples/test-suite/go_subdir_import_a.i
@@ -6,7 +6,7 @@
* This case might happen for two different reasons:
* 1) Importing a module for which the .i file is in a subdirectory relatively
* to this file (this is tested here with go_subdir_import_c).
- * 2) Importing a module whos module name is a path (this is tested here with
+ * 2) Importing a module whose module name is a path (this is tested here with
* go_subdir_import_b).
*
* This file is the "root" file that imports the two modules which will be
diff --git a/Examples/test-suite/guile/Makefile.in b/Examples/test-suite/guile/Makefile.in
index 55885fc29..2efa6adbe 100644
--- a/Examples/test-suite/guile/Makefile.in
+++ b/Examples/test-suite/guile/Makefile.in
@@ -8,6 +8,10 @@ LANGUAGE = guile
VARIANT =
SCRIPTSUFFIX = _runme.scm
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/guile/catches_strings_runme.scm b/Examples/test-suite/guile/catches_strings_runme.scm
new file mode 100644
index 000000000..376f235a3
--- /dev/null
+++ b/Examples/test-suite/guile/catches_strings_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_catches_strings_module" (dynamic-link "./libcatches_strings"))
+(load "testsuite.scm")
+(load "../schemerunme/catches_strings.scm")
diff --git a/Examples/test-suite/guile/cpp11_move_typemaps_runme.scm b/Examples/test-suite/guile/cpp11_move_typemaps_runme.scm
new file mode 100644
index 000000000..43f78e6e4
--- /dev/null
+++ b/Examples/test-suite/guile/cpp11_move_typemaps_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_cpp11_move_typemaps_module" (dynamic-link "./libcpp11_move_typemaps"))
+(load "testsuite.scm")
+(load "../schemerunme/cpp11_move_typemaps.scm")
diff --git a/Examples/test-suite/guile/cpp11_rvalue_reference_move_runme.scm b/Examples/test-suite/guile/cpp11_rvalue_reference_move_runme.scm
new file mode 100644
index 000000000..30ddff722
--- /dev/null
+++ b/Examples/test-suite/guile/cpp11_rvalue_reference_move_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_cpp11_rvalue_reference_move_module" (dynamic-link "./libcpp11_rvalue_reference_move"))
+(load "testsuite.scm")
+(load "../schemerunme/cpp11_rvalue_reference_move.scm")
diff --git a/Examples/test-suite/guile/cpp11_std_unique_ptr_runme.scm b/Examples/test-suite/guile/cpp11_std_unique_ptr_runme.scm
new file mode 100644
index 000000000..9ba124a5e
--- /dev/null
+++ b/Examples/test-suite/guile/cpp11_std_unique_ptr_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_cpp11_std_unique_ptr_module" (dynamic-link "./libcpp11_std_unique_ptr"))
+(load "testsuite.scm")
+(load "../schemerunme/cpp11_std_unique_ptr.scm")
diff --git a/Examples/test-suite/guile/guile_ext_test_external.cxx b/Examples/test-suite/guile/guile_ext_test_external.cxx
index c4f906a97..2729537bd 100644
--- a/Examples/test-suite/guile/guile_ext_test_external.cxx
+++ b/Examples/test-suite/guile/guile_ext_test_external.cxx
@@ -19,6 +19,6 @@ SCM test_create()
SCM test_is_pointer(SCM val)
{
#define FUNC_NAME "test-is-pointer"
- return SCM_BOOL(SWIG_IsPointer(val));
+ return scm_from_bool(SWIG_IsPointer(val));
#undef FUNC_NAME
}
diff --git a/Examples/test-suite/guile/li_std_auto_ptr_runme.scm b/Examples/test-suite/guile/li_std_auto_ptr_runme.scm
new file mode 100644
index 000000000..04d3d6597
--- /dev/null
+++ b/Examples/test-suite/guile/li_std_auto_ptr_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_li_std_auto_ptr_module" (dynamic-link "./libli_std_auto_ptr"))
+(load "testsuite.scm")
+(load "../schemerunme/li_std_auto_ptr.scm")
diff --git a/Examples/test-suite/guile/newobject1_runme.scm b/Examples/test-suite/guile/newobject1_runme.scm
new file mode 100644
index 000000000..21f6d8618
--- /dev/null
+++ b/Examples/test-suite/guile/newobject1_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_newobject1_module" (dynamic-link "./libnewobject1"))
+(load "../schemerunme/newobject1.scm")
+
diff --git a/Examples/test-suite/guile/null_pointer_runme.scm b/Examples/test-suite/guile/null_pointer_runme.scm
new file mode 100644
index 000000000..cad65e898
--- /dev/null
+++ b/Examples/test-suite/guile/null_pointer_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_null_pointer_module" (dynamic-link "./libnull_pointer"))
+(load "testsuite.scm")
+(load "../schemerunme/null_pointer.scm")
diff --git a/Examples/test-suite/ignore_parameter.i b/Examples/test-suite/ignore_parameter.i
index 604ee3b84..d47cb5d78 100644
--- a/Examples/test-suite/ignore_parameter.i
+++ b/Examples/test-suite/ignore_parameter.i
@@ -2,15 +2,24 @@
%module ignore_parameter
-%typemap(in,numinputs=0) char* a "static const char* hi = \"hello\"; $1 = const_cast<char *>(hi);";
-%typemap(in,numinputs=0) int bb "$1 = 101;";
-%typemap(in,numinputs=0) double ccc "$1 = 8.8;";
+%typemap(in,numinputs=0) char* a "static const char* hi = \"hello\"; $1 = const_cast<char *>(hi);"
+%typemap(in,numinputs=0) int bb "$1 = 101; called_argout = 0;"
+%typemap(in,numinputs=0) double ccc "$1 = 8.8;"
-%typemap(freearg) char* a ""; // ensure freearg is not generated (needed for Java at least)
+%typemap(freearg) char* a "" // ensure freearg is not generated (needed for Java at least)
+
+%typemap(argout) int bb "called_argout = 1;"
%ignore unignorable;
+// Don't let SWIG expand this function with its default parameter: instead,
+// always "require" the version of the function with a single argument, but
+// then ignore it using `numinputs=0`.
+%ignore audi();
%inline %{
+// constant for detecting correct "argout" call
+int called_argout = 0;
+
// global function tests
char* jaguar(char* a, int b, double c) { return a; }
int lotus(char* aa, int bb, double cc) { return bb; }
@@ -25,6 +34,7 @@ struct SportsCars {
double bugatti(char* aaa, int bbb, double ccc) { return ccc; }
int lamborghini(int bb) { return bb; }
int maseratti(int unignorable) { return unignorable; }
+ double audi(double ccc=9.5) { return ccc; }
};
// constructor tests
diff --git a/Examples/test-suite/import_nomodule.i b/Examples/test-suite/import_nomodule.i
index 48e119517..2794ad5f3 100644
--- a/Examples/test-suite/import_nomodule.i
+++ b/Examples/test-suite/import_nomodule.i
@@ -6,7 +6,9 @@
// For Python
%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Bar; // Base class 'Foo' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %import directive.
-%import "import_nomodule.h"
+// The "dummy=" attribute is a regression test for #1006, fixed in SWIG 4.1.0.
+// SWIG didn't used to take quoting into account when finding the closing `)`.
+%import(dummy=")foo\"") "import_nomodule.h"
#if !defined(SWIGJAVA) && !defined(SWIGRUBY) && !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGPYTHON_BUILTIN) && !defined(SWIGPHP)
diff --git a/Examples/test-suite/integers.i b/Examples/test-suite/integers.i
index 6a9ede4bc..9569df767 100644
--- a/Examples/test-suite/integers.i
+++ b/Examples/test-suite/integers.i
@@ -17,6 +17,41 @@
signed long long signed_long_long_identity(signed long long x) { return x; }
unsigned long long unsigned_long_long_identity(unsigned long long x) { return x; }
+#ifdef __cplusplus
+ signed char & signed_char_ref_identity( signed char & x) { return x; }
+ unsigned char & unsigned_char_ref_identity( unsigned char & x) { return x; }
+ signed short & signed_short_ref_identity( signed short & x) { return x; }
+ unsigned short & unsigned_short_ref_identity( unsigned short & x) { return x; }
+ signed int & signed_int_ref_identity( signed int & x) { return x; }
+ unsigned int & unsigned_int_ref_identity( unsigned int & x) { return x; }
+ signed long & signed_long_ref_identity( signed long & x) { return x; }
+ unsigned long & unsigned_long_ref_identity( unsigned long & x) { return x; }
+ signed long long & signed_long_long_ref_identity( signed long long & x) { return x; }
+ unsigned long long & unsigned_long_long_ref_identity(unsigned long long & x) { return x; }
+
+ const signed char & const_signed_char_ref_identity( const signed char & x) { return x; }
+ const unsigned char & const_unsigned_char_ref_identity( const unsigned char & x) { return x; }
+ const signed short & const_signed_short_ref_identity( const signed short & x) { return x; }
+ const unsigned short & const_unsigned_short_ref_identity( const unsigned short & x) { return x; }
+ const signed int & const_signed_int_ref_identity( const signed int & x) { return x; }
+ const unsigned int & const_unsigned_int_ref_identity( const unsigned int & x) { return x; }
+ const signed long & const_signed_long_ref_identity( const signed long & x) { return x; }
+ const unsigned long & const_unsigned_long_ref_identity( const unsigned long & x) { return x; }
+ const signed long long & const_signed_long_long_ref_identity( const signed long long & x) { return x; }
+ const unsigned long long & const_unsigned_long_long_ref_identity(const unsigned long long & x) { return x; }
+#endif
+
+ signed char * signed_char_ptr() { return NULL; }
+ unsigned char * unsigned_char_ptr() { return NULL; }
+ signed short * signed_short_ptr() { return NULL; }
+ unsigned short * unsigned_short_ptr() { return NULL; }
+ signed int * signed_int_ptr() { return NULL; }
+ unsigned int * unsigned_int_ptr() { return NULL; }
+ signed long * signed_long_ptr() { return NULL; }
+ unsigned long * unsigned_long_ptr() { return NULL; }
+ signed long long * signed_long_long_ptr() { return NULL; }
+ unsigned long long * unsigned_long_long_ptr() { return NULL; }
+
size_t signed_char_size() { return sizeof (signed char); }
size_t unsigned_char_size() { return sizeof (unsigned char); }
size_t signed_short_size() { return sizeof (signed short); }
diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in
index e2a3d2472..00ebb100b 100644
--- a/Examples/test-suite/java/Makefile.in
+++ b/Examples/test-suite/java/Makefile.in
@@ -11,6 +11,10 @@ JAVA_TOOLS_JAR = @JAVA_TOOLS_JAR@
SCRIPTSUFFIX = _runme.java
SKIP_DOXYGEN_TEST_CASES = @JAVA_SKIP_DOXYGEN_TEST_CASES@
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@
@@ -132,6 +136,7 @@ run_testcase = \
@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/java/catches_strings_runme.java b/Examples/test-suite/java/catches_strings_runme.java
new file mode 100644
index 000000000..75e0cf043
--- /dev/null
+++ b/Examples/test-suite/java/catches_strings_runme.java
@@ -0,0 +1,41 @@
+import catches_strings.*;
+
+public class catches_strings_runme {
+ static {
+ try {
+ System.loadLibrary("catches_strings");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) throws Throwable
+ {
+ {
+ boolean exception_thrown = false;
+ try {
+ StringsThrower.charstring();
+ } catch (RuntimeException e) {
+ if (!e.getMessage().contains("charstring message"))
+ throw new RuntimeException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new RuntimeException("Should have thrown an exception");
+ }
+
+ {
+ boolean exception_thrown = false;
+ try {
+ StringsThrower.stdstring();
+ } catch (RuntimeException e) {
+ if (!e.getMessage().contains("stdstring message"))
+ throw new RuntimeException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new RuntimeException("Should have thrown an exception");
+ }
+ }
+}
diff --git a/Examples/test-suite/java/cpp11_move_only_runme.java b/Examples/test-suite/java/cpp11_move_only_runme.java
new file mode 100644
index 000000000..8f0f2acef
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_move_only_runme.java
@@ -0,0 +1,51 @@
+
+import cpp11_move_only.*;
+
+public class cpp11_move_only_runme {
+
+ static {
+ try {
+ System.loadLibrary("cpp11_move_only");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+
+ // Output
+ {
+ Counter.reset_counts();
+ MoveOnly mo = MoveOnly.create();
+ mo.delete();
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+ }
+
+ {
+ Counter.reset_counts();
+ MovableCopyable mo = MovableCopyable.create();
+ mo.delete();
+ Counter.check_counts(2, 1, 0, 0, 1, 3);
+ }
+
+ // Move semantics not used
+ {
+ Counter.reset_counts();
+ MovableCopyable mo = MovableCopyable.createConst();
+ mo.delete();
+ Counter.check_counts(2, 1, 1, 0, 0, 3);
+ }
+
+ // Input
+ {
+ Counter.reset_counts();
+ MovableCopyable mo = new MovableCopyable(222);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.take(mo);
+ Counter.check_counts(2, 0, 1, 1, 0, 2);
+ mo.delete();
+ Counter.check_counts(2, 0, 1, 1, 0, 3);
+ }
+ }
+}
diff --git a/Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java b/Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java
new file mode 100644
index 000000000..c857a7b81
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java
@@ -0,0 +1,44 @@
+import cpp11_move_only_valuewrapper.*;
+
+public class cpp11_move_only_valuewrapper_runme {
+
+ static {
+ try {
+ System.loadLibrary("cpp11_move_only_valuewrapper");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+ Counter.reset_counts();
+ {
+ XXX xxx = cpp11_move_only_valuewrapper.createXXX();
+ xxx.delete();
+ }
+ if (cpp11_move_only_valuewrapper.has_cplusplus11())
+ // Was (1, 2, 0, 0, 0, 3) before SwigValueWrapper::operator=(T &&) was added.
+ // Was (1, 1, 0, 1, 0, 3) before SwigValueWrapper::operator T&&() was added with new "out" typemaps
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+ Counter.reset_counts();
+ {
+ XXX xxx = cpp11_move_only_valuewrapper.createXXX2();
+ xxx.delete();
+ }
+ if (cpp11_move_only_valuewrapper.has_cplusplus11())
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+ cpp11_move_only_valuewrapper.test1();
+ cpp11_move_only_valuewrapper.test2();
+ cpp11_move_only_valuewrapper.test3();
+ cpp11_move_only_valuewrapper.test4();
+ cpp11_move_only_valuewrapper.test5();
+ cpp11_move_only_valuewrapper.test6();
+
+ // Tests SwigValueWrapper, std::unique_ptr (SWIG not parsing a type that is move-only)
+ Counter.reset_counts();
+ SWIGTYPE_p_std__unique_ptrT_XXX_t ptr = cpp11_move_only_valuewrapper.makeUniqueXXX();
+ cpp11_move_only_valuewrapper.cleanup(ptr);
+ Counter.check_counts(1, 0, 0, 0, 0, 1);
+ }
+}
diff --git a/Examples/test-suite/java/cpp11_move_typemaps_runme.java b/Examples/test-suite/java/cpp11_move_typemaps_runme.java
new file mode 100644
index 000000000..1b5fd2e6c
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_move_typemaps_runme.java
@@ -0,0 +1,51 @@
+
+import cpp11_move_typemaps.*;
+
+public class cpp11_move_typemaps_runme {
+
+ static {
+ try {
+ System.loadLibrary("cpp11_move_typemaps");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+ {
+ Counter.reset_counts();
+ MoveOnly mo = new MoveOnly(111);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MoveOnly.take(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ mo.delete();
+ }
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+ {
+ Counter.reset_counts();
+ MovableCopyable mo = new MovableCopyable(111);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.take(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ mo.delete();
+ }
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+ {
+ MoveOnly mo = new MoveOnly(222);
+ MoveOnly.take(mo);
+ boolean exception_thrown = false;
+ try {
+ MoveOnly.take(mo);
+ } catch (RuntimeException e) {
+ if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+ throw new RuntimeException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new RuntimeException("double usage of take should have been an error");
+ }
+ }
+}
diff --git a/Examples/test-suite/java/cpp11_rvalue_reference_move_runme.java b/Examples/test-suite/java/cpp11_rvalue_reference_move_runme.java
new file mode 100644
index 000000000..70ba2432f
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_rvalue_reference_move_runme.java
@@ -0,0 +1,97 @@
+
+import cpp11_rvalue_reference_move.*;
+
+public class cpp11_rvalue_reference_move_runme {
+
+ static {
+ try {
+ System.loadLibrary("cpp11_rvalue_reference_move");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+
+ {
+ // Function containing rvalue reference parameter
+ Counter.reset_counts();
+ MovableCopyable mo = new MovableCopyable(222);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable.movein(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ if (!MovableCopyable.is_nullptr(mo))
+ throw new RuntimeException("is_nullptr failed");
+ mo.delete();
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+
+ {
+ // Move constructor test
+ Counter.reset_counts();
+ MovableCopyable mo = new MovableCopyable(222);
+ Counter.check_counts(1, 0, 0, 0, 0, 0);
+ MovableCopyable mo_moved = new MovableCopyable(mo);
+ Counter.check_counts(1, 0, 0, 1, 0, 1);
+ if (!MovableCopyable.is_nullptr(mo))
+ throw new RuntimeException("is_nullptr failed");
+ mo.delete();
+ Counter.check_counts(1, 0, 0, 1, 0, 1);
+ mo_moved.delete();
+ Counter.check_counts(1, 0, 0, 1, 0, 2);
+ }
+
+ {
+ // Move assignment operator test
+ Counter.reset_counts();
+ MovableCopyable mo111 = new MovableCopyable(111);
+ MovableCopyable mo222 = new MovableCopyable(222);
+ Counter.check_counts(2, 0, 0, 0, 0, 0);
+ mo111.MoveAssign(mo222);
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ if (!MovableCopyable.is_nullptr(mo222))
+ throw new RuntimeException("is_nullptr failed");
+ mo222.delete();
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ mo111.delete();
+ Counter.check_counts(2, 0, 0, 0, 1, 2);
+ }
+
+ {
+ // null check
+ Counter.reset_counts();
+ boolean exception_thrown = false;
+ try {
+ MovableCopyable.movein(null);
+ } catch (NullPointerException e) {
+ if (!e.getMessage().contains("MovableCopyable && is null"))
+ throw new RuntimeException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new RuntimeException("Should have thrown null error");
+ Counter.check_counts(0, 0, 0, 0, 0, 0);
+ }
+
+ {
+ // output
+ Counter.reset_counts();
+ MovableCopyable mc = MovableCopyable.moveout(1234);
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ MovableCopyable.check_numbers_match(mc, 1234);
+
+ boolean exception_thrown = false;
+ try {
+ MovableCopyable.movein(mc);
+ } catch (RuntimeException e) {
+ if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+ throw new RuntimeException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new RuntimeException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ Counter.check_counts(2, 0, 0, 0, 1, 1);
+ }
+ }
+}
diff --git a/Examples/test-suite/java/cpp11_std_unique_ptr_runme.java b/Examples/test-suite/java/cpp11_std_unique_ptr_runme.java
new file mode 100644
index 000000000..f90ef7041
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_std_unique_ptr_runme.java
@@ -0,0 +1,146 @@
+import cpp11_std_unique_ptr.*;
+
+public class cpp11_std_unique_ptr_runme {
+ static {
+ try {
+ System.loadLibrary("cpp11_std_unique_ptr");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ private static void WaitForGC()
+ {
+ System.gc();
+ System.runFinalization();
+ try {
+ java.lang.Thread.sleep(10);
+ } catch (java.lang.InterruptedException e) {
+ }
+ }
+
+ private static void checkCount(int expected_count) {
+ int actual_count = Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new RuntimeException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+ }
+
+ public static void main(String argv[]) throws Throwable
+ {
+ // Test raw pointer handling involving virtual inheritance
+ {
+ KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ String s = cpp11_std_unique_ptr.useKlassRawPtr(kini);
+ if (!s.equals("KlassInheritanceInput"))
+ throw new RuntimeException("Incorrect string: " + s);
+ kini.delete();
+ checkCount(0);
+ }
+
+ // unique_ptr as input
+ {
+ Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ String s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (!s.equals("KlassInput"))
+ throw new RuntimeException("Incorrect string: " + s);
+ if (!cpp11_std_unique_ptr.is_nullptr(kin))
+ throw new RuntimeException("is_nullptr failed");
+ kin.delete(); // Should not fail, even though already deleted
+ checkCount(0);
+ }
+
+ {
+ Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ String s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (!s.equals("KlassInput"))
+ throw new RuntimeException("Incorrect string: " + s);
+ if (!cpp11_std_unique_ptr.is_nullptr(kin))
+ throw new RuntimeException("is_nullptr failed");
+ boolean exception_thrown = false;
+ try {
+ cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ } catch (RuntimeException e) {
+ if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+ throw new RuntimeException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new RuntimeException("double usage of takeKlassUniquePtr should have been an error");
+ kin.delete(); // Should not fail, even though already deleted
+ checkCount(0);
+ }
+
+ {
+ Klass kin = new Klass("KlassInput");
+ boolean exception_thrown = false;
+ Klass notowned = cpp11_std_unique_ptr.get_not_owned_ptr(kin);
+ try {
+ cpp11_std_unique_ptr.takeKlassUniquePtr(notowned);
+ } catch (RuntimeException e) {
+ if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+ throw new RuntimeException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new RuntimeException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ kin.delete();
+ checkCount(0);
+ }
+
+ {
+ KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ String s = cpp11_std_unique_ptr.takeKlassUniquePtr(kini);
+ checkCount(0);
+ if (!s.equals("KlassInheritanceInput"))
+ throw new RuntimeException("Incorrect string: " + s);
+ if (!cpp11_std_unique_ptr.is_nullptr(kini))
+ throw new RuntimeException("is_nullptr failed");
+ kini.delete(); // Should not fail, even though already deleted
+ checkCount(0);
+ }
+
+ cpp11_std_unique_ptr.takeKlassUniquePtr(null);
+ cpp11_std_unique_ptr.takeKlassUniquePtr(cpp11_std_unique_ptr.make_null());
+ checkCount(0);
+
+ // overloaded parameters
+ if (cpp11_std_unique_ptr.overloadTest() != 0)
+ throw new RuntimeException("overloadTest failed");
+ if (cpp11_std_unique_ptr.overloadTest(null) != 1)
+ throw new RuntimeException("overloadTest failed");
+ if (cpp11_std_unique_ptr.overloadTest(new Klass("over")) != 1)
+ throw new RuntimeException("overloadTest failed");
+ checkCount(0);
+
+
+ // unique_ptr as output
+ Klass k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first");
+ if (!k1.getLabel().equals("first"))
+ throw new RuntimeException("wrong object label");
+
+ Klass k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second");
+ checkCount(2);
+
+ k1.delete();
+ k1 = null;
+ checkCount(1);
+
+ if (!k2.getLabel().equals("second"))
+ throw new RuntimeException("wrong object label");
+
+ k2.delete();
+ k2 = null;
+ checkCount(0);
+
+ if (cpp11_std_unique_ptr.makeNullUniquePtr() != null)
+ throw new RuntimeException("null failure");
+ }
+}
diff --git a/Examples/test-suite/java/director_classes_runme.java b/Examples/test-suite/java/director_classes_runme.java
index 5992b5dd9..9ee6302de 100644
--- a/Examples/test-suite/java/director_classes_runme.java
+++ b/Examples/test-suite/java/director_classes_runme.java
@@ -205,7 +205,7 @@ class JavaDerived extends Base
// Note the following method can never be called from unmanaged code.
// It is here only for code that calls it directly from managed code.
// But should always be defined to ensure behaviour is consistent
- // independent of where DefaultParsms is called from (managed or unmanaged code).
+ // independent of where DefaultParams is called from (managed or unmanaged code).
// Note this method can never be called from unmanaged code
public String DefaultParms(int x)
{
diff --git a/Examples/test-suite/java/director_default_runme.java b/Examples/test-suite/java/director_default_runme.java
index b71e45e25..1ab13237a 100644
--- a/Examples/test-suite/java/director_default_runme.java
+++ b/Examples/test-suite/java/director_default_runme.java
@@ -16,22 +16,29 @@ public class director_default_runme {
{
director_default_MyFoo a = new director_default_MyFoo();
a = new director_default_MyFoo(10);
+ a.delete();
}
- director_default_MyFoo a = new director_default_MyFoo();
- if (!a.GetMsg().equals("director_default_MyFoo-default")) {
- throw new RuntimeException ( "Test 1 failed" );
- }
- if (!a.GetMsg("boo").equals("director_default_MyFoo-boo")) {
- throw new RuntimeException ( "Test 2 failed" );
+ {
+ director_default_MyFoo a = new director_default_MyFoo();
+ if (!a.GetMsg().equals("director_default_MyFoo-default")) {
+ throw new RuntimeException ( "Test 1 failed" );
+ }
+ if (!a.GetMsg("boo").equals("director_default_MyFoo-boo")) {
+ throw new RuntimeException ( "Test 2 failed" );
+ }
+ a.delete();
}
- Foo b = new Foo();
- if (!b.GetMsg().equals("Foo-default")) {
- throw new RuntimeException ( "Test 1 failed" );
- }
- if (!b.GetMsg("boo").equals("Foo-boo")) {
- throw new RuntimeException ( "Test 2 failed" );
+ {
+ Foo b = new Foo();
+ if (!b.GetMsg().equals("Foo-default")) {
+ throw new RuntimeException ( "Test 1 failed" );
+ }
+ if (!b.GetMsg("boo").equals("Foo-boo")) {
+ throw new RuntimeException ( "Test 2 failed" );
+ }
+ b.delete();
}
}
diff --git a/Examples/test-suite/java/director_pass_by_value_runme.java b/Examples/test-suite/java/director_pass_by_value_runme.java
index 24ded2ccf..1d34c3b55 100644
--- a/Examples/test-suite/java/director_pass_by_value_runme.java
+++ b/Examples/test-suite/java/director_pass_by_value_runme.java
@@ -32,6 +32,8 @@ public class director_pass_by_value_runme {
break;
};
}
+ if (director_pass_by_value.has_cplusplus11())
+ Counter.check_counts(1, 0, 0, 1, 0, 1); // check move constructor called and just one destructor
// bug was the passByVal 'global' object was destroyed after the call to virtualMethod had finished.
int ret = director_pass_by_value_runme.passByVal.getVal();
if (ret != 0x12345678)
diff --git a/Examples/test-suite/java/director_property_runme.java b/Examples/test-suite/java/director_property_runme.java
new file mode 100644
index 000000000..cc8727740
--- /dev/null
+++ b/Examples/test-suite/java/director_property_runme.java
@@ -0,0 +1,66 @@
+
+import director_property.*;
+
+public class director_property_runme {
+
+ static {
+ try {
+ System.loadLibrary("director_property");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+
+ {
+ Foo a = new director_property_MyFoo();
+ if (!a.getA().equals("")) {
+ throw new RuntimeException( "Test failed" );
+ }
+ a.setA("Hello");
+ if (!a.getA().equals("Hello set from MyFoo")) {
+ throw new RuntimeException( "Test failed" );
+ }
+ a.setAByRef("Hello");
+ if (!a.getA().equals("Hello setAByRef from MyFoo")) {
+ throw new RuntimeException( "Test failed" );
+ }
+ a.delete();
+ }
+
+ {
+ Foo a_original = new director_property_MyFoo();
+ Foo a = Foo.get_self(a_original);
+ if (!a.getA().equals("")) {
+ throw new RuntimeException( "Test failed" );
+ }
+ a.setA("Hello");
+ if (!a.getA().equals("Hello set from MyFoo")) {
+ throw new RuntimeException( "Test failed" );
+ }
+ a.setAByRef("Hello");
+ if (!a.getA().equals("Hello setAByRef from MyFoo")) {
+ throw new RuntimeException( "Test failed" );
+ }
+ a.delete();
+ }
+ }
+}
+
+class director_property_MyFoo extends Foo {
+ public director_property_MyFoo() {
+ super();
+ }
+ @Override
+ public void setA(String a) {
+ super.setA(a + " set from MyFoo");
+ }
+ @Override
+ public void setAByRef(String a) {
+ super.setA(a + " setAByRef from MyFoo");
+ }
+}
+
+
diff --git a/Examples/test-suite/java/director_using_member_scopes_runme.java b/Examples/test-suite/java/director_using_member_scopes_runme.java
new file mode 100644
index 000000000..d500014e6
--- /dev/null
+++ b/Examples/test-suite/java/director_using_member_scopes_runme.java
@@ -0,0 +1,64 @@
+
+import director_using_member_scopes.*;
+
+public class director_using_member_scopes_runme {
+
+ static {
+ try {
+ System.loadLibrary("director_using_member_scopes");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+ NativeWindowType nwt = new NativeWindowType();
+
+ {
+ director_using_member_scopes_MyApplicationContextSDL a = new director_using_member_scopes_MyApplicationContextSDL();
+
+ if (ApplicationContextBase.call_setWindowGrab(a, nwt, true) != 100)
+ throw new RuntimeException("failed");
+
+ if (ApplicationContextSDL.call_setWindowGrab(a, nwt, true) != 100)
+ throw new RuntimeException("failed");
+ }
+
+ {
+ director_using_member_scopes_MyACSDL a = new director_using_member_scopes_MyACSDL();
+
+ if (ACB.call_setWindowGrab(a, nwt, true) != 100)
+ throw new RuntimeException("failed");
+ if (ACB.call_setWindowGrab(a, "hi", 0) != 200)
+ throw new RuntimeException("failed");
+
+ if (ACSDL.call_setWindowGrab(a, nwt, true) != 100)
+ throw new RuntimeException("failed");
+ if (ACSDL.call_setWindowGrab(a, "hi", 0) != 200)
+ throw new RuntimeException("failed");
+ }
+ }
+}
+
+class director_using_member_scopes_MyApplicationContextSDL extends ApplicationContextSDL {
+ @Override
+ public int setWindowGrab(NativeWindowType win, boolean grab)
+ {
+ return 100;
+ }
+}
+
+class director_using_member_scopes_MyACSDL extends ACSDL {
+ @Override
+ public int setWindowGrab(NativeWindowType win, boolean grab)
+ {
+ return 100;
+ }
+
+ @Override
+ public int setWindowGrab(String s, int val)
+ {
+ return 200;
+ }
+}
diff --git a/Examples/test-suite/java/doxygen_parsing_runme.java b/Examples/test-suite/java/doxygen_parsing_runme.java
index 29e524f78..2c76001db 100644
--- a/Examples/test-suite/java/doxygen_parsing_runme.java
+++ b/Examples/test-suite/java/doxygen_parsing_runme.java
@@ -132,6 +132,14 @@ public class doxygen_parsing_runme {
wantedComments.put("doxygen_parsing.doxygen_parsingConstants.CONSTANT_VALUE",
"The constant comment \n" +
"");
+ wantedComments.put("doxygen_parsing.Foo1750.getA()",
+ "");
+ wantedComments.put("doxygen_parsing.Foo1750.getB()",
+ "");
+ wantedComments.put("doxygen_parsing.Foo1750.setA(int)",
+ "");
+ wantedComments.put("doxygen_parsing.Foo1750.setB(int)",
+ "");
// and ask the parser to check comments for us
System.exit(CommentParser.check(wantedComments));
diff --git a/Examples/test-suite/java/doxygen_translate_all_tags_runme.java b/Examples/test-suite/java/doxygen_translate_all_tags_runme.java
index 56272bf84..80087c65a 100644
--- a/Examples/test-suite/java/doxygen_translate_all_tags_runme.java
+++ b/Examples/test-suite/java/doxygen_translate_all_tags_runme.java
@@ -81,7 +81,7 @@ public class doxygen_translate_all_tags_runme {
" If not: SOMECONDITION {\n" +
" This is printed if not \n" +
" }\n" +
- " <img src=testImage.bmp alt=\"Hello, world!\" />\n" +
+ " <img src=\"testImage.bmp\" alt=\"Hello, world!\"/>\n" +
" Some text \n" +
" describing invariant. \n");
diff --git a/Examples/test-suite/java/doxygen_translate_runme.java b/Examples/test-suite/java/doxygen_translate_runme.java
index b049a6466..c55c95150 100644
--- a/Examples/test-suite/java/doxygen_translate_runme.java
+++ b/Examples/test-suite/java/doxygen_translate_runme.java
@@ -69,7 +69,8 @@ public class doxygen_translate_runme {
" This is printed if not}\n" +
" \n" +
" \n" +
- " <img src=testImage.bmp alt=\"Hello, world!\"/>\n" +
+ " <img src=\"testImage.bmp\" alt=\"Hello, world!\"/>\n" +
+ " <img src=\"test image.jpg\" alt=\"Test jpeg\"/>\n" +
" \n" +
" <ul> \n" +
" \n" +
diff --git a/Examples/test-suite/java/friends_runme.java b/Examples/test-suite/java/friends_runme.java
index 2dced9efa..ebec103c1 100644
--- a/Examples/test-suite/java/friends_runme.java
+++ b/Examples/test-suite/java/friends_runme.java
@@ -32,7 +32,7 @@ public class friends_runme {
if (friends.mix(a,b) != 5)
throw new RuntimeException("failed");
- D_d di = new D_d(2);
+ D_i di = new D_i(2);
D_d dd = new D_d(3.3);
// incredible template overloading working just fine
diff --git a/Examples/test-suite/java/java_typemaps_proxy_runme.java b/Examples/test-suite/java/java_typemaps_proxy_runme.java
index 67a083114..0caeb1c65 100644
--- a/Examples/test-suite/java/java_typemaps_proxy_runme.java
+++ b/Examples/test-suite/java/java_typemaps_proxy_runme.java
@@ -76,6 +76,15 @@ public class java_typemaps_proxy_runme {
java_typemaps_proxyJNI.Without_member_method(nullPtr, nullPtr);
java_typemaps_proxyJNI.delete_Without(nullPtr);
java_typemaps_proxyJNI.global_method_without(nullPtr);
+
+ // $imfuncname substitution
+ ProxyA pa = new ProxyA();
+ if (pa.imfuncname_test() != 123)
+ throw new RuntimeException("imfuncname_test is not 123");
+ if (ProxyA.imfuncname_static_test() != 234)
+ throw new RuntimeException("imfuncname_test is not 234");
+ if (java_typemaps_proxy.imfuncname_global_test() != 345)
+ throw new RuntimeException("imfuncname_test is not 345");
}
}
diff --git a/Examples/test-suite/java/li_std_auto_ptr_runme.java b/Examples/test-suite/java/li_std_auto_ptr_runme.java
index 50ed113a4..24e353ddc 100644
--- a/Examples/test-suite/java/li_std_auto_ptr_runme.java
+++ b/Examples/test-suite/java/li_std_auto_ptr_runme.java
@@ -20,49 +20,127 @@ public class li_std_auto_ptr_runme {
}
}
+ private static void checkCount(int expected_count) {
+ int actual_count = Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new RuntimeException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+ }
+
public static void main(String argv[]) throws Throwable
{
+ // Test raw pointer handling involving virtual inheritance
+ {
+ KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ String s = li_std_auto_ptr.useKlassRawPtr(kini);
+ if (!s.equals("KlassInheritanceInput"))
+ throw new RuntimeException("Incorrect string: " + s);
+ kini.delete();
+ checkCount(0);
+ }
+
+ // auto_ptr as input
+ {
+ Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ String s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (!s.equals("KlassInput"))
+ throw new RuntimeException("Incorrect string: " + s);
+ if (!li_std_auto_ptr.is_nullptr(kin))
+ throw new RuntimeException("is_nullptr failed");
+ kin.delete(); // Should not fail, even though already deleted
+ checkCount(0);
+ }
+
+ {
+ Klass kin = new Klass("KlassInput");
+ checkCount(1);
+ String s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (!s.equals("KlassInput"))
+ throw new RuntimeException("Incorrect string: " + s);
+ if (!li_std_auto_ptr.is_nullptr(kin))
+ throw new RuntimeException("is_nullptr failed");
+ boolean exception_thrown = false;
+ try {
+ li_std_auto_ptr.takeKlassAutoPtr(kin);
+ } catch (RuntimeException e) {
+ if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+ throw new RuntimeException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new RuntimeException("double usage of takeKlassAutoPtr should have been an error");
+ kin.delete(); // Should not fail, even though already deleted
+ checkCount(0);
+ }
+
+ {
+ Klass kin = new Klass("KlassInput");
+ boolean exception_thrown = false;
+ Klass notowned = li_std_auto_ptr.get_not_owned_ptr(kin);
+ try {
+ li_std_auto_ptr.takeKlassAutoPtr(notowned);
+ } catch (RuntimeException e) {
+ if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+ throw new RuntimeException("incorrect exception message");
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new RuntimeException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ kin.delete();
+ checkCount(0);
+ }
+
+ {
+ KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ String s = li_std_auto_ptr.takeKlassAutoPtr(kini);
+ checkCount(0);
+ if (!s.equals("KlassInheritanceInput"))
+ throw new RuntimeException("Incorrect string: " + s);
+ if (!li_std_auto_ptr.is_nullptr(kini))
+ throw new RuntimeException("is_nullptr failed");
+ kini.delete(); // Should not fail, even though already deleted
+ checkCount(0);
+ }
+
+ li_std_auto_ptr.takeKlassAutoPtr(null);
+ li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
+ checkCount(0);
+
+ // overloaded parameters
+ if (li_std_auto_ptr.overloadTest() != 0)
+ throw new RuntimeException("overloadTest failed");
+ if (li_std_auto_ptr.overloadTest(null) != 1)
+ throw new RuntimeException("overloadTest failed");
+ if (li_std_auto_ptr.overloadTest(new Klass("over")) != 1)
+ throw new RuntimeException("overloadTest failed");
+ checkCount(0);
+
+
+ // auto_ptr as output
Klass k1 = li_std_auto_ptr.makeKlassAutoPtr("first");
if (!k1.getLabel().equals("first"))
throw new RuntimeException("wrong object label");
Klass k2 = li_std_auto_ptr.makeKlassAutoPtr("second");
- if (Klass.getTotal_count() != 2)
- throw new RuntimeException("number of objects should be 2");
+ checkCount(2);
+ k1.delete();
k1 = null;
- {
- int countdown = 500;
- int expectedCount = 1;
- while (true) {
- WaitForGC();
- if (--countdown == 0)
- break;
- if (Klass.getTotal_count() == expectedCount)
- break;
- }
- int actualCount = Klass.getTotal_count();
- if (actualCount != expectedCount)
- System.err.println("GC failed to run (li_std_auto_ptr 1). Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
- }
+ checkCount(1);
if (!k2.getLabel().equals("second"))
throw new RuntimeException("wrong object label");
+ k2.delete();
k2 = null;
- {
- int countdown = 500;
- int expectedCount = 0;
- while (true) {
- WaitForGC();
- if (--countdown == 0)
- break;
- if (Klass.getTotal_count() == expectedCount)
- break;
- };
- int actualCount = Klass.getTotal_count();
- if (actualCount != expectedCount)
- System.err.println("GC failed to run (li_std_auto_ptr 2). Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
- }
+ checkCount(0);
+
+ if (li_std_auto_ptr.makeNullAutoPtr() != null)
+ throw new RuntimeException("null failure");
}
}
diff --git a/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java b/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java
index 3f2b00000..df3e217fd 100644
--- a/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java
+++ b/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java
@@ -46,17 +46,17 @@ public class multiple_inheritance_interfaces_runme {
checkBaseAndInterfaces(IC.class, true, "", new String[] {"IA", "IB"});
checkBaseAndInterfaces(A.class, false, "", new String[] {"IA"});
checkBaseAndInterfaces(B.class, false, "", new String[] {"IB"});
- checkBaseAndInterfaces(C.class, false, "", new String[] {"IA", "IB", "IC"});
- checkBaseAndInterfaces(D.class, false, "", new String[] {"IA", "IB", "IC"});
+ checkBaseAndInterfaces(C.class, false, "", new String[] {"IC", "IA", "IB"});
+ checkBaseAndInterfaces(D.class, false, "", new String[] {"IC", "IA", "IB"});
checkBaseAndInterfaces(E.class, false, "D", new String[] {});
checkBaseAndInterfaces(IJ.class, true, "", new String[] {});
checkBaseAndInterfaces(IK.class, true, "", new String[] {"IJ"});
checkBaseAndInterfaces(IL.class, true, "", new String[] {"IK"});
checkBaseAndInterfaces(J.class, false, "", new String[] {"IJ"});
- checkBaseAndInterfaces(K.class, false, "", new String[] {"IJ", "IK"});
- checkBaseAndInterfaces(L.class, false, "", new String[] {"IJ", "IK", "IL"});
- checkBaseAndInterfaces(M.class, false, "", new String[] {"IJ", "IK", "IL"});
+ checkBaseAndInterfaces(K.class, false, "", new String[] {"IK", "IJ"});
+ checkBaseAndInterfaces(L.class, false, "", new String[] {"IL", "IK", "IJ"});
+ checkBaseAndInterfaces(M.class, false, "", new String[] {"IL", "IK", "IJ"});
checkBaseAndInterfaces(P.class, false, "", new String[] {});
checkBaseAndInterfaces(IQ.class, true, "", new String[] {});
@@ -74,5 +74,7 @@ public class multiple_inheritance_interfaces_runme {
d.ia(10);
d.ia("bye");
d.ia("bye", false);
+
+ UndesirablesSwigImpl.UndesiredStaticMethod(UndesirablesSwigImpl.UndesiredEnum.UndesiredEnum1);
}
}
diff --git a/Examples/test-suite/java/multiple_inheritance_overload_runme.java b/Examples/test-suite/java/multiple_inheritance_overload_runme.java
new file mode 100644
index 000000000..e516e7738
--- /dev/null
+++ b/Examples/test-suite/java/multiple_inheritance_overload_runme.java
@@ -0,0 +1,65 @@
+import multiple_inheritance_overload.*;
+
+public class multiple_inheritance_overload_runme {
+
+ static {
+ try {
+ System.loadLibrary("multiple_inheritance_overload");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void check(boolean fail, String msg) {
+ if (fail)
+ throw new RuntimeException(msg);
+ }
+
+ public static void main(String argv[]) {
+ int i = 0;
+ Base b1 = new Derived();
+ check(b1.Method(i) != 0, "b1.Method failed");
+ check(b1.MethodForRenaming(i) != 0, "b1.MethodForRenaming failed");
+ check(b1.MethodForRenamingConst(i) != 1, "b1.MethodForRenamingConst failed");
+ check(b1.MethodWarningSuppressed(i) != 0, "b1.MethodWarningSuppressed failed");
+ check(b1.NotVirtualMethod(i) != 0, "b1.NotVirtualMethod failed");
+ check(b1.SimilarOverloadedMethod(i) != 0, "b1.NotVirtualMethod failed");
+
+ Derived d1 = new Derived();
+ check(d1.Method(i) != 0, "d1.Method failed");
+ check(d1.MethodForRenaming(i) != 0, "d1.MethodForRenaming failed");
+ check(d1.MethodForRenamingConst(i) != 1, "d1.MethodForRenamingConst failed");
+ check(d1.MethodWarningSuppressed(i) != 0, "d1.MethodWarningSuppressed failed");
+ check(d1.NotVirtualMethod(i) != 0, "d1.NotVirtualMethod failed");
+ check(d1.SimilarOverloadedMethod(i) != 0, "d1.NotVirtualMethod failed");
+
+ check(d1.AnotherMethod(i) != 0, "d1.AnotherMethod failed");
+
+ Base db1 = BaseSwigImpl.in_out(d1);
+ check(db1.Method(i) != 0, "db1.Method failed");
+ check(db1.MethodForRenaming(i) != 0, "db1.MethodForRenaming failed");
+ check(db1.MethodForRenamingConst(i) != 1, "db1.MethodForRenamingConst failed");
+ check(db1.MethodWarningSuppressed(i) != 0, "db1.MethodWarningSuppressed failed");
+ check(db1.NotVirtualMethod(i) != 0, "db1.NotVirtualMethod failed");
+ check(db1.SimilarOverloadedMethod(i) != 0, "db1.NotVirtualMethod failed");
+
+ MoreDerived m1 = new MoreDerived();
+ check(m1.Method(i) != 0, "m1.Method failed");
+ check(m1.MethodForRenaming(i) != 0, "m1.MethodForRenaming failed");
+ check(m1.MethodForRenamingConst(i) != 1, "m1.MethodForRenamingConst failed");
+ check(m1.MethodWarningSuppressed(i) != 0, "m1.MethodWarningSuppressed failed");
+ check(m1.NotVirtualMethod(i) != 0, "m1.NotVirtualMethod failed");
+ check(m1.SimilarOverloadedMethod(i) != 0, "m1.NotVirtualMethod failed");
+
+ check(m1.AnotherMethod(i) != 0, "m1.AnotherMethod failed");
+
+ Base mb2 = BaseSwigImpl.in_out(m1);
+ check(mb2.Method(i) != 0, "mb2.Method failed");
+ check(mb2.MethodForRenaming(i) != 0, "mb2.MethodForRenaming failed");
+ check(mb2.MethodForRenamingConst(i) != 1, "mb2.MethodForRenamingConst failed");
+ check(mb2.MethodWarningSuppressed(i) != 0, "mb2.MethodWarningSuppressed failed");
+ check(mb2.NotVirtualMethod(i) != 0, "mb2.NotVirtualMethod failed");
+ check(mb2.SimilarOverloadedMethod(i) != 0, "mb2.NotVirtualMethod failed");
+ }
+}
diff --git a/Examples/test-suite/java/typemap_out_optimal_runme.java b/Examples/test-suite/java/typemap_out_optimal_runme.java
index 8a87f0c4b..254b0c6b6 100644
--- a/Examples/test-suite/java/typemap_out_optimal_runme.java
+++ b/Examples/test-suite/java/typemap_out_optimal_runme.java
@@ -12,10 +12,16 @@ public class typemap_out_optimal_runme {
}
}
- public static XX x = null;
public static void main(String argv[]) {
- XX.setDebug(false);
- x = XX.create();
+ XX.setTrace(false);
+ {
+ XX x = XX.create();
+ x.delete();
+ }
+ {
+ XX x = XX.createConst();
+ x.delete();
+ }
}
}
diff --git a/Examples/test-suite/java_director_exception_feature.i b/Examples/test-suite/java_director_exception_feature.i
index 7978ac2a1..dfc85dea5 100644
--- a/Examples/test-suite/java_director_exception_feature.i
+++ b/Examples/test-suite/java_director_exception_feature.i
@@ -139,7 +139,7 @@
%rename(MyJavaException2) MyNS::Exception2;
%rename(MyJavaUnexpected) MyNS::Unexpected;
-%typemap(javabase) ::MyNS::Exception1,::MyNS::Exception2,::MyNS::Unexpected "java.lang.Exception";
+%typemap(javabase) ::MyNS::Exception1,::MyNS::Exception2,::MyNS::Unexpected "java.lang.Exception"
%rename(getMessage) what() const; // Rename all what() methods
namespace MyNS {
diff --git a/Examples/test-suite/java_director_exception_feature_nspace.i b/Examples/test-suite/java_director_exception_feature_nspace.i
index b52c1acf4..f2f73278f 100644
--- a/Examples/test-suite/java_director_exception_feature_nspace.i
+++ b/Examples/test-suite/java_director_exception_feature_nspace.i
@@ -146,7 +146,7 @@
%rename(MyJavaException2) MyNS::Exception2;
%rename(MyJavaUnexpected) MyNS::Unexpected;
-%typemap(javabase) ::MyNS::Exception1,::MyNS::Exception2,::MyNS::Unexpected "java.lang.Exception";
+%typemap(javabase) ::MyNS::Exception1,::MyNS::Exception2,::MyNS::Unexpected "java.lang.Exception"
%rename(getMessage) what() const; // Rename all what() methods
namespace MyNS {
diff --git a/Examples/test-suite/java_throws.i b/Examples/test-suite/java_throws.i
index 6cd47b448..67d8d4ebc 100644
--- a/Examples/test-suite/java_throws.i
+++ b/Examples/test-suite/java_throws.i
@@ -88,7 +88,7 @@ int ioTest() { return 0; }
%}
// except feature (%javaexception) specifying a checked exception class for the throws clause
-%typemap(javabase) MyException "Throwable";
+%typemap(javabase) MyException "Throwable"
%typemap(javacode) MyException %{
public static final long serialVersionUID = 0x52151000; // Suppress ecj warning
%}
@@ -193,6 +193,37 @@ try {
}
%}
+%typemap(javabody) SWIGTYPE %{
+ private transient long swigCPtr;
+ protected transient boolean swigCMemOwn;
+
+ protected $javaclassname(long cPtr, boolean cMemoryOwn) {
+ swigCMemOwn = cMemoryOwn;
+ swigCPtr = cPtr;
+ }
+
+ protected static long getCPtr($javaclassname obj) {
+ return (obj == null) ? 0 : obj.swigCPtr;
+ }
+
+ protected static long swigRelease($javaclassname obj) {
+ long ptr = 0;
+ if (obj != null) {
+ if (!obj.swigCMemOwn)
+ throw new RuntimeException("Cannot release ownership as memory is not owned");
+ ptr = obj.swigCPtr;
+ obj.swigCMemOwn = false;
+ try {
+ obj.delete();
+ } catch (MyException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return ptr;
+ }
+%}
+
+
%inline %{
struct NoExceptTest {
unsigned int noExceptionPlease() { return 123; }
diff --git a/Examples/test-suite/java_typemaps_proxy.i b/Examples/test-suite/java_typemaps_proxy.i
index 3e9b18335..7e90b5a3f 100644
--- a/Examples/test-suite/java_typemaps_proxy.i
+++ b/Examples/test-suite/java_typemaps_proxy.i
@@ -3,21 +3,21 @@
%module java_typemaps_proxy
-%typemap(javaimports) SWIGTYPE "import java.math.*;";
+%typemap(javaimports) SWIGTYPE "import java.math.*;"
%typemap(javacode) NS::Farewell %{
public void saybye(BigDecimal num_times) {
// BigDecimal requires the java.math library
}
%}
-%typemap(javaclassmodifiers) NS::Farewell "public final class";
+%typemap(javaclassmodifiers) NS::Farewell "public final class"
%typemap(javaimports) NS::Greeting %{
import java.util.*; // for EventListener
import java.lang.*; // for Exception
%};
-%typemap(javabase) NS::Greeting "Exception";
-%typemap(javainterfaces) NS::Greeting "EventListener";
+%typemap(javabase) NS::Greeting "Exception"
+%typemap(javainterfaces) NS::Greeting "EventListener"
%typemap(javacode) NS::Greeting %{
public static final long serialVersionUID = 0x52151000; // Suppress ecj warning
// Pure Java code generated using %typemap(javacode)
@@ -60,7 +60,7 @@ import java.lang.*; // for Exception
%}
// get rid of the finalize method for NS::Farewell
-%typemap(javafinalize) NS::Farewell "";
+%typemap(javafinalize) NS::Farewell ""
// Test typemaps are being found for templated classes
%typemap(javacode) NS::Adieu<int**> %{
@@ -89,7 +89,7 @@ namespace NS {
%template(AdieuIntPtrPtr) NS::Adieu<int**>;
// Check the premature garbage collection prevention parameter can be turned off
-%typemap(jtype, nopgcpp="1") Without * "long";
+%typemap(jtype, nopgcpp="1") Without * "long"
%pragma(java) jniclassclassmodifiers="public class"
%inline %{
@@ -109,7 +109,7 @@ struct With {
void global_method_with(With *p) {}
%}
-%typemap(jtype, nopgcpp="1") const ConstWithout * "long";
+%typemap(jtype, nopgcpp="1") const ConstWithout * "long"
%inline %{
class ConstWithout {
public:
@@ -119,11 +119,26 @@ public:
void const_member_method(const ConstWithout *p) const {}
const ConstWithout * const_var;
const ConstWithout * const var_const;
-private:
- ConstWithout& operator=(const ConstWithout &);
};
const ConstWithout * global_constwithout = 0;
void global_method_constwithout(const ConstWithout *p) {}
%}
+// $imfuncname substitution
+%typemap(javaout) int imfuncname_test {
+ return $moduleJNI.$imfuncname(swigCPtr, this) + 123;
+ }
+%typemap(javaout) int imfuncname_static_test {
+ return $moduleJNI.$imfuncname() + 234;
+ }
+%typemap(javaout) int imfuncname_global_test {
+ return $moduleJNI.$imfuncname() + 345;
+ }
+%inline %{
+struct ProxyA {
+ int imfuncname_test() { return 0; }
+ static int imfuncname_static_test() { return 0; }
+};
+int imfuncname_global_test() { return 0; }
+%}
diff --git a/Examples/test-suite/java_typemaps_typewrapper.i b/Examples/test-suite/java_typemaps_typewrapper.i
index b7bf847ef..d3ee5432b 100644
--- a/Examples/test-suite/java_typemaps_typewrapper.i
+++ b/Examples/test-suite/java_typemaps_typewrapper.i
@@ -3,7 +3,7 @@
%module java_typemaps_typewrapper
-%typemap(javaimports) SWIGTYPE * "import java.math.*;";
+%typemap(javaimports) SWIGTYPE * "import java.math.*;"
%typemap(javacode) Farewell * %{
public static $javaclassname CreateNullPointer() {
return new $javaclassname();
@@ -12,15 +12,15 @@
// BigDecimal requires the java.math library
}
%}
-%typemap(javaclassmodifiers) Farewell * "public final class";
+%typemap(javaclassmodifiers) Farewell * "public final class"
%typemap(javaimports) Greeting * %{
import java.util.*; // for EventListener
import java.lang.*; // for Exception
%};
-%typemap(javabase) Greeting * "Exception";
-%typemap(javainterfaces) Greeting * "EventListener";
+%typemap(javabase) Greeting * "Exception"
+%typemap(javainterfaces) Greeting * "EventListener"
%typemap(javacode) Greeting * %{
public static final long serialVersionUID = 0x52151000; // Suppress ecj warning
// Pure Java code generated using %typemap(javacode)
diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
index 0e11f3d9d..8772851a8 100644
--- a/Examples/test-suite/javascript/Makefile.in
+++ b/Examples/test-suite/javascript/Makefile.in
@@ -9,6 +9,10 @@ SCRIPTSUFFIX = _runme.js
OBJEXT = @OBJEXT@
SO = @SO@
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
@@ -47,9 +51,6 @@ ifeq (node,$(JSENGINE))
SWIGOPT += -v8 -DBUILDING_NODE_EXTENSION=1
# shut up some warnings
- # contract macro has an empty 'else' at the end...
- aggregate.cpptest: GYP_CFLAGS = \"-Wno-empty-body\"
- contract.cpptest: GYP_CFLAGS = \"-Wno-empty-body\"
# dunno... ignoring generously
apply_signed_char.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
@@ -58,6 +59,7 @@ ifeq (node,$(JSENGINE))
director_basic.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
enum_thorough.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
member_funcptr_galore.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
+ director_unwrap_result.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
setup_node = \
test -d $* || mkdir $* && \
@@ -137,7 +139,7 @@ clean:
rm -f imports_a$${ext} imports_b$${ext}; \
rm -f import_stl_a$${ext} import_stl_b$${ext}; \
rm -f mod_a$${ext} mod_b$${ext}; \
- rm -f multi_import_a$${ext} multi_import_b$${ext}; \
+ rm -f multi_import_a$${ext} multi_import_b$${ext} multi_import_d$${ext}; \
rm -f packageoption_a$${ext} packageoption_b$${ext} packageoption_c$${ext}; \
rm -f template_typedef_cplx2$${ext}; \
done
diff --git a/Examples/test-suite/javascript/catches_strings_runme.js b/Examples/test-suite/javascript/catches_strings_runme.js
new file mode 100644
index 000000000..c99e9a05f
--- /dev/null
+++ b/Examples/test-suite/javascript/catches_strings_runme.js
@@ -0,0 +1,23 @@
+var catches_strings = require("catches_strings");
+
+exception_thrown = false;
+try {
+ catches_strings.StringsThrower.charstring();
+} catch (e) {
+ if (!e.message.includes("charstring message"))
+ throw new Error("incorrect exception message " + e.message);
+ exception_thrown = true;
+}
+if (!exception_thrown)
+ throw new Error("Should have thrown an exception");
+
+exception_thrown = false;
+try {
+ catches_strings.StringsThrower.stdstring();
+} catch (e) {
+ if (!e.message.includes("stdstring message"))
+ throw new Error("incorrect exception message " + e.message);
+ exception_thrown = true;
+}
+if (!exception_thrown)
+ throw new Error("Should have thrown an exception");
diff --git a/Examples/test-suite/javascript/cpp11_move_typemaps_runme.js b/Examples/test-suite/javascript/cpp11_move_typemaps_runme.js
new file mode 100644
index 000000000..1e888cb9c
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_move_typemaps_runme.js
@@ -0,0 +1,30 @@
+var cpp11_move_typemaps = require("cpp11_move_typemaps");
+
+cpp11_move_typemaps.Counter.reset_counts();
+mo = new cpp11_move_typemaps.MoveOnly(111);
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0);
+cpp11_move_typemaps.MoveOnly.take(mo);
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
+delete mo;
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+cpp11_move_typemaps.Counter.reset_counts();
+mo = new cpp11_move_typemaps.MovableCopyable(111);
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0);
+cpp11_move_typemaps.MovableCopyable.take(mo);
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
+delete mo;
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+mo = new cpp11_move_typemaps.MoveOnly(222);
+cpp11_move_typemaps.MoveOnly.take(mo);
+exception_thrown = false;
+try {
+ cpp11_move_typemaps.MoveOnly.take(mo);
+} catch (e) {
+ if (!e.message.includes("cannot release ownership as memory is not owned"))
+ throw new Error("incorrect exception message:" + e.message);
+ exception_thrown = true;
+}
+if (!exception_thrown)
+ throw new Error("double usage of take should have been an error");
diff --git a/Examples/test-suite/javascript/cpp11_rvalue_reference_move_runme.js b/Examples/test-suite/javascript/cpp11_rvalue_reference_move_runme.js
new file mode 100644
index 000000000..c642b4265
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_rvalue_reference_move_runme.js
@@ -0,0 +1,87 @@
+var cpp11_rvalue_reference_move = require("cpp11_rvalue_reference_move");
+
+{
+ // Function containing rvalue reference parameter
+ cpp11_rvalue_reference_move.Counter.reset_counts();
+ mo = new cpp11_rvalue_reference_move.MovableCopyable(222);
+ cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0);
+ cpp11_rvalue_reference_move.MovableCopyable.movein(mo);
+ cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2);
+ if (!cpp11_rvalue_reference_move.MovableCopyable.is_nullptr(mo))
+ throw new Error("is_nullptr failed");
+ delete mo;
+ cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2);
+}
+
+{
+ // Move constructor test
+ cpp11_rvalue_reference_move.Counter.reset_counts();
+ mo = new cpp11_rvalue_reference_move.MovableCopyable(222);
+ cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0);
+ mo_moved = new cpp11_rvalue_reference_move.MovableCopyable(mo);
+ cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1);
+ if (!cpp11_rvalue_reference_move.MovableCopyable.is_nullptr(mo))
+ throw new Error("is_nullptr failed");
+ delete mo;
+ cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1);
+ // delete mo_moved;
+ // cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2);
+ // Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
+ cpp11_rvalue_reference_move.MovableCopyable.movein(mo_moved);
+ cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 2, 0, 3);
+}
+
+{
+ // Move assignment operator test
+ cpp11_rvalue_reference_move.Counter.reset_counts();
+ mo111 = new cpp11_rvalue_reference_move.MovableCopyable(111);
+ mo222 = new cpp11_rvalue_reference_move.MovableCopyable(222);
+ cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 0, 0);
+ mo111.MoveAssign(mo222);
+ cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
+ if (!cpp11_rvalue_reference_move.MovableCopyable.is_nullptr(mo222))
+ throw new Error("is_nullptr failed");
+ delete mo222;
+ cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
+ // delete mo111;
+ // cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 2);
+ // Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
+ cpp11_rvalue_reference_move.MovableCopyable.movein(mo111);
+ cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 1, 1, 3);
+}
+
+{
+ // null check
+ cpp11_rvalue_reference_move.Counter.reset_counts();
+ exception_thrown = false;
+ try {
+ cpp11_rvalue_reference_move.MovableCopyable.movein(null);
+ } catch (e) {
+ if (!e.message.includes("invalid null reference"))
+ throw new Error("incorrect exception message " + e.message);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Error("Should have thrown null error");
+ cpp11_rvalue_reference_move.Counter.check_counts(0, 0, 0, 0, 0, 0);
+}
+
+{
+ // output
+ cpp11_rvalue_reference_move.Counter.reset_counts();
+ var mc = cpp11_rvalue_reference_move.MovableCopyable.moveout(1234);
+ cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
+ cpp11_rvalue_reference_move.MovableCopyable.check_numbers_match(mc, 1234);
+
+ exception_thrown = false;
+ try {
+ cpp11_rvalue_reference_move.MovableCopyable.movein(mc);
+ } catch (e) {
+ if (!e.message.includes("cannot release ownership as memory is not owned"))
+ throw new Error("incorrect exception message " + e.message);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
+}
diff --git a/Examples/test-suite/javascript/cpp11_std_unique_ptr_runme.js b/Examples/test-suite/javascript/cpp11_std_unique_ptr_runme.js
new file mode 100644
index 000000000..9e7d87971
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_std_unique_ptr_runme.js
@@ -0,0 +1,129 @@
+var cpp11_std_unique_ptr = require("cpp11_std_unique_ptr");
+
+var checkCount = function(expected_count) {
+ actual_count = cpp11_std_unique_ptr.Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new Error("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+}
+
+// Test raw pointer handling involving virtual inheritance
+{
+ kini = new cpp11_std_unique_ptr.KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ s = cpp11_std_unique_ptr.useKlassRawPtr(kini);
+ if (s !== "KlassInheritanceInput")
+ throw new Error("Incorrect string: " + s);
+ // delete kini;
+ // Above not deleting the C++ object(node v12) - can't reliably control GC
+ cpp11_std_unique_ptr.takeKlassUniquePtr(kini);
+ checkCount(0);
+}
+
+
+// unique_ptr as input
+{
+ kin = new cpp11_std_unique_ptr.Klass("KlassInput");
+ checkCount(1);
+ s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (s !== "KlassInput")
+ throw new Error("Incorrect string: " + s);
+ if (!cpp11_std_unique_ptr.is_nullptr(kin))
+ throw new Error("is_nullptr failed");
+ delete kin; // Should not fail, even though already deleted
+ checkCount(0);
+}
+
+{
+ kin = new cpp11_std_unique_ptr.Klass("KlassInput");
+ checkCount(1);
+ s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ checkCount(0);
+ if (s !== "KlassInput")
+ throw new Error("Incorrect string: " + s);
+ if (!cpp11_std_unique_ptr.is_nullptr(kin))
+ throw new Error("is_nullptr failed");
+ exception_thrown = false;
+ try {
+ cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ } catch (e) {
+ if (!e.message.includes("cannot release ownership as memory is not owned"))
+ throw new Error("incorrect exception message " + e.message);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Error("double usage of takeKlassUniquePtr should have been an error");
+ delete kin; // Should not fail, even though already deleted
+ checkCount(0);
+}
+
+{
+ kin = new cpp11_std_unique_ptr.Klass("KlassInput");
+ exception_thrown = false;
+ notowned = cpp11_std_unique_ptr.get_not_owned_ptr(kin);
+ try {
+ cpp11_std_unique_ptr.takeKlassUniquePtr(notowned);
+ } catch (e) {
+ if (!e.message.includes("cannot release ownership as memory is not owned"))
+ throw new Error("incorrect exception message " + e.message);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ // delete kin;
+ // Above not deleting the C++ object(node v12) - can't reliably control GC
+ cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+ checkCount(0);
+}
+
+{
+ kini = new cpp11_std_unique_ptr.KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ s = cpp11_std_unique_ptr.takeKlassUniquePtr(kini);
+ checkCount(0);
+ if (s !== "KlassInheritanceInput")
+ throw new Error("Incorrect string: " + s);
+ if (!cpp11_std_unique_ptr.is_nullptr(kini))
+ throw new Error("is_nullptr failed");
+ delete kini; // Should not fail, even though already deleted
+ checkCount(0);
+}
+
+cpp11_std_unique_ptr.takeKlassUniquePtr(null);
+cpp11_std_unique_ptr.takeKlassUniquePtr(cpp11_std_unique_ptr.make_null());
+checkCount(0);
+
+// overloaded parameters
+if (cpp11_std_unique_ptr.overloadTest() != 0)
+ throw new RuntimeException("overloadTest failed");
+if (cpp11_std_unique_ptr.overloadTest(null) != 1)
+ throw new RuntimeException("overloadTest failed");
+if (cpp11_std_unique_ptr.overloadTest(new cpp11_std_unique_ptr.Klass("over")) != 1)
+ throw new RuntimeException("overloadTest failed");
+checkCount(0);
+
+
+// unique_ptr as output
+k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first");
+if (k1.getLabel() !== "first")
+ throw new Error("wrong object label");
+
+k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second");
+checkCount(2);
+
+// delete k1;
+// Above not deleting the C++ object(node v12) - can't reliably control GC
+cpp11_std_unique_ptr.takeKlassUniquePtr(k1);
+checkCount(1);
+
+if (k2.getLabel() !== "second")
+ throw new Error("wrong object label");
+
+// delete k2;
+// Above not deleting the C++ object(node v12) - can't reliably control GC
+cpp11_std_unique_ptr.takeKlassUniquePtr(k2);
+checkCount(0);
+
+if (cpp11_std_unique_ptr.makeNullUniquePtr() != null)
+ throw new Error("null failure");
diff --git a/Examples/test-suite/javascript/li_std_auto_ptr_runme.js b/Examples/test-suite/javascript/li_std_auto_ptr_runme.js
new file mode 100644
index 000000000..715b9aca2
--- /dev/null
+++ b/Examples/test-suite/javascript/li_std_auto_ptr_runme.js
@@ -0,0 +1,130 @@
+var li_std_auto_ptr = require("li_std_auto_ptr");
+
+var checkCount = function(expected_count) {
+ actual_count = li_std_auto_ptr.Klass.getTotal_count();
+ if (actual_count != expected_count)
+ throw new Error("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+}
+
+// Test raw pointer handling involving virtual inheritance
+{
+ kini = new li_std_auto_ptr.KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ s = li_std_auto_ptr.useKlassRawPtr(kini);
+ if (s !== "KlassInheritanceInput")
+ throw new Error("Incorrect string: " + s);
+ // delete kini;
+ // Above not deleting the C++ object(node v12) - can't reliably control GC
+ li_std_auto_ptr.takeKlassAutoPtr(kini);
+ checkCount(0);
+}
+
+
+// auto_ptr as input
+{
+ kin = new li_std_auto_ptr.Klass("KlassInput");
+ checkCount(1);
+ s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (s !== "KlassInput")
+ throw new Error("Incorrect string: " + s);
+ if (!li_std_auto_ptr.is_nullptr(kin))
+ throw new Error("is_nullptr failed");
+ delete kin; // Should not fail, even though already deleted
+ checkCount(0);
+}
+
+{
+ kin = new li_std_auto_ptr.Klass("KlassInput");
+ checkCount(1);
+ s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+ checkCount(0);
+ if (s !== "KlassInput")
+ throw new Error("Incorrect string: " + s);
+ if (!li_std_auto_ptr.is_nullptr(kin))
+ throw new Error("is_nullptr failed");
+ exception_thrown = false;
+ try {
+ li_std_auto_ptr.takeKlassAutoPtr(kin);
+ } catch (e) {
+ if (!e.message.includes("cannot release ownership as memory is not owned"))
+ throw new Error("incorrect exception message " + e.message);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Error("double usage of takeKlassAutoPtr should have been an error");
+ delete kin; // Should not fail, even though already deleted
+ checkCount(0);
+}
+
+{
+ kin = new li_std_auto_ptr.Klass("KlassInput");
+ exception_thrown = false;
+ notowned = li_std_auto_ptr.get_not_owned_ptr(kin);
+ try {
+ li_std_auto_ptr.takeKlassAutoPtr(notowned);
+ } catch (e) {
+ if (!e.message.includes("cannot release ownership as memory is not owned"))
+ throw new Error("incorrect exception message " + e.message);
+ exception_thrown = true;
+ }
+ if (!exception_thrown)
+ throw new Error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+ checkCount(1);
+ // delete kin;
+ // Above not deleting the C++ object(node v12) - can't reliably control GC
+ li_std_auto_ptr.takeKlassAutoPtr(kin);
+ checkCount(0);
+}
+
+{
+ kini = new li_std_auto_ptr.KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ s = li_std_auto_ptr.takeKlassAutoPtr(kini);
+ checkCount(0);
+ if (s !== "KlassInheritanceInput")
+ throw new Error("Incorrect string: " + s);
+ if (!li_std_auto_ptr.is_nullptr(kini))
+ throw new Error("is_nullptr failed");
+ delete kini; // Should not fail, even though already deleted
+ checkCount(0);
+}
+
+li_std_auto_ptr.takeKlassAutoPtr(null);
+li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
+checkCount(0);
+
+// overloaded parameters
+if (li_std_auto_ptr.overloadTest() != 0)
+ throw new RuntimeException("overloadTest failed");
+if (li_std_auto_ptr.overloadTest(null) != 1)
+ throw new RuntimeException("overloadTest failed");
+if (li_std_auto_ptr.overloadTest(new li_std_auto_ptr.Klass("over")) != 1)
+ throw new RuntimeException("overloadTest failed");
+checkCount(0);
+
+
+// auto_ptr as output
+k1 = li_std_auto_ptr.makeKlassAutoPtr("first");
+if (k1.getLabel() !== "first")
+ throw new Error("wrong object label");
+
+k2 = li_std_auto_ptr.makeKlassAutoPtr("second");
+checkCount(2);
+
+// delete k1;
+// Above not deleting the C++ object(node v12) - can't reliably control GC
+li_std_auto_ptr.takeKlassAutoPtr(k1);
+checkCount(1);
+
+if (k2.getLabel() !== "second")
+ throw new Error("wrong object label");
+
+// delete k2;
+// Above not deleting the C++ object(node v12) - can't reliably control GC
+li_std_auto_ptr.takeKlassAutoPtr(k2);
+
+if (li_std_auto_ptr.makeNullAutoPtr() != null)
+ throw new Error("null failure");
+
+checkCount(0);
diff --git a/Examples/test-suite/javascript/voidtest_runme.js b/Examples/test-suite/javascript/voidtest_runme.js
new file mode 100644
index 000000000..8ff0c0ba9
--- /dev/null
+++ b/Examples/test-suite/javascript/voidtest_runme.js
@@ -0,0 +1,28 @@
+var voidtest = require("voidtest");
+
+voidtest.globalfunc();
+var f = new voidtest.Foo();
+f.memberfunc();
+
+voidtest.Foo.staticmemberfunc();
+
+if (f.memberfunc() !== (function(){}())) {
+ throw new Error("f.memberfunc() didn't return same result as pure Javascript equivalent");
+}
+
+v1 = voidtest.vfunc1(f);
+v2 = voidtest.vfunc2(f);
+if (!voidtest.test_pointers_equal(v1, v2)) {
+ throw new Error("!voidtest.test_pointers_equal(v1, v2)");
+}
+
+v3 = voidtest.vfunc3(v1);
+if (!voidtest.test_pointers_equal(v3.get_this(), f.get_this())) {
+ throw new Error("!voidtest.test_pointers_equal(v3.get_this(), f.get_this())");
+}
+v4 = voidtest.vfunc1(f);
+if (!voidtest.test_pointers_equal(v4, v1)) {
+ throw new Error("!voidtest.test_pointers_equal(v4, v1)");
+}
+
+v3.memberfunc();
diff --git a/Examples/test-suite/kwargs_feature.i b/Examples/test-suite/kwargs_feature.i
index dd5b2638d..5b9418129 100644
--- a/Examples/test-suite/kwargs_feature.i
+++ b/Examples/test-suite/kwargs_feature.i
@@ -27,6 +27,7 @@
virtual int foo(int a = 1, int b = 0) {return a + b; }
static int statfoo(int a = 1, int b = 0) {return a + b; }
+ static int statfoo_onearg(int x = 10) {return x + x; }
static Foo *create(int a = 1, int b = 0)
{
@@ -127,6 +128,11 @@ struct ExtendingOptArgs1 {};
struct ExtendingOptArgs2 {};
%}
+// For strlen/strcpy
+%{
+#include <string.h>
+%}
+
// Varargs
%warnfilter(SWIGWARN_LANG_VARARGS_KEYWORD) VarargConstructor::VarargConstructor; // Can't wrap varargs with keyword arguments enabled
%warnfilter(SWIGWARN_LANG_VARARGS_KEYWORD) VarargConstructor::vararg_method; // Can't wrap varargs with keyword arguments enabled
diff --git a/Examples/test-suite/li_boost_shared_ptr.i b/Examples/test-suite/li_boost_shared_ptr.i
index b64197be1..001eacb78 100644
--- a/Examples/test-suite/li_boost_shared_ptr.i
+++ b/Examples/test-suite/li_boost_shared_ptr.i
@@ -242,6 +242,10 @@ std::string nullsmartpointerpointertest(SwigBoost::shared_ptr<Klass>* k) {
else
return "also not null";
}
+
+SwigBoost::shared_ptr<Klass>* sp_pointer_null() { return NULL; }
+SwigBoost::shared_ptr<Klass>* null_sp_pointer() { static SwigBoost::shared_ptr<Klass> static_sp; return &static_sp; }
+SwigBoost::shared_ptr<Klass> sp_value_null() { return SwigBoost::shared_ptr<Klass>(); }
// $owner
Klass *pointerownertest() {
return new Klass("pointerownertest");
diff --git a/Examples/test-suite/li_cdata.i b/Examples/test-suite/li_cdata.i
index 2180af96e..4e1a01e4e 100644
--- a/Examples/test-suite/li_cdata.i
+++ b/Examples/test-suite/li_cdata.i
@@ -5,4 +5,8 @@
%cdata(int);
%cdata(double);
+%{
+#include <stdlib.h>
+%}
+
void *malloc(size_t size);
diff --git a/Examples/test-suite/li_cdata_cpp.i b/Examples/test-suite/li_cdata_cpp.i
index 2d7d300e4..80ff2932b 100644
--- a/Examples/test-suite/li_cdata_cpp.i
+++ b/Examples/test-suite/li_cdata_cpp.i
@@ -5,4 +5,8 @@
%cdata(int);
%cdata(double);
+%{
+#include <stdlib.h>
+%}
+
void *malloc(size_t size);
diff --git a/Examples/test-suite/li_factory.i b/Examples/test-suite/li_factory.i
index 7c59d53b2..0de3791b3 100644
--- a/Examples/test-suite/li_factory.i
+++ b/Examples/test-suite/li_factory.i
@@ -16,34 +16,33 @@
struct Geometry {
enum GeomType{
POINT,
- CIRCLE
+ CIRCLE,
+ SHAPELESS
};
-
- virtual ~Geometry() {}
+
+ virtual ~Geometry() {}
virtual int draw() = 0;
static Geometry *create(GeomType i);
- virtual Geometry *clone() = 0;
+ virtual Geometry *clone() = 0;
};
struct Point : Geometry {
int draw() { return 1; }
- double width() { return 1.0; }
- Geometry *clone() { return new Point(); }
+ double width() { return 1.0; }
+ Geometry *clone() { return new Point(); }
};
struct Circle : Geometry {
int draw() { return 2; }
- double radius() { return 1.5; }
- Geometry *clone() { return new Circle(); }
- };
+ double radius() { return 1.5; }
+ Geometry *clone() { return new Circle(); }
+ };
Geometry *Geometry::create(GeomType type) {
switch (type) {
case POINT: return new Point();
- case CIRCLE: return new Circle();
+ case CIRCLE: return new Circle();
default: return 0;
}
}
}
-
-
diff --git a/Examples/test-suite/li_std_auto_ptr.i b/Examples/test-suite/li_std_auto_ptr.i
index d83732af0..18df51368 100644
--- a/Examples/test-suite/li_std_auto_ptr.i
+++ b/Examples/test-suite/li_std_auto_ptr.i
@@ -12,30 +12,51 @@
#endif
%}
-#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY)
+#if !(defined(SWIGGO) || defined(SWIGOCAML) || defined(SWIGR) || defined(SWIGSCILAB))
+%warnfilter(509, 516) overloadTest(Klass);
+
+%include "std_string.i"
+//#include <iostream>
%include "std_auto_ptr.i"
%auto_ptr(Klass)
+%inline %{
+void show_cplusplus_version() {
+ printf("__cplusplus %d\n", (int)__cplusplus);
+}
+%}
+
%{
#if __cplusplus < 201703L
#include <memory>
#else
+
+// If <memory> has already been include (Octave does) then unfortunately gcc incorrectly still provides
+// std::auto_ptr when _GLIBCXX_USE_DEPRECATED is defined by the compiler configuration/OS/who knows what!!
+#include <memory> // Now need to include it in case _GLIBCXX_USE_DEPRECATED is defined and <memory> has not been included, argh
+#if !defined(_GLIBCXX_USE_DEPRECATED)
// Simple std::auto_ptr implementation for testing after its removal in C++17
namespace std {
template <class T> class auto_ptr {
T *ptr;
public:
- auto_ptr(T *ptr = 0) : ptr(ptr) {}
+ explicit auto_ptr(T *p = 0) : ptr(p) {}
auto_ptr(auto_ptr&& a) : ptr(a.ptr) { a.ptr = 0;}
~auto_ptr() { delete ptr; }
T *release() { T *p = ptr; ptr = 0; return p; }
+ T* get() const { return ptr; }
+ void reset(T *p = 0) { delete ptr; ptr = p; }
+ T &operator*() const { return *ptr; }
+ T *operator->() const { return ptr; }
auto_ptr& operator=(auto_ptr&& a) { if (&a != this) { delete ptr; ptr = a.ptr; a.ptr = 0; } return *this; }
};
}
#endif
+#endif
+
#include <string>
#include "swig_examples_lock.h"
%}
@@ -53,7 +74,7 @@ public:
const char* getLabel() const { return m_label.c_str(); }
- ~Klass()
+ virtual ~Klass()
{
SwigExamples::Lock lock(critical_section);
total_count--;
@@ -73,14 +94,62 @@ int Klass::total_count = 0;
%}
-%template(KlassAutoPtr) std::auto_ptr<Klass>;
-
%inline %{
+// Virtual inheritance used as this usually results in different values for Klass* and KlassInheritance*
+// for testing class inheritance and auto_ptr
+struct KlassInheritance : virtual Klass {
+ KlassInheritance(const char* label) : Klass(label) {
+ // std::cout << "ptrs.... " << std::hex << (Klass*)this << " " << (KlassInheritance*)this << std::endl;
+ }
+};
+
+std::string useKlassRawPtr(Klass* k) {
+// std::cout << "useKlassRawPtr " << std::hex << (Klass*)k << std::endl;
+ std::string s(k->getLabel());
+// std::cout << "useKlassRawPtr string: " << s << std::endl;
+ return s;
+}
+
+std::string takeKlassAutoPtr(std::auto_ptr<Klass> k) {
+// std::cout << "takeKlassAutoPtr " << std::hex << (Klass*)k.get() << std::endl;
+ std::string s(k.get() ? k->getLabel() : "null smart pointer");
+// std::cout << "takeKlassAutoPtr string: " << s << std::endl;
+ return s;
+}
+
+Klass *make_null() {
+ return 0;
+}
+
+bool is_nullptr(Klass *p) {
+ return p == 0;
+}
+
+Klass *get_not_owned_ptr(Klass *p) {
+ return p;
+}
+
std::auto_ptr<Klass> makeKlassAutoPtr(const char* label) {
return std::auto_ptr<Klass>(new Klass(label));
}
+std::auto_ptr<Klass> makeNullAutoPtr() {
+ return std::auto_ptr<Klass>();
+}
+
+int overloadTest() {
+ return 0;
+}
+
+int overloadTest(std::auto_ptr<Klass> kover) {
+ return 1;
+}
+
+int overloadTest(Klass k) {
+ return 2;
+}
+
%}
#endif
diff --git a/Examples/test-suite/li_std_except.i b/Examples/test-suite/li_std_except.i
index 60bce999d..9bf70cd3f 100644
--- a/Examples/test-suite/li_std_except.i
+++ b/Examples/test-suite/li_std_except.i
@@ -9,6 +9,8 @@
%}
%inline %{
+ #include <stdexcept>
+ #include <typeinfo>
struct E1 : public std::exception
{
};
diff --git a/Examples/test-suite/li_std_vector.i b/Examples/test-suite/li_std_vector.i
index 33fb79720..64d057d75 100644
--- a/Examples/test-suite/li_std_vector.i
+++ b/Examples/test-suite/li_std_vector.i
@@ -140,3 +140,13 @@ std::vector<std::string> RevStringVec (const std::vector<std::string> &In)
return(result);
}
%}
+
+// regression test for Tcl typecheck bug with empty list fixed in 4.1.0
+%inline %{
+int sum(const std::vector<int> &v) {
+ return std::accumulate(v.begin(),v.end(),0);
+}
+int sum(int v) {
+ return v;
+}
+%}
diff --git a/Examples/test-suite/li_std_wstring.h b/Examples/test-suite/li_std_wstring.h
new file mode 100644
index 000000000..a16b7cd30
--- /dev/null
+++ b/Examples/test-suite/li_std_wstring.h
@@ -0,0 +1,5 @@
+// This file has a BOM set to UTF-8, which is one way for Visual C++ to correctly interpet these strings
+// Alternatively, the /utf-8 command line option could be used
+#define JP_WSTRING L"JP: 日本語"
+#define DE_WSTRING L"DE: Kröpeliner Straße"
+#define RU_WSTRING L"RU: Война и мир" \ No newline at end of file
diff --git a/Examples/test-suite/li_std_wstring.i b/Examples/test-suite/li_std_wstring.i
index a790ca7e0..88f80beb4 100644
--- a/Examples/test-suite/li_std_wstring.i
+++ b/Examples/test-suite/li_std_wstring.i
@@ -3,44 +3,71 @@
// The languages below are yet to provide std_wstring.i
#if !(defined(SWIGD) || defined(SWIGGO) || defined(SWIGGUILE) || defined(SWIGJAVASCRIPT) || defined(SWIGLUA) || defined(SWIGMZSCHEME) || defined(SWIGOCAML) || defined(SWIGOCTAVE) || defined(SWIGPERL) || defined(SWIGPHP) || defined(SWIGR) || defined(SWIGSCILAB))
+%warnfilter(SWIGWARN_TYPEMAP_WCHARLEAK_MSG) wchar_t_const_ptr_member; // Setting a const wchar_t * variable may leak memory.
+
%include <std_wstring.i>
+
// throw is invalid in C++17 and later, only SWIG to use it
#define TESTCASE_THROW1(T1) throw(T1)
%{
#define TESTCASE_THROW1(T1)
%}
+%{
+// Unicode strings are stored in li_std_wstring.h file which has the BOM appropriately set, primarily for Visual C++ to correctly interpret the wide strings
+#include "li_std_wstring.h"
+%}
+
%inline %{
#include <string>
+#include <iostream>
+
+bool trace = false;
+
+void show_wstring_bytes(const std::wstring &s) {
+ unsigned char *p = (unsigned char *)s.data();
+ size_t len = s.size()*sizeof(wchar_t);
+ std::wcout << L"s: " << /*s <<*/ L"[";
+ for (size_t i = 0; i<len; i++) {
+ std::wcout << std::hex << *p << L" ";
+ p++;
+ }
+ std::wcout << L"]" << std::endl;
+ std::wcout << std::flush;
+}
wchar_t test_wcvalue(wchar_t x) {
- return x;
+ return x;
}
const wchar_t* test_ccvalue(const wchar_t* x) {
- return x;
+ return x;
}
wchar_t* test_cvalue(wchar_t* x) {
- return x;
+ return x;
}
wchar_t* test_wchar_overload() {
- return 0;
+ return 0;
}
wchar_t* test_wchar_overload(wchar_t *x) {
- return x;
+ return x;
}
std::wstring test_value(std::wstring x) {
- return x;
+ if (trace) {
+ std::wcout << "received(C++): " /*<< x */<< std::endl;
+ show_wstring_bytes(x);
+ }
+ return x;
}
const std::wstring& test_const_reference(const std::wstring &x) {
- return x;
+ return x;
}
void test_pointer(std::wstring *x) {
@@ -52,13 +79,47 @@ void test_const_pointer(const std::wstring *x) {
void test_reference(std::wstring &x) {
}
+bool test_equal(const wchar_t *wcs, const std::wstring& s) {
+ if (trace) {
+ show_wstring_bytes(wcs);
+ show_wstring_bytes(s);
+ }
+ return wcs == s;
+}
+
bool test_equal_abc(const std::wstring &s) {
- return L"abc" == s;
+ return test_equal(L"abc", s);
+}
+
+bool test_equal_jp(const std::wstring &s) {
+ return test_equal(JP_WSTRING, s);
+}
+
+bool test_equal_de(const std::wstring &s) {
+ return test_equal(DE_WSTRING, s);
}
-void test_throw() TESTCASE_THROW1(std::wstring){
+bool test_equal_ru(const std::wstring &s) {
+ return test_equal(RU_WSTRING, s);
+}
+
+void test_throw() TESTCASE_THROW1(std::wstring) {
static std::wstring x = L"throwing test_throw";
-
+ throw x;
+}
+
+void test_throw_wchar_t_ptr() TESTCASE_THROW1(std::wstring) {
+ static std::wstring x = JP_WSTRING;
+ throw x;
+}
+
+void test_throw_jp() TESTCASE_THROW1(std::wstring) {
+ static std::wstring x = JP_WSTRING;
+ throw x;
+}
+
+void test_throw_ref_jp() TESTCASE_THROW1(const std::wstring&) {
+ static std::wstring x = JP_WSTRING;
throw x;
}
@@ -73,6 +134,8 @@ size_t size_wstring(const std::wstring& s) {
struct wchar_test_struct {
wchar_t wchar_t_member;
wchar_t* wchar_t_ptr_member;
+ const wchar_t* wchar_t_const_ptr_member;
+ wchar_test_struct() : wchar_t_member(), wchar_t_ptr_member(), wchar_t_const_ptr_member() {}
};
%}
diff --git a/Examples/test-suite/lua/Makefile.in b/Examples/test-suite/lua/Makefile.in
index 92559bb8f..af6735101 100644
--- a/Examples/test-suite/lua/Makefile.in
+++ b/Examples/test-suite/lua/Makefile.in
@@ -6,6 +6,10 @@ LANGUAGE = lua
LUA = @LUABIN@
SCRIPTSUFFIX = _runme.lua
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
@@ -53,7 +57,7 @@ run_testcase = \
env LUA_PATH="$(srcdir)/?.lua;" $(RUNTOOL) $(LUA) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
fi
-# Clean: (does nothing, we dont generate extra lua code)
+# Clean: (does nothing, we don't generate extra lua code)
%.clean:
@exit 0
diff --git a/Examples/test-suite/lua/argcargvtest_runme.lua b/Examples/test-suite/lua/argcargvtest_runme.lua
new file mode 100644
index 000000000..7f213665d
--- /dev/null
+++ b/Examples/test-suite/lua/argcargvtest_runme.lua
@@ -0,0 +1,26 @@
+require("import") -- the import fn
+import("argcargvtest") -- import lib
+v = argcargvtest
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+largs = {"hi", "hola", "hello"}
+assert(v.mainc(largs) == 3, "bad main typemap")
+
+targs = {"hi", "hola"}
+assert(v.mainv(targs, 1) == "hola", "bad main typemap")
+
+targs = {"hi", "hola"}
+assert(v.mainv(targs, 1) == "hola", "bad main typemap")
+
+errorVal = 0
+function try()
+ mainv("hello", 1)
+ errorVal = 1
+end
+assert(not pcall(try) and errorVal == 0, "bad main typemap")
+
+v.initializeApp(largs)
diff --git a/Examples/test-suite/lua/catches_strings_runme.lua b/Examples/test-suite/lua/catches_strings_runme.lua
new file mode 100644
index 000000000..b0dbaee0e
--- /dev/null
+++ b/Examples/test-suite/lua/catches_strings_runme.lua
@@ -0,0 +1,13 @@
+require("import") -- the import fn
+import("catches_strings") -- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+s, msg = pcall(function() catches_strings.StringsThrower.charstring() end)
+assert(s == false and msg:find("charstring message", 1, true))
+
+s, msg = pcall(function() catches_strings.StringsThrower.stdstring() end)
+assert(s == false and msg:find("stdstring message", 1, true))
diff --git a/Examples/test-suite/lua/cpp11_move_typemaps_runme.lua b/Examples/test-suite/lua/cpp11_move_typemaps_runme.lua
new file mode 100644
index 000000000..d8947b757
--- /dev/null
+++ b/Examples/test-suite/lua/cpp11_move_typemaps_runme.lua
@@ -0,0 +1,28 @@
+require("import") -- the import fn
+import("cpp11_move_typemaps") -- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+cpp11_move_typemaps.Counter.reset_counts()
+mo = cpp11_move_typemaps.MoveOnly(111)
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0)
+cpp11_move_typemaps.MoveOnly.take(mo)
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
+mo = nil
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+cpp11_move_typemaps.Counter.reset_counts()
+mo = cpp11_move_typemaps.MovableCopyable(111)
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0)
+cpp11_move_typemaps.MovableCopyable.take(mo)
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
+mo = nil
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+mo = cpp11_move_typemaps.MoveOnly(222)
+cpp11_move_typemaps.MoveOnly.take(mo)
+s, msg = pcall(function() cpp11_move_typemaps.MoveOnly.take(mo) end)
+assert(s == false and msg:find("Cannot release ownership as memory is not owned", 1, true))
diff --git a/Examples/test-suite/lua/cpp11_rvalue_reference_move_runme.lua b/Examples/test-suite/lua/cpp11_rvalue_reference_move_runme.lua
new file mode 100644
index 000000000..773760c8f
--- /dev/null
+++ b/Examples/test-suite/lua/cpp11_rvalue_reference_move_runme.lua
@@ -0,0 +1,66 @@
+require("import") -- the import fn
+import("cpp11_rvalue_reference_move") -- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+-- Function containing rvalue reference parameter
+cpp11_rvalue_reference_move.Counter.reset_counts()
+mo = cpp11_rvalue_reference_move.MovableCopyable(222)
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0)
+cpp11_rvalue_reference_move.MovableCopyable.movein(mo)
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2)
+if not (cpp11_rvalue_reference_move.MovableCopyable_is_nullptr(mo)) then
+ error("is_nullptr failed")
+end
+mo = nil
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+-- Move constructor test
+cpp11_rvalue_reference_move.Counter.reset_counts()
+mo = cpp11_rvalue_reference_move.MovableCopyable(222)
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0)
+mo_moved = cpp11_rvalue_reference_move.MovableCopyable(mo)
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1)
+if not (cpp11_rvalue_reference_move.MovableCopyable_is_nullptr(mo)) then
+ error("is_nullptr failed")
+end
+mo = nil
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1)
+mo_moved = nil
+collectgarbage() -- gc nudge needed here
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+-- Move assignment operator test
+cpp11_rvalue_reference_move.Counter.reset_counts()
+mo111 = cpp11_rvalue_reference_move.MovableCopyable(111)
+mo222 = cpp11_rvalue_reference_move.MovableCopyable(222)
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 0, 0)
+mo111:MoveAssign(mo222)
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
+if not (cpp11_rvalue_reference_move.MovableCopyable_is_nullptr(mo222)) then
+ error("is_nullptr failed")
+end
+mo222 = nil
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
+mo111 = nil
+collectgarbage() -- gc nudge needed here
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 2)
+
+-- null check
+cpp11_rvalue_reference_move.Counter.reset_counts()
+s, msg = pcall(function() cpp11_rvalue_reference_move.MovableCopyable.movein(nil) end)
+assert(s == false and msg:find("Error in MovableCopyable::movein (arg 1), expected 'MovableCopyable &&' got 'nil'", 1, true))
+cpp11_rvalue_reference_move.Counter.check_counts(0, 0, 0, 0, 0, 0)
+
+-- output
+cpp11_rvalue_reference_move.Counter.reset_counts()
+mc = cpp11_rvalue_reference_move.MovableCopyable.moveout(1234)
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
+cpp11_rvalue_reference_move.MovableCopyable.check_numbers_match(mc, 1234)
+
+s, msg = pcall(function() cpp11_rvalue_reference_move.MovableCopyable.movein(mc) end)
+assert(s == false and msg:find("Cannot release ownership as memory is not owned", 1, true))
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
diff --git a/Examples/test-suite/lua/cpp11_std_unique_ptr_runme.lua b/Examples/test-suite/lua/cpp11_std_unique_ptr_runme.lua
new file mode 100644
index 000000000..88d453e19
--- /dev/null
+++ b/Examples/test-suite/lua/cpp11_std_unique_ptr_runme.lua
@@ -0,0 +1,112 @@
+require("import") -- the import fn
+import("cpp11_std_unique_ptr") -- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+
+function checkCount(expected_count)
+ -- call gc to make unused objects are collected
+ collectgarbage()
+ actual_count = cpp11_std_unique_ptr.Klass.getTotal_count()
+ if not (actual_count == expected_count) then
+ error("Counts incorrect, expected:"..expected_count.." actual:"..actual_count)
+ end
+end
+
+--Test raw pointer handling involving virtual inheritance
+kini = cpp11_std_unique_ptr.KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = cpp11_std_unique_ptr.useKlassRawPtr(kini)
+if not (s == "KlassInheritanceInput") then
+ error("Incorrect string: "..s)
+end
+kini = nil
+checkCount(0)
+
+-- unique_ptr as input
+kin = cpp11_std_unique_ptr.Klass("KlassInput")
+checkCount(1)
+s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+checkCount(0)
+if not (s == "KlassInput") then
+ error("Incorrect string: "..s)
+end
+if not (cpp11_std_unique_ptr.is_nullptr(kin)) then
+ error("is_nullptr failed")
+end
+kin = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+kin = cpp11_std_unique_ptr.Klass("KlassInput")
+checkCount(1)
+s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+checkCount(0)
+if not (s == "KlassInput") then
+ error("Incorrect string: "..s)
+end
+if not (cpp11_std_unique_ptr.is_nullptr(kin)) then
+ error("is_nullptr failed")
+end
+s, msg = pcall(function() cpp11_std_unique_ptr.takeKlassUniquePtr(kin) end)
+assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassUniquePtr")
+
+kin = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+kin = cpp11_std_unique_ptr.Klass("KlassInput")
+notowned = cpp11_std_unique_ptr.get_not_owned_ptr(kin)
+s, msg = pcall(function() cpp11_std_unique_ptr.takeKlassUniquePtr(notowned) end)
+assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassUniquePtr")
+checkCount(1)
+kin = nil
+checkCount(0)
+
+kini = cpp11_std_unique_ptr.KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = cpp11_std_unique_ptr.takeKlassUniquePtr(kini)
+checkCount(0)
+if not (s == "KlassInheritanceInput") then
+ error("Incorrect string: "..s)
+end
+if not (cpp11_std_unique_ptr.is_nullptr(kini)) then
+ error("is_nullptr failed")
+end
+kini = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+cpp11_std_unique_ptr.takeKlassUniquePtr(nil);
+cpp11_std_unique_ptr.takeKlassUniquePtr(cpp11_std_unique_ptr.make_null());
+checkCount(0);
+
+-- overloaded parameters
+if not (cpp11_std_unique_ptr.overloadTest() == 0) then
+ error("overloadTest failed")
+end
+if not (cpp11_std_unique_ptr.overloadTest(nil) == 1) then
+ error("overloadTest failed")
+end
+if not (cpp11_std_unique_ptr.overloadTest(cpp11_std_unique_ptr.Klass("over")) == 1) then
+ error("overloadTest failed")
+end
+checkCount(0)
+
+
+-- unique_ptr as output
+k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first")
+k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second")
+checkCount(2)
+
+k1 = nil
+checkCount(1)
+
+if not (k2:getLabel() == "second") then
+ error("wrong object label")
+end
+
+k2 = nil
+checkCount(0)
+
+assert(cpp11_std_unique_ptr.makeNullUniquePtr() == nil)
diff --git a/Examples/test-suite/lua/exception_memory_leak_runme.lua b/Examples/test-suite/lua/exception_memory_leak_runme.lua
new file mode 100644
index 000000000..f3fc0f27b
--- /dev/null
+++ b/Examples/test-suite/lua/exception_memory_leak_runme.lua
@@ -0,0 +1,29 @@
+require("import") -- the import fn
+import("exception_memory_leak") -- import code
+eml=exception_memory_leak --alias
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+a = eml.Foo()
+assert(eml.Foo_get_count() == 1)
+b = eml.Foo()
+assert(eml.Foo_get_count() == 2)
+
+-- Normal behaviour
+eml.trigger_internal_swig_exception("no problem", a)
+assert(eml.Foo_get_count() == 2)
+assert(eml.Foo_get_freearg_count() == 1)
+
+-- SWIG exception triggered and handled (return new object case)
+ok,ex=pcall(eml.trigger_internal_swig_exception, "null", b)
+assert(ok==false)
+assert(eml.Foo_get_count() == 2)
+assert(eml.Foo_get_freearg_count() == 2)
+
+-- SWIG exception triggered and handled (return by value case).
+ok,ex=pcall(eml.trigger_internal_swig_exception, "null")
+assert(ok==false)
+assert(eml.Foo_get_count() == 2)
diff --git a/Examples/test-suite/lua/li_std_auto_ptr_runme.lua b/Examples/test-suite/lua/li_std_auto_ptr_runme.lua
new file mode 100644
index 000000000..118a62f01
--- /dev/null
+++ b/Examples/test-suite/lua/li_std_auto_ptr_runme.lua
@@ -0,0 +1,112 @@
+require("import") -- the import fn
+import("li_std_auto_ptr") -- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+
+function checkCount(expected_count)
+ -- call gc to make unused objects are collected
+ collectgarbage()
+ actual_count = li_std_auto_ptr.Klass.getTotal_count()
+ if not (actual_count == expected_count) then
+ error("Counts incorrect, expected:"..expected_count.." actual:"..actual_count)
+ end
+end
+
+--Test raw pointer handling involving virtual inheritance
+kini = li_std_auto_ptr.KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = li_std_auto_ptr.useKlassRawPtr(kini)
+if not (s == "KlassInheritanceInput") then
+ error("Incorrect string: "..s)
+end
+kini = nil
+checkCount(0)
+
+-- auto_ptr as input
+kin = li_std_auto_ptr.Klass("KlassInput")
+checkCount(1)
+s = li_std_auto_ptr.takeKlassAutoPtr(kin)
+checkCount(0)
+if not (s == "KlassInput") then
+ error("Incorrect string: "..s)
+end
+if not (li_std_auto_ptr.is_nullptr(kin)) then
+ error("is_nullptr failed")
+end
+kin = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+kin = li_std_auto_ptr.Klass("KlassInput")
+checkCount(1)
+s = li_std_auto_ptr.takeKlassAutoPtr(kin)
+checkCount(0)
+if not (s == "KlassInput") then
+ error("Incorrect string: "..s)
+end
+if not (li_std_auto_ptr.is_nullptr(kin)) then
+ error("is_nullptr failed")
+end
+s, msg = pcall(function() li_std_auto_ptr.takeKlassAutoPtr(kin) end)
+assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassAutoPtr")
+
+kin = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+kin = li_std_auto_ptr.Klass("KlassInput")
+notowned = li_std_auto_ptr.get_not_owned_ptr(kin)
+s, msg = pcall(function() li_std_auto_ptr.takeKlassAutoPtr(notowned) end)
+assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassAutoPtr")
+checkCount(1)
+kin = nil
+checkCount(0)
+
+kini = li_std_auto_ptr.KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = li_std_auto_ptr.takeKlassAutoPtr(kini)
+checkCount(0)
+if not (s == "KlassInheritanceInput") then
+ error("Incorrect string: "..s)
+end
+if not (li_std_auto_ptr.is_nullptr(kini)) then
+ error("is_nullptr failed")
+end
+kini = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+li_std_auto_ptr.takeKlassAutoPtr(nil);
+li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
+checkCount(0);
+
+-- overloaded parameters
+if not (li_std_auto_ptr.overloadTest() == 0) then
+ error("overloadTest failed")
+end
+if not (li_std_auto_ptr.overloadTest(nil) == 1) then
+ error("overloadTest failed")
+end
+if not (li_std_auto_ptr.overloadTest(li_std_auto_ptr.Klass("over")) == 1) then
+ error("overloadTest failed")
+end
+checkCount(0)
+
+
+-- auto_ptr as output
+k1 = li_std_auto_ptr.makeKlassAutoPtr("first")
+k2 = li_std_auto_ptr.makeKlassAutoPtr("second")
+checkCount(2)
+
+k1 = nil
+checkCount(1)
+
+if not (k2:getLabel() == "second") then
+ error("wrong object label")
+end
+
+k2 = nil
+checkCount(0)
+
+assert(li_std_auto_ptr.makeNullAutoPtr() == nil)
diff --git a/Examples/test-suite/lua/li_std_string_runme.lua b/Examples/test-suite/lua/li_std_string_runme.lua
index a36bf7ef6..40de81e44 100644
--- a/Examples/test-suite/lua/li_std_string_runme.lua
+++ b/Examples/test-suite/lua/li_std_string_runme.lua
@@ -36,7 +36,7 @@ test_const_pointer(cobj)
-- swig doesn't appear to diff between const object ptrs & object ptrs very well
test_pointer(cobj) -- this wants an non const object (give it a const one!)
--- refs are also wrappered as ptrs (unless the correct typemaps are applied)
+-- refs are also wrapped as ptrs (unless the correct typemaps are applied)
robj=test_reference_out()
assert(is_std_string(robj) and robj:c_str()=="test_reference_out message") -- check type & value
diff --git a/Examples/test-suite/memberin_extend.i b/Examples/test-suite/memberin_extend.i
index c6eb10526..43251973f 100644
--- a/Examples/test-suite/memberin_extend.i
+++ b/Examples/test-suite/memberin_extend.i
@@ -11,6 +11,7 @@ struct ExtendMe {
%{
#include <map>
+#include <string.h>
std::map<ExtendMe*, char *> ExtendMeStringMap;
void ExtendMe_thing_set(ExtendMe *self, const char *val) {
char *old_val = ExtendMeStringMap[self];
diff --git a/Examples/test-suite/minherit2.i b/Examples/test-suite/minherit2.i
index 2baea6495..965225c07 100644
--- a/Examples/test-suite/minherit2.i
+++ b/Examples/test-suite/minherit2.i
@@ -40,18 +40,18 @@ $importtype(IRemoteAsyncIO)
#endif
// Modify multiple inherited base classes into inheriting interfaces
-%typemap(javainterfaces) RemoteMpe "IRemoteSyncIO, IRemoteAsyncIO";
-%typemap(javabase, replace="1") RemoteMpe "";
+%typemap(javainterfaces) RemoteMpe "IRemoteSyncIO, IRemoteAsyncIO"
+%typemap(javabase, replace="1") RemoteMpe ""
// Turn the proxy class into an interface
-%typemap(javaclassmodifiers) IRemoteSyncIO "public interface";
-%typemap(javaclassmodifiers) IRemoteAsyncIO "public interface";
-%typemap(javabody) IRemoteSyncIO "";
-%typemap(javabody) IRemoteAsyncIO "";
-%typemap(javafinalize) IRemoteSyncIO "";
-%typemap(javafinalize) IRemoteAsyncIO "";
-%typemap(javadestruct) IRemoteSyncIO "";
-%typemap(javadestruct) IRemoteAsyncIO "";
+%typemap(javaclassmodifiers) IRemoteSyncIO "public interface"
+%typemap(javaclassmodifiers) IRemoteAsyncIO "public interface"
+%typemap(javabody) IRemoteSyncIO ""
+%typemap(javabody) IRemoteAsyncIO ""
+%typemap(javafinalize) IRemoteSyncIO ""
+%typemap(javafinalize) IRemoteAsyncIO ""
+%typemap(javadestruct) IRemoteSyncIO ""
+%typemap(javadestruct) IRemoteAsyncIO ""
// Turn the methods into abstract methods
%typemap(javaout) void IRemoteSyncIO::syncmethod ";"
diff --git a/Examples/test-suite/mod.h b/Examples/test-suite/mod.h
index aae629850..60eb36b77 100644
--- a/Examples/test-suite/mod.h
+++ b/Examples/test-suite/mod.h
@@ -1,4 +1,4 @@
-
+#include <cstddef>
class C;
diff --git a/Examples/test-suite/multi_import.h b/Examples/test-suite/multi_import.h
index fa7a460e9..f893e3de0 100644
--- a/Examples/test-suite/multi_import.h
+++ b/Examples/test-suite/multi_import.h
@@ -1,3 +1,11 @@
+#ifndef MULTI_IMPORT_H
+#define MULTI_IMPORT_H
+
+class WWW {
+ public:
+ void nullop() const {}
+};
+
class XXX
{
public:
@@ -15,3 +23,5 @@ class ZZZ : public XXX
public:
int testz() { return 2;}
};
+
+#endif /* MULTI_IMPORT_H */
diff --git a/Examples/test-suite/multi_import.list b/Examples/test-suite/multi_import.list
index 6f7f98cae..a42944f48 100644
--- a/Examples/test-suite/multi_import.list
+++ b/Examples/test-suite/multi_import.list
@@ -1,2 +1,3 @@
-multi_import_a
+multi_import_d
multi_import_b
+multi_import_a
diff --git a/Examples/test-suite/multi_import_a.i b/Examples/test-suite/multi_import_a.i
index 62d7cc0b8..7cb311051 100644
--- a/Examples/test-suite/multi_import_a.i
+++ b/Examples/test-suite/multi_import_a.i
@@ -2,7 +2,8 @@
%module multi_import_a
-%import multi_import_b.i
+%import multi_import_d.i
+%import "multi_import_b.i"
%{
#include "multi_import.h"
@@ -13,3 +14,7 @@ class ZZZ : public XXX
public:
int testz();
};
+
+%inline %{
+void use_www_a(const WWW& w) {w.nullop();}
+%}
diff --git a/Examples/test-suite/multi_import_b.i b/Examples/test-suite/multi_import_b.i
index a2be27055..f19608292 100644
--- a/Examples/test-suite/multi_import_b.i
+++ b/Examples/test-suite/multi_import_b.i
@@ -11,3 +11,7 @@ class YYY : public XXX
public:
int testy();
};
+
+%inline %{
+void use_www_b(const WWW& w) {w.nullop();}
+%}
diff --git a/Examples/test-suite/multi_import_c.i b/Examples/test-suite/multi_import_c.i
index 854e6b136..0e5a02e74 100644
--- a/Examples/test-suite/multi_import_c.i
+++ b/Examples/test-suite/multi_import_c.i
@@ -1,3 +1,8 @@
+%import "multi_import_d.i"
+
+// NB: this module is only imported, never compiled, so it's not necessary to
+// include the header for testing purposes.
+
class XXX
{
public:
diff --git a/Examples/test-suite/multi_import_d.i b/Examples/test-suite/multi_import_d.i
new file mode 100644
index 000000000..bb9cf0137
--- /dev/null
+++ b/Examples/test-suite/multi_import_d.i
@@ -0,0 +1,12 @@
+%module multi_import_d
+
+%constant int myval = 1234;
+
+%{
+#include "multi_import.h"
+%}
+
+class WWW {
+ public:
+ void nullop() const;
+};
diff --git a/Examples/test-suite/multiple_inheritance_abstract.i b/Examples/test-suite/multiple_inheritance_abstract.i
index 9ac16a235..aea330d39 100644
--- a/Examples/test-suite/multiple_inheritance_abstract.i
+++ b/Examples/test-suite/multiple_inheritance_abstract.i
@@ -1,11 +1,10 @@
-// This is a copy of the multiple_inheritance_abstract test
%module(ruby_minherit="1") multiple_inheritance_abstract
%warnfilter(SWIGWARN_D_MULTIPLE_INHERITANCE,
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
-%include "swiginterface.i"
+%include <swiginterface.i>
%interface_impl(Space::ABase1)
%interface_impl(Space::CBase1)
%interface_impl(Space::CBase2)
diff --git a/Examples/test-suite/multiple_inheritance_interfaces.i b/Examples/test-suite/multiple_inheritance_interfaces.i
index 6bb1d50cb..891e20f72 100644
--- a/Examples/test-suite/multiple_inheritance_interfaces.i
+++ b/Examples/test-suite/multiple_inheritance_interfaces.i
@@ -4,7 +4,7 @@
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
-%include "swiginterface.i"
+%include <swiginterface.i>
%interface_custom("A", "IA", IA)
%interface_custom("B", "IB", IB)
%interface_custom("%(strip:[I])s", "I%s", IC) // same as %interface_custom("C", "IC", IC)
@@ -50,6 +50,33 @@ struct W : T {};
%}
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
+%interface_impl(Undesirables);
+#endif
+
+%inline %{
+// Don't put variables and enums into interface
+class Undesirables
+{
+public:
+ Undesirables() : UndesiredVariable() {}
+ virtual ~Undesirables() {}
+ virtual void Method(int i) = 0;
+
+ enum UndesiredEnum { UndesiredEnum1, UndesiredEnum2 };
+ static void UndesiredStaticMethod(UndesiredEnum e) {}
+ int UndesiredVariable;
+ static int UndesiredStaticVariable;
+ static const int UndesiredStaticConstVariable = 0;
+};
+
+int Undesirables::UndesiredStaticVariable = 0;
+
+struct UndesirablesDerived : Undesirables {
+ virtual void Method(int i) {}
+};
+%}
+
+#if defined(SWIGJAVA) || defined(SWIGCSHARP)
%interface_impl(BaseOverloaded);
#endif
%inline %{
diff --git a/Examples/test-suite/multiple_inheritance_nspace.i b/Examples/test-suite/multiple_inheritance_nspace.i
index 002e6d6ee..f82285fcf 100644
--- a/Examples/test-suite/multiple_inheritance_nspace.i
+++ b/Examples/test-suite/multiple_inheritance_nspace.i
@@ -10,7 +10,7 @@
#endif
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
-%include "swiginterface.i"
+%include <swiginterface.i>
%interface(Space::ABase1)
%interface(Space::CBase1)
%interface(Space::CBase2)
diff --git a/Examples/test-suite/multiple_inheritance_overload.i b/Examples/test-suite/multiple_inheritance_overload.i
new file mode 100644
index 000000000..237ebd6f1
--- /dev/null
+++ b/Examples/test-suite/multiple_inheritance_overload.i
@@ -0,0 +1,67 @@
+%module(ruby_minherit="1") multiple_inheritance_overload
+
+%warnfilter(SWIGWARN_D_MULTIPLE_INHERITANCE,
+ SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
+
+#if defined(SWIGJAVA) || defined(SWIGCSHARP)
+%include <swiginterface.i>
+%interface_impl(Space::Base);
+%interface_impl(Space::AnotherBase);
+#endif
+
+%ignore AnotherSpace::AnotherBase::AnotherMethod(int i) const;
+%ignore Space::Base::Method(int i) const;
+%ignore Space::Base::NotVirtualMethod(int i) const;
+%ignore Space::Base::SimilarOverloadedMethod(unsigned short i);
+%rename(MethodForRenamingConst) Space::Base::MethodForRenaming(int i) const;
+
+// Different overloaded warning filters needed for scripting languages (eg Python) and for statically typed languages (eg C#).
+%warnfilter(509, 516) Space::Base::MethodWarningSuppressed(int i) const;
+
+%inline %{
+namespace AnotherSpace {
+class AnotherBase {
+public:
+ virtual int AnotherMethod(int i) { return 0; }
+ virtual int AnotherMethod(int i) const { return 1; }
+ virtual ~AnotherBase() {}
+};
+}
+
+namespace Space {
+class Base
+{
+public:
+ virtual int Method(int i) { return 0; }
+ virtual int Method(int i) const { return 1; }
+ virtual int MethodForRenaming(int i) { return 0; }
+ virtual int MethodForRenaming(int i) const { return 1; }
+ virtual int MethodWarningSuppressed(int i) { return 0; }
+ virtual int MethodWarningSuppressed(int i) const { return 1; }
+ int NotVirtualMethod(int i) { return 0; }
+ int NotVirtualMethod(int i) const { return 1; }
+
+ typedef int Integer;
+
+ // int and unsigned short are wrapped with a Java int and so would be automatically ignored with a warning
+ virtual int SimilarOverloadedMethod(Integer i) { return 0; }
+ virtual int SimilarOverloadedMethod(unsigned short i) { return 1; }
+ virtual ~Base() {}
+ static Base *in_out(Base *p) { return p; }
+};
+
+class Derived : public Base, public AnotherSpace::AnotherBase
+{
+public:
+ int member_var;
+};
+class MoreDerived : public Derived {
+};
+}
+
+namespace OtherSpace {
+class OtherDerived : public Space::Base
+{
+};
+}
+%}
diff --git a/Examples/test-suite/multiple_inheritance_shared_ptr.i b/Examples/test-suite/multiple_inheritance_shared_ptr.i
index 061db57d9..d68e12d04 100644
--- a/Examples/test-suite/multiple_inheritance_shared_ptr.i
+++ b/Examples/test-suite/multiple_inheritance_shared_ptr.i
@@ -48,7 +48,7 @@
%shared_ptr(Space::Bottom2)
%shared_ptr(Space::Bottom3)
-%include "swiginterface.i"
+%include <swiginterface.i>
SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::ABase1)
SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::CBase1)
SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::CBase2)
diff --git a/Examples/test-suite/mzscheme/Makefile.in b/Examples/test-suite/mzscheme/Makefile.in
index 6a8ef74e4..212379ca8 100644
--- a/Examples/test-suite/mzscheme/Makefile.in
+++ b/Examples/test-suite/mzscheme/Makefile.in
@@ -6,6 +6,10 @@ LANGUAGE = mzscheme
MZSCHEME = mzscheme
SCRIPTSUFFIX = _runme.scm
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
@@ -19,6 +23,11 @@ char_strings \
chartest \
class_scope_weird \
constant_pointers \
+cpp11_alternate_function_syntax \
+cpp11_director_enums \
+cpp11_ref_qualifiers \
+cpp11_rvalue_reference2 \
+cpp11_strongly_typed_enumerations \
cpp_basic \
cpp_enum \
curiously_recurring_template_pattern \
diff --git a/Examples/test-suite/mzscheme/catches_strings_runme.scm b/Examples/test-suite/mzscheme/catches_strings_runme.scm
new file mode 100644
index 000000000..745a7cf0a
--- /dev/null
+++ b/Examples/test-suite/mzscheme/catches_strings_runme.scm
@@ -0,0 +1,18 @@
+(load-extension "catches_strings.so")
+(require (lib "defmacro.ss"))
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+ (set! exception_thrown (exn-message exn)))])
+ (StringsThrower-charstring))
+(unless (string-contains? exception_thrown "charstring message")
+ (error (format "incorrect exception message: ~a" exception_thrown)))
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+ (set! exception_thrown (exn-message exn)))])
+ (StringsThrower-stdstring))
+(unless (string-contains? exception_thrown "stdstring message")
+ (error (format "incorrect exception message: ~a" exception_thrown)))
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/cpp11_move_typemaps_runme.scm b/Examples/test-suite/mzscheme/cpp11_move_typemaps_runme.scm
new file mode 100644
index 000000000..910cb3938
--- /dev/null
+++ b/Examples/test-suite/mzscheme/cpp11_move_typemaps_runme.scm
@@ -0,0 +1,35 @@
+(load-extension "cpp11_move_typemaps.so")
+(require (lib "defmacro.ss"))
+
+; Copied from ../schemerunme/cpp11_move_typemaps.scm and modified for exceptions
+
+; Define an equivalent to Guile's gc procedure
+(define-macro (gc)
+ `(collect-garbage 'major))
+
+(Counter-reset-counts)
+(define mo (new-MoveOnly 111))
+(Counter-check-counts 1 0 0 0 0 0)
+(MoveOnly-take mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(delete-MoveOnly mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 111))
+(Counter-check-counts 1 0 0 0 0 0)
+(MovableCopyable-take mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+(define mo (new-MoveOnly 222))
+(MoveOnly-take mo)
+(define exception_thrown "no exception thrown for mo")
+(with-handlers ([exn:fail? (lambda (exn)
+ (set! exception_thrown (exn-message exn)))])
+ (MoveOnly-take mo))
+(unless (string-contains? exception_thrown "cannot release ownership as memory is not owned")
+ (error "Wrong or no exception thrown: " exception_thrown))
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_runme.scm b/Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_runme.scm
new file mode 100644
index 000000000..6c68fef12
--- /dev/null
+++ b/Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_runme.scm
@@ -0,0 +1,68 @@
+(load-extension "cpp11_rvalue_reference_move.so")
+(require (lib "defmacro.ss"))
+
+; Copied from ../schemerunme/cpp11_rvalue_reference_move.scm and modified for exceptions
+
+; Function containing rvalue reference parameter
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 222))
+(Counter-check-counts 1 0 0 0 0 0)
+(MovableCopyable-movein mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(unless (MovableCopyable-is-nullptr mo)
+ (error "is_nullptr failed"))
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+; Move constructor test
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 222))
+(Counter-check-counts 1 0 0 0 0 0)
+(define mo_moved (new-MovableCopyable mo))
+(Counter-check-counts 1 0 0 1 0 1)
+(unless (MovableCopyable-is-nullptr mo)
+ (error "is_nullptr failed"))
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 1)
+(delete-MovableCopyable mo_moved)
+(Counter-check-counts 1 0 0 1 0 2)
+
+; Move assignment operator test
+(Counter-reset-counts)
+(define mo111 (new-MovableCopyable 111))
+(define mo222 (new-MovableCopyable 222))
+(Counter-check-counts 2 0 0 0 0 0)
+(MovableCopyable-MoveAssign mo111 mo222)
+(Counter-check-counts 2 0 0 0 1 1)
+(unless (MovableCopyable-is-nullptr mo222)
+ (error "is_nullptr failed"))
+(delete-MovableCopyable mo222)
+(Counter-check-counts 2 0 0 0 1 1)
+(delete-MovableCopyable mo111)
+(Counter-check-counts 2 0 0 0 1 2)
+
+; null check
+(Counter-reset-counts)
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+ (set! exception_thrown (exn-message exn)))])
+ (MovableCopyable-movein '()))
+(unless (string=? exception_thrown "MovableCopyable-movein: swig-type-error (null reference)")
+ (error (format "incorrect exception message: ~a" exception_thrown)))
+(Counter-check-counts 0 0 0 0 0 0)
+
+; output
+(Counter-reset-counts)
+(define mc (MovableCopyable-moveout 1234))
+(Counter-check-counts 2 0 0 0 1 1)
+(MovableCopyable-check-numbers-match mc 1234)
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+ (set! exception_thrown (exn-message exn)))])
+ (MovableCopyable-movein mc))
+(unless (string-contains? exception_thrown "cannot release ownership as memory is not owned")
+ (error (format "incorrect exception message: ~a" exception_thrown)))
+(Counter-check-counts 2 0 0 0 1 1)
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/cpp11_std_unique_ptr_runme.scm b/Examples/test-suite/mzscheme/cpp11_std_unique_ptr_runme.scm
new file mode 100644
index 000000000..cd0e18038
--- /dev/null
+++ b/Examples/test-suite/mzscheme/cpp11_std_unique_ptr_runme.scm
@@ -0,0 +1,109 @@
+(load-extension "cpp11_std_unique_ptr.so")
+(require (lib "defmacro.ss"))
+
+; Copied from ../schemerunme/cpp11_std_unique_ptr.scm and modified for exceptions
+
+; Define an equivalent to Guile's gc procedure
+(define-macro (gc)
+ `(collect-garbage 'major))
+
+(define checkCount
+ (lambda (expected-count)
+ (define actual-count (Klass-getTotal-count))
+ (unless (= actual-count expected-count) (error (format "Counts incorrect, expected:~a actual:~a" expected-count actual-count)))))
+
+; Test raw pointer handling involving virtual inheritance
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (useKlassRawPtr kini))
+(unless (string=? s "KlassInheritanceInput")
+ (error "Incorrect string: " s))
+(set! kini '()) (gc)
+(checkCount 0)
+
+; unique_ptr as input
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+ (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+ (error "is_nullptr failed"))
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+ (set! exception_thrown (exn-message exn)))])
+ (takeKlassUniquePtr kin))
+(unless (string=? exception_thrown "takeKlassUniquePtr: cannot release ownership as memory is not owned for argument 1 of type 'Klass *'")
+ (error "Wrong or no exception thrown: " exception_thrown))
+(set! kin '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(define notowned (get-not-owned-ptr kin))
+(set! exception_thrown "no exception thrown for notowned")
+(with-handlers ([exn:fail? (lambda (exn)
+ (set! exception_thrown (exn-message exn)))])
+ (takeKlassUniquePtr notowned))
+(unless (string=? exception_thrown "takeKlassUniquePtr: cannot release ownership as memory is not owned for argument 1 of type 'Klass *'")
+ (error "Wrong or no exception thrown: " exception_thrown))
+(checkCount 1)
+(set! kin '()) (gc)
+(checkCount 0)
+
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kini))
+(checkCount 0)
+(unless (string=? s "KlassInheritanceInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kini)
+ (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define null '())
+(takeKlassUniquePtr null)
+(takeKlassUniquePtr (make-null))
+(checkCount 0)
+
+; overloaded parameters
+(unless (= (overloadTest) 0)
+ (error "overloadTest failed"))
+(unless (= (overloadTest null) 1)
+ (error "overloadTest failed"))
+(unless (= (overloadTest (new-Klass "over")) 1)
+ (error "overloadTest failed"))
+(checkCount 0)
+
+
+; unique_ptr as output
+(define k1 (makeKlassUniquePtr "first"))
+(define k2 (makeKlassUniquePtr "second"))
+(checkCount 2)
+
+(set! k1 '()) (gc)
+(checkCount 1)
+
+(unless (string=? (Klass-getLabel k2) "second")
+ (error "wrong object label" ))
+
+(set! k2 '()) (gc)
+(checkCount 0)
+
+(unless (null? (makeNullUniquePtr))
+ (error "null failure"))
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/integers_runme.scm b/Examples/test-suite/mzscheme/integers_runme.scm
index 03c802166..e2e881702 100644
--- a/Examples/test-suite/mzscheme/integers_runme.scm
+++ b/Examples/test-suite/mzscheme/integers_runme.scm
@@ -6,4 +6,4 @@
,form
#f))
-(load "../schemerunme/integers.scm")
+(load (build-path (path-only (path->complete-path (find-system-path 'run-file))) "../schemerunme/integers.scm"))
diff --git a/Examples/test-suite/mzscheme/li_std_auto_ptr_runme.scm b/Examples/test-suite/mzscheme/li_std_auto_ptr_runme.scm
new file mode 100644
index 000000000..c6c43dba0
--- /dev/null
+++ b/Examples/test-suite/mzscheme/li_std_auto_ptr_runme.scm
@@ -0,0 +1,109 @@
+(load-extension "li_std_auto_ptr.so")
+(require (lib "defmacro.ss"))
+
+; Copied from ../schemerunme/li_std_auto_ptr.scm and modified for exceptions
+
+; Define an equivalent to Guile's gc procedure
+(define-macro (gc)
+ `(collect-garbage 'major))
+
+(define checkCount
+ (lambda (expected-count)
+ (define actual-count (Klass-getTotal-count))
+ (unless (= actual-count expected-count) (error (format "Counts incorrect, expected:~a actual:~a" expected-count actual-count)))))
+
+; Test raw pointer handling involving virtual inheritance
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (useKlassRawPtr kini))
+(unless (string=? s "KlassInheritanceInput")
+ (error "Incorrect string: " s))
+(set! kini '()) (gc)
+(checkCount 0)
+
+; auto_ptr as input
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+ (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+ (error "is_nullptr failed"))
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+ (set! exception_thrown (exn-message exn)))])
+ (takeKlassAutoPtr kin))
+(unless (string=? exception_thrown "takeKlassAutoPtr: cannot release ownership as memory is not owned for argument 1 of type 'Klass *'")
+ (error "Wrong or no exception thrown: " exception_thrown))
+(set! kin '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(define notowned (get-not-owned-ptr kin))
+(set! exception_thrown "no exception thrown for notowned")
+(with-handlers ([exn:fail? (lambda (exn)
+ (set! exception_thrown (exn-message exn)))])
+ (takeKlassAutoPtr notowned))
+(unless (string=? exception_thrown "takeKlassAutoPtr: cannot release ownership as memory is not owned for argument 1 of type 'Klass *'")
+ (error "Wrong or no exception thrown: " exception_thrown))
+(checkCount 1)
+(set! kin '()) (gc)
+(checkCount 0)
+
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kini))
+(checkCount 0)
+(unless (string=? s "KlassInheritanceInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kini)
+ (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define null '())
+(takeKlassAutoPtr null)
+(takeKlassAutoPtr (make-null))
+(checkCount 0)
+
+; overloaded parameters
+(unless (= (overloadTest) 0)
+ (error "overloadTest failed"))
+(unless (= (overloadTest null) 1)
+ (error "overloadTest failed"))
+(unless (= (overloadTest (new-Klass "over")) 1)
+ (error "overloadTest failed"))
+(checkCount 0)
+
+
+; auto_ptr as output
+(define k1 (makeKlassAutoPtr "first"))
+(define k2 (makeKlassAutoPtr "second"))
+(checkCount 2)
+
+(set! k1 '()) (gc)
+(checkCount 1)
+
+(unless (string=? (Klass-getLabel k2) "second")
+ (error "wrong object label" ))
+
+(set! k2 '()) (gc)
+(checkCount 0)
+
+(unless (null? (makeNullAutoPtr))
+ (error "null failure"))
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/newobject1_runme.scm b/Examples/test-suite/mzscheme/newobject1_runme.scm
new file mode 100644
index 000000000..17333ed5c
--- /dev/null
+++ b/Examples/test-suite/mzscheme/newobject1_runme.scm
@@ -0,0 +1,9 @@
+(load-extension "newobject1.so")
+
+(require (lib "defmacro.ss"))
+
+; Define an equivalent to Guile's gc procedure
+(define-macro (gc)
+ `(collect-garbage 'major))
+
+(load (build-path (path-only (path->complete-path (find-system-path 'run-file))) "../schemerunme/newobject1.scm"))
diff --git a/Examples/test-suite/mzscheme/null_pointer_runme.scm b/Examples/test-suite/mzscheme/null_pointer_runme.scm
new file mode 100644
index 000000000..35f83a4f8
--- /dev/null
+++ b/Examples/test-suite/mzscheme/null_pointer_runme.scm
@@ -0,0 +1,3 @@
+(load-extension "null_pointer.so")
+
+(load (build-path (path-only (path->complete-path (find-system-path 'run-file))) "../schemerunme/null_pointer.scm"))
diff --git a/Examples/test-suite/name_warnings.i b/Examples/test-suite/name_warnings.i
index 0b62ec5d7..12e46ac9d 100644
--- a/Examples/test-suite/name_warnings.i
+++ b/Examples/test-suite/name_warnings.i
@@ -69,3 +69,20 @@ namespace std
#endif
double bar(double native, bool boolean) { return 1.0; }
}
+
+// Test that anonymous template instantiations are ignored from
+// %rename/%namewarn
+%namewarn(%warningmsg(SWIGWARN_LANG_IDENTIFIER, "incorrectly warning about non-wrapped instantiated template"), error=1) "__dummy_0__";
+%inline %{
+template<typename T> struct Foo {
+ typedef T value_type;
+};
+%}
+%template() Foo<int>;
+
+// But they should still generate the correct typemaps etc
+%inline %{
+int double_an_int(Foo<int>::value_type v) {
+ return v * 2;
+}
+%}
diff --git a/Examples/test-suite/namespace_struct.i b/Examples/test-suite/namespace_struct.i
new file mode 100644
index 000000000..2d2bf555a
--- /dev/null
+++ b/Examples/test-suite/namespace_struct.i
@@ -0,0 +1,8 @@
+%module namespace_struct
+
+%inline %{
+
+// SWIG/R generated bad code for copyToR for a struct in a namespace in SWIG < 4.1.0
+namespace X { struct Y { int x, y; }; }
+
+%}
diff --git a/Examples/test-suite/namespace_typemap.i b/Examples/test-suite/namespace_typemap.i
index 9c74715f0..2571b5a81 100644
--- a/Examples/test-suite/namespace_typemap.i
+++ b/Examples/test-suite/namespace_typemap.i
@@ -2,6 +2,7 @@
%module namespace_typemap
%{
+#include <string.h>
namespace test {
/* A minimalistic string class */
class string_class {
@@ -15,7 +16,7 @@ namespace test {
strcpy(data,s);
}
~string_class() {
- if (data) delete [] data;
+ delete [] data;
}
char *c_str() {
return data;
diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i
index b10c33949..cb9f27b31 100644
--- a/Examples/test-suite/nested_class.i
+++ b/Examples/test-suite/nested_class.i
@@ -133,8 +133,13 @@ struct Outer {
Integer x;
} InnerClass4Typedef;
-#ifdef _MSC_VER
- int Outer::foo(){ return 1; } // should correctly ignore qualification here (#508)
+#ifdef SWIG
+ // SWIG should ignore the redundant qualification here (#508)...
+ int Outer::foo(){ return 1; }
+#else
+ // ..but that redundant qualification is actually invalid and many compilers
+ // now reject it with an error, so feed a valid version to the compiler.
+ int foo(){ return 1; }
#endif
typedef struct {
@@ -201,7 +206,7 @@ struct Outer {
Integer xx;
} MultipleInstanceAnonDerived1, MultipleInstanceAnonDerived2, *MultipleInstanceAnonDerived3, MultipleInstanceAnonDerived4[2];
-#if defined(__GNUC__) || defined(_MSC_VER) || defined(SWIG)
+#if (defined(__GNUC__) && __GNUC__ < 12) || defined(_MSC_VER) || defined(SWIG)
/* some compilers do not accept these */
struct : public InnerMultiple {
Integer xx;
diff --git a/Examples/test-suite/nested_extend_c.i b/Examples/test-suite/nested_extend_c.i
index f1d7ff2c8..67ca86578 100644
--- a/Examples/test-suite/nested_extend_c.i
+++ b/Examples/test-suite/nested_extend_c.i
@@ -12,6 +12,10 @@
#endif
+%{
+#include "stdlib.h"
+%}
+
#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8)
%extend hiA {
hiA() {
diff --git a/Examples/test-suite/nested_inheritance_interface.i b/Examples/test-suite/nested_inheritance_interface.i
index f8335c0af..09238eadf 100644
--- a/Examples/test-suite/nested_inheritance_interface.i
+++ b/Examples/test-suite/nested_inheritance_interface.i
@@ -5,7 +5,7 @@
SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance or %interface */
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
-%include "swiginterface.i"
+%include <swiginterface.i>
%interface(IA)
#endif
diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in
index c44f02a72..ffd62049d 100644
--- a/Examples/test-suite/ocaml/Makefile.in
+++ b/Examples/test-suite/ocaml/Makefile.in
@@ -9,6 +9,10 @@ OCAMLPP = -pp "camlp4o ./swigp4.cmo"
VARIANT = _static
SCRIPTSUFFIX = _runme.ml
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
@@ -17,6 +21,8 @@ FAILING_CPP_TESTS = \
allprotected \
apply_signed_char \
apply_strings \
+cpp11_director_enums \
+cpp11_strongly_typed_enumerations \
cpp_enum \
default_constructor \
director_binary_string \
@@ -25,10 +31,12 @@ director_enum \
director_primitives \
director_redefined \
director_string \
+director_using_member_scopes \
enum_thorough \
li_windows \
member_pointer_const \
preproc_constants \
+rename_camel \
smart_pointer_inherit \
FAILING_C_TESTS = \
@@ -93,11 +101,12 @@ extra_objects: swig.cmi swig.cmo swigp4.cmi
$(C_TEST_CASES:=.ctest): extra_objects
$(CPP_TEST_CASES:=.cpptest): extra_objects
+$(CPP11_TEST_CASES:=.cpptest): extra_objects
$(MULTI_CPP_TEST_CASES:=.multicpptest): extra_objects
# Clean
%.clean:
- @rm -f $*.ml $*.mli $*_runme;
+ @rm -f $*_wrap.* $*.cmo $*.cmi $*.ml $*.mli $*_runme;
@if test $(srcdir) != .; then rm -f $(ml_runme); fi
clean:
@@ -106,6 +115,6 @@ clean:
rm -f import_stl_a.ml import_stl_b.ml
rm -f imports_a.ml imports_b.ml
rm -f mod_a.ml mod_b.ml
- rm -f multi_import_a.ml multi_import_b.ml
+ rm -f multi_import_a.ml multi_import_b.ml multi_import_d.ml
rm -f packageoption_a.ml packageoption_b.ml packageoption_c.ml
rm -f template_typedef_cplx2.ml
diff --git a/Examples/test-suite/ocaml/catches_strings_runme.ml b/Examples/test-suite/ocaml/catches_strings_runme.ml
new file mode 100644
index 000000000..901aed0ec
--- /dev/null
+++ b/Examples/test-suite/ocaml/catches_strings_runme.ml
@@ -0,0 +1,14 @@
+open Swig
+open Catches_strings
+
+let _ =
+ try
+ ignore (_StringsThrower_charstring (C_void)); assert false
+ with Failure s ->
+ assert (s = "charstring message")
+
+let _ =
+ try
+ ignore (_StringsThrower_stdstring (C_void)); assert false
+ with Failure s ->
+ assert (s = "stdstring message")
diff --git a/Examples/test-suite/ocaml/director_pass_by_value_runme.ml b/Examples/test-suite/ocaml/director_pass_by_value_runme.ml
index af862f189..ce2137fbe 100644
--- a/Examples/test-suite/ocaml/director_pass_by_value_runme.ml
+++ b/Examples/test-suite/ocaml/director_pass_by_value_runme.ml
@@ -14,10 +14,13 @@ let d =
(director_pass_by_value_Derived)
'()
+let cpp11 = _has_cplusplus11 '() as bool
+
let _ =
let caller = new_Caller '() in
assert (caller -> call_virtualMethod (d) = C_void);
assert (Array.length !passByVal = 1);
+(* TODO: only run if cpp11... let _ = _Counter_check_counts (C_list [C_int 0; C_int 0; C_int 0; C_int 1; C_int 0; C_int 1]) in*) (* check move constructor called and just one destructor *)
let a = List.hd (fnhelper (!passByVal.(0))) in
assert (a -> getVal () as int = 0x12345678);
assert (a -> "~" () = C_void);
diff --git a/Examples/test-suite/ocaml/enum_rename_runme.ml b/Examples/test-suite/ocaml/enum_rename_runme.ml
new file mode 100644
index 000000000..4aef31bac
--- /dev/null
+++ b/Examples/test-suite/ocaml/enum_rename_runme.ml
@@ -0,0 +1,10 @@
+open Swig
+open Enum_rename
+
+let mydec = C_enum `M_Dec
+let _ = assert (((enum_to_int `Month mydec)) = C_int 2)
+let _ = assert (((int_to_enum `Month 2)) = C_enum `M_Dec)
+
+let mymay = C_enum `May
+let _ = assert (((enum_to_int `Month mymay)) = C_int 1)
+let _ = assert (((int_to_enum `Month 1)) = C_enum `May)
diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in
index 9602d85f5..5a092f5e3 100644
--- a/Examples/test-suite/octave/Makefile.in
+++ b/Examples/test-suite/octave/Makefile.in
@@ -7,6 +7,10 @@ OCTAVE = @OCTAVE@
SCRIPTSUFFIX = _runme.m
PCHSUPPORT = @PCHSUPPORT@
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/octave/catches_strings_runme.m b/Examples/test-suite/octave/catches_strings_runme.m
new file mode 100644
index 000000000..7e323cc13
--- /dev/null
+++ b/Examples/test-suite/octave/catches_strings_runme.m
@@ -0,0 +1,32 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+ crash_dumps_octave_core(0);
+endif
+
+catches_strings
+
+exception_thrown = false;
+try
+ StringsThrower.charstring();
+catch e
+ if (isempty(strfind(e.message, "charstring message")))
+ error("incorrect exception message: %s", e.message)
+ endif
+ exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+ error("Should have thrown an exception");
+endif
+
+exception_thrown = false;
+try
+ StringsThrower.stdstring();
+catch e
+ if (isempty(strfind(e.message, "stdstring message")))
+ error("incorrect exception message: %s", e.message)
+ endif
+ exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+ error("Should have thrown an exception");
+endif
diff --git a/Examples/test-suite/octave/cpp11_move_typemaps_runme.m b/Examples/test-suite/octave/cpp11_move_typemaps_runme.m
new file mode 100644
index 000000000..c0532565b
--- /dev/null
+++ b/Examples/test-suite/octave/cpp11_move_typemaps_runme.m
@@ -0,0 +1,37 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+ crash_dumps_octave_core(0);
+endif
+
+cpp11_move_typemaps
+
+Counter.reset_counts();
+mo = MoveOnly(111);
+Counter_check_counts(1, 0, 0, 0, 0, 0);
+MoveOnly.take(mo);
+Counter_check_counts(1, 0, 0, 1, 0, 2);
+clear mo;
+Counter_check_counts(1, 0, 0, 1, 0, 2);
+
+Counter.reset_counts();
+mo = MovableCopyable(111);
+Counter_check_counts(1, 0, 0, 0, 0, 0);
+MovableCopyable.take(mo);
+Counter_check_counts(1, 0, 0, 1, 0, 2);
+clear mo;
+Counter_check_counts(1, 0, 0, 1, 0, 2);
+
+mo = MoveOnly(222);
+MoveOnly.take(mo);
+exception_thrown = false;
+try
+ MoveOnly.take(mo);
+catch e
+ if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+ error("incorrect exception message %s", e.message);
+ endif
+ exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+ error("double usage of take should have been an error");
+endif
diff --git a/Examples/test-suite/octave/cpp11_rvalue_reference_move_runme.m b/Examples/test-suite/octave/cpp11_rvalue_reference_move_runme.m
new file mode 100644
index 000000000..5be37cc7e
--- /dev/null
+++ b/Examples/test-suite/octave/cpp11_rvalue_reference_move_runme.m
@@ -0,0 +1,85 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+ crash_dumps_octave_core(0);
+endif
+
+cpp11_rvalue_reference_move
+
+# Function containing rvalue reference parameter
+Counter.reset_counts();
+mo = MovableCopyable(222);
+Counter.check_counts(1, 0, 0, 0, 0, 0);
+MovableCopyable.movein(mo);
+Counter.check_counts(1, 0, 0, 1, 0, 2);
+if (!MovableCopyable_is_nullptr(mo))
+ error("is_nullptr failed");
+endif
+clear mo;
+Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+# Move constructor test
+Counter.reset_counts();
+mo = MovableCopyable(222);
+Counter.check_counts(1, 0, 0, 0, 0, 0);
+mo_moved = MovableCopyable(mo);
+Counter.check_counts(1, 0, 0, 1, 0, 1);
+if (!MovableCopyable_is_nullptr(mo))
+ error("is_nullptr failed");
+endif
+clear mo;
+Counter.check_counts(1, 0, 0, 1, 0, 1);
+clear mo_moved;
+Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+# Move assignment operator test
+Counter.reset_counts();
+mo111 = MovableCopyable(111);
+mo222 = MovableCopyable(222);
+Counter.check_counts(2, 0, 0, 0, 0, 0);
+mo111.MoveAssign(mo222);
+Counter.check_counts(2, 0, 0, 0, 1, 1);
+if (!MovableCopyable_is_nullptr(mo222))
+ error("is_nullptr failed");
+endif
+clear mo222;
+Counter.check_counts(2, 0, 0, 0, 1, 1);
+clear mo111;
+Counter.check_counts(2, 0, 0, 0, 1, 2);
+
+# null check
+null = []; # NULL pointer
+Counter.reset_counts();
+exception_thrown = false;
+try
+ MovableCopyable.movein(null);
+catch e
+ if (isempty(strfind(e.message, "invalid null reference")))
+ error("incorrect exception message: %s", e.message)
+ endif
+ exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+ error("Should have thrown null error");
+endif
+Counter.check_counts(0, 0, 0, 0, 0, 0);
+
+
+# output
+Counter.reset_counts();
+mc = MovableCopyable.moveout(1234);
+Counter.check_counts(2, 0, 0, 0, 1, 1);
+MovableCopyable.check_numbers_match(mc, 1234);
+
+exception_thrown = false;
+try
+ MovableCopyable.movein(mc);
+catch e
+ if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+ error("incorrect exception message: %s", e.message)
+ endif
+ exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+ error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+endif
+Counter.check_counts(2, 0, 0, 0, 1, 1);
diff --git a/Examples/test-suite/octave/cpp11_std_unique_ptr_runme.m b/Examples/test-suite/octave/cpp11_std_unique_ptr_runme.m
new file mode 100644
index 000000000..dbd461711
--- /dev/null
+++ b/Examples/test-suite/octave/cpp11_std_unique_ptr_runme.m
@@ -0,0 +1,138 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+ crash_dumps_octave_core(0);
+endif
+
+cpp11_std_unique_ptr
+
+function checkCount(expected_count)
+ actual_count = Klass_getTotal_count();
+ if (actual_count != expected_count)
+ error("Counts incorrect, expected:%d actual:%d", expected_count, actual_count);
+ endif
+end
+
+# Test raw pointer handling involving virtual inheritance
+kini = KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+s = useKlassRawPtr(kini);
+if (!strcmp(s, "KlassInheritanceInput"))
+ error("Incorrect string: %s", s);
+endif
+clear kini;
+checkCount(0);
+
+
+# unique_ptr as input
+kin = Klass("KlassInput");
+checkCount(1);
+s = takeKlassUniquePtr(kin);
+checkCount(0);
+if (!strcmp(s, "KlassInput"))
+ error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kin))
+ error("is_nullptr failed");
+endif
+clear kin; # Should not fail, even though already deleted
+checkCount(0);
+
+kin = Klass("KlassInput");
+checkCount(1);
+s = takeKlassUniquePtr(kin);
+checkCount(0);
+if (!strcmp(s, "KlassInput"))
+ error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kin))
+ error("is_nullptr failed");
+endif
+exception_thrown = false;
+try
+ takeKlassUniquePtr(kin);
+catch e
+ if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+ error("incorrect exception message %s", e.message);
+ endif
+ exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+ error("double usage of takeKlassUniquePtr should have been an error");
+endif
+clear kin; # Should not fail, even though already deleted
+checkCount(0);
+
+kin = Klass("KlassInput");
+exception_thrown = false;
+notowned = get_not_owned_ptr(kin);
+try
+ takeKlassUniquePtr(notowned);
+catch e
+ if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+ error("incorrect exception message %s", e.message);
+ endif
+ exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+ error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+endif
+checkCount(1);
+clear kin;
+checkCount(0);
+
+kini = KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+s = takeKlassUniquePtr(kini);
+checkCount(0);
+if (!strcmp(s, "KlassInheritanceInput"))
+ error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kini))
+ error("is_nullptr failed");
+endif
+clear kini; # Should not fail, even though already deleted
+checkCount(0);
+
+null = []; # NULL pointer
+null_ptr = make_null();
+takeKlassUniquePtr([]);
+takeKlassUniquePtr(null);
+takeKlassUniquePtr(null_ptr);
+checkCount(0);
+
+# overloaded parameters
+if (overloadTest() != 0)
+ error("overloadTest failed");
+endif
+if (overloadTest(null) != 1)
+ error("overloadTest failed");
+endif
+if (overloadTest(Klass("over")) != 1)
+ error("overloadTest failed");
+endif
+checkCount(0);
+
+
+# unique_ptr as output
+k1 = makeKlassUniquePtr("first");
+if (!strcmp(k1.getLabel(), "first"))
+ error("wrong object label");
+endif
+
+k2 = makeKlassUniquePtr("second");
+checkCount(2);
+
+clear k1;
+checkCount(1);
+
+if (!strcmp(k2.getLabel(), "second"))
+ error("wrong object label");
+endif
+
+clear k2;
+checkCount(0);
+
+null_smart_prt = makeNullUniquePtr();
+assert(ismatrix(null_smart_prt))
+assert(size(null_smart_prt) == size([]))
+assert(isequal([], null_smart_prt))
diff --git a/Examples/test-suite/octave/friends_runme.m b/Examples/test-suite/octave/friends_runme.m
index 50a5b20ef..163f05b8d 100644
--- a/Examples/test-suite/octave/friends_runme.m
+++ b/Examples/test-suite/octave/friends_runme.m
@@ -29,7 +29,7 @@ if (friends.mix(a,b) != 5)
error("failed");
endif
-di = friends.D_d(2);
+di = friends.D_i(2);
dd = friends.D_d(3.3);
# incredible template overloading working just fine
diff --git a/Examples/test-suite/octave/li_std_auto_ptr_runme.m b/Examples/test-suite/octave/li_std_auto_ptr_runme.m
new file mode 100644
index 000000000..9f0dd16cd
--- /dev/null
+++ b/Examples/test-suite/octave/li_std_auto_ptr_runme.m
@@ -0,0 +1,138 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+ crash_dumps_octave_core(0);
+endif
+
+li_std_auto_ptr
+
+function checkCount(expected_count)
+ actual_count = Klass_getTotal_count();
+ if (actual_count != expected_count)
+ error("Counts incorrect, expected:%d actual:%d", expected_count, actual_count);
+ endif
+end
+
+# Test raw pointer handling involving virtual inheritance
+kini = KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+s = useKlassRawPtr(kini);
+if (!strcmp(s, "KlassInheritanceInput"))
+ error("Incorrect string: %s", s);
+endif
+clear kini;
+checkCount(0);
+
+
+# auto_ptr as input
+kin = Klass("KlassInput");
+checkCount(1);
+s = takeKlassAutoPtr(kin);
+checkCount(0);
+if (!strcmp(s, "KlassInput"))
+ error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kin))
+ error("is_nullptr failed");
+endif
+clear kin; # Should not fail, even though already deleted
+checkCount(0);
+
+kin = Klass("KlassInput");
+checkCount(1);
+s = takeKlassAutoPtr(kin);
+checkCount(0);
+if (!strcmp(s, "KlassInput"))
+ error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kin))
+ error("is_nullptr failed");
+endif
+exception_thrown = false;
+try
+ takeKlassAutoPtr(kin);
+catch e
+ if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+ error("incorrect exception message %s", e.message);
+ endif
+ exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+ error("double usage of takeKlassAutoPtr should have been an error");
+endif
+clear kin; # Should not fail, even though already deleted
+checkCount(0);
+
+kin = Klass("KlassInput");
+exception_thrown = false;
+notowned = get_not_owned_ptr(kin);
+try
+ takeKlassAutoPtr(notowned);
+catch e
+ if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+ error("incorrect exception message %s", e.message);
+ endif
+ exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+ error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+endif
+checkCount(1);
+clear kin;
+checkCount(0);
+
+kini = KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+s = takeKlassAutoPtr(kini);
+checkCount(0);
+if (!strcmp(s, "KlassInheritanceInput"))
+ error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kini))
+ error("is_nullptr failed");
+endif
+clear kini; # Should not fail, even though already deleted
+checkCount(0);
+
+null = []; # NULL pointer
+null_ptr = make_null();
+takeKlassAutoPtr([]);
+takeKlassAutoPtr(null);
+takeKlassAutoPtr(null_ptr);
+checkCount(0);
+
+# overloaded parameters
+if (overloadTest() != 0)
+ error("overloadTest failed");
+endif
+if (overloadTest(null) != 1)
+ error("overloadTest failed");
+endif
+if (overloadTest(Klass("over")) != 1)
+ error("overloadTest failed");
+endif
+checkCount(0);
+
+
+# auto_ptr as output
+k1 = makeKlassAutoPtr("first");
+if (!strcmp(k1.getLabel(), "first"))
+ error("wrong object label");
+endif
+
+k2 = makeKlassAutoPtr("second");
+checkCount(2);
+
+clear k1;
+checkCount(1);
+
+if (!strcmp(k2.getLabel(), "second"))
+ error("wrong object label");
+endif
+
+clear k2;
+checkCount(0);
+
+null_smart_prt = makeNullAutoPtr();
+assert(ismatrix(null_smart_prt))
+assert(size(null_smart_prt) == size([]))
+assert(isequal([], null_smart_prt))
diff --git a/Examples/test-suite/octave/null_pointer_runme.m b/Examples/test-suite/octave/null_pointer_runme.m
index 72362f451..7a49d37f0 100644
--- a/Examples/test-suite/octave/null_pointer_runme.m
+++ b/Examples/test-suite/octave/null_pointer_runme.m
@@ -6,3 +6,13 @@ endif
null_pointer;
assert(funk([]));
+null_ptr = getnull();
+assert(ismatrix(null_ptr))
+assert(size(null_ptr) == size([]))
+assert(isequal([], null_ptr))
+
+# Can't use isnull as a test due to null matrix not being copyable...
+# n = []
+# isnull(n) # ans = 0
+# isnull([]) # ans = 1
+# isnull(getnull()) # ans = 0
diff --git a/Examples/test-suite/operator_overload.i b/Examples/test-suite/operator_overload.i
index af884e5b4..ce3454fd9 100644
--- a/Examples/test-suite/operator_overload.i
+++ b/Examples/test-suite/operator_overload.i
@@ -69,6 +69,7 @@ see bottom for a set of possible tests
#endif
#ifdef SWIGPHP
+// "And" and "Or" can't be used as function names in PHP.
%rename(AndOperator) operator &&;
%rename(OrOperator) operator ||;
#endif
@@ -174,8 +175,7 @@ inline bool operator>=(const Op& a,const Op& b){return a.i>=b.i;}
Op operator-(const Op& a,const Op& b){return Op(a.i-b.i);}
%}
-// in order to wrapper this correctly
-// we need to extend the class
+// in order to wrap this correctly we need to extend the class
// to make the friends & non members part of the class
%extend Op{
Op operator &&(const Op& b){return Op($self->i&&b.i);}
diff --git a/Examples/test-suite/operator_overload_break.i b/Examples/test-suite/operator_overload_break.i
index a948f2d49..809498fa7 100644
--- a/Examples/test-suite/operator_overload_break.i
+++ b/Examples/test-suite/operator_overload_break.i
@@ -18,6 +18,7 @@
%{
#include <iostream>
+#include <stdlib.h>
using namespace std;
%}
diff --git a/Examples/test-suite/operator_pointer_ref.i b/Examples/test-suite/operator_pointer_ref.i
index 84182da0d..cd4ed2db0 100644
--- a/Examples/test-suite/operator_pointer_ref.i
+++ b/Examples/test-suite/operator_pointer_ref.i
@@ -4,6 +4,8 @@
#if defined(_MSC_VER)
#pragma warning(disable: 4996) // 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup. See online help for details.
#endif
+#include <string.h>
+#include <stdlib.h>
%}
%rename(AsCharStarRef) operator char*&;
diff --git a/Examples/test-suite/overload_extend.i b/Examples/test-suite/overload_extend.i
index acabdd5e8..7a5c03b2e 100644
--- a/Examples/test-suite/overload_extend.i
+++ b/Examples/test-suite/overload_extend.i
@@ -5,7 +5,7 @@
#include <stdlib.h>
%}
-%typemap(default) double y "$1=1000;";
+%typemap(default) double y "$1=1000;"
#endif
#ifdef SWIGLUA
diff --git a/Examples/test-suite/overload_extend2.i b/Examples/test-suite/overload_extend2.i
index f91738607..ded1e5e3a 100644
--- a/Examples/test-suite/overload_extend2.i
+++ b/Examples/test-suite/overload_extend2.i
@@ -1,6 +1,6 @@
%module overload_extend2
-%typemap(default) int int2 "$1=1000;";
+%typemap(default) int int2 "$1=1000;"
%inline %{
typedef struct Foo {
diff --git a/Examples/test-suite/perl5/Makefile.in b/Examples/test-suite/perl5/Makefile.in
index 6388e5b32..688b985ac 100644
--- a/Examples/test-suite/perl5/Makefile.in
+++ b/Examples/test-suite/perl5/Makefile.in
@@ -7,6 +7,10 @@ PERL = @PERL@
SCRIPTSUFFIX = _runme.pl
TEST_RUNNER = $(srcdir)/run-perl-test.pl
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/perl5/argcargvtest_runme.pl b/Examples/test-suite/perl5/argcargvtest_runme.pl
new file mode 100644
index 000000000..c4157ebf4
--- /dev/null
+++ b/Examples/test-suite/perl5/argcargvtest_runme.pl
@@ -0,0 +1,20 @@
+use strict;
+use warnings;
+use Test::More tests => 8;
+BEGIN { use_ok('argcargvtest') }
+require_ok('argcargvtest');
+
+my $largs = ["hi", "hola", "hello"];
+is(argcargvtest::mainc($largs), 3, "test main typemap 1");
+
+my $targs = ["hi", "hola"];
+is(argcargvtest::mainv($targs, 1), "hola", "test main typemap 2");
+
+my $errorVal = 0;
+my $ret = eval qq(argcargvtest::mainv("hello", 1); \$errorVal = 1;);
+is($ret, undef, "test main typemap 3");
+is($errorVal, 0, "test main typemap 4");
+
+is(argcargvtest::initializeApp($largs), undef, "test main typemap 5");
+
+ok(1, "done");
diff --git a/Examples/test-suite/perl5/catches_strings_runme.pl b/Examples/test-suite/perl5/catches_strings_runme.pl
new file mode 100644
index 000000000..742b5bcab
--- /dev/null
+++ b/Examples/test-suite/perl5/catches_strings_runme.pl
@@ -0,0 +1,15 @@
+use strict;
+use warnings;
+use Test::More tests => 4;
+BEGIN { use_ok('catches_strings') }
+require_ok('catches_strings');
+
+eval {
+ catches_strings::StringsThrower::charstring();
+};
+like($@, qr/\bcharstring message/, "Should have thrown an exception");
+
+eval {
+ catches_strings::StringsThrower::stdstring();
+};
+like($@, qr/\bstdstring message/, "Should have thrown an exception");
diff --git a/Examples/test-suite/perl5/cpp11_move_typemaps_runme.pl b/Examples/test-suite/perl5/cpp11_move_typemaps_runme.pl
new file mode 100644
index 000000000..aae3e4dcb
--- /dev/null
+++ b/Examples/test-suite/perl5/cpp11_move_typemaps_runme.pl
@@ -0,0 +1,34 @@
+use strict;
+use warnings;
+use Test::More tests => 3;
+BEGIN { use_ok('cpp11_move_typemaps') }
+require_ok('cpp11_move_typemaps');
+
+{
+ cpp11_move_typemaps::Counter::reset_counts();
+ my $mo = new cpp11_move_typemaps::MoveOnly(111);
+ cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 0, 0, 0);
+ cpp11_move_typemaps::MoveOnly::take($mo);
+ cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
+ undef $mo;
+}
+cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+{
+ cpp11_move_typemaps::Counter::reset_counts();
+ my $mo = new cpp11_move_typemaps::MovableCopyable(111);
+ cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 0, 0, 0);
+ cpp11_move_typemaps::MovableCopyable::take($mo);
+ cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
+ undef $mo;
+}
+cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+{
+ my $mo = new cpp11_move_typemaps::MoveOnly(222);
+ cpp11_move_typemaps::MoveOnly::take($mo);
+ eval {
+ cpp11_move_typemaps::MoveOnly::take($mo);
+ };
+ like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassUniquePtr should be an error");
+}
diff --git a/Examples/test-suite/perl5/cpp11_rvalue_reference_move_runme.pl b/Examples/test-suite/perl5/cpp11_rvalue_reference_move_runme.pl
new file mode 100644
index 000000000..756691d03
--- /dev/null
+++ b/Examples/test-suite/perl5/cpp11_rvalue_reference_move_runme.pl
@@ -0,0 +1,70 @@
+use strict;
+use warnings;
+use Test::More tests => 7;
+BEGIN { use_ok('cpp11_rvalue_reference_move') }
+require_ok('cpp11_rvalue_reference_move');
+
+{
+ # Function containing rvalue reference parameter
+ cpp11_rvalue_reference_move::Counter::reset_counts();
+ my $mo = new cpp11_rvalue_reference_move::MovableCopyable(222);
+ cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 0, 0, 0);
+ cpp11_rvalue_reference_move::MovableCopyable::movein($mo);
+ cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 2);
+ is(cpp11_rvalue_reference_move::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check");
+ undef $mo;
+ cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 2);
+}
+
+{
+ # Move constructor test
+ cpp11_rvalue_reference_move::Counter::reset_counts();
+ my $mo = new cpp11_rvalue_reference_move::MovableCopyable(222);
+ cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 0, 0, 0);
+ my $mo_moved = new cpp11_rvalue_reference_move::MovableCopyable($mo);
+ cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 1);
+ is(cpp11_rvalue_reference_move::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check");
+ undef $mo;
+ cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 1);
+ undef $mo_moved;
+ cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 2);
+}
+
+{
+ # Move assignment operator test
+ cpp11_rvalue_reference_move::Counter::reset_counts();
+ my $mo111 = new cpp11_rvalue_reference_move::MovableCopyable(111);
+ my $mo222 = new cpp11_rvalue_reference_move::MovableCopyable(222);
+ cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 0, 0);
+ $mo111->MoveAssign($mo222);
+ cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
+ is(cpp11_rvalue_reference_move::MovableCopyable::is_nullptr($mo222), 1, "is_nullptr check");
+ undef $mo222;
+ cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
+ undef $mo111;
+ cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 2);
+}
+
+{
+ # null check
+ cpp11_rvalue_reference_move::Counter::reset_counts();
+ eval {
+ cpp11_rvalue_reference_move::MovableCopyable::movein(undef);
+ };
+ like($@, qr/\binvalid null reference/, "Should have thrown null error");
+ cpp11_rvalue_reference_move::Counter::check_counts(0, 0, 0, 0, 0, 0);
+}
+
+{
+ # output
+ cpp11_rvalue_reference_move::Counter::reset_counts();
+ my $mc = cpp11_rvalue_reference_move::MovableCopyable::moveout(1234);
+ cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
+ cpp11_rvalue_reference_move::MovableCopyable::check_numbers_match($mc, 1234);
+
+ eval {
+ cpp11_rvalue_reference_move::MovableCopyable::movein($mc);
+ };
+ like($@, qr/\bcannot release ownership as memory is not owned\b/, "Should have thrown 'Cannot release ownership as memory is not owned' error");
+ cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
+}
diff --git a/Examples/test-suite/perl5/cpp11_std_unique_ptr_runme.pl b/Examples/test-suite/perl5/cpp11_std_unique_ptr_runme.pl
new file mode 100644
index 000000000..d61964bec
--- /dev/null
+++ b/Examples/test-suite/perl5/cpp11_std_unique_ptr_runme.pl
@@ -0,0 +1,100 @@
+use strict;
+use warnings;
+use Test::More tests => 34;
+BEGIN { use_ok('cpp11_std_unique_ptr') }
+require_ok('cpp11_std_unique_ptr');
+
+# adapted from ../java/cpp11_std_unique_ptr_runme.java
+
+sub checkCount {
+ my($expected_count) = @_;
+ my $actual_count = cpp11_std_unique_ptr::Klass::getTotal_count();
+ is($actual_count, $expected_count, "Counts incorrect, expected: $expected_count actual: $actual_count");
+}
+
+# Test raw pointer handling involving virtual inheritance
+{
+ my $kini = new cpp11_std_unique_ptr::KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ my $s = cpp11_std_unique_ptr::useKlassRawPtr($kini);
+ is($s, "KlassInheritanceInput", "Incorrect string: $s");
+ undef $kini;
+ checkCount(0);
+}
+
+
+# unique_ptr as input
+{
+ my $kin = new cpp11_std_unique_ptr::Klass("KlassInput");
+ checkCount(1);
+ my $s = cpp11_std_unique_ptr::takeKlassUniquePtr($kin);
+ checkCount(0);
+ is($s, "KlassInput", "Incorrect string: $s");
+ is(cpp11_std_unique_ptr::is_nullptr($kin), 1, "is_nullptr check");
+ undef $kin; # Should not fail, even though already deleted
+ checkCount(0);
+}
+
+{
+ my $kin = new cpp11_std_unique_ptr::Klass("KlassInput");
+ checkCount(1);
+ my $s = cpp11_std_unique_ptr::takeKlassUniquePtr($kin);
+ checkCount(0);
+ is($s, "KlassInput", "Incorrect string: $s");
+ is(cpp11_std_unique_ptr::is_nullptr($kin), 1, "is_nullptr check");
+ eval {
+ cpp11_std_unique_ptr::takeKlassUniquePtr($kin);
+ };
+ like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassUniquePtr should be an error");
+ undef $kin; # Should not fail, even though already deleted
+ checkCount(0);
+}
+
+{
+ my $kin = new cpp11_std_unique_ptr::Klass("KlassInput");
+ my $notowned = cpp11_std_unique_ptr::get_not_owned_ptr($kin);
+ eval {
+ cpp11_std_unique_ptr::takeKlassUniquePtr($notowned);
+ };
+ like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassUniquePtr should be an error");
+ checkCount(1);
+ undef $kin;
+ checkCount(0);
+}
+
+{
+ my $kini = new cpp11_std_unique_ptr::KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ my $s = cpp11_std_unique_ptr::takeKlassUniquePtr($kini);
+ checkCount(0);
+ is($s, "KlassInheritanceInput", "Incorrect string: $s");
+ is(cpp11_std_unique_ptr::is_nullptr($kini), 1, "is_nullptr failed");
+ undef $kini; # Should not fail, even though already deleted
+ checkCount(0);
+}
+
+cpp11_std_unique_ptr::takeKlassUniquePtr(undef);
+cpp11_std_unique_ptr::takeKlassUniquePtr(cpp11_std_unique_ptr::make_null());
+checkCount(0);
+
+# overloaded parameters
+is(cpp11_std_unique_ptr::overloadTest(), 0, "overloadTest failed");
+is(cpp11_std_unique_ptr::overloadTest(undef), 1, "overloadTest failed");
+is(cpp11_std_unique_ptr::overloadTest(new cpp11_std_unique_ptr::Klass("over")), 1, "overloadTest failed");
+checkCount(0);
+
+
+# unique_ptr as output
+my $k1 = cpp11_std_unique_ptr::makeKlassUniquePtr("first");
+my $k2 = cpp11_std_unique_ptr::makeKlassUniquePtr("second");
+checkCount(2);
+
+undef $k1;
+checkCount(1);
+
+is($k2->getLabel, "second", "proper label");
+
+undef $k2;
+checkCount(0);
+
+is(cpp11_std_unique_ptr::makeNullUniquePtr(), undef);
diff --git a/Examples/test-suite/perl5/li_std_auto_ptr_runme.pl b/Examples/test-suite/perl5/li_std_auto_ptr_runme.pl
new file mode 100644
index 000000000..bfcd38651
--- /dev/null
+++ b/Examples/test-suite/perl5/li_std_auto_ptr_runme.pl
@@ -0,0 +1,100 @@
+use strict;
+use warnings;
+use Test::More tests => 34;
+BEGIN { use_ok('li_std_auto_ptr') }
+require_ok('li_std_auto_ptr');
+
+# adapted from ../java/li_std_auto_ptr_runme.java
+
+sub checkCount {
+ my($expected_count) = @_;
+ my $actual_count = li_std_auto_ptr::Klass::getTotal_count();
+ is($actual_count, $expected_count, "Counts incorrect, expected: $expected_count actual: $actual_count");
+}
+
+# Test raw pointer handling involving virtual inheritance
+{
+ my $kini = new li_std_auto_ptr::KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ my $s = li_std_auto_ptr::useKlassRawPtr($kini);
+ is($s, "KlassInheritanceInput", "Incorrect string: $s");
+ undef $kini;
+ checkCount(0);
+}
+
+
+# auto_ptr as input
+{
+ my $kin = new li_std_auto_ptr::Klass("KlassInput");
+ checkCount(1);
+ my $s = li_std_auto_ptr::takeKlassAutoPtr($kin);
+ checkCount(0);
+ is($s, "KlassInput", "Incorrect string: $s");
+ is(li_std_auto_ptr::is_nullptr($kin), 1, "is_nullptr check");
+ undef $kin; # Should not fail, even though already deleted
+ checkCount(0);
+}
+
+{
+ my $kin = new li_std_auto_ptr::Klass("KlassInput");
+ checkCount(1);
+ my $s = li_std_auto_ptr::takeKlassAutoPtr($kin);
+ checkCount(0);
+ is($s, "KlassInput", "Incorrect string: $s");
+ is(li_std_auto_ptr::is_nullptr($kin), 1, "is_nullptr check");
+ eval {
+ li_std_auto_ptr::takeKlassAutoPtr($kin);
+ };
+ like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassAutoPtr should be an error");
+ undef $kin; # Should not fail, even though already deleted
+ checkCount(0);
+}
+
+{
+ my $kin = new li_std_auto_ptr::Klass("KlassInput");
+ my $notowned = li_std_auto_ptr::get_not_owned_ptr($kin);
+ eval {
+ li_std_auto_ptr::takeKlassAutoPtr($notowned);
+ };
+ like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassAutoPtr should be an error");
+ checkCount(1);
+ undef $kin;
+ checkCount(0);
+}
+
+{
+ my $kini = new li_std_auto_ptr::KlassInheritance("KlassInheritanceInput");
+ checkCount(1);
+ my $s = li_std_auto_ptr::takeKlassAutoPtr($kini);
+ checkCount(0);
+ is($s, "KlassInheritanceInput", "Incorrect string: $s");
+ is(li_std_auto_ptr::is_nullptr($kini), 1, "is_nullptr failed");
+ undef $kini; # Should not fail, even though already deleted
+ checkCount(0);
+}
+
+li_std_auto_ptr::takeKlassAutoPtr(undef);
+li_std_auto_ptr::takeKlassAutoPtr(li_std_auto_ptr::make_null());
+checkCount(0);
+
+# overloaded parameters
+is(li_std_auto_ptr::overloadTest(), 0, "overloadTest failed");
+is(li_std_auto_ptr::overloadTest(undef), 1, "overloadTest failed");
+is(li_std_auto_ptr::overloadTest(new li_std_auto_ptr::Klass("over")), 1, "overloadTest failed");
+checkCount(0);
+
+
+# auto_ptr as output
+my $k1 = li_std_auto_ptr::makeKlassAutoPtr("first");
+my $k2 = li_std_auto_ptr::makeKlassAutoPtr("second");
+checkCount(2);
+
+undef $k1;
+checkCount(1);
+
+is($k2->getLabel, "second", "proper label");
+
+undef $k2;
+checkCount(0);
+
+is(li_std_auto_ptr::makeNullAutoPtr(), undef);
diff --git a/Examples/test-suite/perl5/operator_overload_break_runme.pl b/Examples/test-suite/perl5/operator_overload_break_runme.pl
index fd3fe3303..c692dfac7 100644
--- a/Examples/test-suite/perl5/operator_overload_break_runme.pl
+++ b/Examples/test-suite/perl5/operator_overload_break_runme.pl
@@ -4,15 +4,6 @@ use Test::More tests => 9;
use operator_overload_break;
-# Workaround for
-# ok( not (expression) , "test description" );
-# does not working in older versions of Perl, eg 5.004_04
-sub ok_not ($;$) {
- my($test, $name) = @_;
- $test = not $test;
- ok($test, $name);
-}
-
pass("loaded");
my $op = operator_overload_break::Op->new(5);
@@ -32,7 +23,7 @@ $op->{k} = 22;
ok((10 == (32 - $op)),
"reversed subtraction");
-ok_not((3 == $op),
+ok(not(3 == $op),
'not equal');
$op->{k} = 3;
diff --git a/Examples/test-suite/perl5/operator_overload_runme.pl b/Examples/test-suite/perl5/operator_overload_runme.pl
index ba3f33a64..43a77a961 100644
--- a/Examples/test-suite/perl5/operator_overload_runme.pl
+++ b/Examples/test-suite/perl5/operator_overload_runme.pl
@@ -4,15 +4,6 @@ use Test::More tests => 39;
use operator_overload;
-# Workaround for
-# ok( not (expression) , "test description" );
-# does not working in older versions of Perl, eg 5.004_04
-sub ok_not ($;$) {
- my($test, $name) = @_;
- $test = not $test;
- ok($test, $name);
-}
-
pass("loaded");
# first check all the operators are implemented correctly from pure C++ code
@@ -30,7 +21,7 @@ isa_ok($op2, "operator_overload::Op");
$op->{i} = 5;
$op2->{i} = 3;
-ok_not(($op == $op2), "operator equal: not equal");
+ok(not($op == $op2), "operator equal: not equal");
$op->{i} = 3;
ok(($op == $op2), "operator equal: equal");
@@ -42,7 +33,7 @@ $op2->{i} = 3;
ok(($op != $op2), "operator not equal: not equal");
$op->{i} = 3;
-ok_not(($op != $op2), "operator not equal: equal");
+ok(not($op != $op2), "operator not equal: equal");
# stringify operator
$op->{i} = 3;
@@ -99,16 +90,16 @@ is($op3->{i}, 2, "operator modulus");
$op->{i} = 8;
$op2->{i} = 3;
ok($op > $op2, "operator greater than");
-ok_not(($op2 > $op), "operator greater than");
+ok(not($op2 > $op), "operator greater than");
$op->{i} = 3;
-ok_not(($op2 > $op), "operator greater than");
-ok_not(($op > $op2), "operator greater than");
+ok(not($op2 > $op), "operator greater than");
+ok(not($op > $op2), "operator greater than");
# greater than or equal operator
$op->{i} = 8;
$op2->{i} = 3;
ok($op >= $op2, "operator greater than or equal");
-ok_not(($op2 >= $op), "operator greater than or equal");
+ok(not($op2 >= $op), "operator greater than or equal");
$op->{i} = 3;
ok(($op2 >= $op), "operator greater than or equal");
ok(($op >= $op2), "operator greater than or equal");
@@ -117,16 +108,16 @@ ok(($op >= $op2), "operator greater than or equal");
$op2->{i} = 8;
$op->{i} = 3;
ok($op < $op2, "operator lesser than");
-ok_not(($op2 < $op), "operator lesser than");
+ok(not($op2 < $op), "operator lesser than");
$op2->{i} = 3;
-ok_not(($op2 < $op), "operator lesser than");
-ok_not(($op < $op2), "operator lesser than");
+ok(not($op2 < $op), "operator lesser than");
+ok(not($op < $op2), "operator lesser than");
# less than or equal operator
$op2->{i} = 8;
$op->{i} = 3;
ok($op <= $op2, "operator lesser than or equal");
-ok_not(($op2 <= $op), "operator lesser than or equal");
+ok(not($op2 <= $op), "operator lesser than or equal");
$op2->{i} = 3;
ok(($op2 <= $op), "operator less than or equal");
ok(($op <= $op2), "operator less than or equal");
diff --git a/Examples/test-suite/perl5/packageoption_runme.pl b/Examples/test-suite/perl5/packageoption_runme.pl
index d94a7a1fd..02e95f7a8 100644
--- a/Examples/test-suite/perl5/packageoption_runme.pl
+++ b/Examples/test-suite/perl5/packageoption_runme.pl
@@ -5,15 +5,6 @@ use Test::More tests => 4;
BEGIN { use_ok('packageoption_a'); }
BEGIN { use_ok('packageoption_b'); }
-# Workaround for
-# ok( not (expression) , "test description" );
-# does not working in older versions of Perl, eg 5.004_04
-sub ok_not ($;$) {
- my($test, $name) = @_;
- $test = not $test;
- ok($test, $name);
-}
-
my $a = CommonPackage::A->new();
isa_ok($a, 'CommonPackage::A');
diff --git a/Examples/test-suite/php/Makefile.in b/Examples/test-suite/php/Makefile.in
index b64918df7..c918581bf 100644
--- a/Examples/test-suite/php/Makefile.in
+++ b/Examples/test-suite/php/Makefile.in
@@ -5,6 +5,10 @@
LANGUAGE = php
SCRIPTSUFFIX = _runme.php
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
@@ -67,18 +71,18 @@ missingtests: missingcpptests missingctests
@echo ' $(MULTI_CPP_TEST_CASES) '|grep -F -v ' $* ' >/dev/null ||\
$(MAKE) $*.multicpptest
-# Runs the testcase. Tries to run testcase_runme.php, and if that's not
-# found, runs testcase.php, except for multicpptests.
+# Runs the testcase. Tries to run testcase_runme.php, and if that's not found,
+# at least test that the module loads without errors, except for multicpptests.
run_testcase = \
if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) RUNTOOL='$(RUNTOOL)' php_run; \
- elif [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*.php -a ! -f $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list ]; then \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*.php RUNTOOL='$(RUNTOOL)' php_run; \
+ elif [ ! -f $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list ]; then \
+ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT= RUNTOOL='$(RUNTOOL)' php_run; \
fi
-# Clean: remove the generated .php file
+# Clean: remove the generated PHP-specific files
%.clean:
- @rm -f $*.php php_$*.h
+ @rm -f php_$*.h
clean:
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' php_clean
@@ -86,6 +90,6 @@ clean:
rm -f import_stl_a.php import_stl_b.php php_import_stl_a.h php_import_stl_b.h
rm -f imports_a.php imports_b.php php_imports_a.h php_imports_b.h
rm -f mod_a.php mod_b.php php_mod_a.h php_mod_b.h
- rm -f multi_import_a.php multi_import_b.php php_multi_import_a.h php_multi_import_b.h
+ rm -f multi_import_a.php multi_import_b.php multi_import_d.php php_multi_import_a.h php_multi_import_b.h php_multi_import_d.h
rm -f packageoption_a.php packageoption_b.php packageoption_c.php php_packageoption_a.h php_packageoption_b.h php_packageoption_c.h
rm -f template_typedef_cplx2.php php_template_typedef_cplx2.h
diff --git a/Examples/test-suite/php/abstract_inherit_ok_runme.php b/Examples/test-suite/php/abstract_inherit_ok_runme.php
index 6cfea2341..add4191c2 100644
--- a/Examples/test-suite/php/abstract_inherit_ok_runme.php
+++ b/Examples/test-suite/php/abstract_inherit_ok_runme.php
@@ -2,9 +2,24 @@
require "tests.php";
+// No new functions
+check::functions(array());
+
check::classes(array('Foo','Spam'));
-$spam=new Spam();
+// No new vars
+check::globals(array());
+
+// We shouldn't be able to instantiate abstract class Foo.
+$class = 'Foo';
+try {
+ $obj = eval("new $class();");
+ check::fail("Should not be able to instantiate abstract class $class");
+} catch (Error $e) {
+ check::equal($e->getMessage(), "Cannot instantiate abstract class $class", "Unexpected exception: {$e->getMessage()}");
+}
+
+$spam=new Spam();
check::equal(0,$spam->blah(),"spam object method");
check::done();
diff --git a/Examples/test-suite/php/abstract_inherit_runme.php b/Examples/test-suite/php/abstract_inherit_runme.php
index 6a0180d78..376a2adaa 100644
--- a/Examples/test-suite/php/abstract_inherit_runme.php
+++ b/Examples/test-suite/php/abstract_inherit_runme.php
@@ -3,10 +3,17 @@
require "tests.php";
check::classes(array('Foo','Bar','Spam','NRFilter_i','NRRCFilter_i','NRRCFilterpro_i','NRRCFilterpri_i'));
-// This constructor attempt should fail as there isn't one
-//$spam=new Spam();
-//check::equal(0,$spam->blah(),"spam object method");
-//check::equal(0,Spam::blah($spam),"spam class method");
+// We shouldn't be able to instantiate any of these classes since they are all
+// abstract (in each case there's a pure virtual function in the base class
+// which isn't implemented).
+foreach (array('Foo','Bar','Spam','NRFilter_i','NRRCFilter_i','NRRCFilterpro_i','NRRCFilterpri_i')as $class) {
+ try {
+ $obj = eval("new $class();");
+ check::fail("Should not be able to instantiate abstract class $class");
+ } catch (Error $e) {
+ check::equal($e->getMessage(), "Cannot instantiate abstract class $class", "Unexpected exception: {$e->getMessage()}");
+ }
+}
check::done();
diff --git a/Examples/test-suite/php/argcargvtest_runme.php b/Examples/test-suite/php/argcargvtest_runme.php
new file mode 100644
index 000000000..4a675d0ed
--- /dev/null
+++ b/Examples/test-suite/php/argcargvtest_runme.php
@@ -0,0 +1,29 @@
+<?php
+
+require "tests.php";
+
+// New functions
+check::functions(array('mainc', 'mainv', 'initializeapp'));
+// New classes
+check::classes(array('argcargvtest'));
+// No new vars
+check::globals(array());
+
+$largs = array('hi', 'hola', 'hello');
+check::equal(mainc($largs), 3, 'Test main typemap 1');
+
+$targs = array('hi', 'hola');
+check::equal(mainv($targs, 1), 'hola', 'Test main typemap 2');
+
+$error = 0;
+try {
+ mainv('hello', 1);
+ $error = 1;
+}
+catch (exception $e) {
+}
+check::equal($error, 0, 'Test main typemap 3');
+
+initializeApp($largs);
+
+check::done();
diff --git a/Examples/test-suite/php/argout_runme.php b/Examples/test-suite/php/argout_runme.php
index d233cf0f6..554d07756 100644
--- a/Examples/test-suite/php/argout_runme.php
+++ b/Examples/test-suite/php/argout_runme.php
@@ -20,11 +20,14 @@ $tr=copy_intp(4);
check::equal(4,inctr($tr),"4==incr($tr)");
check::equal(5,intp_value($tr),"5==$tr");
-# Check the voidhandle call, first with null
+# Check the voidhandle call, first with NULL and then with the SWIG\p_void we
+# get from the first call.
$handle=NULL;
-voidhandle($handle);
-check::equal(get_class($handle),"SWIG\\_p_void",'$handle is not _p_void');
-$handledata=handle($handle);
-check::equal($handledata,"Here it is","\$handledata != \"Here it is\"");
+for ($i=0; $i != 1; $i++) {
+ voidhandle($handle);
+ check::equal(get_class($handle),"SWIG\\_p_void",'$handle is not _p_void');
+ $handledata=handle($handle);
+ check::equal($handledata,"Here it is","\$handledata != \"Here it is\"");
+}
check::done();
diff --git a/Examples/test-suite/php/arrays_scope_runme.php b/Examples/test-suite/php/arrays_scope_runme.php
index f18037ca7..8455b837c 100644
--- a/Examples/test-suite/php/arrays_scope_runme.php
+++ b/Examples/test-suite/php/arrays_scope_runme.php
@@ -10,5 +10,9 @@ check::classes(array('arrays_scope','Bar'));
check::globals(array());
$bar=new bar();
+$bar->blah($bar->adata, $bar->bdata, $bar->cdata);
+// Like C/C++, SWIG treats `int asize[ASIZE]` as `int*` so there's no checking
+// of the passed array size.
+$bar->blah($bar->bdata, $bar->cdata, $bar->adata);
check::done();
diff --git a/Examples/test-suite/php/catches_strings_runme.php b/Examples/test-suite/php/catches_strings_runme.php
new file mode 100644
index 000000000..f727ea26a
--- /dev/null
+++ b/Examples/test-suite/php/catches_strings_runme.php
@@ -0,0 +1,23 @@
+<?php
+
+require "tests.php";
+
+$exception_thrown = false;
+try {
+ StringsThrower::charstring();
+} catch (Exception $e) {
+ check::str_contains($e->getMessage(), "charstring message", "incorrect exception message: {$e->getMessage()}");
+ $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "Should have thrown an exception");
+
+$exception_thrown = false;
+try {
+ StringsThrower::stdstring();
+} catch (Exception $e) {
+ check::str_contains($e->getMessage(), "stdstring message", "incorrect exception message: {$e->getMessage()}");
+ $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "Should have thrown an exception");
+
+check::done();
diff --git a/Examples/test-suite/php/cpp11_attribute_specifiers_runme.php b/Examples/test-suite/php/cpp11_attribute_specifiers_runme.php
new file mode 100644
index 000000000..2336b319a
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_attribute_specifiers_runme.php
@@ -0,0 +1,14 @@
+<?php
+
+require "tests.php";
+
+// New functions
+check::functions(array('noReturn','noDiscard','noDiscardDeprecated','maybeUnused1','maybeUnused2','likely','test_string_literal'));
+// New classes
+check::classes(array('cpp11_attribute_specifiers','S'));
+// No new vars
+check::globals(array());
+
+check::equal(test_string_literal(), 'Test [[ and ]] in string literal', "test_string_literal() wrong");
+
+check::done();
diff --git a/Examples/test-suite/php/cpp11_final_directors_runme.php b/Examples/test-suite/php/cpp11_final_directors_runme.php
new file mode 100644
index 000000000..07e04b15f
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_final_directors_runme.php
@@ -0,0 +1,16 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('Base','BaseFinalDestructor','BaseFinalDestructor2','Derived'));
+// No new vars
+check::globals(array());
+
+class Derived2 extends Derived {
+ function meth() { return 3; }
+}
+
+$b = new Derived2();
+check::equal($b->meth(), 3, "Wrong return value");
diff --git a/Examples/test-suite/php/cpp11_move_typemaps_runme.php b/Examples/test-suite/php/cpp11_move_typemaps_runme.php
new file mode 100644
index 000000000..2d4b5e090
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_move_typemaps_runme.php
@@ -0,0 +1,32 @@
+<?php
+
+require "tests.php";
+
+Counter::reset_counts();
+$mo = new MoveOnly(111);
+Counter::check_counts(1, 0, 0, 0, 0, 0);
+MoveOnly::take($mo);
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+$mo = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+Counter::reset_counts();
+$mo = new MovableCopyable(111);
+Counter::check_counts(1, 0, 0, 0, 0, 0);
+MovableCopyable::take($mo);
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+$mo = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+$mo = new MoveOnly(222);
+MoveOnly::take($mo);
+$exception_thrown = false;
+try {
+ MoveOnly::take($mo);
+} catch (TypeError $e) {
+ check::str_contains($e->getMessage(), "Cannot release ownership as memory is not owned", "incorrect exception message: {$e->getMessage()}");
+ $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassUniquePtr should have been an error");
+
+check::done();
diff --git a/Examples/test-suite/php/cpp11_rvalue_reference_move_runme.php b/Examples/test-suite/php/cpp11_rvalue_reference_move_runme.php
new file mode 100644
index 000000000..38bb758ed
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_rvalue_reference_move_runme.php
@@ -0,0 +1,80 @@
+<?php
+
+require "tests.php";
+
+# Function containing rvalue reference parameter
+Counter::reset_counts();
+$mo = new MovableCopyable(222);
+Counter::check_counts(1, 0, 0, 0, 0, 0);
+MovableCopyable::movein($mo);
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+try {
+ MovableCopyable::is_nullptr($mo);
+ check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$mo = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+# Move constructor test
+Counter::reset_counts();
+$mo = new MovableCopyable(222);
+Counter::check_counts(1, 0, 0, 0, 0, 0);
+$mo_moved = new MovableCopyable($mo);
+Counter::check_counts(1, 0, 0, 1, 0, 1);
+try {
+ MovableCopyable::is_nullptr($mo);
+ check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$mo = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 1);
+$mo_moved = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+# Move assignment operator test
+Counter::reset_counts();
+$mo111 = new MovableCopyable(111);
+$mo222 = new MovableCopyable(222);
+Counter::check_counts(2, 0, 0, 0, 0, 0);
+$mo111->MoveAssign($mo222);
+Counter::check_counts(2, 0, 0, 0, 1, 1);
+try {
+ MovableCopyable::is_nullptr($mo222);
+ check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$mo222 = NULL;
+Counter::check_counts(2, 0, 0, 0, 1, 1);
+$mo111 = NULL;
+Counter::check_counts(2, 0, 0, 0, 1, 2);
+
+# null check
+Counter::reset_counts();
+$exception_thrown = false;
+try {
+ MovableCopyable::movein(NULL);
+} catch (TypeError $e) {
+ check::str_contains($e->getMessage(), "Invalid null reference", "incorrect exception message: {$e->getMessage()}");
+ $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "Should have thrown null error");
+Counter::check_counts(0, 0, 0, 0, 0, 0);
+
+# output
+Counter::reset_counts();
+$mc = MovableCopyable::moveout(1234);
+Counter::check_counts(2, 0, 0, 0, 1, 1);
+MovableCopyable::check_numbers_match($mc, 1234);
+
+$exception_thrown = false;
+try {
+ MovableCopyable::movein($mc);
+} catch (TypeError $e) {
+ check::str_contains($e->getMessage(), "Cannot release ownership as memory is not owned", "incorrect exception message: {$e->getMessage()}");
+ $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "Should have thrown 'Cannot release ownership as memory is not owned' error");
+Counter::check_counts(2, 0, 0, 0, 1, 1);
+
+check::done();
diff --git a/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php b/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php
new file mode 100644
index 000000000..425f6535f
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php
@@ -0,0 +1,108 @@
+<?php
+
+require "tests.php";
+
+function checkCount($expected_count) {
+ $actual_count = Klass::getTotal_count();
+ check::equal($actual_count, $expected_count, "Counts incorrect");
+}
+
+# Test raw pointer handling involving virtual inheritance
+$kini = new KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+$s = useKlassRawPtr($kini);
+check::equal($s, "KlassInheritanceInput", "Incorrect string: $s");
+$kini = NULL;
+checkCount(0);
+
+
+# unique_ptr as input
+$kin = new Klass("KlassInput");
+checkCount(1);
+$s = takeKlassUniquePtr($kin);
+checkCount(0);
+check::equal($s, "KlassInput", "Incorrect string: $s");
+try {
+ is_nullptr($kin);
+ check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$kin = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+$kin = new Klass("KlassInput");
+checkCount(1);
+$s = takeKlassUniquePtr($kin);
+checkCount(0);
+check::equal($s, "KlassInput", "Incorrect string: $s");
+try {
+ is_nullptr($kin);
+ check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$exception_thrown = false;
+try {
+ takeKlassUniquePtr($kin);
+} catch (TypeError $e) {
+ check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassUniquePtr", "Unexpected exception: {$e->getMessage()}");
+ $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassUniquePtr should have been an error");
+$kin = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+$kin = new Klass("KlassInput");
+$exception_thrown = false;
+$notowned = get_not_owned_ptr($kin);
+try {
+ takeKlassUniquePtr($notowned);
+} catch (TypeError $e) {
+ check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassUniquePtr", "Unexpected exception: {$e->getMessage()}");
+ $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassUniquePtr should have been an error");
+checkCount(1);
+$kin = NULL;
+checkCount(0);
+
+$kini = new KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+$s = takeKlassUniquePtr($kini);
+checkCount(0);
+check::equal($s, "KlassInheritanceInput", "Incorrect string: $s");
+try {
+ is_nullptr($kini);
+ check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+
+$kini = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+takeKlassUniquePtr(NULL);
+takeKlassUniquePtr(make_null());
+checkCount(0);
+
+# overloaded parameters
+check::equal(overloadTest(), 0, "overloadTest failed");
+check::equal(overloadTest(NULL), 1, "overloadTest failed");
+check::equal(overloadTest(new Klass("over")), 1, "overloadTest failed");
+checkCount(0);
+
+
+# unique_ptr as output
+$k1 = makeKlassUniquePtr("first");
+$k2 = makeKlassUniquePtr("second");
+checkCount(2);
+
+$k1 = NULL;
+checkCount(1);
+
+check::equal($k2->getLabel(), "second", "proper label");
+
+$k2 = NULL;
+checkCount(0);
+
+check::equal(makeNullUniquePtr(), NULL);
+
+check::done();
diff --git a/Examples/test-suite/php/cpp11_strongly_typed_enumerations_runme.php b/Examples/test-suite/php/cpp11_strongly_typed_enumerations_runme.php
index 82296deb7..ca327d502 100644
--- a/Examples/test-suite/php/cpp11_strongly_typed_enumerations_runme.php
+++ b/Examples/test-suite/php/cpp11_strongly_typed_enumerations_runme.php
@@ -164,3 +164,5 @@ enumCheck($class1->class1Test2(Class1::Enum12_Val5c), 1121);
enumCheck(globalTest1(Enum1_Val5a), 13);
enumCheck(globalTest2(Class1::Enum12_Val5c), 1121);
#enumCheck(globalTest3(Class1::Struct1.Enum12_Val5f), 3121);
+
+check::done();
diff --git a/Examples/test-suite/php/cpp20_spaceship_operator_runme.php b/Examples/test-suite/php/cpp20_spaceship_operator_runme.php
new file mode 100644
index 000000000..00484f742
--- /dev/null
+++ b/Examples/test-suite/php/cpp20_spaceship_operator_runme.php
@@ -0,0 +1,23 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('f', 'spaceship'));
+check::classes(array('cpp20_spaceship_operator','A'));
+check::globals(array('v', 'SPACE'));
+
+//check::equal(ALIEN, true);
+check::equal(SPACE_get(), 1);
+check::equal(COMET, 1);
+check::equal(v_get(), 42);
+
+$x = new A(1);
+$y = new A(2);
+
+check::equal(spaceship($x, $y) < 0, true);
+check::equal(spaceship($x, $x), 0);
+check::equal(spaceship($y, $x) > 0, true);
+
+check::equal(f(), 42);
+
+check::done();
diff --git a/Examples/test-suite/php/cpp_basic_runme.php b/Examples/test-suite/php/cpp_basic_runme.php
index fb34bc936..daca7d35d 100644
--- a/Examples/test-suite/php/cpp_basic_runme.php
+++ b/Examples/test-suite/php/cpp_basic_runme.php
@@ -3,9 +3,9 @@
require "tests.php";
// New functions
-check::functions(array('get_func1_ptr','get_func2_ptr','test_func_ptr'));
+check::functions(array('get_func1_ptr','get_func2_ptr','get_const_reference','get_reference','test_func_ptr'));
// New classes
-check::classes(array('cpp_basic','Foo','FooSub','FooSubSub','Bar','Fl_Window'));
+check::classes(array('cpp_basic','Foo','FooSub','FooSubSub','Bar','Fl_Window','JustConst'));
// No new vars
check::globals(array());
diff --git a/Examples/test-suite/php/cpp_static_runme.php b/Examples/test-suite/php/cpp_static_runme.php
index a1fd85c2e..2687333b0 100644
--- a/Examples/test-suite/php/cpp_static_runme.php
+++ b/Examples/test-suite/php/cpp_static_runme.php
@@ -2,8 +2,8 @@
require "tests.php";
-// New functions
-check::functions(array('is_python_builtin'));
+// No new functions
+check::functions(array());
// New classes
check::classes(array('StaticMemberTest','StaticFunctionTest','cpp_static','StaticBase','StaticDerived'));
// No new vars
diff --git a/Examples/test-suite/php/default_args_runme.php b/Examples/test-suite/php/default_args_runme.php
new file mode 100644
index 000000000..59350644f
--- /dev/null
+++ b/Examples/test-suite/php/default_args_runme.php
@@ -0,0 +1,161 @@
+<?php
+require "tests.php";
+
+// New functions
+check::functions(array('doublevalue1','doublevalue2','seek','seek2','seek3','seek4','seek5','seek6','seek7','seek8','seek9','seeka','seekb','anonymous','booltest','casts1','casts2','chartest1','chartest2','chartest3','chartest4','chartest5','chartest6','dummy','afunction','reftest1','reftest2','chops','exceptionspec','constructorcall','cfunc1','cfunc2','cfunc3','slightly_off_square'));
+// New classes
+check::classes(array('TrickyInPython','default_args','EnumClass','DerivedEnumClass','Tree','Foo','MyClass1','MyClass2','Except','Statics','Tricky','Klass','ConstMethods','Pointf','CDA'));
+// New vars
+check::globals(array('CONST_NUM'));
+
+$ec = new EnumClass();
+check::equal($ec->blah(), true, "EnumClass::blah() default arguments don't work");
+
+$de = new DerivedEnumClass();
+$de->accelerate();
+$de->accelerate(EnumClass::SLOW);
+
+check::equal(Statics::staticMethod(), 60, "Statics::staticMethod()");
+
+check::equal(cfunc1(1), 2.0, "cfunc1(1)");
+
+check::equal(cfunc2(1), 3.0, "cfunc2(1)");
+
+check::equal(cfunc3(1), 4.0, "cfunc3(1)");
+
+$f = new Foo();
+
+$f->newname();
+$f->newname(1);
+$f->defaulted1();
+$f->defaulted2();
+
+check::equal($f->double_if_void_ptr_is_null(2, Null), 4, "\$f->double_if_void_ptr_is_null(2, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(3), 6, "\$f->double_if_void_ptr_is_null(3)");
+
+check::equal($f->double_if_void_ptr_is_null(4, Null), 8, "\$f->double_if_void_ptr_is_null(4, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(5, Null), 10, "\$f->double_if_void_ptr_is_null(5, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(6, Null), 12, "\$f->double_if_void_ptr_is_null(6, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(7), 14, "\$f->double_if_void_ptr_is_null(7)");
+
+# For the testcases below, PHP 7 emits an error, while PHP 8 throws an
+# exception. To simplify the testcases we install an error handler function
+# for PHP7 which throws an ArgumentCountError exception (which we have to
+# define ourselves for PHP 7.0).
+
+if (PHP_MAJOR_VERSION == 7) {
+ if (PHP_MINOR_VERSION == 0) {
+ # ArgumentCountError was added in PHP 7.1.
+ class ArgumentCountError extends Error {}
+ }
+ $old_error_handler = set_error_handler(function($n,$s,$f,$l){throw preg_match('/^Wrong parameter count/', $s) ? new ArgumentCountError($s) : new Error($s);});
+}
+
+try {
+ $f = new Foo(1);
+ check::fail("Foo::Foo ignore is not working");
+} catch (ArgumentCountError $e) {
+}
+
+try {
+ $f = new Foo(1, 2);
+ check::fail("Foo::Foo ignore is not working");
+} catch (ArgumentCountError $e) {
+}
+
+try {
+ $f = new Foo(1, 2, 3);
+ check::fail("Foo::Foo ignore is not working");
+} catch (ArgumentCountError $e) {
+}
+
+try {
+ $m = $f->meth(1);
+ check::fail("Foo::meth ignore is not working");
+} catch (Error $e) {
+}
+
+try {
+ $m = $f->meth(1, 2);
+ check::fail("Foo::meth ignore is not working");
+} catch (Error $e) {
+}
+
+try {
+ $m = $f->meth(1, 2, 3);
+ check::fail("Foo::meth ignore is not working");
+} catch (Error $e) {
+}
+
+if (PHP_MAJOR_VERSION == 7) {
+ set_error_handler($old_error_handler);
+}
+
+check::equal(Klass::inc(100, new Klass(22))->val, 122, "Klass::inc failed");
+
+check::equal(klass::inc(100)->val, 99, "klass::inc failed");
+
+check::equal(klass::inc()->val, 0, "klass::inc failed");
+
+$tricky = new TrickyInPython();
+check::equal($tricky->value_m1(10), -1, "trickyvalue_m1 failed");
+check::equal($tricky->value_m1(10, 10), 10, "trickyvalue_m1 failed");
+check::equal($tricky->value_0xabcdef(10), 0xabcdef, "trickyvalue_0xabcdef failed");
+check::equal($tricky->value_0644(10), 420, "trickyvalue_0644 failed");
+check::equal($tricky->value_perm(10), 420, "trickyvalue_perm failed");
+check::equal($tricky->value_m01(10), -1, "trickyvalue_m01 failed");
+check::equal($tricky->booltest2(), True, "booltest2 failed");
+
+check::equal($tricky->max_32bit_int1(), 0x7FFFFFFF, "max_32bit_int1 failed");
+// On 32-bit platforms -2147483648 is a PHP float (rather than
+// PHP int on 64-bit platforms) so only check equivalence rather
+// than strict equality.
+check::equivalent($tricky->min_32bit_int1(), -2147483648, "min_32bit_int1 failed");
+check::equal($tricky->max_32bit_int2(), 0x7FFFFFFF, "max_32bit_int2 failed");
+
+$tricky->too_big_32bit_int1();
+$tricky->too_small_32bit_int1();
+$tricky->too_big_32bit_int2();
+$tricky->too_small_32bit_int2();
+
+seek();
+seek(10);
+
+check::equal(booltest(), True, "booltest failed");
+
+check::equal(slightly_off_square(10), 102, "slightly_off_square(10)");
+
+check::equal(slightly_off_square(), 291, "slightly_off_square()");
+
+check::equal(chartest1(), "x", "chartest1()");
+
+check::equal(chartest2(), "\0", "chartest2()");
+
+check::equal(chartest3(), "\1", "chartest3()");
+
+check::equal(chartest4(), "\n", "chartest4()");
+
+check::equal(chartest5(), "B", "chartest5()");
+
+check::equal(chartest6(), "C", "chartest6()");
+
+if (PHP_MAJOR_VERSION >= 8) {
+ // Regression test for bug in initial implementation of PHP type declarations.
+ $p = (new ReflectionMethod('TrickyInPython', 'value_m1'))->getParameters();
+ // empty array in buggy version
+ check::equal(count($p), 2, "Expected 2 parameters");
+ check::equal((string)$p[0]->getType(), 'int', "Expected int parameter");
+ check::equal((string)$p[1]->getType(), 'int', "Expected int parameter");
+
+ $p = (new ReflectionMethod('EnumClass', 'blah'))->getParameters();
+ // empty array in buggy version
+ check::equal(count($p), 2, "Expected 2 parameters");
+ check::equal((string)$p[0]->getType(), 'int', "Expected int parameter");
+ check::equal((string)$p[1]->getType(), 'int', "Expected int parameter");
+}
+
+check::done();
diff --git a/Examples/test-suite/php/director_abstract_runme.php b/Examples/test-suite/php/director_abstract_runme.php
index bb424f9ea..2d9799f2f 100644
--- a/Examples/test-suite/php/director_abstract_runme.php
+++ b/Examples/test-suite/php/director_abstract_runme.php
@@ -22,19 +22,19 @@ check::equal($a->ping(), "MyFoo::ping()", "MyFoo::ping failed");
check::equal($a->pong(), "Foo::pong();MyFoo::ping()", "MyFoo::pong failed");
class MyExample1 extends Example1 {
- function Color($r, $g, $b) {
+ function Color($r, $g = NULL, $b = NULL) {
return $r;
}
}
class MyExample2 extends Example1 {
- function Color($r, $g, $b) {
+ function Color($r, $g = NULL, $b = NULL) {
return $g;
}
}
class MyExample3 extends Example1 {
- function Color($r, $g, $b) {
+ function Color($r, $g = NULL, $b = NULL) {
return $b;
}
}
diff --git a/Examples/test-suite/php/director_alternating_runme.php b/Examples/test-suite/php/director_alternating_runme.php
new file mode 100644
index 000000000..de33038be
--- /dev/null
+++ b/Examples/test-suite/php/director_alternating_runme.php
@@ -0,0 +1,11 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('getBar','idFromGetBar'));
+check::classes(array('Foo','Bar','Baz','director_alternating'));
+// No new vars
+check::globals(array());
+
+$id = director_alternating::getBar()->id();
+check::equal($id, director_alternating::idFromGetBar(), "idFromGetBar() failed");
diff --git a/Examples/test-suite/php/director_classes_runme.php b/Examples/test-suite/php/director_classes_runme.php
new file mode 100644
index 000000000..d187ed82e
--- /dev/null
+++ b/Examples/test-suite/php/director_classes_runme.php
@@ -0,0 +1,114 @@
+<?php
+require "tests.php";
+
+// No new functions
+check::functions(array());
+// New classes
+check::classes(array('director_classes', 'Base', 'BaseClass', 'Caller', 'Derived', 'DerivedClass', 'DoubleHolder'));
+// New vars
+check::globals(array('PrintDebug'));
+
+if (PHP_MAJOR_VERSION < 8) {
+ // Without type declarations since we don't generate them for PHP < 8
+ // and we need to be compatible with method declarations in Base.
+ class PHPDerived extends Base {
+ function Val($x) { return $x; }
+ function Ref($x) { return $x; }
+ function Ptr($x) { return $x; }
+ function ConstPtrRef($x) { return $x; }
+ function FullyOverloaded($x) {
+ $rv = parent::FullyOverloaded($x);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ function SemiOverloaded($x) {
+ # this is going to be awkward because we can't really
+ # semi-overload in PHP, but we can sort of fake it.
+ if (!is_int($x)) {
+ return parent::SemiOverloaded($x);
+ }
+ $rv = parent::SemiOverloaded($x);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ function DefaultParms($x, $y = 1.1) {
+ $rv = parent::DefaultParms($x, $y);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ }
+} else {
+ class PHPDerived extends Base {
+ function Val(DoubleHolder $x) { return $x; }
+ function Ref(DoubleHolder $x) { return $x; }
+ // PHP 7.0 fails to parse the `?` - revert once we drop 7.0 support:
+ // function Ptr(?DoubleHolder $x) { return $x; }
+ function Ptr($x) { return $x; }
+ // PHP 7.0 fails to parse the `?` - revert once we drop 7.0 support:
+ // function ConstPtrRef(?DoubleHolder $x) { return $x; }
+ function ConstPtrRef($x) { return $x; }
+ function FullyOverloaded($x) {
+ $rv = parent::FullyOverloaded($x);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ function SemiOverloaded($x) {
+ # this is going to be awkward because we can't really
+ # semi-overload in PHP, but we can sort of fake it.
+ if (!is_int($x)) {
+ return parent::SemiOverloaded($x);
+ }
+ $rv = parent::SemiOverloaded($x);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ function DefaultParms(int $x, float $y = 1.1) {
+ $rv = parent::DefaultParms($x, $y);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ }
+}
+
+{
+ $c = new Caller();
+ makeCalls($c, new Base(100.0));
+ makeCalls($c, new Derived(200.0));
+ makeCalls($c, new PHPDerived(300.0));
+}
+
+function makeCalls($caller, $base) {
+ $bname = get_class($base);
+ if ($bname == 'PHPDerived') {
+ // TODO: Debug and make this work:
+ return;
+ }
+ $caller->set($base);
+ $dh = new DoubleHolder(444.555);
+ check::equal($caller->ValCall($dh)->val, $dh->val, "$bname.Val");
+ check::equal($caller->RefCall($dh)->val, $dh->val, "$bname.Ref");
+ check::equal($caller->PtrCall($dh)->val, $dh->val, "$bname.Ptr");
+ check::equal($caller->ConstPtrRefCall($dh)->val, $dh->val, "$bname.ConstPtrRef");
+ check::equal($caller->FullyOverloadedCall(1),
+ "{$bname}::FullyOverloaded(int)",
+ "$bname.FullyOverloaded(int)");
+ check::equal($caller->FullyOverloadedCall(false),
+ "{$bname}::FullyOverloaded(bool)",
+ "$bname.FullyOverloaded(bool)");
+ // This next one is TODO for Perl with PerlDerived.
+ check::equal($caller->SemiOverloadedCall(-678),
+ "{$bname}::SemiOverloaded(int)",
+ "$bname.SemiOverloaded(int)");
+ check::equal($caller->SemiOverloadedCall(false),
+ "Base::SemiOverloaded(bool)",
+ "$bname.SemiOverloaded(bool)");
+ check::equal($caller->DefaultParmsCall(10, 2.2),
+ "{$bname}::DefaultParms(int, double)",
+ "$bname.DefaultParms(int, double)");
+ check::equal($caller->DefaultParmsCall(10),
+ "{$bname}::DefaultParms(int)",
+ "$bname.DefaultParms(int)");
+ $caller->reset();
+}
+
+check::done();
diff --git a/Examples/test-suite/php/director_detect_runme.php b/Examples/test-suite/php/director_detect_runme.php
index ae92f7a0c..b9d0a6e0a 100644
--- a/Examples/test-suite/php/director_detect_runme.php
+++ b/Examples/test-suite/php/director_detect_runme.php
@@ -10,6 +10,8 @@ check::classes(array('A','Foo','Bar'));
check::globals(array());
class MyBar extends Bar {
+ public $val;
+
function __construct($val = 2) {
parent::__construct();
$this->val = $val;
diff --git a/Examples/test-suite/php/director_exception_catches_runme.php b/Examples/test-suite/php/director_exception_catches_runme.php
new file mode 100644
index 000000000..51c5663d5
--- /dev/null
+++ b/Examples/test-suite/php/director_exception_catches_runme.php
@@ -0,0 +1,26 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+// New classes
+check::classes(array('BaseClass'));
+// No new vars
+check::globals(array());
+
+class MyClass extends BaseClass {
+ function description() {
+ throw new Exception("Testing exception thrown in description()");
+ }
+}
+
+$b = new MyClass();
+try {
+ BaseClass::call_description($b);
+ check::fail("No exception thrown by BaseClass::call_description(\$b)");
+} catch (Exception $e) {
+ check::equal($e->getMessage(), "Testing exception thrown in description()", "Unexpected exception message: ".$e->getMessage());
+}
+
+check::done();
diff --git a/Examples/test-suite/php/director_exception_nothrow_runme.php b/Examples/test-suite/php/director_exception_nothrow_runme.php
new file mode 100644
index 000000000..2bc4a0c4a
--- /dev/null
+++ b/Examples/test-suite/php/director_exception_nothrow_runme.php
@@ -0,0 +1,23 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+// New classes
+check::classes(array('Bar', 'Base'));
+// No new vars
+check::globals(array());
+
+class MyBar extends Bar {
+ function pang() {
+ return "MyBar::pang()";
+ }
+}
+
+$a = new MyBar();
+check::equal($a->pang(), "MyBar::pang()", "MyBar::pang() not called as expected");
+$b = new Bar();
+check::equal($b->pang(), "Bar::pang()", "Bar::pang() not called as expected");
+
+check::done();
diff --git a/Examples/test-suite/php/director_exception_runme.php b/Examples/test-suite/php/director_exception_runme.php
index e49c12da6..6f33df028 100644
--- a/Examples/test-suite/php/director_exception_runme.php
+++ b/Examples/test-suite/php/director_exception_runme.php
@@ -3,13 +3,15 @@
require "tests.php";
// New functions
-check::functions(array('launder','is_python_builtin'));
+check::functions(array('launder'));
// New classes
check::classes(array('director_exception','Foo','Exception1','Exception2','Base','Bar','ReturnAllTypes'));
// No new vars
check::globals(array());
class MyException extends Exception {
+ public $msg;
+
function __construct($a, $b) {
$this->msg = $a . $b;
}
diff --git a/Examples/test-suite/php/director_extend_runme.php b/Examples/test-suite/php/director_extend_runme.php
index 418985476..3c6dd6b1d 100644
--- a/Examples/test-suite/php/director_extend_runme.php
+++ b/Examples/test-suite/php/director_extend_runme.php
@@ -17,6 +17,6 @@ class MyObject extends SpObject{
$m = new MyObject();
check::equal($m->dummy(), 666, "1st call");
-check::equal($m->dummy(), 666, "2st call"); // Locked system
+check::equal($m->dummy(), 666, "2nd call"); // Locked system
check::done();
diff --git a/Examples/test-suite/php/director_ignore_runme.php b/Examples/test-suite/php/director_ignore_runme.php
new file mode 100644
index 000000000..87bc4757d
--- /dev/null
+++ b/Examples/test-suite/php/director_ignore_runme.php
@@ -0,0 +1,24 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('DAbstractIgnores','DIgnores','DTemplateAbstractIgnoresInt','DIgnoreConstructor','DIgnoreOnlyConstructor','DIgnoreDestructor'));
+// No new vars
+check::globals(array());
+
+class DIgnoresDerived extends DIgnores {
+ function PublicMethod1() {
+ return 18.75;
+ }
+}
+
+class DAbstractIgnoresDerived extends DAbstractIgnores {
+}
+
+$a = new DIgnoresDerived();
+check::equal($a->Triple(5), 15, "Wrong return value");
+
+$b = new DAbstractIgnoresDerived();
+check::equal($b->Quadruple(5), 20, "Wrong return value");
diff --git a/Examples/test-suite/php/director_ownership_runme.php b/Examples/test-suite/php/director_ownership_runme.php
new file mode 100644
index 000000000..a78fb9c03
--- /dev/null
+++ b/Examples/test-suite/php/director_ownership_runme.php
@@ -0,0 +1,28 @@
+<?php
+require "tests.php";
+
+check::functions(array('make_content'));
+check::classes(array('ContentBase','ContentDerived','Container','director_ownership'));
+// No new vars
+check::globals(array());
+
+function set_content_and_release(Container $container, ContentBase $content) {
+ $content->thisown = false;
+ $container->set_content($content);
+}
+
+$container = new Container();
+
+// make a content in PHP (newobject is 1)
+$content_php = new ContentDerived();
+
+// make a content in C++ (newobject is 1)
+$content_cpp = make_content();
+
+set_content_and_release($container, $content_php);
+check::equal($container->get_content()->get_name(), "ContentDerived", "get_content() not ContentDerived");
+
+set_content_and_release($container, $content_cpp);
+check::equal($container->get_content()->get_name(), "ContentDerived", "get_content() not ContentDerived");
+
+check::done();
diff --git a/Examples/test-suite/php/director_pass_by_value_runme.php b/Examples/test-suite/php/director_pass_by_value_runme.php
index d3763292f..b8f1bb9f9 100644
--- a/Examples/test-suite/php/director_pass_by_value_runme.php
+++ b/Examples/test-suite/php/director_pass_by_value_runme.php
@@ -14,6 +14,9 @@ class director_pass_by_value_Derived extends DirectorPassByValueAbstractBase {
# bug was the passByVal global object was destroyed after the call to virtualMethod had finished.
$caller = new Caller();
$caller->call_virtualMethod(new director_pass_by_value_Derived());
+if (has_cplusplus11()) {
+ Counter::check_counts(1, 0, 0, 1, 0, 1); # check move constructor called and just one destructor
+}
$ret = $passByVal->getVal();
if ($ret != 0x12345678) {
check::fail("Bad return value, got " . dechex($ret));
diff --git a/Examples/test-suite/php/director_stl_runme.php b/Examples/test-suite/php/director_stl_runme.php
index 654251a30..031a87ae7 100644
--- a/Examples/test-suite/php/director_stl_runme.php
+++ b/Examples/test-suite/php/director_stl_runme.php
@@ -26,7 +26,7 @@ class MyFoo extends Foo {
return $v;
}
- function vsecond($v1, $v2) {
+ function vsecond($v1, $v2 = NULL) {
return $v2;
}
}
diff --git a/Examples/test-suite/php/director_string_runme.php b/Examples/test-suite/php/director_string_runme.php
index 3127f13fb..f146898c3 100644
--- a/Examples/test-suite/php/director_string_runme.php
+++ b/Examples/test-suite/php/director_string_runme.php
@@ -10,6 +10,8 @@ check::classes(array('A','StringVector'));
check::globals(array());
class B extends A {
+ public $smem;
+
function get_first() {
return parent::get_first() . " world!";
}
diff --git a/Examples/test-suite/php/director_wombat_runme.php b/Examples/test-suite/php/director_wombat_runme.php
new file mode 100644
index 000000000..3e308044f
--- /dev/null
+++ b/Examples/test-suite/php/director_wombat_runme.php
@@ -0,0 +1,52 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('Bar', 'Foo_integers'));
+// No new vars
+check::globals(array());
+
+// Test base class functionality
+$barObj = new Bar();
+
+// Bar::meth should return a Foo_integers instance
+$fooIntsObj = $barObj->meth();
+check::equal(get_class($fooIntsObj), "Foo_integers", "wrong class");
+
+check::equal($fooIntsObj->meth(42) , 42, "Foo_integers::meth(n) should return n");
+
+//
+// Now subclass Foo_integers, but override its virtual method
+// meth(n) so that it returns the number plus one.
+//
+class MyFooInts extends Foo_integers {
+ function meth($n) {
+ return $n + 1;
+ }
+}
+
+//
+// Subclass Bar and override its virtual method meth()
+// so that it returns a new MyFooInts instance instead of
+// a Foo_integers instance.
+//
+class MyBar extends Bar {
+ function meth() {
+ return new MyFooInts();
+ }
+}
+
+//
+// Now repeat previous tests:
+//
+// Create a MyBar instance...
+//
+$barObj = new MyBar();
+
+// MyBar::meth should return a MyFooInts instance
+$fooIntsObj = $barObj->meth();
+check::equal(get_class($fooIntsObj), "MyFooInts", "wrong class");
+
+check::equal($fooIntsObj->meth(42) , 43, "MyFooInts::meth(n) should return n + 1");
diff --git a/Examples/test-suite/php/exception_memory_leak_runme.php b/Examples/test-suite/php/exception_memory_leak_runme.php
new file mode 100644
index 000000000..116ab2f0e
--- /dev/null
+++ b/Examples/test-suite/php/exception_memory_leak_runme.php
@@ -0,0 +1,35 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('trigger_internal_swig_exception'));
+check::classes(array('Foo', 'exception_memory_leak'));
+// No new vars
+check::globals(array());
+
+$a = new Foo();
+check::equal(Foo::get_count(), 1, "Should have 1 Foo objects");
+$b = new Foo();
+check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
+
+// Normal behaviour
+trigger_internal_swig_exception("no problem", $a);
+check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
+check::equal(Foo::get_freearg_count(), 1, "freearg should have been used once");
+
+// SWIG exception triggered and handled (return new object case).
+try {
+ trigger_internal_swig_exception("null", $b);
+ check::fail("Expected exception not thrown");
+} catch (Exception $e) {
+}
+check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
+check::equal(Foo::get_freearg_count(), 2, "freearg should have been used twice");
+
+// SWIG exception triggered and handled (return by value case).
+try {
+ trigger_internal_swig_exception("null");
+ check::fail("Expected exception not thrown");
+} catch (Exception $e) {
+}
+check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
diff --git a/Examples/test-suite/php/exception_order_runme.php b/Examples/test-suite/php/exception_order_runme.php
index 9a2c9118b..835a83ca3 100644
--- a/Examples/test-suite/php/exception_order_runme.php
+++ b/Examples/test-suite/php/exception_order_runme.php
@@ -1,7 +1,7 @@
-<?
+<?php
require "tests.php";
-check::functions(array('is_python_builtin'));
+check::functions(array());
check::classes(array('A','E1','E2','E3','exception_order','ET_i','ET_d'));
check::globals(array('efoovar','foovar','cfoovar'));
@@ -35,3 +35,5 @@ try {
} catch (Exception $e) {
check::equal($e->getMessage(), 'C++ E2 * exception thrown', '');
}
+
+check::done();
diff --git a/Examples/test-suite/php/friends_runme.php b/Examples/test-suite/php/friends_runme.php
new file mode 100644
index 000000000..f0ef5df58
--- /dev/null
+++ b/Examples/test-suite/php/friends_runme.php
@@ -0,0 +1,37 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('globalscope','mix','get_val2','get_val3','bas','baz','bar','get_val1','set'));
+check::classes(array('friends','Foo','A','B','D_i','D_d'));
+// No new vars
+check::globals(array());
+
+$a = new A(2);
+
+check::equal(get_val1($a), 2);
+check::equal(get_val2($a), 4);
+check::equal(get_val3($a), 6);
+
+# nice overload working fine
+check::equal(get_val1(1, 2, 3), 1);
+
+$b = new B(3);
+
+# David's case
+check::equal(mix($a, $b), 5);
+
+$di = new D_i(2);
+$dd = new D_d(3.3);
+
+# incredible template overloading working just fine
+check::equal(get_val1($di), 2);
+check::equal(get_val1($dd), 3.3);
+
+set($di, 4);
+set($dd, 1.3);
+
+check::equal(get_val1($di), 4);
+check::equal(get_val1($dd), 1.3);
+
+check::done();
diff --git a/Examples/test-suite/php/ignore_parameter_runme.php b/Examples/test-suite/php/ignore_parameter_runme.php
index d9db2d795..90b82d7da 100644
--- a/Examples/test-suite/php/ignore_parameter_runme.php
+++ b/Examples/test-suite/php/ignore_parameter_runme.php
@@ -7,7 +7,7 @@ check::functions(array('jaguar','lotus','tvr','ferrari','fiat'));
// New classes
check::classes(array('ignore_parameter','SportsCars','MiniCooper','MorrisMinor','FordAnglia','AustinAllegro'));
// No new vars
-check::globals(array());
+check::globals(array('called_argout'));
check::equal(jaguar(2,3.4),"hello",'jaguar(2,3.4)=="hello"');
check::equal(lotus("eek",3.4),101,'lotus("eek",3.4)==101');
@@ -17,7 +17,7 @@ check::equal(ferrari(),101,'ferrari(2)==101');
$sc=new sportscars();
check::classname("sportscars",$sc);
check::equal($sc->daimler(2,3.4),"hello",'$sc->daimler(2,3.4)=="hello"');
-check::equal($sc->astonmartin("eek",3.4),101,'$sc->mastonmartin("eek",3.4)==101');
+check::equal($sc->astonmartin("eek",3.4),101,'$sc->astonmartin("eek",3.4)==101');
check::equal($sc->bugatti("eek",2),8.8,'$sc->bugatti("eek",2)==8.8');
check::equal($sc->lamborghini(),101,'$sc->lamborghini(2)==101');
diff --git a/Examples/test-suite/php/import_nomodule_runme.php b/Examples/test-suite/php/import_nomodule_runme.php
index e639c781d..3dda18b0d 100644
--- a/Examples/test-suite/php/import_nomodule_runme.php
+++ b/Examples/test-suite/php/import_nomodule_runme.php
@@ -2,7 +2,8 @@
require "tests.php";
-check::functions(array('is_python_builtin'));
+// No new functions
+check::functions(array());
check::classes(array('import_nomodule'));
// No new globals
check::globals(array());
diff --git a/Examples/test-suite/php/li_factory_runme.php b/Examples/test-suite/php/li_factory_runme.php
index 3ccdd035f..18545fec7 100644
--- a/Examples/test-suite/php/li_factory_runme.php
+++ b/Examples/test-suite/php/li_factory_runme.php
@@ -17,4 +17,7 @@ $point = Geometry::create(Geometry::POINT);
$w = $point->width();
check::equal($w, 1.0, "w failed");
+$point = Geometry::create(Geometry::SHAPELESS);
+check::equal($point, NULL, "NULL failed");
+
check::done();
diff --git a/Examples/test-suite/php/li_std_auto_ptr_runme.php b/Examples/test-suite/php/li_std_auto_ptr_runme.php
new file mode 100644
index 000000000..7ebcf97b1
--- /dev/null
+++ b/Examples/test-suite/php/li_std_auto_ptr_runme.php
@@ -0,0 +1,108 @@
+<?php
+
+require "tests.php";
+
+function checkCount($expected_count) {
+ $actual_count = Klass::getTotal_count();
+ check::equal($actual_count, $expected_count, "Counts incorrect");
+}
+
+# Test raw pointer handling involving virtual inheritance
+$kini = new KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+$s = useKlassRawPtr($kini);
+check::equal($s, "KlassInheritanceInput", "Incorrect string: $s");
+$kini = NULL;
+checkCount(0);
+
+
+# auto_ptr as input
+$kin = new Klass("KlassInput");
+checkCount(1);
+$s = takeKlassAutoPtr($kin);
+checkCount(0);
+check::equal($s, "KlassInput", "Incorrect string: $s");
+try {
+ is_nullptr($kin);
+ check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$kin = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+$kin = new Klass("KlassInput");
+checkCount(1);
+$s = takeKlassAutoPtr($kin);
+checkCount(0);
+check::equal($s, "KlassInput", "Incorrect string: $s");
+try {
+ is_nullptr($kin);
+ check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$exception_thrown = false;
+try {
+ takeKlassAutoPtr($kin);
+} catch (TypeError $e) {
+ check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassAutoPtr", "Unexpected exception: {$e->getMessage()}");
+ $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassAutoPtr should have been an error");
+$kin = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+$kin = new Klass("KlassInput");
+$exception_thrown = false;
+$notowned = get_not_owned_ptr($kin);
+try {
+ takeKlassAutoPtr($notowned);
+} catch (TypeError $e) {
+ check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassAutoPtr", "Unexpected exception: {$e->getMessage()}");
+ $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassAutoPtr should have been an error");
+checkCount(1);
+$kin = NULL;
+checkCount(0);
+
+$kini = new KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+$s = takeKlassAutoPtr($kini);
+checkCount(0);
+check::equal($s, "KlassInheritanceInput", "Incorrect string: $s");
+try {
+ is_nullptr($kini);
+ check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+
+$kini = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+takeKlassAutoPtr(NULL);
+takeKlassAutoPtr(make_null());
+checkCount(0);
+
+# overloaded parameters
+check::equal(overloadTest(), 0, "overloadTest failed");
+check::equal(overloadTest(NULL), 1, "overloadTest failed");
+check::equal(overloadTest(new Klass("over")), 1, "overloadTest failed");
+checkCount(0);
+
+
+# auto_ptr as output
+$k1 = makeKlassAutoPtr("first");
+$k2 = makeKlassAutoPtr("second");
+checkCount(2);
+
+$k1 = NULL;
+checkCount(1);
+
+check::equal($k2->getLabel(), "second", "proper label");
+
+$k2 = NULL;
+checkCount(0);
+
+check::equal(makeNullAutoPtr(), NULL);
+
+check::done();
diff --git a/Examples/test-suite/php/long_long_runme.php b/Examples/test-suite/php/long_long_runme.php
new file mode 100644
index 000000000..544a59c18
--- /dev/null
+++ b/Examples/test-suite/php/long_long_runme.php
@@ -0,0 +1,65 @@
+<?php
+// This is the long_long runtime testcase. It checks that the long long and
+// unsigned long long types map correctly to PHP int or string (for values
+// which don't fit in a PHP int).
+
+require "tests.php";
+
+check::functions(array("foo1","foo2","foo3","foo4","foo5","foo6","bar1","bar2","bar3","bar4","bar5","bar6","UnsignedToSigned"));
+check::classes(array("long_long"));
+check::globals(array("ll","ull"));
+
+function check_ll($ll) {
+ long_long::ll_set($ll);
+ check::equivalent($ll, long_long::ll_get(), "Round tripping of long long failed");
+}
+
+function check_ull($ull) {
+ long_long::ull_set($ull);
+ check::equivalent($ull, long_long::ull_get(), "Round tripping of unsigned long long failed");
+}
+
+check_ll("0");
+check_ll(0);
+check_ll("9223372036854775807"); // 0x7FFFFFFFFFFFFFFF
+if ((int)0x100000000 !== 0) {
+ // This check doesn't work if PHP int is 32 bits.
+ check_ll(0x7FFFFFFFFFFFFFFF);
+}
+check_ll(-10);
+
+$testNumber = 0;
+const COUNT = 1025;
+
+for ($i=0; $i<COUNT; $i++) {
+ check_ull($testNumber);
+ $testNumber += 1;
+}
+
+$testNumber = 256*256/2-COUNT;
+for ($i=0; $i<COUNT*2; $i++) {
+ check_ull($testNumber);
+ $testNumber += 1;
+}
+
+$testNumber = 256*256-COUNT;
+for ($i=0; $i<COUNT*2; $i++) {
+ check_ull($testNumber);
+ $testNumber += 1;
+}
+
+$testNumber = 0x7FFFFFFFFFFFFFFF-COUNT;
+for ($i=0; $i<COUNT*2; $i++) {
+ check_ull($testNumber);
+ $testNumber += 1;
+}
+
+// Check that conversion from unsigned long long to long long gives expected
+// value (including negative numbers)
+
+check::equal(long_long::UnsignedToSigned(0), 0, "UnsignedToSigned test failed");
+check::equal(long_long::UnsignedToSigned(0xff), 0xff, "UnsignedToSigned test failed");
+check::equal(long_long::UnsignedToSigned(-0xff), -0xff, "UnsignedToSigned test failed");
+check::equal(long_long::UnsignedToSigned(-1), -1, "UnsignedToSigned test failed");
+
+check::done();
diff --git a/Examples/test-suite/php/member_pointer_const_runme.php b/Examples/test-suite/php/member_pointer_const_runme.php
index 3f55549a8..bd8eaa87c 100644
--- a/Examples/test-suite/php/member_pointer_const_runme.php
+++ b/Examples/test-suite/php/member_pointer_const_runme.php
@@ -57,3 +57,5 @@ check::equal(3, member_pointer_const::call1(member_pointer_const::ADD_BY_VALUE,
check::equal(7, member_pointer_const::call2(member_pointer_const::ADD_BY_VALUE, 3, 4), "Add by pointer");
check::equal(11, member_pointer_const::call3(member_pointer_const::ADD_BY_VALUE, 5, 6), "Add by reference");
*/
+
+check::done();
diff --git a/Examples/test-suite/php/newobject1_runme.php b/Examples/test-suite/php/newobject1_runme.php
index a495ab15d..464f09b0b 100644
--- a/Examples/test-suite/php/newobject1_runme.php
+++ b/Examples/test-suite/php/newobject1_runme.php
@@ -9,9 +9,16 @@ check::classes(array('Foo'));
// No new vars
check::globals(array());
+check::equal(Foo::fooCount(), 0, "no Foo objects expected");
$foo = Foo::makeFoo();
check::equal(get_class($foo), "Foo", "static failed");
+check::equal(Foo::fooCount(), 1, "1 Foo object expected");
$bar = $foo->makeMore();
check::equal(get_class($bar), "Foo", "regular failed");
+check::equal(Foo::fooCount(), 2, "2 Foo objects expected");
+$foo = null;
+check::equal(Foo::fooCount(), 1, "1 Foo object expected");
+$bar = null;
+check::equal(Foo::fooCount(), 0, "no Foo objects expected");
check::done();
diff --git a/Examples/test-suite/php/newobject2_runme.php b/Examples/test-suite/php/newobject2_runme.php
new file mode 100644
index 000000000..f20a6a4f9
--- /dev/null
+++ b/Examples/test-suite/php/newobject2_runme.php
@@ -0,0 +1,17 @@
+<?php
+
+require "tests.php";
+
+check::equal(fooCount(), 0, "no Foo objects expected");
+$foo = makeFoo();
+check::equal(get_class($foo), "Foo", "static failed");
+check::equal(fooCount(), 1, "1 Foo object expected");
+$bar = makeFoo();
+check::equal(get_class($bar), "Foo", "regular failed");
+check::equal(fooCount(), 2, "2 Foo objects expected");
+$foo = null;
+check::equal(fooCount(), 1, "1 Foo object expected");
+$bar = null;
+check::equal(fooCount(), 0, "no Foo objects expected");
+
+check::done();
diff --git a/Examples/test-suite/php/newobject3_runme.php b/Examples/test-suite/php/newobject3_runme.php
index 8efa9891d..29e16be61 100644
--- a/Examples/test-suite/php/newobject3_runme.php
+++ b/Examples/test-suite/php/newobject3_runme.php
@@ -13,3 +13,5 @@ check::isnull($factory->create(0), "create(0) should be NULL");
check::isnull($factory->create(7, -1), "create(7, -1) should be NULL");
check::isnull($factory->create(0, -1), "create(0, -1) should be NULL");
check::isnull($factory->create("bad", -1), "create(\"bad\", -1) should be NULL");
+
+check::done();
diff --git a/Examples/test-suite/php/overload_bool_runme.php b/Examples/test-suite/php/overload_bool_runme.php
new file mode 100644
index 000000000..e477330ef
--- /dev/null
+++ b/Examples/test-suite/php/overload_bool_runme.php
@@ -0,0 +1,42 @@
+<?php
+require "tests.php";
+
+# Overloading bool, int, string
+check::equal(overloaded(true), "bool", "wrong!");
+check::equal(overloaded(false), "bool", "wrong!");
+
+check::equal(overloaded(0), "int", "wrong!");
+check::equal(overloaded(1), "int", "wrong!");
+check::equal(overloaded(2), "int", "wrong!");
+
+check::equal(overloaded("1234"), "string", "wrong!");
+
+# Test bool masquerading as int
+check::equal(intfunction(true), "int", "wrong!");
+check::equal(intfunction(false), "int", "wrong!");
+
+# Test int masquerading as bool
+check::equal(boolfunction(1), "true", "wrong!");
+check::equal(boolfunction(0), "false", "wrong!");
+
+#############################################
+
+# Overloading bool, int, string
+check::equal(overloaded_ref(true), "bool", "wrong!");
+check::equal(overloaded_ref(false), "bool", "wrong!");
+
+check::equal(overloaded_ref(0), "int", "wrong!");
+check::equal(overloaded_ref(1), "int", "wrong!");
+check::equal(overloaded_ref(2), "int", "wrong!");
+
+check::equal(overloaded_ref("1234"), "string", "wrong!");
+
+# Test bool masquerading as int
+check::equal(intfunction_ref(true), "int", "wrong!");
+check::equal(intfunction_ref(false), "int", "wrong!");
+
+# Test int masquerading as bool
+check::equal(boolfunction(1), "true", "wrong!");
+check::equal(boolfunction(0), "false", "wrong!");
+
+check::done();
diff --git a/Examples/test-suite/php/overload_complicated_runme.php b/Examples/test-suite/php/overload_complicated_runme.php
new file mode 100644
index 000000000..6a5f8b480
--- /dev/null
+++ b/Examples/test-suite/php/overload_complicated_runme.php
@@ -0,0 +1,39 @@
+<?php
+require "tests.php";
+
+$pInt = NULL;
+
+# Check the correct constructors are available
+$p = new Pop($pInt);
+
+$p = new Pop($pInt, false);
+
+# Check overloaded in const only and pointers/references which target
+# languages cannot disambiguate
+check::equal($p->hip(false), 701, "Test 1 failed");
+
+check::equal($p->hip($pInt), 702, "Test 2 failed");
+
+# Reverse the order for the above
+check::equal($p->hop($pInt), 805, "Test 3 failed");
+
+check::equal($p->hop(false), 801, "Test 4 failed");
+
+# Few more variations and order shuffled
+check::equal($p->pop(false), 901, "Test 5 failed");
+
+check::equal($p->pop($pInt), 904, "Test 6 failed");
+
+check::equal($p->pop(), 905, "Test 7 failed");
+
+# Overload on const only
+check::equal($p->bop($pInt), 1001, "Test 8 failed");
+
+check::equal($p->bip($pInt), 2002, "Test 9 failed");
+
+# Globals
+check::equal(muzak(false), 3001, "Test 10 failed");
+
+check::equal(muzak($pInt), 3002, "Test 11 failed");
+
+check::done();
diff --git a/Examples/test-suite/php/overload_copy_runme.php b/Examples/test-suite/php/overload_copy_runme.php
new file mode 100644
index 000000000..893a715c5
--- /dev/null
+++ b/Examples/test-suite/php/overload_copy_runme.php
@@ -0,0 +1,13 @@
+<?php
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('Foo'));
+// No new vars
+check::globals(array());
+
+$f = new Foo();
+$g = new Foo($f);
+
+check::done();
diff --git a/Examples/test-suite/php/overload_extend2_runme.php b/Examples/test-suite/php/overload_extend2_runme.php
new file mode 100644
index 000000000..6964a0d7a
--- /dev/null
+++ b/Examples/test-suite/php/overload_extend2_runme.php
@@ -0,0 +1,16 @@
+<?php
+require "tests.php";
+
+$f = new Foo();
+check::equal($f->test(3), 1, '$f->test(3)');
+check::equal($f->test("hello"), 2, '$f->test("hello")');
+check::equal($f->test(3.5, 2.5), 3, '$f->test(3.5, 2.5)');
+check::equal($f->test("hello", 20), 1020, '$f->test("hello", 20)');
+check::equal($f->test("hello", 20, 100), 120, '$f->test("hello", 20, 100)');
+
+// C default args
+check::equal($f->test($f), 30, '$f->test(f)');
+check::equal($f->test($f, 100), 120, '$f->test(f, 100)');
+check::equal($f->test($f, 100, 200), 300, '$f->test(f, 100, 200)');
+
+check::done();
diff --git a/Examples/test-suite/php/overload_extend_c_runme.php b/Examples/test-suite/php/overload_extend_c_runme.php
new file mode 100644
index 000000000..55f426c13
--- /dev/null
+++ b/Examples/test-suite/php/overload_extend_c_runme.php
@@ -0,0 +1,11 @@
+<?php
+require "tests.php";
+
+$f = new Foo();
+check::equal($f->test(), 0, '$f->test()');
+check::equal($f->test(3), 1, '$f->test(3)');
+check::equal($f->test("hello"), 2, '$f->test("hello")');
+check::equal($f->test(3.0, 2.0), 5.0, '$f->test(3, 2)');
+check::equal($f->test(3.0), 1003.0, '$f->test(3.0)');
+
+check::done();
diff --git a/Examples/test-suite/php/overload_extend_runme.php b/Examples/test-suite/php/overload_extend_runme.php
new file mode 100644
index 000000000..89c0499eb
--- /dev/null
+++ b/Examples/test-suite/php/overload_extend_runme.php
@@ -0,0 +1,11 @@
+<?php
+require "tests.php";
+
+$f = new Foo();
+check::equal($f->test(), 0, '$f->test()');
+check::equal($f->test(3), 1, '$f->test(3)');
+check::equal($f->test("hello"), 2, '$f->test("hello")');
+check::equal($f->test(3.0, 2.0), 5.0, '$f->test(3.0, 2.0)');
+check::equal($f->test(3.0), 1003.0, '$f->test(3.0)');
+
+check::done();
diff --git a/Examples/test-suite/php/overload_return_type_runme.php b/Examples/test-suite/php/overload_return_type_runme.php
index 5f01bbe19..f03a85d7f 100644
--- a/Examples/test-suite/php/overload_return_type_runme.php
+++ b/Examples/test-suite/php/overload_return_type_runme.php
@@ -8,3 +8,5 @@ check::classname("A", $b->foo("test"));
check::equal(overload_return_type::foo(), 1, "overload_return_type::foo() should be 1");
check::equal(overload_return_type::bar(), 1, "overload_return_type::bar() should be 1");
+
+check::done();
diff --git a/Examples/test-suite/php/overload_simple_runme.php b/Examples/test-suite/php/overload_simple_runme.php
new file mode 100644
index 000000000..949de9d98
--- /dev/null
+++ b/Examples/test-suite/php/overload_simple_runme.php
@@ -0,0 +1,195 @@
+<?php
+require "tests.php";
+
+check::functions(array('foo','blah','fbool','fint','fdouble','num','fid','ull','ll','malloc_void','free_void','int_object'));
+check::classes(array('Foo','Bar','overload_simple','Spam','ClassA'));
+// No new vars
+check::globals(array());
+
+$f = new Foo();
+check::classname("Foo", $f);
+$b = new Bar();
+check::classname("Bar", $b);
+$v = overload_simple::malloc_void(32);
+check::classname("SWIG\_p_void", $v);
+
+#
+# 'simple' dispatch (no overload) of int and double arguments
+#
+
+check::equal(overload_simple::fint(3), "fint:int", "fint(int) - int");
+
+check::equal(overload_simple::fint("1"), "fint:int", "fint(int) - string int");
+
+check::equal(overload_simple::fint(3.0), "fint:int", "fint(int) - double");
+
+check::equal(overload_simple::fint("3.0"), "fint:int", "fint(int) - string double");
+
+# Test handling of cases which aren't simple numbers.
+
+check::equal(overload_simple::fint("l"), "fint:int", "fint(int) - int");
+
+check::equal(overload_simple::fdouble("l"), "fdouble:double", "fint(double) - int");
+
+check::equal(overload_simple::fdouble("1.5/2.0"), "fdouble:double", "fint(double) - double");
+
+# adapted from Perl regression testcase
+$n = 3;
+$n = $n + 1;
+check::equal(overload_simple::fint($n), "fint:int", "fint(int) - int var");
+
+check::equal(overload_simple::fint(4/2), "fint:int", "fint(int) - divide int denom");
+
+check::equal(overload_simple::fint(4/2.0), "fint:int", "fint(int) - divide double denom");
+
+check::equal(overload_simple::fdouble(3), "fdouble:double", "fdouble(double) - int");
+
+check::equal(overload_simple::fdouble("3"), "fdouble:double", "fdouble(double) - string int");
+
+check::equal(overload_simple::fdouble(3.0), "fdouble:double", "fdouble(double) - double");
+
+check::equal(overload_simple::fdouble("3.0"), "fdouble:double", "fdouble(double) - string doubl");
+
+#
+# Overload between int and double
+#
+check::equal(overload_simple::num(3), "num:int", "num(int) - int");
+
+check::equal(overload_simple::num(3.0), "num:double", "num(int) - double");
+
+#
+# Overload between int, double, char * and many types.
+#
+check::equal(overload_simple::foo(3), "foo:int", "foo:int - int");
+
+check::equal(overload_simple::foo(3.0), "foo:double", "foo:double - double");
+
+check::equal(overload_simple::foo("3"), "foo:char *", "foo:char * - string int");
+
+check::equal(overload_simple::foo("3.0"), "foo:char *", "foo:char * - string double");
+
+check::equal(overload_simple::foo("hello"), "foo:char *", "foo:char * string");
+
+check::equal(overload_simple::foo($f), "foo:Foo *", "foo:Foo *");
+
+check::equal(overload_simple::foo($b), "foo:Bar *", "foo:Bar *");
+
+check::equal(overload_simple::foo($v), "foo:void *", "foo:void *");
+
+check::equal(overload_simple::blah("hello"), "blah:char *", "blah:char *");
+
+$s = new Spam();
+
+check::equal($s->foo(3), "foo:int", "Spam::foo:int");
+
+check::equal($s->foo(3.0), "foo:double", "Spam::foo(double)");
+
+check::equal($s->foo("hello"), "foo:char *", "Spam::foo:char *");
+
+check::equal($s->foo($f), "foo:Foo *", "Spam::foo(Foo *)");
+
+check::equal($s->foo($b), "foo:Bar *", "Spam::foo(Bar *)");
+
+check::equal($s->foo($v), "foo:void *", "Spam::foo(void *)");
+
+check::equal(Spam::bar(3), "bar:int", "Spam::bar(int)");
+
+check::equal(Spam::bar(3.0), "bar:double", "Spam::bar(double)");
+
+check::equal(Spam::bar("hello"), "bar:char *", "Spam::bar(char *)");
+
+check::equal(Spam::bar($f), "bar:Foo *", "Spam::bar(Foo *)");
+
+check::equal(Spam::bar($b), "bar:Bar *", "Spam::bar(Bar *)");
+
+check::equal(Spam::bar($v), "bar:void *", "Spam::bar(void *)");
+
+# Test constructors
+
+$s = new Spam();
+check::is_a($s, "spam");
+
+check::equal($s->type, "none", "Spam()");
+
+$s = new Spam(3);
+check::is_a($s, "spam");
+
+check::equal($s->type, "int", "Spam(int)");
+
+$s = new Spam(3.0);
+check::is_a($s, "spam");
+check::equal($s->type, "double", "Spam(double)");
+
+$s = new Spam("hello");
+check::is_a($s, "spam");
+check::equal($s->type, "char *", "Spam(char *)");
+
+$s = new Spam($f);
+check::is_a($s, "spam");
+check::equal($s->type, "Foo *", "Spam(Foo *)");
+
+$s = new Spam($b);
+check::is_a($s, "spam");
+check::equal($s->type, "Bar *", "Spam(Bar *)");
+
+$s = new Spam($v);
+check::is_a($s, "spam");
+check::equal($s->type, "void *", "Spam(void *)");
+
+#
+# Combine dispatch
+#
+
+check::equal(overload_simple::fid(3, 3.0), "fid:intdouble", "fid(int,double)");
+
+check::equal(overload_simple::fid(3.0, 3), "fid:doubleint", "fid(double,int)");
+
+check::equal(overload_simple::fid(3.0, 3.0), "fid:doubledouble", "fid(double,double)");
+
+check::equal(overload_simple::fid(3, 3), "fid:intint", "fid(int,int)");
+
+check::equal(false, overload_simple::fbool(false), "fbool(bool)");
+check::equal(true, overload_simple::fbool(true), "fbool(bool)");
+check::equal(2, overload_simple::fbool(2), "fbool(int)");
+
+# int and object overload
+
+check::equal(overload_simple::int_object(1), 1, "int_object(1)");
+check::equal(overload_simple::int_object(0), 0, "int_object(0)");
+check::equal(overload_simple::int_object(NULL), 999, "int_object(Spam*)");
+check::equal(overload_simple::int_object($s), 999, "int_object(Spam*)");
+
+function check($args, $want) {
+ if ($want === NULL) {
+ try {
+ eval("return Spam::bar($args);");
+ check::fail("Expected exception");
+ } catch (TypeError $e) {
+ check::equal(substr($e->getMessage(), 0, 35), "No matching function for overloaded", "Not the expected I expected");
+ }
+ return;
+ }
+ check::equal(eval("return Spam::bar($args);"), "bar:$want", "bar($args) => $want");
+}
+
+# normal use patterns
+check("11", 'int');
+check("11.0", 'double');
+check("'11'", 'char *');
+check("'11.0'", 'char *');
+check("-13", 'int');
+check("-13.0", 'double');
+check("'-13'", 'char *');
+check("'-13.0'", 'char *');
+
+check("' '", 'char *');
+check("' 11 '", 'char *');
+
+# Check TypeError is thrown when the wrong type is passed.
+check("array()", NULL);
+check("function(){}", NULL);
+check("new stdClass()", NULL);
+class NotASwigWrappedClass { };
+check("new NotASwigWrappedClass()", NULL);
+
+check::done();
diff --git a/Examples/test-suite/php/overload_subtype_runme.php b/Examples/test-suite/php/overload_subtype_runme.php
new file mode 100644
index 000000000..f12025cf8
--- /dev/null
+++ b/Examples/test-suite/php/overload_subtype_runme.php
@@ -0,0 +1,11 @@
+<?php
+require "tests.php";
+
+$f = new Foo();
+$b = new Bar();
+
+check::equal(spam($f), 1, "foo");
+
+check::equal(spam($b), 2, "bar");
+
+check::done();
diff --git a/Examples/test-suite/php/overload_template_fast_runme.php b/Examples/test-suite/php/overload_template_fast_runme.php
new file mode 100644
index 000000000..7aa19f693
--- /dev/null
+++ b/Examples/test-suite/php/overload_template_fast_runme.php
@@ -0,0 +1,110 @@
+<?php
+
+require "tests.php";
+
+$f = foo();
+
+$a = maximum(3, 4);
+$b = maximum(3.4, 5.2);
+
+# mix 1
+check::equal(mix1("hi"), 101, "mix1(const char*)");
+
+check::equal(mix1(1.0, 1.0), 102, "mix1(double, const double &)");
+
+check::equal(mix1(1.0), 103, "mix1(double)");
+
+# mix 2
+check::equal(mix2("hi"), 101, "mix2(const char*)");
+
+check::equal(mix2(1.0, 1.0), 102, "mix2(double, const double &)");
+
+check::equal(mix2(1.0), 103, "mix2(double)");
+
+# mix 3
+check::equal(mix3("hi"), 101, "mix3(const char*)");
+
+check::equal(mix3(1.0, 1.0), 102, "mix3(double, const double &)");
+
+check::equal(mix3(1.0), 103, "mix3(double)");
+
+# Combination 1
+check::equal(overtparams1(100), 10, "overtparams1(int)");
+
+check::equal(overtparams1(100.0, 100), 20, "overtparams1(double, int)");
+
+# Combination 2
+check::equal(overtparams2(100.0, 100), 40, "overtparams2(double, int)");
+
+# Combination 3
+check::equal(overloaded(), 60, "overloaded()");
+
+check::equal(overloaded(100.0, 100), 70, "overloaded(double, int)");
+
+# Combination 4
+check::equal(overloadedagain("hello"), 80, "overloadedagain(const char *)");
+
+check::equal(overloadedagain(), 90, "overloadedagain(double)");
+
+# specializations
+check::equal(specialization(10), 202, "specialization(int)");
+
+check::equal(specialization(10.0), 203, "specialization(double)");
+
+check::equal(specialization(10, 10), 204, "specialization(int, int)");
+
+check::equal(specialization(10.0, 10.0), 205, "specialization(double, double)");
+
+check::equal(specialization("hi", "hi"), 201, "specialization(const char *, const char *)");
+
+# simple specialization
+xyz();
+xyz_int();
+xyz_double();
+
+# a bit of everything
+check::equal(overload("hi"), 0, "overload()");
+
+check::equal(overload(1), 10, "overload(int t)");
+
+check::equal(overload(1, 1), 20, "overload(int t, const int &)");
+
+check::equal(overload(1, "hello"), 30, "overload(int t, const char *)");
+
+$k = new Klass();
+check::equal(overload($k), 10, "overload(Klass t)");
+
+check::equal(overload($k, $k), 20, "overload(Klass t, const Klass &)");
+
+check::equal(overload($k, "hello"), 30, "overload(Klass t, const char *)");
+
+check::equal(overload(10.0, "hi"), 40, "overload(double t, const char *)");
+
+check::equal(overload(), 50, "overload(const char *)");
+
+# everything put in a namespace
+check::equal(nsoverload("hi"), 1000, "nsoverload()");
+
+check::equal(nsoverload(1), 1010, "nsoverload(int t)");
+
+check::equal(nsoverload(1, 1), 1020, "nsoverload(int t, const int &)");
+
+check::equal(nsoverload(1, "hello"), 1030, "nsoverload(int t, const char *)");
+
+check::equal(nsoverload($k), 1010, "nsoverload(Klass t)");
+
+check::equal(nsoverload($k, $k), 1020, "nsoverload(Klass t, const Klass &)");
+
+check::equal(nsoverload($k, "hello"), 1030, "nsoverload(Klass t, const char *)");
+
+check::equal(nsoverload(10.0, "hi"), 1040, "nsoverload(double t, const char *)");
+
+check::equal(nsoverload(), 1050, "nsoverload(const char *)");
+
+
+A::foo(1);
+$b = new B();
+$b->foo(1);
+
+
+check::done();
diff --git a/Examples/test-suite/php/overload_template_runme.php b/Examples/test-suite/php/overload_template_runme.php
new file mode 100644
index 000000000..7aa19f693
--- /dev/null
+++ b/Examples/test-suite/php/overload_template_runme.php
@@ -0,0 +1,110 @@
+<?php
+
+require "tests.php";
+
+$f = foo();
+
+$a = maximum(3, 4);
+$b = maximum(3.4, 5.2);
+
+# mix 1
+check::equal(mix1("hi"), 101, "mix1(const char*)");
+
+check::equal(mix1(1.0, 1.0), 102, "mix1(double, const double &)");
+
+check::equal(mix1(1.0), 103, "mix1(double)");
+
+# mix 2
+check::equal(mix2("hi"), 101, "mix2(const char*)");
+
+check::equal(mix2(1.0, 1.0), 102, "mix2(double, const double &)");
+
+check::equal(mix2(1.0), 103, "mix2(double)");
+
+# mix 3
+check::equal(mix3("hi"), 101, "mix3(const char*)");
+
+check::equal(mix3(1.0, 1.0), 102, "mix3(double, const double &)");
+
+check::equal(mix3(1.0), 103, "mix3(double)");
+
+# Combination 1
+check::equal(overtparams1(100), 10, "overtparams1(int)");
+
+check::equal(overtparams1(100.0, 100), 20, "overtparams1(double, int)");
+
+# Combination 2
+check::equal(overtparams2(100.0, 100), 40, "overtparams2(double, int)");
+
+# Combination 3
+check::equal(overloaded(), 60, "overloaded()");
+
+check::equal(overloaded(100.0, 100), 70, "overloaded(double, int)");
+
+# Combination 4
+check::equal(overloadedagain("hello"), 80, "overloadedagain(const char *)");
+
+check::equal(overloadedagain(), 90, "overloadedagain(double)");
+
+# specializations
+check::equal(specialization(10), 202, "specialization(int)");
+
+check::equal(specialization(10.0), 203, "specialization(double)");
+
+check::equal(specialization(10, 10), 204, "specialization(int, int)");
+
+check::equal(specialization(10.0, 10.0), 205, "specialization(double, double)");
+
+check::equal(specialization("hi", "hi"), 201, "specialization(const char *, const char *)");
+
+# simple specialization
+xyz();
+xyz_int();
+xyz_double();
+
+# a bit of everything
+check::equal(overload("hi"), 0, "overload()");
+
+check::equal(overload(1), 10, "overload(int t)");
+
+check::equal(overload(1, 1), 20, "overload(int t, const int &)");
+
+check::equal(overload(1, "hello"), 30, "overload(int t, const char *)");
+
+$k = new Klass();
+check::equal(overload($k), 10, "overload(Klass t)");
+
+check::equal(overload($k, $k), 20, "overload(Klass t, const Klass &)");
+
+check::equal(overload($k, "hello"), 30, "overload(Klass t, const char *)");
+
+check::equal(overload(10.0, "hi"), 40, "overload(double t, const char *)");
+
+check::equal(overload(), 50, "overload(const char *)");
+
+# everything put in a namespace
+check::equal(nsoverload("hi"), 1000, "nsoverload()");
+
+check::equal(nsoverload(1), 1010, "nsoverload(int t)");
+
+check::equal(nsoverload(1, 1), 1020, "nsoverload(int t, const int &)");
+
+check::equal(nsoverload(1, "hello"), 1030, "nsoverload(int t, const char *)");
+
+check::equal(nsoverload($k), 1010, "nsoverload(Klass t)");
+
+check::equal(nsoverload($k, $k), 1020, "nsoverload(Klass t, const Klass &)");
+
+check::equal(nsoverload($k, "hello"), 1030, "nsoverload(Klass t, const char *)");
+
+check::equal(nsoverload(10.0, "hi"), 1040, "nsoverload(double t, const char *)");
+
+check::equal(nsoverload(), 1050, "nsoverload(const char *)");
+
+
+A::foo(1);
+$b = new B();
+$b->foo(1);
+
+
+check::done();
diff --git a/Examples/test-suite/php/php_pragma_runme.php b/Examples/test-suite/php/php_pragma_runme.php
index e70f2ceda..cf297701d 100644
--- a/Examples/test-suite/php/php_pragma_runme.php
+++ b/Examples/test-suite/php/php_pragma_runme.php
@@ -2,6 +2,13 @@
require "tests.php";
+// No new functions
+check::functions(array());
+// No new classes
+check::classes(array());
+// No new vars
+check::globals(array());
+
check::equal('1.5',(new ReflectionExtension('php_pragma'))->getVersion(),"1.5==version(php_pragma)");
check::done();
diff --git a/Examples/test-suite/php/prefix_runme.php b/Examples/test-suite/php/prefix_runme.php
index d1c0ab1ea..9f83df1e1 100644
--- a/Examples/test-suite/php/prefix_runme.php
+++ b/Examples/test-suite/php/prefix_runme.php
@@ -2,10 +2,10 @@
require "tests.php";
-// No new functions
-check::functions(array());
+// New functions
+check::functions(array('self'));
// New classes
-check::classes(array('ProjectBar','ProjectFoo'));
+check::classes(array('Project','ProjectBar','ProjectFoo'));
// No new vars
check::globals(array());
@@ -13,4 +13,6 @@ $f = new ProjectFoo();
// This resulted in "Fatal error: Class 'Foo' not found"
$f->get_self();
+Project::self(new ProjectBar());
+
check::done();
diff --git a/Examples/test-suite/php/preproc_constants_c_runme.php b/Examples/test-suite/php/preproc_constants_c_runme.php
index a26892b42..688da52f6 100644
--- a/Examples/test-suite/php/preproc_constants_c_runme.php
+++ b/Examples/test-suite/php/preproc_constants_c_runme.php
@@ -51,6 +51,8 @@ check::equal(gettype(preproc_constants_c::EXPR_PLUS), "integer", "preproc_consta
check::equal(gettype(preproc_constants_c::EXPR_MINUS), "integer", "preproc_constants.EXPR_MINUS has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_LSHIFT), "integer", "preproc_constants.EXPR_LSHIFT has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_RSHIFT), "integer", "preproc_constants.EXPR_RSHIFT has unexpected type");
+check::equal(gettype(preproc_constants_c::EXPR_LT), "integer", "preproc_constants.EXPR_LTE has unexpected type");
+check::equal(gettype(preproc_constants_c::EXPR_GT), "integer", "preproc_constants.EXPR_GTE has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_LTE), "integer", "preproc_constants.EXPR_LTE has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_GTE), "integer", "preproc_constants.EXPR_GTE has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_INEQUALITY), "integer", "preproc_constants.EXPR_INEQUALITY has unexpected type");
@@ -64,3 +66,5 @@ check::equal(gettype(preproc_constants_c::EXPR_CONDITIONAL), "double", "preproc_
check::equal(gettype(preproc_constants_c::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_WCHAR_MAX), "integer", "preproc_constants.EXPR_WCHAR_MAX has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_WCHAR_MIN), "integer", "preproc_constants.EXPR_WCHAR_MIN has unexpected type");
+
+check::done();
diff --git a/Examples/test-suite/php/preproc_constants_runme.php b/Examples/test-suite/php/preproc_constants_runme.php
index 7f45a1bae..80f1a9a59 100644
--- a/Examples/test-suite/php/preproc_constants_runme.php
+++ b/Examples/test-suite/php/preproc_constants_runme.php
@@ -63,3 +63,5 @@ check::equal(gettype(preproc_constants::EXPR_CONDITIONAL), "double", "preproc_co
check::equal(gettype(preproc_constants::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type");
check::equal(gettype(preproc_constants::EXPR_WCHAR_MAX), "integer", "preproc_constants.EXPR_WCHAR_MAX has unexpected type");
check::equal(gettype(preproc_constants::EXPR_WCHAR_MIN), "integer", "preproc_constants.EXPR_WCHAR_MIN has unexpected type");
+
+check::done();
diff --git a/Examples/test-suite/php/rename_camel_runme.php b/Examples/test-suite/php/rename_camel_runme.php
new file mode 100644
index 000000000..9aaeda01d
--- /dev/null
+++ b/Examples/test-suite/php/rename_camel_runme.php
@@ -0,0 +1,13 @@
+<?php
+
+require "tests.php";
+
+// We want to fail if any extra classes/function/constants are defined.
+check::werror(true);
+
+check::classes(array("rename_camel","GeometryFactory","ByteOrderValues"));
+check::functions(array("CamelCase","CamelCase1","CamelCase2","CamelCase3","lowerCamelCase","lowerCamelCase1","lowerCamelCase2","lowerCamelCase3","under_case","under_case1","under_case2","under_case3","Import","foo","hello"));
+check::constants(array("HELLO","HI_THERE","BYE","SEE_YOU"));
+
+
+check::done();
diff --git a/Examples/test-suite/php/swig_exception_runme.php b/Examples/test-suite/php/swig_exception_runme.php
index 37a7a59ee..c218890e4 100644
--- a/Examples/test-suite/php/swig_exception_runme.php
+++ b/Examples/test-suite/php/swig_exception_runme.php
@@ -28,3 +28,5 @@ $e = NULL;
if (Shape::nshapes() != 0) {
check::fail("Shape::nshapes() should be 0, actually ".Shape::nshapes());
}
+
+check::done();
diff --git a/Examples/test-suite/php/tests.php b/Examples/test-suite/php/tests.php
index cec6e581f..0ff20e377 100644
--- a/Examples/test-suite/php/tests.php
+++ b/Examples/test-suite/php/tests.php
@@ -7,6 +7,8 @@ class check {
private static $_extension = null;
+ private static $_werror = false;
+
// This is called automatically at the end of this file.
static function init() {
foreach(get_included_files() as $f) {
@@ -21,6 +23,10 @@ class check {
self::$_extension = new ReflectionExtension($module_name);
}
+ static function werror($v) {
+ self::$_werror = $v;
+ }
+
static function classname($string,$object) {
if (!is_object($object))
return check::fail("The second argument is a " . gettype($object) . ", not an object.");
@@ -109,7 +115,7 @@ class check {
else unset($extra[$func]);
}
$extra = array_filter(array_keys($extra),
- function ($e) { return !preg_match('/_[gs]et$/', $e); });
+ function ($e) { return !preg_match('/_[gs]et$|^is_python_/', $e); });
if ($missing) $message[]=sprintf("Functions missing: %s",join(",",$missing));
if ($message) return check::fail(join("\n ",$message));
if ($extra) $message[]=sprintf("These extra functions are defined: %s",join(",",$extra));
@@ -139,34 +145,66 @@ class check {
}
+ static function constants($constants) {
+ if (! is_array($constants)) $constants=array($constants);
+ $message=array();
+ $missing=array();
+ $extra = self::$_extension->getConstants();
+ unset($extra['swig_runtime_data_type_pointer']);
+ foreach($constants as $constant) {
+ if (! defined($constant)) $missing[]=$constant;
+ else unset($extra[$constant]);
+ }
+ if ($missing) $message[]=sprintf("Constants missing: %s",join(",",$missing));
+ if ($message) return check::fail(join("\n ",$message));
+ if ($extra) $message[]=sprintf("These extra constants are defined: %s",join(",",array_keys($extra)));
+ if ($message) return check::warn(join("\n ",$message));
+ return TRUE;
+ }
+
static function functionref($a,$type,$message) {
if (! preg_match("/^_[a-f0-9]+$type$/i", $a))
return check::fail($message);
return TRUE;
}
- static function equal($a,$b,$message) {
- if (! ($a===$b)) return check::fail($message . ": '$a'!=='$b'");
+ static function equal($a,$b,$message=null) {
+ if (! ($a===$b)) return check::fail_($message, "'$a'!=='$b'");
return TRUE;
}
- static function equivalent($a,$b,$message) {
- if (! ($a==$b)) return check::fail($message . ": '$a'!='$b'");
+ static function equivalent($a,$b,$message=null) {
+ if (! ($a==$b)) return check::fail_($message, "'$a'!='$b'");
return TRUE;
}
- static function isnull($a,$message) {
+ static function str_contains($a,$b,$message=null) {
+ # Use strpos as PHP function str_contains requires PHP 8
+ return check::equal(strpos($a,$b)!==false,true,$message);
+ }
+
+ static function isnull($a,$message=null) {
return check::equal($a,NULL,$message);
}
- static function fail($pattern) {
+ private static function fail_($message, $pattern) {
+ $bt = debug_backtrace(0);
+ $bt = $bt[array_key_last($bt)-1];
+ print("{$bt['file']}:{$bt['line']}: Failed on: ");
+ if ($message !== NULL) print("$message: ");
$args=func_get_args();
- print("Failed on: ".call_user_func_array("sprintf",$args)."\n");
+ array_shift($args);
+ print(call_user_func_array("sprintf",$args)."\n");
exit(1);
}
+ static function fail($pattern) {
+ check::fail_(null, $pattern);
+ }
+
static function warn($pattern) {
$args=func_get_args();
+ if (self::$_werror) self::fail($pattern);
print("Warning on: ".call_user_func_array("sprintf",$args)."\n");
return FALSE;
}
diff --git a/Examples/test-suite/php/threads_exception_runme.php b/Examples/test-suite/php/threads_exception_runme.php
index 38873dffd..e9103f018 100644
--- a/Examples/test-suite/php/threads_exception_runme.php
+++ b/Examples/test-suite/php/threads_exception_runme.php
@@ -2,8 +2,8 @@
require "tests.php";
-// Check functions
-check::functions(array('is_python_builtin'));
+// No new functions
+check::functions(array());
// Check classes.
check::classes(array('Exc','Test','threads_exception'));
// No new vars
@@ -40,3 +40,5 @@ foreach (Array(1,2,3,4) as $i) {
} catch (Exception $e) {
}
}
+
+check::done();
diff --git a/Examples/test-suite/php/virtual_vs_nonvirtual_base_runme.php b/Examples/test-suite/php/virtual_vs_nonvirtual_base_runme.php
index abfb4d307..8d8d40560 100644
--- a/Examples/test-suite/php/virtual_vs_nonvirtual_base_runme.php
+++ b/Examples/test-suite/php/virtual_vs_nonvirtual_base_runme.php
@@ -1,4 +1,4 @@
-<?
+<?php
require "tests.php";
@@ -6,3 +6,5 @@ $fail = new SimpleClassFail();
$work = new SimpleClassWork();
check::equal($work->getInner()->get(), $fail->getInner()->get(), "should both be 10");
+
+check::done();
diff --git a/Examples/test-suite/php_iterator.i b/Examples/test-suite/php_iterator.i
index 43ab68b55..e0b82a5c4 100644
--- a/Examples/test-suite/php_iterator.i
+++ b/Examples/test-suite/php_iterator.i
@@ -1,7 +1,7 @@
/* php_iterator.i - PHP-specific testcase for wrapping to a PHP Iterator */
%module php_iterator
-%typemap("phpinterfaces") MyIterator "Iterator";
+%typemap("phpinterfaces") MyIterator "Iterator"
%inline %{
diff --git a/Examples/test-suite/php_namewarn_rename.i b/Examples/test-suite/php_namewarn_rename.i
index bb54dba5e..d70cad770 100644
--- a/Examples/test-suite/php_namewarn_rename.i
+++ b/Examples/test-suite/php_namewarn_rename.i
@@ -8,6 +8,7 @@
%warnfilter(SWIGWARN_PARSE_KEYWORD) null;
%warnfilter(SWIGWARN_PARSE_KEYWORD) True;
%warnfilter(SWIGWARN_PARSE_KEYWORD) FALSE;
+%warnfilter(SWIGWARN_PARSE_KEYWORD) ns::readonly;
#endif
%ignore prev::operator++;
@@ -50,4 +51,17 @@
class FALSE
{
};
+
+ // PHP 8.1 made `readonly` a keyword, but (unlike any other keyword it seems)
+ // it may still be used as a function name.
+ namespace ns {
+ class readonly { };
+ }
+
+ class readonly_should_be_ok_as_method {
+ public:
+ bool readonly() const { return true; }
+ };
+
+ bool readonly() { return false; }
%}
diff --git a/Examples/test-suite/prefix.i b/Examples/test-suite/prefix.i
index 90cdf5593..ca9e4c442 100644
--- a/Examples/test-suite/prefix.i
+++ b/Examples/test-suite/prefix.i
@@ -15,6 +15,16 @@ public:
// __set and __isset methods weren't getting the prefix.
class Bar : public Foo {
public:
+ Bar *get_self() {
+ return this;
+ }
};
+// This failed in git pre 4.1.0 with PHP 8.x because we weren't adding the
+// prefix to class names in type declarations. Error was at extension load
+// time:
+//
+// Fatal error: Bar must be registered before ProjectBar in Unknown on line 0
+Bar* self(Bar* bar) { return bar->get_self(); }
+
%}
diff --git a/Examples/test-suite/preproc.i b/Examples/test-suite/preproc.i
index 1bcdcf7ac..dff6dbca1 100644
--- a/Examples/test-suite/preproc.i
+++ b/Examples/test-suite/preproc.i
@@ -11,13 +11,29 @@
#pragma SWIG nowarn=890 /* lots of Go name conflicts */
#pragma SWIG nowarn=206 /* Unexpected tokens after #endif directive. */
+/* Regression test: in SWIG < 4.1.0 this triggered the two #error cases.
+ * Github issue #1384
+ */
+#if "" != ""
+#endif
+#if 1 && (!0)
+// Should go here
+#else
+# error BUG
+#endif
+#if ((("" == ""))) || (1 && (!1))
+// Should go here
+#else
+# error BUG
+#endif
+
%{
#if defined(__clang__)
-//Suppress: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
+/*Suppress: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]*/
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
#endif
#if defined(_MSC_VER)
- #pragma warning(disable: 4003) // not enough actual parameters for macro 'FOO2'
+ #pragma warning(disable: 4003) /* not enough actual parameters for macro 'FOO2' */
#endif
%}
@@ -72,14 +88,14 @@ extern "C"
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(boolean)
-// preproc_3
+/* preproc_3 */
#define Sum( A, B, \
C) \
A + B + C
-// preproc_4
+/* preproc_4 */
%{
int hello0()
{
@@ -102,33 +118,30 @@ TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(boolean)
#define HELLO_TYPE(A, B) ARITH_RTYPE(A, ARITH_RTYPE(A,B))
-//
-// These two work fine
-//
int hello0();
ARITH_RTYPE(double,int) hello1();
-//
-// This doesn't work with 1.3.17+ ( but it was ok in 1.3.16 )
-// it gets expanded as (using -E)
-//
-// ARITH_RTYPE(double,int) hello2();
-//
+/*
+ This doesn't work with 1.3.17+ ( but it was ok in 1.3.16 )
+ it gets expanded as (using -E)
+
+ ARITH_RTYPE(double,int) hello2();
+*/
HELLO_TYPE(double,int) hello2();
#define min(x,y) ((x) < (y)) ? (x) : (y)
int f(int min);
-// preproc_5
+/* preproc_5 */
-%warnfilter(SWIGWARN_PARSE_REDEFINED) A5; // Ruby, wrong constant name
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) a5; // Ruby, wrong constant name
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) b5; // Ruby, wrong constant name
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) c5; // Ruby, wrong constant name
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) d5; // Ruby, wrong constant name
+%warnfilter(SWIGWARN_PARSE_REDEFINED) A5; /* Ruby, wrong constant name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) a5; /* Ruby, wrong constant name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) b5; /* Ruby, wrong constant name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) c5; /* Ruby, wrong constant name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) d5; /* Ruby, wrong constant name */
-// Various preprocessor bits of nastiness.
+/* Various preprocessor bits of nastiness. */
/* Test argument name substitution */
@@ -138,7 +151,7 @@ int f(int min);
%constant char *a5 = foo(hello,world);
%constant int b5 = bar(3,4);
-// Wrap your brain around this one ;-)
+/* Wrap your brain around this one ;-) */
%{
#define cat(x,y) x ## y
@@ -168,7 +181,7 @@ NAME 42
#define C4"Hello"
-// preproc_6
+/* preproc_6 */
%warnfilter(SWIGWARN_PARSE_REDEFINED) A6; /* Ruby, wrong constant name */
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) a6; /* Ruby, wrong constant name */
@@ -206,7 +219,7 @@ NAME 42
MACRO2(int)
-// cpp_macro_noarg. Tests to make sure macros with no arguments work right.
+/* cpp_macro_noarg. Tests to make sure macros with no arguments work right. */
#define MACROWITHARG(x) something(x)
typedef int MACROWITHARG;
@@ -373,8 +386,11 @@ int methodX(int x);
int methodX(int x) { return x+100; }
%}
-// Comma in macro - https://github.com/swig/swig/issues/974 (for /* */)
-// and https://github.com/swig/swig/pull/1166 (for //)
+/*
+ Comma in macro - https://github.com/swig/swig/issues/974 (for C comments)
+ and https://github.com/swig/swig/pull/1166 (for //)
+ Also see preproc_cpp.i
+*/
%inline %{
#define swig__attribute__(x)
#define TCX_PACKED(d) d swig__attribute__ ((__packed__))
@@ -392,21 +408,9 @@ TCX_PACKED (typedef struct tcxMessageBugImpl
}) tcxMessageBug;
-TCX_PACKED (typedef struct tcxMessageTestImpl2
-{
- int mHeader; ///< comment
-}) tcxMessageTest2;
-
-
-TCX_PACKED (typedef struct tcxMessageBugImpl2
-{
- int mBid; ///< Bid price and size, check PresentMap if available in message
-}) tcxMessageBug2;
-
-
%}
-// Regression tests for https://github.com/swig/swig/pull/1111
+/* Regression tests for https://github.com/swig/swig/pull/1111 */
%{
static int foo_func(int x) { return x; }
static int foo_func2() { return 0; }
@@ -422,22 +426,22 @@ static int baz_func(int a, int b, int c) { return a + b - c; }
#define FOOVAR(...) foo_func(__VA_ARGS__)
#define BARVAR(...) bar_func(__VA_ARGS__)
#define BAZVAR(...) baz_func(__VA_ARGS__)
-// This has probably always worked, but make sure that the fix to accept
-// an empty X doesn't cause this case to be incorrectly expanded:
+/* This has probably always worked, but make sure that the fix to accept
+ an empty X doesn't cause this case to be incorrectly expanded:*/
const int FOO = 7;
-// BAR was incorrectly expanded here, causing:
-// Error: Syntax error in input(1).
+/* BAR was incorrectly expanded here, causing:
+ Error: Syntax error in input(1). */
const int BAR = 6;
-// This has probably always worked, but make sure that the fix to accept
-// an empty X doesn't stop a non-empty X from working:
+/* This has probably always worked, but make sure that the fix to accept
+ an empty X doesn't stop a non-empty X from working: */
FOO(int x)
-// FOO() didn't used to get expanded here, causing:
-// Syntax error in input(1).
+/* FOO() didn't used to get expanded here, causing:
+ Syntax error in input(1). */
FOO2()
-// Check BAR2() still gets expanded here.
+/* Check BAR2() still gets expanded here. */
BAR2() {
- // Regression test - this used to fail with:
- // Error: Macro 'BAZ' expects 3 arguments
+ /* Regression test - this used to fail with:
+ Error: Macro 'BAZ' expects 3 arguments */
BAZ(,2,3);
BARVAR();
FOOVAR(1);
diff --git a/Examples/test-suite/preproc_constants.i b/Examples/test-suite/preproc_constants.i
index 3050baa06..3873d2608 100644
--- a/Examples/test-suite/preproc_constants.i
+++ b/Examples/test-suite/preproc_constants.i
@@ -65,17 +65,15 @@
#define EXPR_MULTIPLY 0xFF * 2
#define EXPR_DIVIDE 0xFF / 2
-//FIXME #define EXPR_MOD 0xFF % 2
+#define EXPR_MOD 0xFF % 2
#define EXPR_PLUS 0xFF + 2
#define EXPR_MINUS 0xFF + 2
#define EXPR_LSHIFT 0xFF << 2
#define EXPR_RSHIFT 0xFF >> 2
-/* FIXME
-#define EXPR_LT 0xFF < 255
-#define EXPR_GT 0xFF > 255
-*/
+#define EXPR_LT (0xFF < 255)
+#define EXPR_GT (0xFF > 255)
#define EXPR_LTE 0xFF <= 255
#define EXPR_GTE 0xFF >= 255
#define EXPR_INEQUALITY 0xFF != 255
diff --git a/Examples/test-suite/preproc_cpp.i b/Examples/test-suite/preproc_cpp.i
new file mode 100644
index 000000000..c81f9a74f
--- /dev/null
+++ b/Examples/test-suite/preproc_cpp.i
@@ -0,0 +1,36 @@
+%module preproc_cpp
+
+
+// Comma in macro - https://github.com/swig/swig/issues/974 (for /* */)
+// and https://github.com/swig/swig/pull/1166 (for //)
+// Also see preproc.i
+%inline %{
+#define swig__attribute__(x)
+#define TCX_PACKED(d) d swig__attribute__ ((__packed__))
+
+
+TCX_PACKED (typedef struct tcxMessageTestImpl
+{
+ int mHeader; /**< comment */
+}) tcxMessageTest;
+
+
+TCX_PACKED (typedef struct tcxMessageBugImpl
+{
+ int mBid; /**< Bid price and size, check PresentMap if available in message */
+}) tcxMessageBug;
+
+
+TCX_PACKED (typedef struct tcxMessageTestImpl2
+{
+ int mHeader; ///< comment
+}) tcxMessageTest2;
+
+
+TCX_PACKED (typedef struct tcxMessageBugImpl2
+{
+ int mBid; ///< Bid price and size, check PresentMap if available in message
+}) tcxMessageBug2;
+
+
+%}
diff --git a/Examples/test-suite/preproc_defined.i b/Examples/test-suite/preproc_defined.i
index e1958515d..5ebf0a099 100644
--- a/Examples/test-suite/preproc_defined.i
+++ b/Examples/test-suite/preproc_defined.i
@@ -86,7 +86,7 @@ struct Defined {
void defined_not(TYPE);
#endif
-#if !( defined(AAA) \
+#if !( defined(AAA) &&\
defined(BBB) \\
&& defined(CCC) )
void bumpf_not(TYPE);
diff --git a/Examples/test-suite/preproc_expr.i b/Examples/test-suite/preproc_expr.i
new file mode 100644
index 000000000..a24f7715c
--- /dev/null
+++ b/Examples/test-suite/preproc_expr.i
@@ -0,0 +1,34 @@
+%module preproc_expr
+
+// Check expressions which suffered from incorrect operator precedence prior
+// to SWIG 4.1.0.
+
+%inline %{
+// `!` should have higher precedence than binary `+`.
+#if !0 + 1
+#else
+# error Bad preprocessor expression operator precedence
+#endif
+
+// `!=` should have higher precedence than bitwise and.
+#if 1 & 2 != 0
+#else
+# error Bad preprocessor expression operator precedence
+#endif
+
+// `==` should have higher precedence than bitwise or.
+#if (2 | 1 == 3) != 2
+# error Bad preprocessor expression operator precedence
+#endif
+
+// `!=` should have higher precedence than bitwise xor.
+#if 1 ^ 2 != 4
+# error Bad preprocessor expression operator precedence
+#endif
+
+// `<` should have higher precedence than '=='.
+#if 2 == 2 < 2
+# error Bad preprocessor expression operator precedence
+#endif
+
+%}
diff --git a/Examples/test-suite/preproc_predefined.h b/Examples/test-suite/preproc_predefined.h
new file mode 100644
index 000000000..8d6b6ee28
--- /dev/null
+++ b/Examples/test-suite/preproc_predefined.h
@@ -0,0 +1,27 @@
+/* This list will need updating when new target languages are added. */
+#if (0\
+ +defined(SWIGCSHARP)\
+ +defined(SWIGD)\
+ +defined(SWIGGO)\
+ +defined(SWIGGUILE)\
+ +defined(SWIGJAVA)\
+ +defined(SWIGJAVASCRIPT)\
+ +defined(SWIGLUA)\
+ +defined(SWIGMZSCHEME)\
+ +defined(SWIGOCAML)\
+ +defined(SWIGOCTAVE)\
+ +defined(SWIGPERL)\
+ +defined(SWIGPHP)\
+ +defined(SWIGPYTHON)\
+ +defined(SWIGR)\
+ +defined(SWIGRUBY)\
+ +defined(SWIGSCILAB)\
+ +defined(SWIGTCL)\
+ +defined(SWIGXML)\
+ ) != 1
+# ifdef SWIG
+# error Did not detect exactly one target-language-specific macro defined at SWIG time.
+# else
+# error Did not detect exactly one target-language-specific macro defined in the generated wrapper.
+# endif
+#endif
diff --git a/Examples/test-suite/preproc_predefined.i b/Examples/test-suite/preproc_predefined.i
new file mode 100644
index 000000000..252ef9a1a
--- /dev/null
+++ b/Examples/test-suite/preproc_predefined.i
@@ -0,0 +1,62 @@
+%module preproc_predefined
+
+/* Test that SWIG_VERSION is defined at SWIG-time and in the wrapper. */
+#ifndef SWIG_VERSION
+# error SWIG_VERSION not defined at SWIG-time
+#endif
+%{
+#ifndef SWIG_VERSION
+# error SWIG_VERSION not defined in the generated wrapper
+#endif
+%}
+
+/* Test that SWIG_VERSION has a plausible value - in particular catch if
+ * it isn't defined to a numeric value (which will get replaced by 0).
+ */
+#if SWIG_VERSION < 0x040100
+# error SWIG_VERSION value not plausible at SWIG-time
+#endif
+%{
+#if SWIG_VERSION < 0x040100
+# error SWIG_VERSION value not plausible in the generated wrapper
+#endif
+%}
+
+%define %generate_swig_version_from_preprocessor()%#define SWIG_VERSION_FROM_SWIG_PREPROCESSOR SWIG_VERSION %enddef
+%insert("header") {
+%generate_swig_version_from_preprocessor()
+}
+%insert("header") %{
+#if SWIG_VERSION != SWIG_VERSION_FROM_SWIG_PREPROCESSOR
+# error SWIG_VERSION in SWIG preprocessor does not match SWIG_VERSION from C preprocessor
+#endif
+%}
+
+/* Test that SWIGVERSION is NOT defined at SWIG-time or in the wrapper.
+ * It used to be defined in the wrapper as a side-effect of how SWIG_VERSION
+ * was defined in the wrapper but was never documented and is redundant.
+ */
+#ifdef SWIGVERSION
+# error SWIGVERSION should not be defined at SWIG-time
+#endif
+%{
+#ifdef SWIGVERSION
+# error SWIGVERSION should not be defined in the generated wrapper
+#endif
+%}
+
+/* Test that SWIG is defined at SWIG-time but not in the wrapper. */
+#ifndef SWIG
+# error SWIG not defined at SWIG-time
+#endif
+%{
+#ifdef SWIG
+# error SWIG should not be defined in the generated wrapper
+#endif
+%}
+
+/* Test that SWIGxxx is defined at SWIG-time and in the wrapper. */
+%include "preproc_predefined.h"
+%{
+#include "preproc_predefined.h"
+%}
diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in
index 0bdbad51e..baa89859a 100644
--- a/Examples/test-suite/python/Makefile.in
+++ b/Examples/test-suite/python/Makefile.in
@@ -2,7 +2,7 @@
# Makefile for python test-suite
#######################################################################
-ifeq (,$(PY3))
+ifneq (,$(PY2))
PYBIN = @PYTHON@
else
PYBIN = @PYTHON3@
@@ -14,12 +14,15 @@ SCRIPTSUFFIX = _runme.py
PYCODESTYLE = @PYCODESTYLE@
PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,E741,W291,W391
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CPP_TEST_CASES += \
- argcargvtest \
callback \
complextest \
director_stl \
@@ -48,12 +51,15 @@ CPP_TEST_CASES += \
li_std_wstring_inherit \
primitive_types \
python_abstractbase \
+ python_annotations_c \
+ python_annotations_variable_c \
python_append \
python_builtin \
python_destructor_exception \
python_director \
python_docstring \
python_extranative \
+ python_flatstaticmethod \
python_moduleimport \
python_overload_simple_cast \
python_pickle \
@@ -90,6 +96,9 @@ C_TEST_CASES += \
python_nondynamic \
python_varargs_typemap \
+MULTI_CPP_TEST_CASES += \
+ python_runtime_data \
+
include $(srcdir)/../common.mk
# Overridden variables here
@@ -97,7 +106,14 @@ LIBS = -L.
VALGRIND_OPT += --suppressions=pythonswig.supp
# Custom tests - tests with additional commandline options
-# none!
+python_flatstaticmethod.cpptest: SWIGOPT += -flatstaticmethod
+
+# Make sure just python_runtime_data_builtin.i uses the -builtin option. Note: does not use python_runtime_data.list for all steps.
+python_runtime_data.multicpptest: override SWIG_FEATURES := $(filter-out -builtin,$(SWIG_FEATURES))
+python_runtime_data.multicpptest: override SWIGOPT := $(filter-out -builtin,$(SWIGOPT))
+python_runtime_data.multicpptest: swig_and_compile_multi_cpp = \
+ $(call swig_and_compile_cpp_helper,python_runtime_data_builtin,'$(SWIGOPT) -builtin') && \
+ $(call swig_and_compile_cpp_helper,python_runtime_data_nobuiltin,'$(SWIGOPT)')
# Rules for the different types of tests
%.cpptest:
@@ -145,8 +161,8 @@ clean:
rm -f clientdata_prop_a.py clientdata_prop_b.py import_stl_a.py import_stl_b.py
rm -f hugemod.h hugemod_a.i hugemod_b.i hugemod_a.py hugemod_b.py hugemod_runme.py
rm -f imports_a.py imports_b.py mod_a.py mod_b.py multi_import_a.py
- rm -f multi_import_b.py packageoption_a.py packageoption_b.py packageoption_c.py
- rm -f template_typedef_cplx2.py
+ rm -f multi_import_b.py multi_import_d.py packageoption_a.py packageoption_b.py packageoption_c.py
+ rm -f template_typedef_cplx2.py python_runtime_data_builtin.py python_runtime_data_nobuiltin.py
hugemod_runme = hugemod$(SCRIPTPREFIX)
diff --git a/Examples/test-suite/python/README b/Examples/test-suite/python/README
index 71db759b5..402724c23 100644
--- a/Examples/test-suite/python/README
+++ b/Examples/test-suite/python/README
@@ -1,8 +1,9 @@
See ../README for common README file.
-Any testcases which have _runme.py (or _runme3.py for Python 3) appended after the testcase name will be detected and run.
+Any testcases which have _runme.py appended after the testcase name will be detected and run.
-If you intend to write a testcase for both Python 2.x and 3.x, do *not* directly put the _runme3.py in this directory. Just write Python 2.x's _runme.py testcase and it will be automatically converted to Python 3 code during test.
+The _runme.py files needs to work for both Python 2.x and 3.x.
-You can run make with PY3=y to run test case with Python 3.x, eg.
- $ make voidtest.cpptest PY3=y
+By default testcases are run with Python 3. You can run make with PY2=1 to run test case with Python 2, eg.
+
+ $ make voidtest.cpptest PY2=1
diff --git a/Examples/test-suite/python/abstract_basecast_runme.py b/Examples/test-suite/python/abstract_basecast_runme.py
new file mode 100644
index 000000000..4a3f4a9e1
--- /dev/null
+++ b/Examples/test-suite/python/abstract_basecast_runme.py
@@ -0,0 +1,15 @@
+from abstract_basecast import *
+
+def check(flag):
+ if not flag:
+ raise RuntimeError("Test failed")
+
+derived = DerivedClass()
+derived.g()
+check(isinstance(derived, BaseClass))
+check(isinstance(derived, DerivedClass))
+
+base = derived.f()
+base.g()
+check(isinstance(base, BaseClass))
+check(not isinstance(base, DerivedClass))
diff --git a/Examples/test-suite/python/autodoc_runme.py b/Examples/test-suite/python/autodoc_runme.py
index 7bc918644..18330f76f 100644
--- a/Examples/test-suite/python/autodoc_runme.py
+++ b/Examples/test-suite/python/autodoc_runme.py
@@ -63,16 +63,8 @@ check(inspect.getdoc(A.func3default),
check(inspect.getdoc(A.func0static),
"func0static(e, arg2, hello, f=2) -> int")
-check(inspect.getdoc(_autodoc.A_func0static),
- "A_func0static(e, arg2, hello, f=2) -> int")
-check(inspect.getdoc(A_func0static),
- "A_func0static(e, arg2, hello, f=2) -> int")
check(inspect.getdoc(A.func1static),
"func1static(A e, short arg2, Tuple hello, double f=2) -> int")
-check(inspect.getdoc(_autodoc.A_func1static),
- "A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
-check(inspect.getdoc(A_func1static),
- "A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
check(inspect.getdoc(A.func2static),
"func2static(e, arg2, hello, f=2) -> int\n"
"\n"
@@ -82,24 +74,6 @@ check(inspect.getdoc(A.func2static),
"arg2: short\n"
"hello: int tuple[2]\n"
"f: double")
-check(inspect.getdoc(_autodoc.A_func2static),
- "A_func2static(e, arg2, hello, f=2) -> int\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "e: A *\n"
- "arg2: short\n"
- "hello: int tuple[2]\n"
- "f: double")
-check(inspect.getdoc(A_func2static),
- "A_func2static(e, arg2, hello, f=2) -> int\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "e: A *\n"
- "arg2: short\n"
- "hello: int tuple[2]\n"
- "f: double")
check(inspect.getdoc(A.func3static),
"func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
"\n"
@@ -109,24 +83,6 @@ check(inspect.getdoc(A.func3static),
"arg2: short\n"
"hello: int tuple[2]\n"
"f: double")
-check(inspect.getdoc(_autodoc.A_func3static),
- "A_func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "e: A *\n"
- "arg2: short\n"
- "hello: int tuple[2]\n"
- "f: double")
-check(inspect.getdoc(A_func3static),
- "A_func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "e: A *\n"
- "arg2: short\n"
- "hello: int tuple[2]\n"
- "f: double")
check(inspect.getdoc(A.variable_a),
"variable_a"
@@ -141,7 +97,7 @@ check(inspect.getdoc(A.variable_d),
"variable_d : int"
)
-# Check the low-level functions (not present when using -builtin except for the static ones)
+# Check the low-level functions (not present when using -builtin)
if not is_python_builtin():
check(inspect.getdoc(_autodoc.A_funk), "just a string.")
check(inspect.getdoc(_autodoc.A_func0),
@@ -184,6 +140,28 @@ if not is_python_builtin():
"arg3: short\n"
"hello: int tuple[2]\n"
"f: double")
+ check(inspect.getdoc(_autodoc.A_func0static),
+ "A_func0static(e, arg2, hello, f=2) -> int")
+ check(inspect.getdoc(_autodoc.A_func1static),
+ "A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
+ check(inspect.getdoc(_autodoc.A_func2static),
+ "A_func2static(e, arg2, hello, f=2) -> int\n"
+ "\n"
+ "Parameters\n"
+ "----------\n"
+ "e: A *\n"
+ "arg2: short\n"
+ "hello: int tuple[2]\n"
+ "f: double")
+ check(inspect.getdoc(_autodoc.A_func3static),
+ "A_func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
+ "\n"
+ "Parameters\n"
+ "----------\n"
+ "e: A *\n"
+ "arg2: short\n"
+ "hello: int tuple[2]\n"
+ "f: double")
check(inspect.getdoc(_autodoc.A_variable_a_set), "A_variable_a_set(self, variable_a)")
check(inspect.getdoc(_autodoc.A_variable_a_get), "A_variable_a_get(self) -> int" )
check(inspect.getdoc(_autodoc.A_variable_b_set), "A_variable_b_set(A self, int variable_b)")
diff --git a/Examples/test-suite/python/callback_runme.py b/Examples/test-suite/python/callback_runme.py
index de8a372f6..dbf957cbb 100644
--- a/Examples/test-suite/python/callback_runme.py
+++ b/Examples/test-suite/python/callback_runme.py
@@ -1,10 +1,14 @@
import _callback
from callback import *
+# callbacks are implemented by modifying docstrings, useful for debugging:
+# print("A_bar doc: {}".format(A_bar.__doc__))
+# print("A.bar doc: {}".format(A.bar.__doc__))
+
if foo(2) != 2:
raise RuntimeError
-if A_bar(2) != 4:
+if A.bar(2) != 4:
raise RuntimeError
if foobar(3, _callback.foo) != foo(3):
@@ -13,11 +17,7 @@ if foobar(3, _callback.foo) != foo(3):
if foobar(3, foo) != foo(3):
raise RuntimeError
-# Needs some more work for -builtin
-# if foobar(3, A.bar) != A.bar(3):
-# raise RuntimeError
-
-if foobar(3, A_bar) != A_bar(3):
+if foobar(3, A.bar) != A.bar(3):
raise RuntimeError
if foobar(3, foof) != foof(3):
diff --git a/Examples/test-suite/python/catches_strings_runme.py b/Examples/test-suite/python/catches_strings_runme.py
new file mode 100644
index 000000000..95b55a264
--- /dev/null
+++ b/Examples/test-suite/python/catches_strings_runme.py
@@ -0,0 +1,21 @@
+from catches_strings import *
+
+exception_thrown = False
+try:
+ StringsThrower.charstring()
+except RuntimeError as e:
+ if "charstring message" not in str(e):
+ raise RuntimeError("incorrect exception message:" + str(e))
+ exception_thrown = True
+if not exception_thrown:
+ raise RuntimeError("Should have thrown an exception")
+
+exception_thrown = False
+try:
+ StringsThrower.stdstring()
+except RuntimeError as e:
+ if "stdstring message" not in str(e):
+ raise RuntimeError("incorrect exception message:" + str(e))
+ exception_thrown = True
+if not exception_thrown:
+ raise RuntimeError("Should have thrown an exception")
diff --git a/Examples/test-suite/python/contract_runme.py b/Examples/test-suite/python/contract_runme.py
index b6bab3a09..3194b6ac7 100644
--- a/Examples/test-suite/python/contract_runme.py
+++ b/Examples/test-suite/python/contract_runme.py
@@ -58,15 +58,15 @@ try:
except RuntimeError:
pass
-contract.Foo_stest_prepost(4, 0)
+contract.Foo.stest_prepost(4, 0)
try:
- contract.Foo_stest_prepost(-4, 2)
+ contract.Foo.stest_prepost(-4, 2)
raise Exception("Failed! Static method preassertion")
except RuntimeError:
pass
try:
- contract.Foo_stest_prepost(4, -10)
+ contract.Foo.stest_prepost(4, -10)
raise Exception("Failed! Static method posteassertion")
except RuntimeError:
pass
diff --git a/Examples/test-suite/python/cpp11_final_class_runme.py b/Examples/test-suite/python/cpp11_final_class_runme.py
new file mode 100644
index 000000000..54e289043
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_final_class_runme.py
@@ -0,0 +1,65 @@
+from cpp11_final_class import *
+
+fc1 = FinalClass1()
+fc1.method1()
+
+fc2 = FinalClass2()
+fc2.method2()
+
+fc3 = FinalClass3()
+fc3.method3()
+
+fc4 = FinalClass4()
+fc4.method4()
+fc4final = cvar.final
+cvar.final.method4()
+
+fc5 = FinalClass5()
+fc5.method5()
+fc5.final_member_var.finalmethod()
+fc5final = fc5.get_final_member()
+fc5final.finalmethod()
+fc5final = fc5.get_final_member2()
+fc5final.finalmethod()
+
+fc6 = FinalClass6()
+fc6.method6()
+fc6.final()
+
+o = override()
+o.omethod();
+
+y = Y()
+fv4 = FinalVar4()
+yy = fv4.final
+
+fv5 = FinalVar5()
+yy = fv5.final
+
+fv6 = FinalVar6()
+yy = fv6.final
+
+fv7 = FinalVar7()
+yy = fv7.final
+
+fv8 = FinalVar8()
+yy = fv8.final
+
+fv9 = FinalVar9()
+yy = fv9.final
+
+fv10 = FinalVar10()
+fv10.b10(y)
+
+# Removed due to Visual C++ compiler limitations
+# fv11 = FinalVar11()
+# fv11.a11(y)
+#
+# fe1 = FinalEnum1()
+# fe1.enum_in(FinalEnum1.final)
+#
+# fe2 = FinalEnum2()
+# fe2f = fe2.final
+
+s3f = Space3_final()
+s3f.fmethod();
diff --git a/Examples/test-suite/python/cpp11_move_only_runme.py b/Examples/test-suite/python/cpp11_move_only_runme.py
new file mode 100644
index 000000000..9727f3fcc
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_move_only_runme.py
@@ -0,0 +1,27 @@
+from cpp11_move_only import *
+
+# Output
+Counter.reset_counts()
+mo = MoveOnly.create()
+del mo
+Counter.check_counts(1, 0, 0, 2, 0, 3)
+
+Counter.reset_counts()
+mo = MovableCopyable.create()
+del mo
+Counter.check_counts(2, 1, 0, 0, 1, 3)
+
+# Move semantics not used
+Counter.reset_counts()
+mo = MovableCopyable.createConst()
+del mo
+Counter.check_counts(2, 1, 1, 0, 0, 3)
+
+# Input
+Counter.reset_counts()
+mo = MovableCopyable(222)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+MovableCopyable.take(mo)
+Counter.check_counts(2, 0, 1, 1, 0, 2)
+del mo
+Counter.check_counts(2, 0, 1, 1, 0, 3)
diff --git a/Examples/test-suite/python/cpp11_move_typemaps_runme.py b/Examples/test-suite/python/cpp11_move_typemaps_runme.py
new file mode 100644
index 000000000..e4cf06c53
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_move_typemaps_runme.py
@@ -0,0 +1,29 @@
+from cpp11_move_typemaps import *
+
+Counter.reset_counts()
+mo = MoveOnly(111)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+MoveOnly.take(mo)
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+del mo
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+Counter.reset_counts()
+mo = MovableCopyable(111)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+MovableCopyable.take(mo)
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+del mo
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+mo = MoveOnly(222)
+MoveOnly.take(mo)
+exception_thrown = False
+try:
+ MoveOnly.take(mo)
+except RuntimeError as e:
+ if "cannot release ownership as memory is not owned" not in str(e):
+ raise RuntimeError("incorrect exception message:" + str(e))
+ exception_thrown = True
+if not exception_thrown:
+ raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
diff --git a/Examples/test-suite/python/cpp11_rvalue_reference_move_runme.py b/Examples/test-suite/python/cpp11_rvalue_reference_move_runme.py
new file mode 100644
index 000000000..43e586f9a
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_rvalue_reference_move_runme.py
@@ -0,0 +1,69 @@
+from cpp11_rvalue_reference_move import *
+
+# Function containing rvalue reference parameter
+Counter.reset_counts()
+mo = MovableCopyable(222)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+MovableCopyable.movein(mo)
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+if not MovableCopyable.is_nullptr(mo):
+ raise RuntimeError("is_nullptr check")
+del mo
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+# Move constructor test
+Counter.reset_counts()
+mo = MovableCopyable(222)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+mo_moved = MovableCopyable(mo)
+Counter.check_counts(1, 0, 0, 1, 0, 1)
+if not MovableCopyable.is_nullptr(mo):
+ raise RuntimeError("is_nullptr check")
+del mo
+Counter.check_counts(1, 0, 0, 1, 0, 1)
+del mo_moved
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+# Move assignment operator test
+Counter.reset_counts()
+mo111 = MovableCopyable(111)
+mo222 = MovableCopyable(222)
+Counter.check_counts(2, 0, 0, 0, 0, 0)
+mo111.MoveAssign(mo222)
+Counter.check_counts(2, 0, 0, 0, 1, 1)
+if not MovableCopyable.is_nullptr(mo222):
+ raise RuntimeError("is_nullptr check")
+del mo222
+Counter.check_counts(2, 0, 0, 0, 1, 1)
+del mo111
+Counter.check_counts(2, 0, 0, 0, 1, 2)
+
+# null check
+Counter.reset_counts()
+exception_thrown = False
+try:
+ MovableCopyable.movein(None)
+except ValueError as e:
+ if "invalid null reference" not in str(e):
+ raise RuntimeError("incorrect exception message:" + str(e))
+ exception_thrown = True
+if not exception_thrown:
+ raise RuntimeError("Should have thrown null error")
+Counter.check_counts(0, 0, 0, 0, 0, 0)
+
+# output
+Counter.reset_counts()
+mc = MovableCopyable.moveout(1234)
+Counter.check_counts(2, 0, 0, 0, 1, 1)
+MovableCopyable.check_numbers_match(mc, 1234)
+
+exception_thrown = False
+try:
+ MovableCopyable.movein(mc)
+except RuntimeError as e:
+ if "cannot release ownership as memory is not owned" not in str(e):
+ raise RuntimeError("incorrect exception message:" + str(e))
+ exception_thrown = True
+if not exception_thrown:
+ raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
+Counter.check_counts(2, 0, 0, 0, 1, 1)
diff --git a/Examples/test-suite/python/cpp11_rvalue_reference_runme.py b/Examples/test-suite/python/cpp11_rvalue_reference_runme.py
index 85d64a581..fad8b76d6 100644
--- a/Examples/test-suite/python/cpp11_rvalue_reference_runme.py
+++ b/Examples/test-suite/python/cpp11_rvalue_reference_runme.py
@@ -4,24 +4,24 @@ a = cpp11_rvalue_reference.A()
a.setAcopy(5)
if a.getAcopy() != 5:
- raise RunTimeError("int A::getAcopy() value is ",
+ raise RuntimeError("int A::getAcopy() value is ",
a.getAcopy(), " should be 5")
ptr = a.getAptr()
a.setAptr(ptr)
if a.getAcopy() != 5:
- raise RunTimeError("after A::setAptr(): int A::getAcopy() value is ", a.getAcopy(
+ raise RuntimeError("after A::setAptr(): int A::getAcopy() value is ", a.getAcopy(
), " should be 5")
a.setAref(ptr)
if a.getAcopy() != 5:
- raise RunTimeError("after A::setAref(): int A::getAcopy() value is ", a.getAcopy(
+ raise RuntimeError("after A::setAref(): int A::getAcopy() value is ", a.getAcopy(
), " should be 5")
rvalueref = a.getAmove()
-a.setAmove(rvalueref)
+a.setAref(rvalueref)
if a.getAcopy() != 5:
- raise RunTimeError("after A::setAmove(): int A::getAcopy() value is ", a.getAcopy(
+ raise RuntimeError("after A::setAmove(): int A::getAcopy() value is ", a.getAcopy(
), " should be 5")
diff --git a/Examples/test-suite/python/cpp11_std_unique_ptr_runme.py b/Examples/test-suite/python/cpp11_std_unique_ptr_runme.py
new file mode 100644
index 000000000..9548fc28a
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_std_unique_ptr_runme.py
@@ -0,0 +1,109 @@
+from cpp11_std_unique_ptr import *
+
+def checkCount(expected_count):
+ actual_count = Klass.getTotal_count()
+ if (actual_count != expected_count):
+ raise RuntimeError("Counts incorrect, expected:" + expected_count + " actual:" + actual_count)
+
+# Test raw pointer handling involving virtual inheritance
+kini = KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = useKlassRawPtr(kini)
+if s != "KlassInheritanceInput":
+ raise RuntimeError("Incorrect string: " + s)
+del kini
+checkCount(0)
+
+
+# unique_ptr as input
+kin = Klass("KlassInput")
+checkCount(1)
+s = takeKlassUniquePtr(kin)
+checkCount(0)
+if kin.thisown:
+ raise RuntimeError("thisown should be false")
+if s != "KlassInput":
+ raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kin):
+ raise RuntimeError("is_nullptr failed")
+del kin # Should not fail, even though already deleted
+checkCount(0)
+
+kin = Klass("KlassInput")
+checkCount(1)
+s = takeKlassUniquePtr(kin)
+checkCount(0)
+if kin.thisown:
+ raise RuntimeError("thisown should be false")
+if s != "KlassInput":
+ raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kin):
+ raise RuntimeError("is_nullptr failed")
+exception_thrown = False
+try:
+ s = takeKlassUniquePtr(kin)
+except RuntimeError as e:
+ if "cannot release ownership as memory is not owned" not in str(e):
+ raise RuntimeError("incorrect exception message");
+ exception_thrown = True
+if not exception_thrown:
+ raise RuntimeError("double usage of takeKlassUniquePtr should have been an error")
+del kin # Should not fail, even though already deleted
+checkCount(0)
+
+kin = Klass("KlassInput")
+exception_thrown = False
+notowned = get_not_owned_ptr(kin)
+try:
+ takeKlassUniquePtr(notowned)
+except RuntimeError as e:
+ exception_thrown = True
+if not exception_thrown:
+ raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
+checkCount(1)
+del kin
+checkCount(0)
+
+kini = KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = takeKlassUniquePtr(kini)
+checkCount(0)
+if kini.thisown:
+ raise RuntimeError("thisown should be false")
+if s != "KlassInheritanceInput":
+ raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kini):
+ raise RuntimeError("is_nullptr failed")
+del kini # Should not fail, even though already deleted
+checkCount(0)
+
+takeKlassUniquePtr(None)
+takeKlassUniquePtr(make_null())
+checkCount(0)
+
+# overloaded parameters
+if overloadTest() != 0:
+ raise RuntimeError("overloadTest failed")
+if overloadTest(None) != 1:
+ raise RuntimeError("overloadTest failed")
+if overloadTest(Klass("over")) != 1:
+ raise RuntimeError("overloadTest failed")
+checkCount(0);
+
+
+# unique_ptr as output
+k1 = makeKlassUniquePtr("first")
+k2 = makeKlassUniquePtr("second")
+checkCount(2)
+
+del k1
+checkCount(1)
+
+if k2.getLabel() != "second":
+ raise "wrong object label"
+
+del k2
+checkCount(0)
+
+if (makeNullUniquePtr() != None):
+ raise RuntimeError("null failure")
diff --git a/Examples/test-suite/python/cpp11_template_explicit_runme.py b/Examples/test-suite/python/cpp11_template_explicit_runme.py
new file mode 100644
index 000000000..dacfb74c8
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_template_explicit_runme.py
@@ -0,0 +1,15 @@
+import cpp11_template_explicit
+
+def swig_assert_isinstance(a, b):
+ if not isinstance(a, b):
+ raise RuntimeError(str(a) + " not an instance of " + str(b))
+
+# Call variants of the same templated function
+t1 = cpp11_template_explicit.my_templated_function_int (1,1.0)
+t2 = cpp11_template_explicit.my_templated_function_A (2,2.0)
+t3 = cpp11_template_explicit.my_templated_function_TemperInt(3,3.0)
+
+# Check return types
+swig_assert_isinstance(t1,int)
+swig_assert_isinstance(t2,cpp11_template_explicit.A)
+swig_assert_isinstance(t3,cpp11_template_explicit.TemperInt)
diff --git a/Examples/test-suite/python/cpp14_binary_integer_literals_runme.py b/Examples/test-suite/python/cpp14_binary_integer_literals_runme.py
index 8274ec6b5..ee308aa39 100644
--- a/Examples/test-suite/python/cpp14_binary_integer_literals_runme.py
+++ b/Examples/test-suite/python/cpp14_binary_integer_literals_runme.py
@@ -14,3 +14,12 @@ if cvar.b4 != 4:
if cvar.b5 != 5:
raise RuntimeError
+
+if b6 != 6:
+ raise RuntimeError
+
+if b7 != 7:
+ raise RuntimeError
+
+if b8 != 8:
+ raise RuntimeError
diff --git a/Examples/test-suite/python/cpp20_spaceship_operator_runme.py b/Examples/test-suite/python/cpp20_spaceship_operator_runme.py
new file mode 100644
index 000000000..f13fd48f6
--- /dev/null
+++ b/Examples/test-suite/python/cpp20_spaceship_operator_runme.py
@@ -0,0 +1,19 @@
+from cpp20_spaceship_operator import *
+
+def check_equal(a, b):
+ if a != b:
+ raise RuntimeError("{} is not equal to {}".format(a, b))
+
+check_equal(ALIEN, 1)
+check_equal(SPACE, 1)
+check_equal(COMET, 1)
+check_equal(cvar.v, 42)
+
+x = A(1)
+y = A(2)
+
+check_equal(spaceship(x, y) < 0, True)
+check_equal(spaceship(x, x), 0)
+check_equal(spaceship(y, x) > 0, True)
+
+check_equal(f(), 42)
diff --git a/Examples/test-suite/python/default_args_runme.py b/Examples/test-suite/python/default_args_runme.py
index 0ce47ab79..b8077cc28 100644
--- a/Examples/test-suite/python/default_args_runme.py
+++ b/Examples/test-suite/python/default_args_runme.py
@@ -12,7 +12,7 @@ def run(module_name):
de.accelerate()
de.accelerate(default_args.EnumClass.SLOW)
- if default_args.Statics_staticMethod() != 60:
+ if default_args.Statics.staticMethod() != 60:
raise RuntimeError
if default_args.cfunc1(1) != 2:
diff --git a/Examples/test-suite/python/director_abstract_runme.py b/Examples/test-suite/python/director_abstract_runme.py
index c8c4b36dc..fbc54808e 100644
--- a/Examples/test-suite/python/director_abstract_runme.py
+++ b/Examples/test-suite/python/director_abstract_runme.py
@@ -37,7 +37,7 @@ class MyExample3(director_abstract.Example3_i):
return b
me1 = MyExample1()
-if director_abstract.Example1_get_color(me1, 1, 2, 3) != 1:
+if director_abstract.Example1.get_color(me1, 1, 2, 3) != 1:
raise RuntimeError
me2 = MyExample2(1, 2)
diff --git a/Examples/test-suite/python/director_basic_runme.py b/Examples/test-suite/python/director_basic_runme.py
index 79cd0e2eb..2d07c3ad5 100644
--- a/Examples/test-suite/python/director_basic_runme.py
+++ b/Examples/test-suite/python/director_basic_runme.py
@@ -44,8 +44,8 @@ b = director_basic.Bar(3)
d = director_basic.MyClass()
c = PyClass()
-cc = director_basic.MyClass_get_self(c)
-dd = director_basic.MyClass_get_self(d)
+cc = director_basic.MyClass.get_self(c)
+dd = director_basic.MyClass.get_self(d)
bc = cc.cmethod(b)
bd = dd.cmethod(b)
@@ -86,8 +86,8 @@ for i in range(0, 100):
pymult = PyMulti()
-p1 = director_basic.Foo_get_self(pymult)
-p2 = director_basic.MyClass_get_self(pymult)
+p1 = director_basic.Foo.get_self(pymult)
+p2 = director_basic.MyClass.get_self(pymult)
p1.ping()
p2.vmethod(bc)
diff --git a/Examples/test-suite/python/director_multiple_inheritance_runme.py b/Examples/test-suite/python/director_multiple_inheritance_runme.py
new file mode 100644
index 000000000..8c8ea0bf6
--- /dev/null
+++ b/Examples/test-suite/python/director_multiple_inheritance_runme.py
@@ -0,0 +1,36 @@
+import director_multiple_inheritance as st
+
+class TestBCD(st.B, st.C, st.D):
+ def __init__(self):
+ st.B.__init__(self)
+ st.C.__init__(self)
+ st.D.__init__(self)
+
+class TestBDC(st.B, st.C, st.D):
+ def __init__(self):
+ st.B.__init__(self)
+ st.D.__init__(self)
+ st.C.__init__(self)
+
+class TestCBD(st.B, st.C, st.D):
+ def __init__(self):
+ st.C.__init__(self)
+ st.B.__init__(self)
+ st.D.__init__(self)
+
+def dotest(test):
+ e = st.E()
+ if e.testE(test) != 5:
+ raise RuntimeError(e.testE(test))
+
+ f = st.F()
+ if f.testF(test) != 6:
+ raise RuntimeError(f.testF(test))
+
+ t = st.T()
+ if t.testT(test) != 20:
+ raise RuntimeError(t.testT(test))
+
+dotest(TestBCD())
+dotest(TestCBD())
+dotest(TestBDC())
diff --git a/Examples/test-suite/python/director_nested_runme.py b/Examples/test-suite/python/director_nested_runme.py
index b2c4b0d40..24216f9dd 100644
--- a/Examples/test-suite/python/director_nested_runme.py
+++ b/Examples/test-suite/python/director_nested_runme.py
@@ -54,7 +54,7 @@ class C(FooBar_int):
pass
cc = C()
-c = FooBar_int_get_self(cc)
+c = FooBar_int.get_self(cc)
c.advance()
if c.get_name() != "FooBar::get_name hello":
diff --git a/Examples/test-suite/python/director_pass_by_value_runme.py b/Examples/test-suite/python/director_pass_by_value_runme.py
index 7744db962..9dbd64ad6 100644
--- a/Examples/test-suite/python/director_pass_by_value_runme.py
+++ b/Examples/test-suite/python/director_pass_by_value_runme.py
@@ -8,6 +8,8 @@ class director_pass_by_value_Derived(director_pass_by_value.DirectorPassByValueA
# bug was the passByVal global object was destroyed after the call to virtualMethod had finished.
director_pass_by_value.Caller().call_virtualMethod(director_pass_by_value_Derived())
+if director_pass_by_value.has_cplusplus11():
+ director_pass_by_value.Counter.check_counts(1, 0, 0, 1, 0, 1) # check move constructor called and just one destructor
ret = passByVal.getVal();
if ret != 0x12345678:
raise RuntimeError("Bad return value, got " + hex(ret))
diff --git a/Examples/test-suite/python/director_property_runme.py b/Examples/test-suite/python/director_property_runme.py
index 5d713c27f..2fa41968c 100644
--- a/Examples/test-suite/python/director_property_runme.py
+++ b/Examples/test-suite/python/director_property_runme.py
@@ -14,6 +14,43 @@ foo.setA("BLABLA")
if foo.getA() != "BLABLA":
raise RuntimeError
+# test property addition in PyFoo
+if foo.a != "BLABLA":
+ raise RuntimeError
+
foo.a = "BIBI"
if foo.a != "BIBI":
raise RuntimeError
+if foo.getA() != "BIBI":
+ raise RuntimeError
+
+
+
+class MyFoo(director_property.Foo):
+ def setA(self, a):
+ director_property.Foo.setA(self, a + " set from MyFoo")
+ def setAByRef(self, a):
+ director_property.Foo.setA(self, a + " setAByRef from MyFoo")
+
+a = MyFoo()
+if (a.getA() != ""):
+ raise RuntimeError("Test failed")
+a.setA("Hello")
+if (a.getA() != "Hello set from MyFoo"):
+ raise RuntimeError("Test failed")
+a.setAByRef("Hello")
+if (a.getA() != "Hello setAByRef from MyFoo"):
+ raise RuntimeError("Test failed")
+del a
+
+a_original = MyFoo()
+a = director_property.Foo.get_self(a_original)
+if (a.getA() != ""):
+ raise RuntimeError("Test failed")
+a.setA("Hello")
+if (a.getA() != "Hello set from MyFoo"):
+ raise RuntimeError("Test failed")
+a.setAByRef("Hello")
+if (a.getA() != "Hello setAByRef from MyFoo"):
+ raise RuntimeError("Test failed")
+del a
diff --git a/Examples/test-suite/python/director_wstring_runme.py b/Examples/test-suite/python/director_wstring_runme.py
index 5facc1f1d..659cf1854 100644
--- a/Examples/test-suite/python/director_wstring_runme.py
+++ b/Examples/test-suite/python/director_wstring_runme.py
@@ -12,6 +12,12 @@ class B(A):
def process_text(self, s):
self.smem = s
+ def process_wstring_text(self, s):
+ self.smem = s + " (wstring)"
+
+ def process_wstring_ref_text(self, s):
+ self.smem = s + " (wstring ref)"
+
b = B("hello")
@@ -24,3 +30,13 @@ b.call_process_func()
if b.smem != "hello":
raise RuntimeError("smem: {}".format(smem))
+
+b.call_process_wstring_func()
+
+if b.smem != "hello (wstring)":
+ raise RuntimeError("smem: {}".format(smem))
+
+b.call_process_wstring_ref_func()
+
+if b.smem != "hello (wstring ref)":
+ raise RuntimeError("smem: {}".format(smem))
diff --git a/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
new file mode 100644
index 000000000..9780516b9
--- /dev/null
+++ b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
@@ -0,0 +1,44 @@
+from doxygen_autodoc_docstring import *
+import inspect
+import string
+import os
+import sys
+import comment_verifier
+
+# documentation from autogenerated 'feature:autodoc'
+comment_verifier.check(inspect.getdoc(ClassWithoutDoxygenComment),
+ "::ClassWithoutDoxygenComment" if is_python_builtin() else "Proxy of C++ ClassWithoutDoxygenComment class.")
+comment_verifier.check(inspect.getdoc(functionWithoutDoxygenComment),
+ "functionWithoutDoxygenComment(int number)")
+
+# documentation from doxygen comments
+comment_verifier.check(inspect.getdoc(ClassWithDoxygenComment),
+ "Class doxygen comment")
+comment_verifier.check(inspect.getdoc(functionWithDoxygenComment),
+ "Function doxygen comment")
+
+# documentation from 'feature:docstring'
+comment_verifier.check(inspect.getdoc(ClassWithDocString),
+ "Class doc from docstring")
+comment_verifier.check(inspect.getdoc(functionWithDocString),
+ "functionWithDocString(int number)\n"
+ "Function doc from docstring")
+
+# documentation from 'feature:docstring' + autodoc (overriding doxycomment)
+comment_verifier.check(inspect.getdoc(ClassWithDocStringAndDoxygenComment),
+ "Class doc from docstring overriding doxycomment")
+comment_verifier.check(inspect.getdoc(functionWithDocStringAndDoxygenComment),
+ "functionWithDocStringAndDoxygenComment(int number)\n"
+ "Function doc from docstring overriding doxycomment")
+
+# documentation from 'feature:docstring' (overriding doxycomment)
+comment_verifier.check(inspect.getdoc(ClassWithDocStringAndDoxygenCommentNoAutodoc),
+ "Class doc from docstring overriding doxycomment (no autodoc)")
+comment_verifier.check(inspect.getdoc(functionWithDocStringAndDoxygenCommentNoAutodoc),
+ "Function doc from docstring overriding doxycomment (no autodoc)")
+
+# documentation from doxygen comments (2) no autodoc feature present
+comment_verifier.check(inspect.getdoc(ClassWithDoxygenComment2),
+ "Class doxygen comment 2")
+comment_verifier.check(inspect.getdoc(functionWithDoxygenComment2),
+ "Function doxygen comment 2")
diff --git a/Examples/test-suite/python/doxygen_translate_runme.py b/Examples/test-suite/python/doxygen_translate_runme.py
index 38dca2ef9..a62df4a1d 100644
--- a/Examples/test-suite/python/doxygen_translate_runme.py
+++ b/Examples/test-suite/python/doxygen_translate_runme.py
@@ -58,6 +58,7 @@ If not: SOMECONDITION {
}
Image: testImage.bmp("Hello, world!")
+Image: "test image.jpg"("Test jpeg")
diff --git a/Examples/test-suite/python/extern_c_runme.py b/Examples/test-suite/python/extern_c_runme.py
index 91a218a87..c30509d07 100644
--- a/Examples/test-suite/python/extern_c_runme.py
+++ b/Examples/test-suite/python/extern_c_runme.py
@@ -1,3 +1,10 @@
import extern_c
+def check(flag):
+ if not flag:
+ raise RuntimeError("Test failed")
+
extern_c.RealFunction(2)
+check(extern_c.cvar.int2 == 123)
+check(extern_c.cvar.int3 == 456)
+check(extern_c.cvar.int4 == 789)
diff --git a/Examples/test-suite/python/final_c_runme.py b/Examples/test-suite/python/final_c_runme.py
new file mode 100644
index 000000000..9ef4ded62
--- /dev/null
+++ b/Examples/test-suite/python/final_c_runme.py
@@ -0,0 +1,6 @@
+import final_c
+
+final_c.init()
+f = final_c.cvar.final
+if (f.yval != 123):
+ raise RuntimeError("f.yval fail")
diff --git a/Examples/test-suite/python/friends_runme.py b/Examples/test-suite/python/friends_runme.py
index 2d377fdd1..7c7bbabfe 100644
--- a/Examples/test-suite/python/friends_runme.py
+++ b/Examples/test-suite/python/friends_runme.py
@@ -19,7 +19,7 @@ b = friends.B(3)
if friends.mix(a, b) != 5:
raise RuntimeError
-di = friends.D_d(2)
+di = friends.D_i(2)
dd = friends.D_d(3.3)
# incredible template overloading working just fine
diff --git a/Examples/test-suite/python/ignore_parameter_runme.py b/Examples/test-suite/python/ignore_parameter_runme.py
index 2b5c21235..0f40f96c8 100644
--- a/Examples/test-suite/python/ignore_parameter_runme.py
+++ b/Examples/test-suite/python/ignore_parameter_runme.py
@@ -16,6 +16,7 @@ check(car.astonmartin("foo", 1), 101)
check(car.bugatti("bar", 2), 8.8)
check(car.lamborghini(), 101)
check(car.maseratti(289), 289)
+check(car.audi(), 8.8) # Typemap overrides default argument
MiniCooper(200, 0)
MorrisMinor("baz", 0)
diff --git a/Examples/test-suite/python/kwargs_feature_runme.py b/Examples/test-suite/python/kwargs_feature_runme.py
index 387658ec3..677c9ebd8 100644
--- a/Examples/test-suite/python/kwargs_feature_runme.py
+++ b/Examples/test-suite/python/kwargs_feature_runme.py
@@ -15,13 +15,16 @@ f = Foo(b=2, a=1)
if f.foo(b=1, a=2) != 3:
raise RuntimeError
-if Foo_statfoo(b=2) != 3:
+if Foo.statfoo(b=2) != 3:
+ raise RuntimeError
+
+if Foo.statfoo_onearg(x=4) != 8:
raise RuntimeError
if f.efoo(b=2) != 3:
raise RuntimeError
-if Foo_sfoo(b=2) != 3:
+if Foo.sfoo(b=2) != 3:
raise RuntimeError
@@ -31,13 +34,13 @@ b = BarInt(b=2, a=1)
if b.bar(b=1, a=2) != 3:
raise RuntimeError
-if BarInt_statbar(b=2) != 3:
+if BarInt.statbar(b=2) != 3:
raise RuntimeError
if b.ebar(b=2) != 3:
raise RuntimeError
-if BarInt_sbar(b=2) != 3:
+if BarInt.sbar(b=2) != 3:
raise RuntimeError
diff --git a/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py b/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py
index 52868eacc..b4382ca1e 100644
--- a/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py
+++ b/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py
@@ -1,5 +1,9 @@
from li_boost_shared_ptr_director import *
+def swig_assert_equal(a, b):
+ if a != b:
+ raise RuntimeError(str(a) + " != " + str(b))
+
class Derived(Base):
def __init__(self, flag):
self.return_none = flag
@@ -59,22 +63,22 @@ class Derived(Base):
a = Derived(False)
b = Derived(True)
-assert call_ret_c_shared_ptr(a) == 1
-assert call_ret_c_shared_ptr(b) == -1
-assert call_ret_c_by_value(a) == 1
-
-assert call_take_c_by_value(a) == 5
-assert call_take_c_by_ref(a) == 6
-assert call_take_c_by_pointer(a) == 7
-assert call_take_c_by_pointer_ref(a) == 8
-assert call_take_c_shared_ptr_by_value(a) == 9
-assert call_take_c_shared_ptr_by_ref(a) == 10
-assert call_take_c_shared_ptr_by_pointer(a) == 11
-assert call_take_c_shared_ptr_by_pointer_ref(a) == 12
-
-assert call_take_c_by_pointer_with_null(a) == -2
-assert call_take_c_by_pointer_ref_with_null(a) == -3
-assert call_take_c_shared_ptr_by_value_with_null(a) == -4
-assert call_take_c_shared_ptr_by_ref_with_null(a) == -5
-assert call_take_c_shared_ptr_by_pointer_with_null(a) == -6
-assert call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -7
+swig_assert_equal(call_ret_c_shared_ptr(a), 1)
+swig_assert_equal(call_ret_c_shared_ptr(b), -1)
+swig_assert_equal(call_ret_c_by_value(a), 1)
+
+swig_assert_equal(call_take_c_by_value(a), 5)
+swig_assert_equal(call_take_c_by_ref(a), 6)
+swig_assert_equal(call_take_c_by_pointer(a), 7)
+swig_assert_equal(call_take_c_by_pointer_ref(a), 8)
+swig_assert_equal(call_take_c_shared_ptr_by_value(a), 9)
+swig_assert_equal(call_take_c_shared_ptr_by_ref(a), 10)
+swig_assert_equal(call_take_c_shared_ptr_by_pointer(a), 11)
+swig_assert_equal(call_take_c_shared_ptr_by_pointer_ref(a), 12)
+
+swig_assert_equal(call_take_c_by_pointer_with_null(a), -2)
+swig_assert_equal(call_take_c_by_pointer_ref_with_null(a), -3)
+swig_assert_equal(call_take_c_shared_ptr_by_value_with_null(a), -4)
+swig_assert_equal(call_take_c_shared_ptr_by_ref_with_null(a), -5)
+swig_assert_equal(call_take_c_shared_ptr_by_pointer_with_null(a), -6)
+swig_assert_equal(call_take_c_shared_ptr_by_pointer_ref_with_null(a), -7)
diff --git a/Examples/test-suite/python/li_boost_shared_ptr_runme.py b/Examples/test-suite/python/li_boost_shared_ptr_runme.py
index ecda7fdb1..bde79fd61 100644
--- a/Examples/test-suite/python/li_boost_shared_ptr_runme.py
+++ b/Examples/test-suite/python/li_boost_shared_ptr_runme.py
@@ -20,7 +20,7 @@ class li_boost_shared_ptr_runme:
self.runtest()
# Expect 1 instance - the one global variable (GlobalValue)
- if (li_boost_shared_ptr.Klass_getTotal_count() != 1):
+ if (li_boost_shared_ptr.Klass.getTotal_count() != 1):
raise RuntimeError("Klass.total_count=%s" %
li_boost_shared_ptr.Klass.getTotal_count())
@@ -168,6 +168,19 @@ class li_boost_shared_ptr_runme:
except ValueError:
pass
+ # test null pointers emitted from C++
+ k = li_boost_shared_ptr.sp_pointer_null()
+ if (li_boost_shared_ptr.smartpointertest(k) != None):
+ raise RuntimeError("return was not null")
+
+ k = li_boost_shared_ptr.null_sp_pointer()
+ if (li_boost_shared_ptr.smartpointertest(k) != None):
+ raise RuntimeError("return was not null")
+
+ k = li_boost_shared_ptr.sp_value_null()
+ if (li_boost_shared_ptr.smartpointertest(k) != None):
+ raise RuntimeError("return was not null")
+
# $owner
k = li_boost_shared_ptr.pointerownertest()
val = k.getValue()
diff --git a/Examples/test-suite/python/li_factory_runme.py b/Examples/test-suite/python/li_factory_runme.py
index fb2c81e45..ce0e3caef 100644
--- a/Examples/test-suite/python/li_factory_runme.py
+++ b/Examples/test-suite/python/li_factory_runme.py
@@ -1,11 +1,11 @@
from li_factory import *
-circle = Geometry_create(Geometry.CIRCLE)
+circle = Geometry.create(Geometry.CIRCLE)
r = circle.radius()
if (r != 1.5):
raise RuntimeError
-point = Geometry_create(Geometry.POINT)
+point = Geometry.create(Geometry.POINT)
w = point.width()
if (w != 1.0):
raise RuntimeError
diff --git a/Examples/test-suite/python/li_std_auto_ptr_runme.py b/Examples/test-suite/python/li_std_auto_ptr_runme.py
index 6d2479f87..dd8893f40 100644
--- a/Examples/test-suite/python/li_std_auto_ptr_runme.py
+++ b/Examples/test-suite/python/li_std_auto_ptr_runme.py
@@ -1,17 +1,109 @@
from li_std_auto_ptr import *
+def checkCount(expected_count):
+ actual_count = Klass.getTotal_count()
+ if (actual_count != expected_count):
+ raise RuntimeError("Counts incorrect, expected:" + expected_count + " actual:" + actual_count)
+
+# Test raw pointer handling involving virtual inheritance
+kini = KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = useKlassRawPtr(kini)
+if s != "KlassInheritanceInput":
+ raise RuntimeError("Incorrect string: " + s)
+del kini
+checkCount(0)
+
+
+# auto_ptr as input
+kin = Klass("KlassInput")
+checkCount(1)
+s = takeKlassAutoPtr(kin)
+checkCount(0)
+if kin.thisown:
+ raise RuntimeError("thisown should be false")
+if s != "KlassInput":
+ raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kin):
+ raise RuntimeError("is_nullptr failed")
+del kin # Should not fail, even though already deleted
+checkCount(0)
+
+kin = Klass("KlassInput")
+checkCount(1)
+s = takeKlassAutoPtr(kin)
+checkCount(0)
+if kin.thisown:
+ raise RuntimeError("thisown should be false")
+if s != "KlassInput":
+ raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kin):
+ raise RuntimeError("is_nullptr failed")
+exception_thrown = False
+try:
+ s = takeKlassAutoPtr(kin)
+except RuntimeError as e:
+ if "cannot release ownership as memory is not owned" not in str(e):
+ raise RuntimeError("incorrect exception message");
+ exception_thrown = True
+if not exception_thrown:
+ raise RuntimeError("double usage of takeKlassAutoPtr should have been an error")
+del kin # Should not fail, even though already deleted
+checkCount(0)
+
+kin = Klass("KlassInput")
+exception_thrown = False
+notowned = get_not_owned_ptr(kin)
+try:
+ takeKlassAutoPtr(notowned)
+except RuntimeError as e:
+ exception_thrown = True
+if not exception_thrown:
+ raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
+checkCount(1)
+del kin
+checkCount(0)
+
+kini = KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = takeKlassAutoPtr(kini)
+checkCount(0)
+if kini.thisown:
+ raise RuntimeError("thisown should be false")
+if s != "KlassInheritanceInput":
+ raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kini):
+ raise RuntimeError("is_nullptr failed")
+del kini # Should not fail, even though already deleted
+checkCount(0)
+
+takeKlassAutoPtr(None)
+takeKlassAutoPtr(make_null())
+checkCount(0)
+
+# overloaded parameters
+if overloadTest() != 0:
+ raise RuntimeError("overloadTest failed")
+if overloadTest(None) != 1:
+ raise RuntimeError("overloadTest failed")
+if overloadTest(Klass("over")) != 1:
+ raise RuntimeError("overloadTest failed")
+checkCount(0);
+
+
+# auto_ptr as output
k1 = makeKlassAutoPtr("first")
k2 = makeKlassAutoPtr("second")
-if Klass_getTotal_count() != 2:
- raise "number of objects should be 2"
+checkCount(2)
del k1
-if Klass_getTotal_count() != 1:
- raise "number of objects should be 1"
+checkCount(1)
if k2.getLabel() != "second":
raise "wrong object label"
del k2
-if Klass_getTotal_count() != 0:
- raise "no objects should be left"
+checkCount(0)
+
+if (makeNullAutoPtr() != None):
+ raise RuntimeError("null failure")
diff --git a/Examples/test-suite/python/li_std_string_extra_runme.py b/Examples/test-suite/python/li_std_string_extra_runme.py
index 96c64163d..71620e7fb 100644
--- a/Examples/test-suite/python/li_std_string_extra_runme.py
+++ b/Examples/test-suite/python/li_std_string_extra_runme.py
@@ -15,6 +15,11 @@ if li_std_string_extra.test_value(x) != x:
if li_std_string_extra.test_const_reference(x) != x:
raise RuntimeError("bad string mapping")
+s = li_std_string_extra.string("1234567890")
+size = s.size()
+if size != 10:
+ raise "Incorrect size"
+s.shrink_to_fit()
s = li_std_string_extra.string("he")
#s += "ll"
diff --git a/Examples/test-suite/python/multivalue_runme.py b/Examples/test-suite/python/multivalue_runme.py
new file mode 100644
index 000000000..ba832724a
--- /dev/null
+++ b/Examples/test-suite/python/multivalue_runme.py
@@ -0,0 +1,19 @@
+import multivalue
+
+q, r = multivalue.divide_l(37, 5);
+if q != 7:
+ raise RuntimeError("Test divide_l quotient")
+if r != 2:
+ raise RuntimeError("Test divide_l remainder")
+
+q, r = multivalue.divide_v(41, 7);
+if q != 5:
+ raise RuntimeError("Test divide_v quotient")
+if r != 6:
+ raise RuntimeError("Test divide_v remainder")
+
+q, r = multivalue.divide_l(91, 13);
+if q != 7:
+ raise RuntimeError("Test divide_mv quotient")
+if r != 0:
+ raise RuntimeError("Test divide_mv remainder")
diff --git a/Examples/test-suite/python/name_warnings_runme.py b/Examples/test-suite/python/name_warnings_runme.py
new file mode 100644
index 000000000..0387436e0
--- /dev/null
+++ b/Examples/test-suite/python/name_warnings_runme.py
@@ -0,0 +1,9 @@
+from name_warnings import *
+
+def check(flag):
+ if not flag:
+ raise RuntimeError("Test failed")
+
+four = double_an_int(2)
+check(four == 4)
+
diff --git a/Examples/test-suite/python/operator_overload_runme.py b/Examples/test-suite/python/operator_overload_runme.py
index 31c49058e..cd565f619 100644
--- a/Examples/test-suite/python/operator_overload_runme.py
+++ b/Examples/test-suite/python/operator_overload_runme.py
@@ -1,7 +1,7 @@
from operator_overload import *
# first check all the operators are implemented correctly from pure C++ code
-Op_sanity_check()
+Op.sanity_check()
pop = Op(6)/Op(3)
diff --git a/Examples/test-suite/python/overload_simple_runme.py b/Examples/test-suite/python/overload_simple_runme.py
index 8ad813b86..56763828d 100644
--- a/Examples/test-suite/python/overload_simple_runme.py
+++ b/Examples/test-suite/python/overload_simple_runme.py
@@ -43,22 +43,22 @@ if s.foo(b) != "foo:Bar *":
if s.foo(v) != "foo:void *":
raise RuntimeError("Spam::foo(void *)")
-if Spam_bar(3) != "bar:int":
+if Spam.bar(3) != "bar:int":
raise RuntimeError("Spam::bar(int)")
-if Spam_bar(3.0) != "bar:double":
+if Spam.bar(3.0) != "bar:double":
raise RuntimeError("Spam::bar(double)")
-if Spam_bar("hello") != "bar:char *":
+if Spam.bar("hello") != "bar:char *":
raise RuntimeError("Spam::bar(char *)")
-if Spam_bar(f) != "bar:Foo *":
+if Spam.bar(f) != "bar:Foo *":
raise RuntimeError("Spam::bar(Foo *)")
-if Spam_bar(b) != "bar:Bar *":
+if Spam.bar(b) != "bar:Bar *":
raise RuntimeError("Spam::bar(Bar *)")
-if Spam_bar(v) != "bar:void *":
+if Spam.bar(v) != "bar:void *":
raise RuntimeError("Spam::bar(void *)")
# Test constructors
diff --git a/Examples/test-suite/python/overload_template_runme.py b/Examples/test-suite/python/overload_template_runme.py
index a484d8f0e..8bd105add 100644
--- a/Examples/test-suite/python/overload_template_runme.py
+++ b/Examples/test-suite/python/overload_template_runme.py
@@ -140,6 +140,6 @@ if (nsoverload() != 1050):
raise RuntimeError(("nsoverload(const char *)"))
-A_foo(1)
+A.foo(1)
b = B()
b.foo(1)
diff --git a/Examples/test-suite/python/preproc_cpp_runme.py b/Examples/test-suite/python/preproc_cpp_runme.py
new file mode 100644
index 000000000..8c3e21237
--- /dev/null
+++ b/Examples/test-suite/python/preproc_cpp_runme.py
@@ -0,0 +1,4 @@
+import preproc_cpp
+
+t1 = preproc_cpp.tcxMessageTest()
+t2 = preproc_cpp.tcxMessageBug()
diff --git a/Examples/test-suite/python/python_abstractbase_runme.py b/Examples/test-suite/python/python_abstractbase_runme.py
index 9f99dcb54..0790c5ca7 100644
--- a/Examples/test-suite/python/python_abstractbase_runme.py
+++ b/Examples/test-suite/python/python_abstractbase_runme.py
@@ -1,31 +1,36 @@
import sys
# collections.abc requires Python 3.3+
-if sys.version_info[0:2] < (3, 3):
- exit(0)
from python_abstractbase import *
-import collections.abc
+if sys.version_info[0:2] >= (3, 3):
+ import collections.abc
+else:
+ import collections
# This is expected to fail with -builtin option
# Builtin types can't inherit from pure-python abstract bases
if is_python_builtin():
exit(0)
-# Python abc is only turned on when -py3 option is passed to SWIG
-if not is_swig_py3:
- exit(0)
-
def check_issubclass(derived, base):
if not issubclass(derived, base):
raise RuntimeError("{} is not a subclass of {}".format(derived, base))
-check_issubclass(Mapii, collections.abc.MutableMapping)
-check_issubclass(Multimapii, collections.abc.MutableMapping)
-check_issubclass(IntSet, collections.abc.MutableSet)
-check_issubclass(IntMultiset, collections.abc.MutableSet)
-check_issubclass(IntVector, collections.abc.MutableSequence)
-check_issubclass(IntList, collections.abc.MutableSequence)
+if sys.version_info[0:2] >= (3, 3):
+ check_issubclass(Mapii, collections.abc.MutableMapping)
+ check_issubclass(Multimapii, collections.abc.MutableMapping)
+ check_issubclass(IntSet, collections.abc.MutableSet)
+ check_issubclass(IntMultiset, collections.abc.MutableSet)
+ check_issubclass(IntVector, collections.abc.MutableSequence)
+ check_issubclass(IntList, collections.abc.MutableSequence)
+else:
+ check_issubclass(Mapii, collections.MutableMapping)
+ check_issubclass(Multimapii, collections.MutableMapping)
+ check_issubclass(IntSet, collections.MutableSet)
+ check_issubclass(IntMultiset, collections.MutableSet)
+ check_issubclass(IntVector, collections.MutableSequence)
+ check_issubclass(IntList, collections.MutableSequence)
mapii = Mapii()
multimapii = Multimapii()
diff --git a/Examples/test-suite/python/python_annotations_c_runme.py b/Examples/test-suite/python/python_annotations_c_runme.py
new file mode 100644
index 000000000..3110d8f83
--- /dev/null
+++ b/Examples/test-suite/python/python_annotations_c_runme.py
@@ -0,0 +1,31 @@
+import sys
+
+if sys.version_info[0:2] >= (3, 2):
+ from python_annotations_c import *
+
+ # No __annotations__ support with -builtin or -fastproxy
+ annotations_supported = not(is_python_builtin() or is_python_fastproxy())
+
+ if annotations_supported:
+ anno = MakeShort.__annotations__
+ if anno != {'x': 'int', 'return': 'Space::Template< short >'}:
+ raise RuntimeError("annotations mismatch: {}".format(anno))
+
+ anno = global_ints.__annotations__
+ if anno != {'ri': 'int &', 't': 'TemplateShort', 'return': 'int *'}:
+ raise RuntimeError("annotations mismatch: {}".format(anno))
+
+ ts = MakeShort(10)
+
+ anno = MakeShort.__annotations__
+ if anno != {'x': 'int', 'return': 'Space::Template< short >'}:
+ raise RuntimeError("annotations mismatch: {}".format(anno))
+
+ anno = ts.mymethod.__annotations__
+ if anno != {'arg2': 'int', 'tt': 'TemplateShort', 'return': 'void'}:
+ raise RuntimeError("annotations mismatch: {}".format(anno))
+
+ # No annotations
+ anno = no_annotations.__annotations__
+ if anno != {}:
+ raise RuntimeError("annotations mismatch: {}".format(anno))
diff --git a/Examples/test-suite/python/python_annotations_variable_c_runme.py b/Examples/test-suite/python/python_annotations_variable_c_runme.py
new file mode 100644
index 000000000..153852d05
--- /dev/null
+++ b/Examples/test-suite/python/python_annotations_variable_c_runme.py
@@ -0,0 +1,24 @@
+import sys
+
+# Variable annotations for properties is only supported in python-3.6 and later (PEP 526)
+if sys.version_info[0:2] >= (3, 6):
+ from python_annotations_variable_c import *
+
+ # No SWIG __annotations__ support with -builtin or -fastproxy
+ annotations_supported = not(is_python_builtin() or is_python_fastproxy())
+
+ if annotations_supported:
+ ts = TemplateShort()
+ anno = ts.__annotations__
+ if anno != {'member_variable': 'int'}:
+ raise RuntimeError("annotations mismatch: {}".format(anno))
+
+ ts = StructWithVar()
+ anno = ts.__annotations__
+ if anno != {'member_variable': 'int'}:
+ raise RuntimeError("annotations mismatch: {}".format(anno))
+
+ ts = StructWithVarNotAnnotated()
+ if getattr(ts, "__annotations__", None) != None:
+ anno = ts.__annotations__
+ raise RuntimeError("annotations mismatch: {}".format(anno))
diff --git a/Examples/test-suite/python/python_flatstaticmethod_runme.py b/Examples/test-suite/python/python_flatstaticmethod_runme.py
new file mode 100644
index 000000000..13d935f47
--- /dev/null
+++ b/Examples/test-suite/python/python_flatstaticmethod_runme.py
@@ -0,0 +1,92 @@
+from python_flatstaticmethod import *
+import inspect
+
+# This testcase tests C++ class static functions when using legacy "flattened"
+# staticmethod access, A_bar, as well as the normal staticmethod access, A.bar.
+
+
+def check(got, expected):
+ if got != expected:
+ raise RuntimeError("\ngot :{}\nwant:{}\n".format(got, expected))
+
+if A_bar(2) != 4:
+ raise RuntimeError
+
+if A.bar(2) != 4:
+ raise RuntimeError
+
+# %callback
+if foobar(3, A_bar) != A_bar(3):
+ raise RuntimeError
+
+if foobar(3, A.bar) != A_bar(3):
+ raise RuntimeError
+
+# kwargs
+if A_pub() != 1:
+ raise RuntimeError
+
+if A_pub(b=2) != 3:
+ raise RuntimeError
+
+if A_pub(b=10,a=20) != 30:
+ raise RuntimeError
+
+if A.pub() != 1:
+ raise RuntimeError
+
+if A.pub(b=2) != 3:
+ raise RuntimeError
+
+if A.pub(b=10,a=20) != 30:
+ raise RuntimeError
+
+check(inspect.getdoc(A_func0static),
+ "A_func0static(e, arg2, hello, f=2) -> int")
+check(inspect.getdoc(A_func1static),
+ "A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
+
+# overloaded static functions
+if A_over(3) != "over:int":
+ raise RuntimeError("A::over(int)")
+
+if A_over(3.0) != "over:double":
+ raise RuntimeError("A::over(double)")
+
+if A_over("hello") != "over:char *":
+ raise RuntimeError("A::over(char *)")
+
+if A.over(3) != "over:int":
+ raise RuntimeError("A::over(int)")
+
+if A.over(3.0) != "over:double":
+ raise RuntimeError("A::over(double)")
+
+if A.over("hello") != "over:char *":
+ raise RuntimeError("A::over(char *)")
+
+# default args
+if A_defargs() != 30:
+ raise RuntimeError
+
+if A_defargs(1) != 21:
+ raise RuntimeError
+
+if A_defargs(1, 2) != 3:
+ raise RuntimeError
+
+if A.defargs() != 30:
+ raise RuntimeError
+
+if A.defargs(1) != 21:
+ raise RuntimeError
+
+if A.defargs(1, 2) != 3:
+ raise RuntimeError
+
+# %extend
+if A_staticextended(11) != 11:
+ raise RuntimeError
+
+if A.staticextended(11) != 11:
+ raise RuntimeError
diff --git a/Examples/test-suite/python/python_nondynamic_runme.py b/Examples/test-suite/python/python_nondynamic_runme.py
index 524f4d1c4..870c70b3b 100644
--- a/Examples/test-suite/python/python_nondynamic_runme.py
+++ b/Examples/test-suite/python/python_nondynamic_runme.py
@@ -1,9 +1,5 @@
import python_nondynamic
-def is_python_modern():
- """Return True if SWIG is generating Python code using -modern. Works only if %python_nondynamic has been used."""
- return hasattr(python_nondynamic, "_swig_setattr_nondynamic_class_variable")
-
def debug_print(s):
show_debug = False
if show_debug:
@@ -66,7 +62,7 @@ except AttributeError as e:
cc = python_nondynamic.C()
cc.d = 3
-# An inconsistency between builtin and (non-builtin/modern).
+# An inconsistency between builtin and non-builtin.
# Class variables cannot be set on builtin types, like other Python builtins, eg list.classvar=111 fails
if python_nondynamic.is_python_builtin():
try:
@@ -78,8 +74,8 @@ if python_nondynamic.is_python_builtin():
else:
python_nondynamic.C.classvar = 111
-if is_python_modern() and not python_nondynamic.is_python_builtin():
- # Not working with builtin or non-modern :(
+if not python_nondynamic.is_python_builtin():
+ # Not working with builtin :(
try:
B.a = 10
raise RuntimeError("B should not allow adding a class variable by setting it as an instance variable")
diff --git a/Examples/test-suite/python/python_overload_simple_cast_runme.py b/Examples/test-suite/python/python_overload_simple_cast_runme.py
index 7a0174af8..2aee5bb53 100644
--- a/Examples/test-suite/python/python_overload_simple_cast_runme.py
+++ b/Examples/test-suite/python/python_overload_simple_cast_runme.py
@@ -115,22 +115,22 @@ if s.foo(b) != "foo:Bar *":
if s.foo(v) != "foo:void *":
raise RuntimeError("Spam::foo(void *)")
-if Spam_bar(3) != "bar:int":
+if Spam.bar(3) != "bar:int":
raise RuntimeError("Spam::bar(int)")
-if Spam_bar(3.0) != "bar:double":
+if Spam.bar(3.0) != "bar:double":
raise RuntimeError("Spam::bar(double)")
-if Spam_bar("hello") != "bar:char *":
+if Spam.bar("hello") != "bar:char *":
raise RuntimeError("Spam::bar(char *)")
-if Spam_bar(f) != "bar:Foo *":
+if Spam.bar(f) != "bar:Foo *":
raise RuntimeError("Spam::bar(Foo *)")
-if Spam_bar(b) != "bar:Bar *":
+if Spam.bar(b) != "bar:Bar *":
raise RuntimeError("Spam::bar(Bar *)")
-if Spam_bar(v) != "bar:void *":
+if Spam.bar(v) != "bar:void *":
raise RuntimeError("Spam::bar(void *)")
# Test constructors
diff --git a/Examples/test-suite/python/python_pickle_runme.py b/Examples/test-suite/python/python_pickle_runme.py
index cbe425fa2..7cb07ef59 100644
--- a/Examples/test-suite/python/python_pickle_runme.py
+++ b/Examples/test-suite/python/python_pickle_runme.py
@@ -8,13 +8,13 @@ def check(p):
if msg != "hi there":
raise RuntimeError("Bad, got: " + msg)
-python_pickle.cvar.debug = False
+python_pickle.cvar.trace = False
p = python_pickle.PickleMe("hi there")
check(p)
r = p.__reduce__()
-if python_pickle.cvar.debug:
+if python_pickle.cvar.trace:
print("__reduce__ returned: {}".format(r))
pickle_string = pickle.dumps(p)
newp = pickle.loads(pickle_string)
diff --git a/Examples/test-suite/python/python_runtime_data_runme.py b/Examples/test-suite/python/python_runtime_data_runme.py
new file mode 100644
index 000000000..063bf82d1
--- /dev/null
+++ b/Examples/test-suite/python/python_runtime_data_runme.py
@@ -0,0 +1,15 @@
+import python_runtime_data_builtin as builtin
+import python_runtime_data_nobuiltin as nobuiltin
+
+def swig_assert(a):
+ if not a:
+ raise RuntimeError("Failed")
+
+swig_assert(builtin.is_python_builtin())
+swig_assert(not nobuiltin.is_python_builtin())
+
+for i in range(1, 5):
+ v1 = builtin.vectord([1.] * i)
+ swig_assert(len(v1) == i)
+ v2 = nobuiltin.vectord([1.] * i)
+ swig_assert(len(v2) == i)
diff --git a/Examples/test-suite/python/refcount_runme.py b/Examples/test-suite/python/refcount_runme.py
index 2cab6a77e..5bea25fa1 100644
--- a/Examples/test-suite/python/refcount_runme.py
+++ b/Examples/test-suite/python/refcount_runme.py
@@ -5,7 +5,7 @@ from refcount import *
a = A3()
b1 = B(a)
-b2 = B_create(a)
+b2 = B.create(a)
if a.ref_count() != 3:
@@ -13,7 +13,7 @@ if a.ref_count() != 3:
rca = b2.get_rca()
-b3 = B_create(rca)
+b3 = B.create(rca)
if a.ref_count() != 5:
raise RuntimeError("Count = %d" % a.ref_count())
@@ -38,7 +38,7 @@ b5 = global_create(a)
if b5.ref_count() != 1:
raise RuntimeError
-b6 = Factory_create(a)
+b6 = Factory.create(a)
if b6.ref_count() != 1:
raise RuntimeError
diff --git a/Examples/test-suite/python/return_const_value_runme.py b/Examples/test-suite/python/return_const_value_runme.py
index 809eed97a..8cbac125c 100644
--- a/Examples/test-suite/python/return_const_value_runme.py
+++ b/Examples/test-suite/python/return_const_value_runme.py
@@ -1,10 +1,10 @@
import return_const_value
import sys
-p = return_const_value.Foo_ptr_getPtr()
+p = return_const_value.Foo_ptr.getPtr()
if (p.getVal() != 17):
raise RuntimeError("Runtime test1 failed. p.getVal()={}".format(p.getVal()))
-p = return_const_value.Foo_ptr_getConstPtr()
+p = return_const_value.Foo_ptr.getConstPtr()
if (p.getVal() != 17):
raise RuntimeError("Runtime test2 failed. p.getVal()={}".format(p.getVal()))
diff --git a/Examples/test-suite/python/special_variable_macros_runme.py b/Examples/test-suite/python/special_variable_macros_runme.py
index e487f9a50..a67abcbc4 100644
--- a/Examples/test-suite/python/special_variable_macros_runme.py
+++ b/Examples/test-suite/python/special_variable_macros_runme.py
@@ -1,10 +1,15 @@
import special_variable_macros
+cvar = special_variable_macros.cvar
name = special_variable_macros.Name()
if special_variable_macros.testFred(name) != "none":
raise "test failed"
+if cvar.accessed_examplekw != 0:
+ raise "Precondition failed"
if special_variable_macros.testJack(name) != "$specialname":
raise "test failed"
+if cvar.accessed_examplekw != 1:
+ raise "Postcondition failed"
if special_variable_macros.testJill(name) != "jilly":
raise "test failed"
if special_variable_macros.testMary(name) != "SWIGTYPE_p_NameWrap":
diff --git a/Examples/test-suite/python/template_static_runme.py b/Examples/test-suite/python/template_static_runme.py
index c87a52439..84da28438 100644
--- a/Examples/test-suite/python/template_static_runme.py
+++ b/Examples/test-suite/python/template_static_runme.py
@@ -1,3 +1,3 @@
from template_static import *
-Foo_bar_double(1)
+Foo.bar_double(1)
diff --git a/Examples/test-suite/python/typemap_out_optimal_runme.py b/Examples/test-suite/python/typemap_out_optimal_runme.py
index c7a34308e..6f6cc5490 100644
--- a/Examples/test-suite/python/typemap_out_optimal_runme.py
+++ b/Examples/test-suite/python/typemap_out_optimal_runme.py
@@ -1,4 +1,7 @@
from typemap_out_optimal import *
-cvar.XX_debug = False
-x = XX_create()
+cvar.XX_trace = False
+x = XX.create()
+del x
+x = XX.createConst()
+del x
diff --git a/Examples/test-suite/python/using_member_runme.py b/Examples/test-suite/python/using_member_runme.py
new file mode 100644
index 000000000..a0ea64888
--- /dev/null
+++ b/Examples/test-suite/python/using_member_runme.py
@@ -0,0 +1,24 @@
+from using_member import *
+
+def swig_assert_equal(a, b):
+ if a != b:
+ raise RuntimeError(str(a) + " != " + str(b))
+
+b = B()
+swig_assert_equal(b.get(int(1)), 10)
+swig_assert_equal(b.get(float(1)), 20)
+
+bb = BB()
+swig_assert_equal(bb.greater(int(1)), 0)
+swig_assert_equal(bb.greater(float(1)), 1)
+swig_assert_equal(bb.great(True), 2)
+
+cc = CC()
+swig_assert_equal(cc.greater(int(10)), 0)
+swig_assert_equal(cc.greater(float(10)), 1)
+swig_assert_equal(cc.greater(True), 20)
+
+dd = DD()
+swig_assert_equal(dd.greater(int(10)), 0)
+swig_assert_equal(dd.greater(float(10)), 1)
+swig_assert_equal(dd.greaterstill(True), 30)
diff --git a/Examples/test-suite/python/virtual_poly_runme.py b/Examples/test-suite/python/virtual_poly_runme.py
index 0df6271ef..6708b6f99 100644
--- a/Examples/test-suite/python/virtual_poly_runme.py
+++ b/Examples/test-suite/python/virtual_poly_runme.py
@@ -29,10 +29,10 @@ if d.get() != dr.get():
#
# 'narrowing' also works
#
-ddc = virtual_poly.NDouble_narrow(d.nnumber())
+ddc = virtual_poly.NDouble.narrow(d.nnumber())
if d.get() != ddc.get():
raise RuntimeError
-dic = virtual_poly.NInt_narrow(i.nnumber())
+dic = virtual_poly.NInt.narrow(i.nnumber())
if i.get() != dic.get():
raise RuntimeError
diff --git a/Examples/test-suite/python/voidtest_runme.py b/Examples/test-suite/python/voidtest_runme.py
index b16cacf00..dd25b4c25 100644
--- a/Examples/test-suite/python/voidtest_runme.py
+++ b/Examples/test-suite/python/voidtest_runme.py
@@ -4,7 +4,7 @@ voidtest.globalfunc()
f = voidtest.Foo()
f.memberfunc()
-voidtest.Foo_staticmemberfunc()
+voidtest.Foo.staticmemberfunc()
def fvoid():
diff --git a/Examples/test-suite/python_abstractbase.i b/Examples/test-suite/python_abstractbase.i
index 2146e758e..65f3d9931 100644
--- a/Examples/test-suite/python_abstractbase.i
+++ b/Examples/test-suite/python_abstractbase.i
@@ -24,9 +24,3 @@ bool is_python_builtin() { return true; }
bool is_python_builtin() { return false; }
#endif
%}
-
-#ifdef SWIGPYTHON_PY3 // set when using -py3
-#define is_swig_py3 1
-#else
-#define is_swig_py3 0
-#endif
diff --git a/Examples/test-suite/python_annotations_c.i b/Examples/test-suite/python_annotations_c.i
new file mode 100644
index 000000000..c023e4d07
--- /dev/null
+++ b/Examples/test-suite/python_annotations_c.i
@@ -0,0 +1,40 @@
+%module python_annotations_c
+
+// Tests the C/C++ annotations that were automatically added by using -py3 before swig-4.1.0
+// In swig-4.1.0 and later, the feature below is needed as the -py3 option was dropped
+%feature("python:annotations", "c") mymethod;
+%feature("python:annotations", "c") makeT<short>;
+%feature("python:annotations", "c") global_ints;
+
+%inline %{
+namespace Space {
+template<class T>
+struct Template {
+ void mymethod(int, Template* tt) {}
+};
+}
+template<typename T>
+Space::Template<T> makeT(int x) {
+ return Space::Template<T>();
+};
+int *global_ints(int &ri, Space::Template<short> t) { return &ri; }
+int *global_overloaded(int &ri) { return &ri; }
+int *global_overloaded() { return NULL; }
+int *no_annotations(int &ri, const char *c) { return NULL; }
+%}
+%template(TemplateShort) Space::Template<short>;
+%template(MakeShort) makeT<short>;
+
+%inline %{
+#ifdef SWIGPYTHON_BUILTIN
+int is_python_builtin() { return 1; }
+#else
+int is_python_builtin() { return 0; }
+#endif
+
+#if defined SWIGPYTHON_FASTPROXY
+int is_python_fastproxy() { return 1; }
+#else
+int is_python_fastproxy() { return 0; }
+#endif
+%}
diff --git a/Examples/test-suite/python_annotations_variable_c.i b/Examples/test-suite/python_annotations_variable_c.i
new file mode 100644
index 000000000..876bbee75
--- /dev/null
+++ b/Examples/test-suite/python_annotations_variable_c.i
@@ -0,0 +1,44 @@
+%module python_annotations_variable_c
+
+// Tests Python variable annotations, containing C/C++ types, in C++ member variables wrappers.
+// Member variables are wrapped using Python properties.
+// This is in a separate test to python_annotations_c.i (which tests function annotations) so that runtime testing
+// of variable annotations can be done which requires Python 3.6 and later. A syntax error occurs in earlier
+// versions of Python when importing code containing variable annotations.
+
+%feature("python:annotations", "c");
+%feature("python:annotations:novar") member_variable_not_annotated;
+
+
+%inline %{
+namespace Space {
+template<class T>
+struct Template {
+ int member_variable;
+ int member_variable_not_annotated;
+};
+struct StructWithVar{
+ int member_variable;
+};
+struct StructWithVarNotAnnotated {
+ int member_variable_not_annotated;
+};
+short global_variable;
+}
+%}
+%template(TemplateShort) Space::Template<short>;
+
+%inline %{
+#ifdef SWIGPYTHON_BUILTIN
+int is_python_builtin() { return 1; }
+#else
+int is_python_builtin() { return 0; }
+#endif
+
+#if defined SWIGPYTHON_FASTPROXY
+int is_python_fastproxy() { return 1; }
+#else
+int is_python_fastproxy() { return 0; }
+#endif
+%}
+
diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i
index 994c625e8..754526dad 100644
--- a/Examples/test-suite/python_builtin.i
+++ b/Examples/test-suite/python_builtin.i
@@ -244,4 +244,3 @@ public:
}
};
%}
-
diff --git a/Examples/test-suite/python_flatstaticmethod.i b/Examples/test-suite/python_flatstaticmethod.i
new file mode 100644
index 000000000..0e131d669
--- /dev/null
+++ b/Examples/test-suite/python_flatstaticmethod.i
@@ -0,0 +1,40 @@
+%module python_flatstaticmethod
+
+// This testcase tests C++ class static functions when using legacy "flattened"
+// staticmethod access, A_bar, as well as the normal staticmethod access, A.bar.
+
+%callback(1) A::bar;
+%feature("kwargs") A::pub;
+%feature("autodoc","0") A::func0static; // names
+%feature("autodoc","1") A::func1static; // names + types
+// special typemap and its docs
+%typemap(in) (int c, int d) "$1 = 0; $2 = 0;"
+%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]"
+
+%extend A {
+static int staticextended(int i) { return i; }
+}
+
+%inline %{
+ struct A {
+ static int bar(int a) {
+ return 2*a;
+ }
+ static int pub(int a = 1, int b = 0) {
+ return a + b;
+ }
+ static int func0static(A *e, short, int c, int d, double f = 2) { return 0; }
+ static int func1static(A *e, short, int c, int d, double f = 2) { return 0; }
+
+ static const char *over(int) { return "over:int"; }
+ static const char *over(double) { return "over:double"; }
+ static const char *over(char *) { return "over:char *"; }
+
+ static int defargs(int xx = 10, int yy = 20) { return xx + yy; }
+ };
+
+ extern "C" int foobar(int a, int (*pf)(int a)) {
+ return pf(a);
+ }
+%}
+
diff --git a/Examples/test-suite/python_pickle.i b/Examples/test-suite/python_pickle.i
index fbb3d05a8..10be972a0 100644
--- a/Examples/test-suite/python_pickle.i
+++ b/Examples/test-suite/python_pickle.i
@@ -14,7 +14,7 @@ def __reduce__(self):
#else
// Equivalent to Python code above
PyObject *__reduce__() {
- if (debug)
+ if (trace)
std::cout << "In C++ __reduce__" << std::endl;
PyObject *args = PyTuple_New(1);
PyTuple_SetItem(args, 0, SWIG_From_std_string(self->msg));
@@ -39,12 +39,12 @@ def __reduce__(self):
%inline %{
#include <iostream>
-bool debug = false;
+bool trace = false;
struct PickleMe {
std::string msg;
PickleMe(const std::string& msg) : msg(msg) {
- if (debug)
+ if (trace)
std::cout << "In C++ constructor " << " [" << msg << "]" << std::endl;
}
};
diff --git a/Examples/test-suite/python_runtime_data.list b/Examples/test-suite/python_runtime_data.list
new file mode 100644
index 000000000..e88ef0c3b
--- /dev/null
+++ b/Examples/test-suite/python_runtime_data.list
@@ -0,0 +1,2 @@
+python_runtime_data_builtin
+python_runtime_data_nobuiltin
diff --git a/Examples/test-suite/python_runtime_data_builtin.i b/Examples/test-suite/python_runtime_data_builtin.i
new file mode 100644
index 000000000..1001b837c
--- /dev/null
+++ b/Examples/test-suite/python_runtime_data_builtin.i
@@ -0,0 +1,15 @@
+// Test swig_runtime_data with and without -builtin
+
+%module python_runtime_data_builtin
+
+%inline %{
+#ifdef SWIGPYTHON_BUILTIN
+bool is_python_builtin() { return true; }
+#else
+bool is_python_builtin() { return false; }
+#endif
+%}
+
+%include std_vector.i
+
+%template(vectord) std::vector<double>;
diff --git a/Examples/test-suite/python_runtime_data_nobuiltin.i b/Examples/test-suite/python_runtime_data_nobuiltin.i
new file mode 100644
index 000000000..18c041468
--- /dev/null
+++ b/Examples/test-suite/python_runtime_data_nobuiltin.i
@@ -0,0 +1,3 @@
+%module python_runtime_data_nobuiltin
+
+%include "python_runtime_data_builtin.i"
diff --git a/Examples/test-suite/python_varargs_typemap.i b/Examples/test-suite/python_varargs_typemap.i
index d809bf1fa..65ce72f43 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/r/Makefile.in b/Examples/test-suite/r/Makefile.in
index 98835b958..78cc4bb53 100644
--- a/Examples/test-suite/r/Makefile.in
+++ b/Examples/test-suite/r/Makefile.in
@@ -8,6 +8,10 @@ WRAPSUFFIX = .R
R_OPT = --quiet --no-save --no-restore
RUNR = R CMD BATCH $(R_OPT) '--args $(SCRIPTDIR)'
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
@@ -18,7 +22,6 @@ C_TEST_CASES += \
CPP_TEST_CASES += \
r_double_delete \
- r_memory_leak \
r_overload_array \
r_sexp \
r_overload_comma \
diff --git a/Examples/test-suite/r/catches_strings_runme.R b/Examples/test-suite/r/catches_strings_runme.R
new file mode 100644
index 000000000..db6783d91
--- /dev/null
+++ b/Examples/test-suite/r/catches_strings_runme.R
@@ -0,0 +1,24 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("catches_strings", .Platform$dynlib.ext, sep=""))
+source("catches_strings.R")
+cacheMetaData(1)
+
+exception_thrown = FALSE
+tryCatch({
+ StringsThrower_charstring()
+}, error = function(e) {
+ exception_thrown <<- grepl(e$message, "charstring message", fixed=TRUE)
+}
+)
+unittest(exception_thrown, TRUE)
+
+exception_thrown = FALSE
+tryCatch({
+ StringsThrower_stdstring()
+}, error = function(e) {
+ exception_thrown <<- grepl(e$message, "stdstring message", fixed=TRUE)
+}
+)
+unittest(exception_thrown, TRUE)
diff --git a/Examples/test-suite/r/constant_pointers_runme.R b/Examples/test-suite/r/constant_pointers_runme.R
new file mode 100644
index 000000000..d6f1c945d
--- /dev/null
+++ b/Examples/test-suite/r/constant_pointers_runme.R
@@ -0,0 +1,13 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("constant_pointers", .Platform$dynlib.ext, sep=""))
+source("constant_pointers.R")
+cacheMetaData(1)
+
+myb <- B()
+bret = bar(myb)
+bret2 = cbar(myb)
+bret3 = bar(bret2)
+
+q(save="no")
diff --git a/Examples/test-suite/r/r_memory_leak_runme.R b/Examples/test-suite/r/exception_memory_leak_runme.R
index ef6533aef..889fbedc9 100644
--- a/Examples/test-suite/r/r_memory_leak_runme.R
+++ b/Examples/test-suite/r/exception_memory_leak_runme.R
@@ -1,8 +1,8 @@
clargs <- commandArgs(trailing=TRUE)
source(file.path(clargs[1], "unittest.R"))
-dyn.load(paste("r_memory_leak", .Platform$dynlib.ext, sep=""))
-source("r_memory_leak.R")
+dyn.load(paste("exception_memory_leak", .Platform$dynlib.ext, sep=""))
+source("exception_memory_leak.R")
cacheMetaData(1)
a <- Foo();
@@ -13,7 +13,8 @@ unittest(Foo_get_count(), 2);
# Normal behaviour
invisible(trigger_internal_swig_exception("no problem", a));
unittest(Foo_get_count(), 2);
-# SWIG exception introduced
+unittest(Foo_get_freearg_count(), 1);
+# SWIG exception introduced (return new object case).
result <- tryCatch({
trigger_internal_swig_exception("null", b);
}, warning = function(w) {
@@ -24,3 +25,15 @@ result <- tryCatch({
unittest(1,1);
})
unittest(Foo_get_count(), 2);
+unittest(Foo_get_freearg_count(), 2);
+# SWIG exception introduced (return by value case).
+result <- tryCatch({
+ trigger_internal_swig_exception("null");
+}, warning = function(w) {
+ # print(" Hum... We received a warning, but this should be an error");
+ unittest(1,0);
+}, error = function(e) {
+ # print(" Gotcha!");
+ unittest(1,1);
+})
+unittest(Foo_get_count(), 2);
diff --git a/Examples/test-suite/r/namespace_struct_runme.R b/Examples/test-suite/r/namespace_struct_runme.R
new file mode 100644
index 000000000..f84ef3054
--- /dev/null
+++ b/Examples/test-suite/r/namespace_struct_runme.R
@@ -0,0 +1,11 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("namespace_struct", .Platform$dynlib.ext, sep=""))
+source("namespace_struct.R")
+cacheMetaData(1)
+
+xy = Y()
+xy$x = as.integer(2)
+xy$y = as.integer(4)
+copyToR(xy)
diff --git a/Examples/test-suite/r_memory_leak.i b/Examples/test-suite/r_memory_leak.i
deleted file mode 100644
index a240097e3..000000000
--- a/Examples/test-suite/r_memory_leak.i
+++ /dev/null
@@ -1,40 +0,0 @@
-%module r_memory_leak
-
-%include <std_string.i>
-
-%typemap(in) Foo* foo
-{
- $1 = new Foo;
-}
-%typemap(freearg) Foo* foo
-{
- printf(" \" Object deleted\"\n");
- delete $1;
-}
-%typemap(out) Foo* verify_no_memory_leak
-{
- if ($1 == NULL)
- SWIG_exception_fail(SWIG_RuntimeError, "Let's see how the bindings manage this exception!");
-}
-%typemap(scoerceout) Foo*
- %{ if (!is.null($result) && !is.logical($result)) {$result <- new("$R_class", ref=$result) ;}; %}
-
-%inline %{
- #include <string>
-
- class Foo {
- static unsigned count;
- public:
- Foo() { ++count; }
- ~Foo() { --count; }
- static unsigned get_count() { return count; }
- };
-
- unsigned Foo::count = 0;
-
- static Foo* trigger_internal_swig_exception(const std::string& message, Foo* foo)
- {
- return (message == "null") ? NULL : foo;
- };
-
-%}
diff --git a/Examples/test-suite/refcount.h b/Examples/test-suite/refcount.h
index 7d07e7242..f3ebbf2ec 100644
--- a/Examples/test-suite/refcount.h
+++ b/Examples/test-suite/refcount.h
@@ -1,5 +1,5 @@
-#ifndef TEST_SUITE_REFCOUNT_H__
-#define TEST_SUITE_REFCOUNT_H__
+#ifndef TEST_SUITE_REFCOUNT_H
+#define TEST_SUITE_REFCOUNT_H
struct RCObjBase {
/*!
@@ -195,4 +195,4 @@ RCPtr<T>& RCPtr<T>::operator=(const RCPtr& rhs)
-#endif //TEST_SUITE_REFCOUNT_H__
+#endif // TEST_SUITE_REFCOUNT_H
diff --git a/Examples/test-suite/rename_camel.i b/Examples/test-suite/rename_camel.i
index 970bb9215..466f179f7 100644
--- a/Examples/test-suite/rename_camel.i
+++ b/Examples/test-suite/rename_camel.i
@@ -4,65 +4,72 @@
%rename("%(ctitle)s",%$isvariable,%$ismember) "";
%inline {
- struct GeometryFactory
- {
- void createPointFromInternalCoord(int);
- void BIG_METHOD(int);
+ struct GeometryFactory {
+ void createPointFromInternalCoord(int) {}
+ void BIG_METHOD(int) {}
};
class ByteOrderValues {
public:
- void readHEX();
+ void readHEX() {}
static int ENDIAN_BIG;
};
+ int ByteOrderValues::ENDIAN_BIG = 4321;
}
-
-%define SedCmd "%(command:sed -e 's/\([a-z]\)/\U\\1/' -e 's/\(_\)\([a-z]\)/\U\\2/g' <<<)s" %enddef
-
%rename(CamelCase1) camel_case_1;
-%rename(SedCmd) camel_case_2;
+%rename("%(camelcase)s") camel_case_2;
+// ctitle is an alias for camelcase.
%rename("%(ctitle)s") camel_case_3;
+%rename(lowerCamelCase1) Lower_camel_case_1;
+%rename("%(lowercamelcase)s") Lower_camel_case_2;
+// lctitle is an alias for lowercamelcase.
+%rename("%(lctitle)s") Lower_camel_case_3;
-%rename("%(utitle)s") CamelCase_5;
-
-%define awk_cmd "%(command:awk '/^i/{print toupper($1)}' <<<)s" %enddef
+%rename(under_case1) UnderCase1;
+%rename("%(undercase)s") UnderCase2;
+// utitle is an alias for undercase.
+%rename("%(utitle)s") UnderCase3;
-%rename(awk_cmd) "";
+// This should change "import" to "Import", but "hi_there" should be handled by
+// the rule below and become "HI_THERE".
+%rename("%(regex:/(.*i.*)/\\u\\1/)s") "";
-%rename("%(title)s",regexmatch$parentNode$type="enum .*") "";
+%rename("%(upper)s",regexmatch$parentNode$type="enum .*") "";
%inline
{
- int camel_case_1(int);
- int camel_case_2(int);
- int camel_case_3(int);
- int camel_case_4(int);
- int camel_case(int);
- int CamelCase_5(int);
- int also_works_here(int);
+ void CamelCase(int) {}
+ void camel_case_1(int) {}
+ void camel_case_2(int) {}
+ void camel_case_3(int) {}
+
+ void under_case(int) {}
+ void UnderCase1(int) {}
+ void UnderCase2(int) {}
+ void UnderCase3(int) {}
+
+ void lowerCamelCase(int) {}
+ void Lower_camel_case_1(int) {}
+ void Lower_camel_case_2(int) {}
+ void Lower_camel_case_3(int) {}
enum HelloEnum {
hello, hi_there
};
-
enum ChaoEnum {
bye, see_you
};
- int import(int);
- int foo(int);
-
+ void import(int) {}
+ void foo(int) {}
}
%rename("%(lowercase)s",sourcefmt="%(regex:/GSL_(.*)/\\1/)s",%$isfunction) "";
%inline {
void GSL_Hello() {}
}
-
-
-
diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in
index f982eca1f..09ff02842 100644
--- a/Examples/test-suite/ruby/Makefile.in
+++ b/Examples/test-suite/ruby/Makefile.in
@@ -6,6 +6,10 @@ LANGUAGE = ruby
RUBY = @RUBY@
SCRIPTSUFFIX = _runme.rb
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/ruby/argcargvtest_runme.rb b/Examples/test-suite/ruby/argcargvtest_runme.rb
new file mode 100644
index 000000000..8f4cd7d03
--- /dev/null
+++ b/Examples/test-suite/ruby/argcargvtest_runme.rb
@@ -0,0 +1,32 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+require 'argcargvtest'
+
+include Argcargvtest
+
+
+$largs = ["hi", "hola", "hello"]
+if mainc($largs) != 3
+ raise RuntimeError, "bad main typemap"
+end
+
+$targs = ["hi", "hola"]
+if mainv($targs, 1) != "hola"
+ raise RuntimeError, "bad main typemap"
+end
+
+$error = 0
+$ret = 0
+begin
+ mainv("hello", 1)
+ $error = 1
+rescue => e
+ $ret = 1
+end
+
+if $error == 1 or $ret != 1
+ raise RuntimeError, "bad main typemap"
+end
+
+initializeApp($largs)
diff --git a/Examples/test-suite/ruby/catches_strings_runme.rb b/Examples/test-suite/ruby/catches_strings_runme.rb
new file mode 100644
index 000000000..fb7466765
--- /dev/null
+++ b/Examples/test-suite/ruby/catches_strings_runme.rb
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'catches_strings'
+
+exception_thrown = false
+begin
+ Catches_strings::StringsThrower.charstring()
+rescue RuntimeError => e
+ if (!e.to_s.include? "charstring message")
+ raise RuntimeError, "incorrect exception message: #{e.to_s}"
+ end
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "Should have thrown an exception"
+end
+
+exception_thrown = false
+begin
+ Catches_strings::StringsThrower.stdstring()
+rescue RuntimeError => e
+ if (!e.to_s.include? "stdstring message")
+ raise RuntimeError, "incorrect exception message: #{e.to_s}"
+ end
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "Should have thrown an exception"
+end
diff --git a/Examples/test-suite/ruby/cpp11_move_typemaps_runme.rb b/Examples/test-suite/ruby/cpp11_move_typemaps_runme.rb
new file mode 100644
index 000000000..d2c9fe3df
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_move_typemaps_runme.rb
@@ -0,0 +1,36 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'cpp11_move_typemaps'
+
+Cpp11_move_typemaps::Counter.reset_counts()
+mo = Cpp11_move_typemaps::MoveOnly.new(111)
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 0, 0, 0)
+Cpp11_move_typemaps::MoveOnly.take(mo)
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
+mo = nil
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+Cpp11_move_typemaps::Counter.reset_counts()
+mo = Cpp11_move_typemaps::MovableCopyable.new(111)
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 0, 0, 0)
+Cpp11_move_typemaps::MovableCopyable.take(mo)
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
+mo = nil
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+mo = Cpp11_move_typemaps::MoveOnly.new(222)
+Cpp11_move_typemaps::MoveOnly.take(mo)
+exception_thrown = false
+begin
+ Cpp11_move_typemaps::MoveOnly.take(mo)
+rescue RuntimeError => e
+ if (!e.to_s.include? "cannot release ownership as memory is not owned")
+ raise RuntimeError, "incorrect exception message: #{e.to_s}"
+ end
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
+end
diff --git a/Examples/test-suite/ruby/cpp11_rvalue_reference_move_runme.rb b/Examples/test-suite/ruby/cpp11_rvalue_reference_move_runme.rb
new file mode 100644
index 000000000..0a423d6c4
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_rvalue_reference_move_runme.rb
@@ -0,0 +1,106 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'cpp11_rvalue_reference_move'
+
+# Function containing rvalue reference parameter
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+mo = Cpp11_rvalue_reference_move::MovableCopyable.new(222)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 0, 0, 0)
+Cpp11_rvalue_reference_move::MovableCopyable.movein(mo)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 2)
+exception_thrown = false
+begin
+ Cpp11_rvalue_reference_move::MovableCopyable.is_nullptr(mo)
+rescue ObjectPreviouslyDeleted
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "is_nullptr failed to throw"
+end
+mo = nil
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+# Move constructor test
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+mo = Cpp11_rvalue_reference_move::MovableCopyable.new(222)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 0, 0, 0)
+mo_moved = Cpp11_rvalue_reference_move::MovableCopyable.new(mo)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 1)
+exception_thrown = false
+begin
+ Cpp11_rvalue_reference_move::MovableCopyable.is_nullptr(mo)
+rescue ObjectPreviouslyDeleted
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "is_nullptr failed to throw"
+end
+mo = nil
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 1)
+# mo_moved = nil
+# Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 2)
+# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
+Cpp11_rvalue_reference_move::MovableCopyable.movein(mo_moved)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 2, 0, 3)
+
+# Move assignment operator test
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+mo111 = Cpp11_rvalue_reference_move::MovableCopyable.new(111)
+mo222 = Cpp11_rvalue_reference_move::MovableCopyable.new(222)
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 0, 0)
+mo111.MoveAssign(mo222)
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
+exception_thrown = false
+begin
+ Cpp11_rvalue_reference_move::MovableCopyable.is_nullptr(mo222)
+rescue ObjectPreviouslyDeleted
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "is_nullptr failed to throw"
+end
+mo222 = nil
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
+# mo111 = nil
+# Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 2)
+# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
+Cpp11_rvalue_reference_move::MovableCopyable.movein(mo111)
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 1, 1, 3)
+
+# null check
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+exception_thrown = false
+begin
+ Cpp11_rvalue_reference_move::MovableCopyable.movein(nil)
+rescue ArgumentError => e
+ if (!e.to_s.include? "invalid null reference")
+ raise RuntimeError, "incorrect exception message: #{e.to_s}"
+ end
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "Should have thrown null error"
+end
+Cpp11_rvalue_reference_move::Counter.check_counts(0, 0, 0, 0, 0, 0)
+
+# output
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+mc = Cpp11_rvalue_reference_move::MovableCopyable.moveout(1234)
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
+Cpp11_rvalue_reference_move::MovableCopyable.check_numbers_match(mc, 1234)
+
+exception_thrown = false
+begin
+ Cpp11_rvalue_reference_move::MovableCopyable.movein(mc)
+rescue RuntimeError => e
+ if (!e.to_s.include? "cannot release ownership as memory is not owned")
+ raise RuntimeError, "incorrect exception message: #{e.to_s}"
+ end
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
+end
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
diff --git a/Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb b/Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb
new file mode 100644
index 000000000..59e9691be
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb
@@ -0,0 +1,151 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'cpp11_std_unique_ptr'
+
+def gc_check(expected_count)
+# GC.start(full_mark: true, immediate_sweep: true)
+ GC.start
+# GC is not reliably run, skip check
+# swig_assert_equal_simple(expected_count, Cpp11_std_unique_ptr::Klass::getTotal_count())
+end
+
+def checkCount(expected_count)
+ actual_count = Cpp11_std_unique_ptr::Klass.getTotal_count()
+ if (actual_count != expected_count)
+ raise RuntimeError, "Counts incorrect, expected:" + expected_count + " actual:" + actual_count
+ end
+end
+
+# Test raw pointer handling involving virtual inheritance
+kini = Cpp11_std_unique_ptr::KlassInheritance.new("KlassInheritanceInput")
+checkCount(1)
+s = Cpp11_std_unique_ptr.useKlassRawPtr(kini)
+if (s != "KlassInheritanceInput")
+ raise RuntimeError, "Incorrect string: " + s
+end
+# kini = nil
+Cpp11_std_unique_ptr.takeKlassUniquePtr(kini) # Ensure object is deleted (can't rely on GC)
+checkCount(0)
+
+
+# unique_ptr as input
+kin = Cpp11_std_unique_ptr::Klass.new("KlassInput")
+checkCount(1)
+s = Cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+checkCount(0)
+if (s != "KlassInput")
+ raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+ Cpp11_std_unique_ptr.is_nullptr(kin)
+rescue ObjectPreviouslyDeleted
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "is_nullptr failed to throw"
+end
+kin = nil
+checkCount(0)
+
+kin = Cpp11_std_unique_ptr::Klass.new("KlassInput")
+checkCount(1)
+s = Cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+checkCount(0)
+if (s != "KlassInput")
+ raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+ Cpp11_std_unique_ptr.is_nullptr(kin)
+rescue ObjectPreviouslyDeleted
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "is_nullptr failed to throw"
+end
+exception_thrown = false
+begin
+ Cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+rescue RuntimeError => e
+ # puts e.message
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "double usage of takeKlassUniquePtr should have been an error"
+end
+kin = nil
+checkCount(0)
+
+kin = Cpp11_std_unique_ptr::Klass.new("KlassInput")
+exception_thrown = false
+notowned = Cpp11_std_unique_ptr::get_not_owned_ptr(kin)
+begin
+ Cpp11_std_unique_ptr::takeKlassUniquePtr(notowned)
+rescue RuntimeError => e
+ if (!e.to_s.include? "cannot release ownership as memory is not owned")
+ raise RuntimeError, "incorrect exception message"
+ end
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
+end
+checkCount(1)
+Cpp11_std_unique_ptr.takeKlassUniquePtr(kin) # Ensure object is deleted (can't rely on GC)
+checkCount(0)
+
+kini = Cpp11_std_unique_ptr::KlassInheritance.new("KlassInheritanceInput")
+checkCount(1)
+s = Cpp11_std_unique_ptr.takeKlassUniquePtr(kini)
+checkCount(0)
+if (s != "KlassInheritanceInput")
+ raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+ Cpp11_std_unique_ptr.is_nullptr(kini)
+rescue ObjectPreviouslyDeleted
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "is_nullptr failed to throw"
+end
+kini = nil
+checkCount(0)
+
+Cpp11_std_unique_ptr::takeKlassUniquePtr(nil)
+Cpp11_std_unique_ptr::takeKlassUniquePtr(Cpp11_std_unique_ptr::make_null())
+checkCount(0)
+
+# overloaded parameters
+if (Cpp11_std_unique_ptr::overloadTest() != 0)
+ raise RuntimeError, "overloadTest failed"
+end
+if (Cpp11_std_unique_ptr::overloadTest(nil) != 1)
+ raise RuntimeError, "overloadTest failed"
+end
+if (Cpp11_std_unique_ptr::overloadTest(Cpp11_std_unique_ptr::Klass.new("over")) != 1)
+ raise RuntimeError, "overloadTest failed"
+end
+checkCount(0);
+
+
+# unique_ptr as output
+k1 = Cpp11_std_unique_ptr::makeKlassUniquePtr("first")
+k2 = Cpp11_std_unique_ptr::makeKlassUniquePtr("second")
+swig_assert_equal_simple(2, Cpp11_std_unique_ptr::Klass::getTotal_count())
+
+gc_check(2)
+k1 = nil
+gc_check(1)
+
+swig_assert_equal_simple(k2.getLabel(), "second")
+gc_check(1)
+
+k2 = nil
+gc_check(0)
+
+swig_assert_equal_simple(Cpp11_std_unique_ptr::makeNullUniquePtr(), nil)
diff --git a/Examples/test-suite/ruby/director_unwrap_result_runme.rb b/Examples/test-suite/ruby/director_unwrap_result_runme.rb
new file mode 100644
index 000000000..26206ae5c
--- /dev/null
+++ b/Examples/test-suite/ruby/director_unwrap_result_runme.rb
@@ -0,0 +1,120 @@
+#!/usr/bin/env ruby
+#
+# This test checks the proper unwrapping of director objects before returning
+# a pointer to the (wrapped) instance.
+# Unwrapping must not happen for return-by-value and returning higher
+# reference levels (pointer to pointer, reference to pointer, etc.), but this
+# is already checked by the C++ compiler.
+#
+
+require 'swig_assert'
+
+require 'director_unwrap_result'
+
+############################
+# test with a regular (non-template) class
+
+class MyElement < Director_unwrap_result::Element
+end
+
+class MyStorage < Director_unwrap_result::Storage
+ def initialize(e)
+ super()
+ @elem = e
+ end
+ def getIt
+ @elem.getPtrPtr
+ end
+end
+
+e = MyElement.new
+s = MyStorage.new(e)
+
+swig_assert_equal('s.getElement.class', 'Director_unwrap_result::Element', binding)
+swig_assert('s.getElement != e', binding)
+
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getElementPtr.class', 'MyElement', binding)
+swig_assert_equal('s.getElementPtr', 'e', binding)
+
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getElementRef.class', 'MyElement', binding)
+swig_assert_equal('s.getElementRef', 'e', binding)
+
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getElementPtrTypedef.class', 'MyElement', binding)
+swig_assert_equal('s.getElementPtrTypedef', 'e', binding)
+
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getElementRefTypedef.class', 'MyElement', binding)
+swig_assert_equal('s.getElementRefTypedef', 'e', binding)
+
+# this is not unwrapped:
+swig_assert_equal('s.getElementPtrPtr.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getElementPtrPtr.class', 'SWIG::TYPE_p_p_Element', binding)
+
+# this is not unwrapped:
+swig_assert_equal('s.getElementPtrRef.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getElementPtrRef.class', 'SWIG::TYPE_p_p_Element', binding)
+
+# this is not unwrapped:
+swig_assert_equal('s.getElementPtrRefTypedef.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getElementPtrRefTypedef.class', 'SWIG::TYPE_p_p_Element', binding)
+
+############################
+# test with a template class
+
+class MyElementStorage < Director_unwrap_result::ElementStorage
+ def initialize(e)
+ super()
+ @elem = e
+ end
+ def getIt
+ @elem
+ end
+end
+
+class MyElementPtrStorage < Director_unwrap_result::ElementPtrStorage
+ def initialize(e)
+ super()
+ @elem = e
+ end
+ def getIt
+ @elem.getPtrPtr
+ end
+end
+
+class MyElementPtrPtrStorage < Director_unwrap_result::ElementPtrPtrStorage
+ def initialize(e)
+ super()
+ @elem = e
+ end
+ def getIt
+ @elem.getPtrPtrPtr
+ end
+end
+
+e = MyElement.new
+
+s = MyElementStorage.new(e)
+swig_assert_equal('s.getVal.class', 'Director_unwrap_result::Element', binding)
+swig_assert('s.getVal != e', binding)
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getPtr.class', 'MyElement', binding)
+swig_assert_equal('s.getPtr', 'e', binding)
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getRef.class', 'MyElement', binding)
+swig_assert_equal('s.getRef', 'e', binding)
+
+s = MyElementPtrStorage.new(e)
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getVal.class', 'MyElement', binding)
+swig_assert_equal('s.getVal', 'e', binding)
+swig_assert_equal('s.getPtr.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getRef.class', 'SWIG::TYPE_p_p_Element', binding)
+
+s = MyElementPtrPtrStorage.new(e)
+swig_assert_equal('s.getVal.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getPtr.class', 'SWIG::TYPE_p_p_p_Element', binding)
+swig_assert_equal('s.getRef.class', 'SWIG::TYPE_p_p_p_Element', binding)
+
diff --git a/Examples/test-suite/ruby/ignore_parameter_runme.rb b/Examples/test-suite/ruby/ignore_parameter_runme.rb
index c5466a2a6..1d1e0bac0 100644
--- a/Examples/test-suite/ruby/ignore_parameter_runme.rb
+++ b/Examples/test-suite/ruby/ignore_parameter_runme.rb
@@ -25,6 +25,7 @@ raise RuntimeError unless sc.daimler(0, 1.0) == "hello"
raise RuntimeError unless sc.astonmartin("foo", 1.0) == 101
raise RuntimeError unless sc.bugatti("foo", 0) == 8.8
raise RuntimeError unless sc.lamborghini() == 101
+raise RuntimeError unless sc.audi() == 8.8
# Constructor tests
MiniCooper.new(0, 1.0)
diff --git a/Examples/test-suite/ruby/li_std_auto_ptr_runme.rb b/Examples/test-suite/ruby/li_std_auto_ptr_runme.rb
index cec48a58c..48276a888 100644
--- a/Examples/test-suite/ruby/li_std_auto_ptr_runme.rb
+++ b/Examples/test-suite/ruby/li_std_auto_ptr_runme.rb
@@ -11,6 +11,129 @@ def gc_check(expected_count)
# swig_assert_equal_simple(expected_count, Li_std_auto_ptr::Klass::getTotal_count())
end
+def checkCount(expected_count)
+ actual_count = Li_std_auto_ptr::Klass.getTotal_count()
+ if (actual_count != expected_count)
+ raise RuntimeError, "Counts incorrect, expected:" + expected_count + " actual:" + actual_count
+ end
+end
+
+# Test raw pointer handling involving virtual inheritance
+kini = Li_std_auto_ptr::KlassInheritance.new("KlassInheritanceInput")
+checkCount(1)
+s = Li_std_auto_ptr.useKlassRawPtr(kini)
+if (s != "KlassInheritanceInput")
+ raise RuntimeError, "Incorrect string: " + s
+end
+# kini = nil
+Li_std_auto_ptr.takeKlassAutoPtr(kini) # Ensure object is deleted (can't rely on GC)
+checkCount(0)
+
+
+# auto_ptr as input
+kin = Li_std_auto_ptr::Klass.new("KlassInput")
+checkCount(1)
+s = Li_std_auto_ptr.takeKlassAutoPtr(kin)
+checkCount(0)
+if (s != "KlassInput")
+ raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+ Li_std_auto_ptr.is_nullptr(kin)
+rescue ObjectPreviouslyDeleted
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "is_nullptr failed to throw"
+end
+kin = nil
+checkCount(0)
+
+kin = Li_std_auto_ptr::Klass.new("KlassInput")
+checkCount(1)
+s = Li_std_auto_ptr.takeKlassAutoPtr(kin)
+checkCount(0)
+if (s != "KlassInput")
+ raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+ Li_std_auto_ptr.is_nullptr(kin)
+rescue ObjectPreviouslyDeleted
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "is_nullptr failed to throw"
+end
+exception_thrown = false
+begin
+ Li_std_auto_ptr.takeKlassAutoPtr(kin)
+rescue RuntimeError => e
+ # puts e.message
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "double usage of takeKlassAutoPtr should have been an error"
+end
+kin = nil
+checkCount(0)
+
+kin = Li_std_auto_ptr::Klass.new("KlassInput")
+exception_thrown = false
+notowned = Li_std_auto_ptr::get_not_owned_ptr(kin)
+begin
+ Li_std_auto_ptr::takeKlassAutoPtr(notowned)
+rescue RuntimeError
+ if (!e.to_s.include? "cannot release ownership as memory is not owned")
+ raise RuntimeError, "incorrect exception message"
+ end
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
+end
+checkCount(1)
+Li_std_auto_ptr.takeKlassAutoPtr(kin) # Ensure object is deleted (can't rely on GC)
+checkCount(0)
+
+kini = Li_std_auto_ptr::KlassInheritance.new("KlassInheritanceInput")
+checkCount(1)
+s = Li_std_auto_ptr.takeKlassAutoPtr(kini)
+checkCount(0)
+if (s != "KlassInheritanceInput")
+ raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+ Li_std_auto_ptr.is_nullptr(kini)
+rescue ObjectPreviouslyDeleted
+ exception_thrown = true
+end
+if (!exception_thrown)
+ raise RuntimeError, "is_nullptr failed to throw"
+end
+kini = nil
+checkCount(0)
+
+Li_std_auto_ptr::takeKlassAutoPtr(nil)
+Li_std_auto_ptr::takeKlassAutoPtr(Li_std_auto_ptr::make_null())
+checkCount(0)
+
+# overloaded parameters
+if (Li_std_auto_ptr::overloadTest() != 0)
+ raise RuntimeError, "overloadTest failed"
+end
+if (Li_std_auto_ptr::overloadTest(nil) != 1)
+ raise RuntimeError, "overloadTest failed"
+end
+if (Li_std_auto_ptr::overloadTest(Li_std_auto_ptr::Klass.new("over")) != 1)
+ raise RuntimeError, "overloadTest failed"
+end
+checkCount(0);
+
+
+# auto_ptr as output
k1 = Li_std_auto_ptr::makeKlassAutoPtr("first")
k2 = Li_std_auto_ptr::makeKlassAutoPtr("second")
swig_assert_equal_simple(2, Li_std_auto_ptr::Klass::getTotal_count())
@@ -25,3 +148,4 @@ gc_check(1)
k2 = nil
gc_check(0)
+swig_assert_equal_simple(Li_std_auto_ptr::makeNullAutoPtr(), nil)
diff --git a/Examples/test-suite/ruby/li_std_set_runme.rb b/Examples/test-suite/ruby/li_std_set_runme.rb
index efc163bee..455a1706e 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 @@ m.value == 'c'
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/Examples/test-suite/ruby/ruby_naming_bugs_runme.rb b/Examples/test-suite/ruby/ruby_naming_bugs_runme.rb
new file mode 100644
index 000000000..49311352d
--- /dev/null
+++ b/Examples/test-suite/ruby/ruby_naming_bugs_runme.rb
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+#
+# Regression tests for Ruby naming bugs
+#
+
+require 'swig_assert'
+
+require 'ruby_naming_bugs'
+
+# Prior to SWIG 4.1.0 the "Cool_" here was overzealously removed
+# while trying to remove a class name prefix, so this method would be
+# named "somethingFast" in Ruby instead.
+c = Ruby_naming_bugs::Cool.new()
+if c.somethingCool_Fast != 42
+ raise RuntimeError, "Incorrect value for somethingCool_Fast"
+end
diff --git a/Examples/test-suite/ruby_manual_proxy.i b/Examples/test-suite/ruby_manual_proxy.i
index 2cb154e6a..7cfbfb1b3 100644
--- a/Examples/test-suite/ruby_manual_proxy.i
+++ b/Examples/test-suite/ruby_manual_proxy.i
@@ -1,7 +1,7 @@
%module ruby_manual_proxy
-%typemap(in, numinputs=0) SWIGTYPE ** ($*1_ltype temp) "$1 = &temp;";
+%typemap(in, numinputs=0) SWIGTYPE ** ($*1_ltype temp) "$1 = &temp;"
%typemap(argout) SWIGTYPE **OUTPARAM {
$result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
diff --git a/Examples/test-suite/ruby_naming_bugs.i b/Examples/test-suite/ruby_naming_bugs.i
new file mode 100644
index 000000000..6449addf1
--- /dev/null
+++ b/Examples/test-suite/ruby_naming_bugs.i
@@ -0,0 +1,9 @@
+%module ruby_naming_bugs
+
+%inline %{
+ // Prior to SWIG 4.1.0 the "Cool_" here was overzealously removed while
+ // trying to remove a class name prefix.
+ struct Cool {
+ int somethingCool_Fast() { return 42; }
+ };
+%}
diff --git a/Examples/test-suite/schemerunme/catches_strings.scm b/Examples/test-suite/schemerunme/catches_strings.scm
new file mode 100644
index 000000000..8a83db07c
--- /dev/null
+++ b/Examples/test-suite/schemerunme/catches_strings.scm
@@ -0,0 +1,9 @@
+(expect-throw 'swig-exception
+ (StringsThrower-charstring))
+; TODO: check the exception message
+
+(expect-throw 'swig-exception
+ (StringsThrower-stdstring))
+; TODO: check the exception message
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/cpp11_move_typemaps.scm b/Examples/test-suite/schemerunme/cpp11_move_typemaps.scm
new file mode 100644
index 000000000..0a8b85a58
--- /dev/null
+++ b/Examples/test-suite/schemerunme/cpp11_move_typemaps.scm
@@ -0,0 +1,23 @@
+(Counter-reset-counts)
+(define mo (new-MoveOnly 111))
+(Counter-check-counts 1 0 0 0 0 0)
+(MoveOnly-take mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(delete-MoveOnly mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 111))
+(Counter-check-counts 1 0 0 0 0 0)
+(MovableCopyable-take mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+(define mo (new-MoveOnly 222))
+(MoveOnly-take mo)
+(expect-throw 'misc-error
+ (MoveOnly-take mo))
+; TODO: check the exception message
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/cpp11_rvalue_reference_move.scm b/Examples/test-suite/schemerunme/cpp11_rvalue_reference_move.scm
new file mode 100644
index 000000000..1cbb6115b
--- /dev/null
+++ b/Examples/test-suite/schemerunme/cpp11_rvalue_reference_move.scm
@@ -0,0 +1,57 @@
+; Function containing rvalue reference parameter
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 222))
+(Counter-check-counts 1 0 0 0 0 0)
+(MovableCopyable-movein mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(unless (MovableCopyable-is-nullptr mo)
+ (error "is_nullptr failed"))
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+; Move constructor test
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 222))
+(Counter-check-counts 1 0 0 0 0 0)
+(define mo_moved (new-MovableCopyable mo))
+(Counter-check-counts 1 0 0 1 0 1)
+(unless (MovableCopyable-is-nullptr mo)
+ (error "is_nullptr failed"))
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 1)
+(delete-MovableCopyable mo_moved)
+(Counter-check-counts 1 0 0 1 0 2)
+
+; Move assignment operator test
+(Counter-reset-counts)
+(define mo111 (new-MovableCopyable 111))
+(define mo222 (new-MovableCopyable 222))
+(Counter-check-counts 2 0 0 0 0 0)
+(MovableCopyable-MoveAssign mo111 mo222)
+(Counter-check-counts 2 0 0 0 1 1)
+(unless (MovableCopyable-is-nullptr mo222)
+ (error "is_nullptr failed"))
+(delete-MovableCopyable mo222)
+(Counter-check-counts 2 0 0 0 1 1)
+(delete-MovableCopyable mo111)
+(Counter-check-counts 2 0 0 0 1 2)
+
+; null check
+(Counter-reset-counts)
+(expect-throw 'misc-error
+ (MovableCopyable-movein '()))
+; TODO: check the exception message
+(Counter-check-counts 0 0 0 0 0 0)
+
+; output
+(Counter-reset-counts)
+(define mc (MovableCopyable-moveout 1234))
+(Counter-check-counts 2 0 0 0 1 1)
+(MovableCopyable-check-numbers-match mc 1234)
+
+(expect-throw 'misc-error
+ (MovableCopyable-movein mc))
+; TODO: check the exception message
+(Counter-check-counts 2 0 0 0 1 1)
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/cpp11_std_unique_ptr.scm b/Examples/test-suite/schemerunme/cpp11_std_unique_ptr.scm
new file mode 100644
index 000000000..5e6d0dfcc
--- /dev/null
+++ b/Examples/test-suite/schemerunme/cpp11_std_unique_ptr.scm
@@ -0,0 +1,95 @@
+(define checkCount
+ (lambda (expected-count)
+ (define actual-count (Klass-getTotal-count))
+ (unless (= actual-count expected-count) (error (format "Counts incorrect, expected:~a actual:~a" expected-count actual-count)))))
+
+; Test raw pointer handling involving virtual inheritance
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (useKlassRawPtr kini))
+(unless (string=? s "KlassInheritanceInput")
+ (error "Incorrect string: " s))
+(set! kini '()) (gc)
+(checkCount 0)
+
+; unique_ptr as input
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+ (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+ (error "is_nullptr failed"))
+(expect-throw 'misc-error
+ (takeKlassUniquePtr kin))
+; TODO: check the exception message
+(set! kin '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(define notowned (get-not-owned-ptr kin))
+(expect-throw 'misc-error
+ (takeKlassUniquePtr notowned))
+; TODO: check the exception message
+(checkCount 1)
+(set! kin '()) (gc)
+(checkCount 0)
+
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kini))
+(checkCount 0)
+(unless (string=? s "KlassInheritanceInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kini)
+ (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define null '())
+(takeKlassUniquePtr null)
+(define nullnil #nil)
+(takeKlassUniquePtr nullnil)
+(takeKlassUniquePtr (make-null))
+(checkCount 0)
+
+; overloaded parameters
+(unless (= (overloadTest) 0)
+ (error "overloadTest failed"))
+(unless (= (overloadTest nullnil) 1)
+ (error "overloadTest failed"))
+(unless (= (overloadTest (new-Klass "over")) 1)
+ (error "overloadTest failed"))
+(checkCount 0)
+
+
+; unique_ptr as output
+(define k1 (makeKlassUniquePtr "first"))
+(define k2 (makeKlassUniquePtr "second"))
+(checkCount 2)
+
+(set! k1 '()) (gc)
+(checkCount 1)
+
+(unless (string=? (Klass-getLabel k2) "second")
+ (error "wrong object label" ))
+
+(set! k2 '()) (gc)
+(checkCount 0)
+
+(unless (null? (makeNullUniquePtr))
+ (error "null failure"))
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/li_std_auto_ptr.scm b/Examples/test-suite/schemerunme/li_std_auto_ptr.scm
new file mode 100644
index 000000000..3ccd83fdb
--- /dev/null
+++ b/Examples/test-suite/schemerunme/li_std_auto_ptr.scm
@@ -0,0 +1,95 @@
+(define checkCount
+ (lambda (expected-count)
+ (define actual-count (Klass-getTotal-count))
+ (unless (= actual-count expected-count) (error (format "Counts incorrect, expected:~a actual:~a" expected-count actual-count)))))
+
+; Test raw pointer handling involving virtual inheritance
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (useKlassRawPtr kini))
+(unless (string=? s "KlassInheritanceInput")
+ (error "Incorrect string: " s))
+(set! kini '()) (gc)
+(checkCount 0)
+
+; auto_ptr as input
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+ (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+ (error "is_nullptr failed"))
+(expect-throw 'misc-error
+ (takeKlassAutoPtr kin))
+; TODO: check the exception message
+(set! kin '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(define notowned (get-not-owned-ptr kin))
+(expect-throw 'misc-error
+ (takeKlassAutoPtr notowned))
+; TODO: check the exception message
+(checkCount 1)
+(set! kin '()) (gc)
+(checkCount 0)
+
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kini))
+(checkCount 0)
+(unless (string=? s "KlassInheritanceInput")
+ (error "Incorrect string: " s))
+(unless (is-nullptr kini)
+ (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define null '())
+(takeKlassAutoPtr null)
+(define nullnil #nil)
+(takeKlassAutoPtr nullnil)
+(takeKlassAutoPtr (make-null))
+(checkCount 0)
+
+; overloaded parameters
+(unless (= (overloadTest) 0)
+ (error "overloadTest failed"))
+(unless (= (overloadTest nullnil) 1)
+ (error "overloadTest failed"))
+(unless (= (overloadTest (new-Klass "over")) 1)
+ (error "overloadTest failed"))
+(checkCount 0)
+
+
+; auto_ptr as output
+(define k1 (makeKlassAutoPtr "first"))
+(define k2 (makeKlassAutoPtr "second"))
+(checkCount 2)
+
+(set! k1 '()) (gc)
+(checkCount 1)
+
+(unless (string=? (Klass-getLabel k2) "second")
+ (error "wrong object label" ))
+
+(set! k2 '()) (gc)
+(checkCount 0)
+
+(unless (null? (makeNullAutoPtr))
+ (error "null failure"))
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/newobject1.scm b/Examples/test-suite/schemerunme/newobject1.scm
new file mode 100644
index 000000000..9d9d43a18
--- /dev/null
+++ b/Examples/test-suite/schemerunme/newobject1.scm
@@ -0,0 +1,18 @@
+(define-macro (check test)
+ `(unless ,test (error "Error in test" ',test)))
+
+(define foo1 (Foo-makeFoo))
+(check (= (Foo-fooCount) 1))
+
+(define foo2 (Foo-makeMore foo1))
+(check (= (Foo-fooCount) 2))
+
+(set! foo1 '())
+(gc)
+(check (= (Foo-fooCount) 1))
+
+(set! foo2 '())
+(gc)
+(check (= (Foo-fooCount) 0))
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/null_pointer.scm b/Examples/test-suite/schemerunme/null_pointer.scm
new file mode 100644
index 000000000..5b249ff50
--- /dev/null
+++ b/Examples/test-suite/schemerunme/null_pointer.scm
@@ -0,0 +1,8 @@
+(define null '())
+(unless (funk null)
+ (error "funk(null) does not return true"))
+
+(unless (null? (getnull))
+ (error "NULL pointer should be null"))
+
+(exit 0)
diff --git a/Examples/test-suite/scilab/Makefile.in b/Examples/test-suite/scilab/Makefile.in
index f873b8687..cf36794e3 100644
--- a/Examples/test-suite/scilab/Makefile.in
+++ b/Examples/test-suite/scilab/Makefile.in
@@ -7,6 +7,10 @@ SCILAB = @SCILAB@
SCILAB_OPT = @SCILABOPT@
SCRIPTSUFFIX = _runme.sci
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@
diff --git a/Examples/test-suite/scilab/allprotected_runme.sci b/Examples/test-suite/scilab/allprotected_runme.sci
index 7bc74fac0..b76bd7c89 100644
--- a/Examples/test-suite/scilab/allprotected_runme.sci
+++ b/Examples/test-suite/scilab/allprotected_runme.sci
@@ -21,10 +21,10 @@ checkequal(PubBase_virtualMethod(pubBase), "PublicBase", "PubBase_virtualMethod(
class = PubBase_instanceMethod(pubBase, klass);
checkequal(Klass_getName(class), "allprotected_klass", "Klass_getName(PubBase_instanceMethod(pubBase, klass))");
-class = PubBase_instanceOverload(pubBase, klass);
+class = PubBase_instanceOverloaded(pubBase, klass);
checkequal(Klass_getName(class), "allprotected_klass", "Klass_getName(PubBase_instanceOverloaded(pubBase, klass))");
-class = PubBase_instanceOverload(pubBase, klass, "allprotected_klass2");
+class = PubBase_instanceOverloaded(pubBase, klass, "allprotected_klass2");
checkequal(Klass_getName(class), "allprotected_klass2", "Klass_getName(PubBase_instanceOverloaded(pubBase, klass, ""allprotected_klass2""))");
class = PubBase_staticMethod(klass);
@@ -40,12 +40,22 @@ checkequal(Klass_getName(class), "allprotected_klass3", "Klass_getName(PubBase_s
checkequal(PubBase_EnumVal1_get(), 0, "PubBase_EnumVal1_get()");
checkequal(PubBase_EnumVal2_get(), 1, "(PubBase_EnumVal2_get()");
+v=getversion("scilab");
+if v(1) < 6 then
+ PubBase_instanceMemb_set(pubBase, 12);
+ checkequal(PubBase_instanceMemb_get(pubBase), 12, "PubBase_instanceMemb_get(pubBase)");
+else
+ PubBase_instanceMemberVariable_set(pubBase, 12);
+ checkequal(PubBase_instanceMemberVariable_get(pubBase), 12, "PubBase_instanceMemberVariable_get(pubBase)");
+end
-PubBase_instanceMemb_set(pubBase, 12);
-checkequal(PubBase_instanceMemb_get(pubBase), 12, "PubBase_instanceMemb_get(pubBase)");
-
-checkequal(PubBase_staticConstM_get(), 20, "PubBase_staticConstM_get()");
-checkequal(PubBase_staticMember_get(), 10, "PubBase_staticMember_get()")
+if v(1) < 6 then
+ checkequal(PubBase_staticConstM_get(), 20, "PubBase_staticConstMemberVariable_get()");
+ checkequal(PubBase_staticMember_get(), 10, "PubBase_staticMemberVariable_get()")
+else
+ checkequal(PubBase_staticConstMemberVariable_get(), 20, "PubBase_staticConstMemberVariable_get()");
+ checkequal(PubBase_staticMemberVariable_get(), 10, "PubBase_staticMemberVariable_get()")
+end
PubBase_stringMember_set(pubBase, "dummy");
checkequal(PubBase_stringMember_get(pubBase), "dummy", "PubBase_stringMember_get()");
diff --git a/Examples/test-suite/scilab/catches_strings_runme.sci b/Examples/test-suite/scilab/catches_strings_runme.sci
new file mode 100644
index 000000000..f9226c728
--- /dev/null
+++ b/Examples/test-suite/scilab/catches_strings_runme.sci
@@ -0,0 +1,17 @@
+exec("swigtest.start", -1);
+
+ierr = execstr("StringsThrower_charstring()", 'errcatch');
+checkequal(ierr, 20000, "wrong/no exception thrown")
+if (strstr(lasterror(), "charstring message") == '')
+ printf("Should have thrown an exception")
+ exit(1)
+end
+
+ierr = execstr("StringsThrower_stdstring()", 'errcatch');
+checkequal(ierr, 20000, "wrong/no exception thrown")
+if (strstr(lasterror(), "stdstring message") == '')
+ printf("Should have thrown an exception")
+ exit(1)
+end
+
+exec("swigtest.quit", -1);
diff --git a/Examples/test-suite/scilab/li_std_except_runme.sci b/Examples/test-suite/scilab/li_std_except_runme.sci
index 3b6522f45..272f03261 100644
--- a/Examples/test-suite/scilab/li_std_except_runme.sci
+++ b/Examples/test-suite/scilab/li_std_except_runme.sci
@@ -14,7 +14,7 @@ checkException('Test_throw_domain_error(t)', 20009, 'ValueError: oops');
checkException('Test_throw_exception(t)', 20010, 'SystemError: std::exception');
-checkException('Test_throw_invalid_argum(t)', 20009, 'ValueError: oops');
+checkException('Test_throw_invalid_argument(t)', 20009, 'ValueError: oops');
checkException('Test_throw_length_error(t)', 20004, 'IndexError: oops');
@@ -22,7 +22,7 @@ checkException('Test_throw_logic_error(t)', 20003, 'RuntimeError: oops');
checkException('Test_throw_out_of_range(t)', 20004, 'IndexError: oops');
-checkException('Test_throw_overflow_erro(t)', 20007, 'OverflowError: oops');
+checkException('Test_throw_overflow_error(t)', 20007, 'OverflowError: oops');
checkException('Test_throw_range_error(t)', 20007, 'OverflowError: oops');
diff --git a/Examples/test-suite/scilab/li_std_string_extra_runme.sci b/Examples/test-suite/scilab/li_std_string_extra_runme.sci
index b96b07e84..c4f254425 100644
--- a/Examples/test-suite/scilab/li_std_string_extra_runme.sci
+++ b/Examples/test-suite/scilab/li_std_string_extra_runme.sci
@@ -42,8 +42,12 @@ checkequal(Structure_StaticStr2_get(), "static member string 2", "Structure_Stat
Structure_StaticStr2_set(s);
checkequal(Structure_StaticStr2_get(), s, "Structure_StaticStr2_get()");
-checkequal(Structure_ConstStati_get(), "const static member string", "Structure_ConstStaticStr_get()");
-
+v = getversion("scilab");
+if v(1) < 6 then
+ checkequal(Structure_ConstStati_get(), "const static member string", "Structure_ConstStati_get()");
+else
+ checkequal(Structure_ConstStaticStr_get(), "const static member string", "Structure_ConstStaticStr_get()");
+end
checkequal(stdstring_empty(), "", "stdstring_empty()");
checkequal(c_empty(), "", "c_empty()");
diff --git a/Examples/test-suite/scilab/scilab_identifier_name_runme.sci b/Examples/test-suite/scilab/scilab_identifier_name_runme.sci
index 9a4f3cc08..1665ec91a 100644
--- a/Examples/test-suite/scilab/scilab_identifier_name_runme.sci
+++ b/Examples/test-suite/scilab/scilab_identifier_name_runme.sci
@@ -1,29 +1,46 @@
exec("swigtest.start", -1);
+v = getversion("scilab");
-// Test truncating variables, constants, functions identifier names
+// Test truncating variables, constants, functions identifier names in Scilab 5
// not truncated
gvar_identifier_name_set(-101);
checkequal(gvar_identifier_name_get(), -101, "gvar_identifier_name_get()");
checkequal(CONS_IDENTIFIER_NAME_get(), -11, "CONS_IDENTIFIER_NAME_get()");
checkequal(function_identifier_name(), -21, "function_identifier_name()");
-// truncated
+// truncated in Scilab 5
+if v(1) < 6 then
too_long_gvar_identi_set(101);
checkequal(too_long_gvar_identi_get(), 101, "too_long_variable_id_get()");
-checkequal(TOO_LONG_CONST_IDENT_get(), 11, "TOO_LONG_CONST_IDENT_get()");
-checkequal(too_long_function_identi(), 21, "too_long_function_identi()");
+checkequal(TOO_LONG_CONST_IDENT_get(), 11, "TOO_LONG_CONST_IDENTIFIER_NAME_1_get");
+checkequal(too_long_function_identi(), 21, "too_long_function_identifier_name_1()");
+else
+too_long_gvar_identifier_name_1_set(101);
+checkequal(too_long_gvar_identifier_name_1_get(), 101, "too_long_variable_id_get()");
+checkequal(TOO_LONG_CONST_IDENTIFIER_NAME_1_get(), 11, "TOO_LONG_CONST_IDENTIFIER_NAME_1_get");
+checkequal(too_long_function_identifier_name_1(), 21, "too_long_function_identifier_name_1()");
+end
// Test truncating when %scilabconst mode is activated
-checkequal(SC_CONST_IDENTIFIER_NAME, int32(-12), "SC_TOO_LONG_IDENTIF");
-checkequal(SC_TOO_LONG_CONST_IDENTI, int32(14), "SC_TOO_LONG_IDENTIF");
+checkequal(SC_CONST_IDENTIFIER_NAME, int32(-12), "SC_CONST_IDENTIFIER_NAME");
+if v(1) < 6 then
+checkequal(SC_TOO_LONG_CONST_IDENTI, int32(14), "SC_TOO_LONG_CONST_IDENTIFIER_NAME_2");
+else
+checkequal(SC_TOO_LONG_CONST_IDENTIFIER_NAME_2, int32(14), "SC_TOO_LONG_CONST_IDENTIFIER_NAME_2");
+end
// Test truncating in the case of struct
st = new_st();
st_m_identifier_name_set(st, 15);
checkequal(st_m_identifier_name_get(st), 15, "st_m_identifier_name_get(st)");
+if v(1) < 6 then
st_too_long_member_i_set(st, 25);
-checkequal(st_too_long_member_i_get(st), 25, "st_too_long_member_i_get(st)");
+checkequal(st_too_long_member_i_get(st), 25, "st_too_long_member_identifier_name_get(st)");
+else
+st_too_long_member_identifier_name_set(st, 25);
+checkequal(st_too_long_member_identifier_name_get(st), 25, "st_too_long_member_identifier_name_get(st)");
+end
delete_st(st);
exec("swigtest.quit", -1);
diff --git a/Examples/test-suite/scilab/swigtest.start b/Examples/test-suite/scilab/swigtest.start
index e4347bd90..161337115 100644
--- a/Examples/test-suite/scilab/swigtest.start
+++ b/Examples/test-suite/scilab/swigtest.start
@@ -2,6 +2,8 @@ lines(0);
warning('off');
ilib_verbose(0);
+ver = getversion('scilab');
+
// Get test name (used in swigtest.quit file)
[units, typ, names] = file(1);
swigtestname = strsubst(fileparts(names, "fname"), "_runme", "");
@@ -23,7 +25,12 @@ end
// Module initialization
try
- moduleInit = sprintf("%s_Init()", swigtestname);
+ if ver(1) < 6 then
+ entry = stripblanks(part(swigtestname, 1:24-5));
+ else
+ entry = swigtestname;
+ end
+ moduleInit = sprintf("%s_Init()", entry);
execstr(moduleInit);
catch
mfprintf(0, "*** MODULE INIT FAILED ***\n");
diff --git a/Examples/test-suite/smart_pointer_const_overload.i b/Examples/test-suite/smart_pointer_const_overload.i
index 75a137b73..526bcc9bd 100644
--- a/Examples/test-suite/smart_pointer_const_overload.i
+++ b/Examples/test-suite/smart_pointer_const_overload.i
@@ -3,6 +3,10 @@
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED) Bar::operator->; // Overloaded method Bar::operator ->() ignored
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED) Bar2::operator->; // Overloaded method Bar2::operator ->() ignored
+%{
+#include <stdlib.h>
+%}
+
%inline %{
int CONST_ACCESS = 1;
int MUTABLE_ACCESS = 2;
diff --git a/Examples/test-suite/special_variable_macros.i b/Examples/test-suite/special_variable_macros.i
index ca2edaa98..d1878e71b 100644
--- a/Examples/test-suite/special_variable_macros.i
+++ b/Examples/test-suite/special_variable_macros.i
@@ -9,6 +9,8 @@
#if defined(_MSC_VER)
#pragma warning(disable: 4996) // 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup. See online help for details.
#endif
+#include <stdlib.h>
+#include <string.h>
%}
%ignore Name::operator=;
@@ -37,10 +39,13 @@ struct NameWrap {
private:
Name name;
};
+
+// Global variable for testing whether examplekw was touched
+int accessed_examplekw = 0;
%}
// check $1 and $input get expanded properly when used from $typemap()
-%typemap(in) Name *GENERIC ($*1_type temp)
+%typemap(in, examplekw="accessed_examplekw=1;") Name *GENERIC ($*1_type temp)
%{
/*%typemap(in) Name *GENERIC start */
temp = Name("$specialname");
@@ -78,6 +83,7 @@ static const char *nameDescriptor = "$descriptor(Name)";
%typemap(in) Name *jack {
// %typemap(in) Name *jack start
$typemap(in, Name *GENERIC)
+$typemap(in:examplekw, Name *GENERIC)
// %typemap(in) Name *jack end
}
diff --git a/Examples/test-suite/string_simple.i b/Examples/test-suite/string_simple.i
index 537daa570..55cb950b0 100644
--- a/Examples/test-suite/string_simple.i
+++ b/Examples/test-suite/string_simple.i
@@ -3,6 +3,7 @@
%newobject copy_str;
%inline %{
+#include <stdlib.h>
#include <string.h>
const char* copy_str(const char* str) {
size_t len = strlen(str);
diff --git a/Examples/test-suite/tcl/Makefile.in b/Examples/test-suite/tcl/Makefile.in
index 322e71914..db8eaa874 100644
--- a/Examples/test-suite/tcl/Makefile.in
+++ b/Examples/test-suite/tcl/Makefile.in
@@ -6,6 +6,10 @@ LANGUAGE = tcl
TCLSH = tclsh
SCRIPTSUFFIX = _runme.tcl
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/tcl/argcargvtest_runme.tcl b/Examples/test-suite/tcl/argcargvtest_runme.tcl
new file mode 100644
index 000000000..14c0e92cb
--- /dev/null
+++ b/Examples/test-suite/tcl/argcargvtest_runme.tcl
@@ -0,0 +1,28 @@
+if [ catch { load ./argcargvtest[info sharedlibextension] argcargvtest} err_msg ] {
+ puts stderr "Could not load shared object:\n$err_msg"
+}
+
+set largs {hi hola hello}
+if {[mainc $largs] != 3} {
+ puts stderr "bad main typemap"
+ exit 1
+}
+
+set targs {hi hola}
+if {[mainv $targs 1] != "hola"} {
+ puts stderr "bad main typemap"
+ exit 1
+}
+
+set targs " hi hola "
+if {[mainv $targs 1] != "hola"} {
+ puts stderr "bad main typemap"
+ exit 1
+}
+
+if { ! [ catch { mainv("hello", 1) } ] } {
+ puts stderr "bad main typemap"
+ exit 1
+}
+
+initializeApp $largs
diff --git a/Examples/test-suite/tcl/catches_strings_runme.tcl b/Examples/test-suite/tcl/catches_strings_runme.tcl
new file mode 100644
index 000000000..e60b660d7
--- /dev/null
+++ b/Examples/test-suite/tcl/catches_strings_runme.tcl
@@ -0,0 +1,31 @@
+
+if [ catch { load ./catches_strings[info sharedlibextension] catches_strings} err_msg ] {
+ puts stderr "Could not load shared object:\n$err_msg"
+}
+
+
+set exception_thrown 0
+if [ catch {
+ StringsThrower_charstring
+} e ] {
+ if {[string first "charstring message" $e] == -1} {
+ error "incorrect exception message: $e"
+ }
+ set exception_thrown 1
+}
+if {!$exception_thrown} {
+ error "Should have thrown an exception"
+}
+
+set exception_thrown 0
+if [ catch {
+ StringsThrower_stdstring
+} e ] {
+ if {[string first "stdstring message" $e] == -1} {
+ error "incorrect exception message: $e"
+ }
+ set exception_thrown 1
+}
+if {!$exception_thrown} {
+ error "Should have thrown an exception"
+}
diff --git a/Examples/test-suite/tcl/cpp11_move_typemaps_runme.tcl b/Examples/test-suite/tcl/cpp11_move_typemaps_runme.tcl
new file mode 100644
index 000000000..48f860101
--- /dev/null
+++ b/Examples/test-suite/tcl/cpp11_move_typemaps_runme.tcl
@@ -0,0 +1,35 @@
+
+if [ catch { load ./cpp11_move_typemaps[info sharedlibextension] cpp11_move_typemaps} err_msg ] {
+ puts stderr "Could not load shared object:\n$err_msg"
+}
+
+Counter_reset_counts
+MoveOnly mo 111
+Counter_check_counts 1 0 0 0 0 0
+MoveOnly_take mo
+Counter_check_counts 1 0 0 1 0 2
+mo -delete
+Counter_check_counts 1 0 0 1 0 2
+
+Counter_reset_counts
+MovableCopyable mo 111
+Counter_check_counts 1 0 0 0 0 0
+MovableCopyable_take mo
+Counter_check_counts 1 0 0 1 0 2
+mo -delete
+Counter_check_counts 1 0 0 1 0 2
+
+MoveOnly mo 222
+MoveOnly_take mo
+set exception_thrown 0
+if [ catch {
+ MoveOnly_take mo
+} e ] {
+ if {[string first "cannot release ownership as memory is not owned" $e] == -1} {
+ error "incorrect exception message: $e"
+ }
+ set exception_thrown 1
+}
+if {!$exception_thrown} {
+ error "Should have thrown 'Cannot release ownership as memory is not owned' error"
+}
diff --git a/Examples/test-suite/tcl/cpp11_rvalue_reference_move_runme.tcl b/Examples/test-suite/tcl/cpp11_rvalue_reference_move_runme.tcl
new file mode 100644
index 000000000..876b0425d
--- /dev/null
+++ b/Examples/test-suite/tcl/cpp11_rvalue_reference_move_runme.tcl
@@ -0,0 +1,82 @@
+
+if [ catch { load ./cpp11_rvalue_reference_move[info sharedlibextension] cpp11_rvalue_reference_move} err_msg ] {
+ puts stderr "Could not load shared object:\n$err_msg"
+}
+
+
+# Function containing rvalue reference parameter
+Counter_reset_counts
+MovableCopyable mo 222
+Counter_check_counts 1 0 0 0 0 0
+MovableCopyable_movein mo
+Counter_check_counts 1 0 0 1 0 2
+if {![MovableCopyable_is_nullptr mo]} {
+ error "is_nullptr failed to throw"
+}
+mo -delete
+Counter_check_counts 1 0 0 1 0 2
+
+# Move constructor test
+Counter_reset_counts
+MovableCopyable mo 222
+Counter_check_counts 1 0 0 0 0 0
+MovableCopyable mo_moved mo
+Counter_check_counts 1 0 0 1 0 1
+if {![MovableCopyable_is_nullptr mo]} {
+ error "is_nullptr failed to throw"
+}
+mo -delete
+Counter_check_counts 1 0 0 1 0 1
+mo_moved -delete
+Counter_check_counts 1 0 0 1 0 2
+
+# Move assignment operator test
+Counter_reset_counts
+MovableCopyable mo111 111
+MovableCopyable mo222 222
+Counter_check_counts 2 0 0 0 0 0
+mo111 MoveAssign mo222
+Counter_check_counts 2 0 0 0 1 1
+if {![MovableCopyable_is_nullptr mo222]} {
+ error "is_nullptr failed to throw"
+}
+mo222 -delete
+Counter_check_counts 2 0 0 0 1 1
+mo111 -delete
+Counter_check_counts 2 0 0 0 1 2
+
+# null check
+Counter_reset_counts
+set exception_thrown 0
+if [ catch {
+ MovableCopyable_movein "NULL"
+} e ] {
+ if {[string first "invalid null reference" $e] == -1} {
+ error "incorrect exception message: $e"
+ }
+ set exception_thrown 1
+}
+if {!$exception_thrown} {
+ error "Should have thrown null error"
+}
+Counter_check_counts 0 0 0 0 0 0
+
+# output
+Counter_reset_counts
+set mc [MovableCopyable_moveout 1234]
+Counter_check_counts 2 0 0 0 1 1
+MovableCopyable_check_numbers_match $mc 1234
+
+set exception_thrown 0
+if [ catch {
+ MovableCopyable_movein $mc
+} e ] {
+ if {[string first "cannot release ownership as memory is not owned" $e] == -1} {
+ error "incorrect exception message: $e"
+ }
+ set exception_thrown 1
+}
+if {!$exception_thrown} {
+ error "Should have thrown 'Cannot release ownership as memory is not owned' error"
+}
+Counter_check_counts 2 0 0 0 1 1
diff --git a/Examples/test-suite/tcl/cpp11_std_unique_ptr_runme.tcl b/Examples/test-suite/tcl/cpp11_std_unique_ptr_runme.tcl
new file mode 100644
index 000000000..9e641df7e
--- /dev/null
+++ b/Examples/test-suite/tcl/cpp11_std_unique_ptr_runme.tcl
@@ -0,0 +1,163 @@
+
+if [ catch { load ./cpp11_std_unique_ptr[info sharedlibextension] cpp11_std_unique_ptr} err_msg ] {
+ puts stderr "Could not load shared object:\n$err_msg"
+}
+
+
+proc checkCount {expected_count} {
+ set actual_count [Klass_getTotal_count]
+ if {$actual_count != $expected_count} {
+ error "Counts incorrect, expected: $expected_count actual: $actual_count"
+ }
+}
+
+################################# Tcl pointer recycling bug start
+#
+# ### Possibly related to premature object deletion problem mentioned in newobject1_runme.tcl. ###
+#
+# While this won't be repeatable on all machines, the following caused the underlying C++
+# pointer value for k1 to be reused for k4.
+#
+# If the C/C++ memory allocator uses the same pointer value again, then a command name that
+# contains a pointer encoding, such as, _b09b1148bd550000_p_Klass (not a variable name) will be
+# re-used in SWIG_Tcl_NewInstanceObj. The command should have disappeared from the Tcl side when
+# the object was deleted, but there is some sort of bug preventing this from happening in this
+# scenario as follows:
+#
+# Below creates a struct via the call to Tcl_CreateObjCommand in
+# SWIG_Tcl_NewInstanceObj (creates a command name with a pointer encoding such as
+# _50fb3608ce550000_p_Klass) which also makes a second call to Tcl_CreateObjCommand in
+# SWIG_Tcl_ObjectConstructor (creates a command name with the name k1).
+Klass k1 "one"
+# Line below calls Tcl_DeleteCommandFromToken but is only called for the command created in the
+# second call (k1) and not the first call to Tcl_CreateObjCommand.
+k1 -delete
+set k2 [makeKlassUniquePtr "two"]
+set k3 [makeKlassUniquePtr "three"]
+$k2 -delete
+# If the memory allocator uses the same pointer value, then SWIG_Tcl_NewInstanceObj will find
+# the undeleted command _50fb3608ce550000_p_Klass and re-use it. This command should surely
+# have been deleted !??
+set k4 [makeKlassUniquePtr "four"]
+$k3 -delete
+$k4 -delete
+checkCount 0
+################################# Tcl pointer recycling bug end
+
+# Test raw pointer handling involving virtual inheritance
+KlassInheritance kini "KlassInheritanceInput"
+checkCount 1
+set s [useKlassRawPtr kini]
+kini -delete
+checkCount 0
+
+
+# unique_ptr as input
+Klass kin "KlassInput"
+checkCount 1
+set s [takeKlassUniquePtr kin]
+checkCount 0
+if {[kin cget -thisown]} {
+ error "thisown should be false"
+}
+if {$s != "KlassInput"} {
+ error "Incorrect string: $s"
+}
+if {![is_nullptr kin]} {
+ error "is_nullptr failed"
+}
+kin -delete # Should not fail, even though already deleted
+checkCount 0
+
+Klass kin "KlassInput"
+checkCount 1
+set s [takeKlassUniquePtr kin]
+checkCount 0
+if {[kin cget -thisown]} {
+ error "thisown should be false"
+}
+if {$s != "KlassInput"} {
+ error "Incorrect string: $s"
+}
+if {![is_nullptr kin]} {
+ error "is_nullptr failed"
+}
+set exception_thrown 0
+if [ catch { set s [takeKlassUniquePtr kin] } e ] {
+ if {[string first "cannot release ownership as memory is not owned" $e] == -1} {
+ error "incorrect exception message: $e"
+ }
+ set exception_thrown 1
+}
+if {!$exception_thrown} {
+ error "double usage of takeKlassUniquePtr should have been an error"
+}
+kin -delete # Should not fail, even though already deleted
+checkCount 0
+
+Klass kin "KlassInput"
+set exception_thrown 0
+set notowned [get_not_owned_ptr kin]
+if [ catch {
+ takeKlassUniquePtr notowned
+} ] {
+ set exception_thrown 1
+}
+if {!$exception_thrown} {
+ error "Should have thrown 'Cannot release ownership as memory is not owned' error"
+}
+checkCount 1
+kin -delete
+checkCount 0
+
+KlassInheritance kini "KlassInheritanceInput"
+checkCount 1
+set s [takeKlassUniquePtr kini]
+checkCount 0
+if {[kini cget -thisown]} {
+ error "thisown should be false"
+}
+if {$s != "KlassInheritanceInput"} {
+ error "Incorrect string: $s"
+}
+if {![is_nullptr kini]} {
+ error "is_nullptr failed"
+}
+kini -delete # Should not fail, even though already deleted
+checkCount 0
+
+takeKlassUniquePtr "NULL"
+takeKlassUniquePtr [make_null]
+checkCount 0
+
+# overloaded parameters
+if {[overloadTest] != 0} {
+ error "overloadTest failed"
+}
+if {[overloadTest "NULL"] != 1} {
+ error "overloadTest failed"
+}
+if {[overloadTest [Klass k "over"]] != 1} {
+ error "overloadTest failed"
+}
+checkCount 0
+
+
+# unique_ptr as output
+set k1 [makeKlassUniquePtr "first"]
+set k2 [makeKlassUniquePtr "second"]
+checkCount 2
+
+$k1 -delete
+checkCount 1
+
+if {[$k2 getLabel] != "second"} {
+ error "wrong object label"
+}
+
+$k2 -delete
+checkCount 0
+
+if {[makeNullUniquePtr] != "NULL"} {
+ error "null failure"
+}
diff --git a/Examples/test-suite/tcl/integers_runme.tcl b/Examples/test-suite/tcl/integers_runme.tcl
new file mode 100644
index 000000000..261c4c289
--- /dev/null
+++ b/Examples/test-suite/tcl/integers_runme.tcl
@@ -0,0 +1,26 @@
+if [ catch { load ./integers[info sharedlibextension] integers} err_msg ] {
+ puts stderr "Could not load shared object:\n$err_msg"
+}
+
+# 32-bit long max
+set val 2147483647
+if {[signed_long_identity $val] != $val} {
+ puts stderr "Runtime test 1 failed"
+ exit 1
+}
+
+set val 3902408827
+if {[unsigned_long_identity $val] != $val} {
+ puts stderr "Runtime test 2 failed"
+ exit 1
+}
+
+if {[signed_long_long_identity $val] != $val} {
+ puts stderr "Runtime test 3 failed"
+ exit 1
+}
+
+if {[unsigned_long_long_identity $val] != $val} {
+ puts stderr "Runtime test 4 failed"
+ exit 1
+}
diff --git a/Examples/test-suite/tcl/li_std_auto_ptr_runme.tcl b/Examples/test-suite/tcl/li_std_auto_ptr_runme.tcl
new file mode 100644
index 000000000..502a758dc
--- /dev/null
+++ b/Examples/test-suite/tcl/li_std_auto_ptr_runme.tcl
@@ -0,0 +1,134 @@
+
+if [ catch { load ./li_std_auto_ptr[info sharedlibextension] li_std_auto_ptr} err_msg ] {
+ puts stderr "Could not load shared object:\n$err_msg"
+}
+
+
+proc checkCount {expected_count} {
+ set actual_count [Klass_getTotal_count]
+ if {$actual_count != $expected_count} {
+ error "Counts incorrect, expected: $expected_count actual: $actual_count"
+ }
+}
+
+################################# Tcl pointer recycling bug start
+# Not copied from cpp11_std_unique_ptr_runme.tcl
+################################# Tcl pointer recycling bug end
+
+# Test raw pointer handling involving virtual inheritance
+KlassInheritance kini "KlassInheritanceInput"
+checkCount 1
+set s [useKlassRawPtr kini]
+kini -delete
+checkCount 0
+
+
+# auto_ptr as input
+Klass kin "KlassInput"
+checkCount 1
+set s [takeKlassAutoPtr kin]
+checkCount 0
+if {[kin cget -thisown]} {
+ error "thisown should be false"
+}
+if {$s != "KlassInput"} {
+ error "Incorrect string: $s"
+}
+if {![is_nullptr kin]} {
+ error "is_nullptr failed"
+}
+kin -delete # Should not fail, even though already deleted
+checkCount 0
+
+Klass kin "KlassInput"
+checkCount 1
+set s [takeKlassAutoPtr kin]
+checkCount 0
+if {[kin cget -thisown]} {
+ error "thisown should be false"
+}
+if {$s != "KlassInput"} {
+ error "Incorrect string: $s"
+}
+if {![is_nullptr kin]} {
+ error "is_nullptr failed"
+}
+set exception_thrown 0
+if [ catch { set s [takeKlassAutoPtr kin] } e ] {
+ if {[string first "cannot release ownership as memory is not owned" $e] == -1} {
+ error "incorrect exception message: $e"
+ }
+ set exception_thrown 1
+}
+if {!$exception_thrown} {
+ error "double usage of takeKlassAutoPtr should have been an error"
+}
+kin -delete # Should not fail, even though already deleted
+checkCount 0
+
+Klass kin "KlassInput"
+set exception_thrown 0
+set notowned [get_not_owned_ptr kin]
+if [ catch {
+ takeKlassAutoPtr notowned
+} ] {
+ set exception_thrown 1
+}
+if {!$exception_thrown} {
+ error "Should have thrown 'Cannot release ownership as memory is not owned' error"
+}
+checkCount 1
+kin -delete
+checkCount 0
+
+KlassInheritance kini "KlassInheritanceInput"
+checkCount 1
+set s [takeKlassAutoPtr kini]
+checkCount 0
+if {[kini cget -thisown]} {
+ error "thisown should be false"
+}
+if {$s != "KlassInheritanceInput"} {
+ error "Incorrect string: $s"
+}
+if {![is_nullptr kini]} {
+ error "is_nullptr failed"
+}
+kini -delete # Should not fail, even though already deleted
+checkCount 0
+
+takeKlassAutoPtr "NULL"
+takeKlassAutoPtr [make_null]
+checkCount 0
+
+# overloaded parameters
+if {[overloadTest] != 0} {
+ error "overloadTest failed"
+}
+if {[overloadTest "NULL"] != 1} {
+ error "overloadTest failed"
+}
+if {[overloadTest [Klass k "over"]] != 1} {
+ error "overloadTest failed"
+}
+checkCount 0
+
+
+# auto_ptr as output
+set k1 [makeKlassAutoPtr "first"]
+set k2 [makeKlassAutoPtr "second"]
+checkCount 2
+
+$k1 -delete
+checkCount 1
+
+if {[$k2 getLabel] != "second"} {
+ error "wrong object label"
+}
+
+$k2 -delete
+checkCount 0
+
+if {[makeNullAutoPtr] != "NULL"} {
+ error "null failure"
+}
diff --git a/Examples/test-suite/tcl/li_std_vector_runme.tcl b/Examples/test-suite/tcl/li_std_vector_runme.tcl
new file mode 100644
index 000000000..743565d95
--- /dev/null
+++ b/Examples/test-suite/tcl/li_std_vector_runme.tcl
@@ -0,0 +1,15 @@
+
+if [ catch { load ./li_std_vector[info sharedlibextension] li_std_vector} err_msg ] {
+ puts stderr "Could not load shared object:\n$err_msg"
+}
+
+# Regression test for bug fixed in SWIG 4.1.0.
+if {[sum []] != 0} { error "bad vector sum" }
+
+IntPtrVector v 6
+if {[v empty] != 0} { error "bad std::vector::empty()" }
+if {[v size] != 6} { error "bad std::vector::size()" }
+# Test that calling get succeeds
+v get 0
+v pop
+if {[v size] != 5} { error "bad std::vector::size()" }
diff --git a/Examples/test-suite/template_arg_replace.i b/Examples/test-suite/template_arg_replace.i
index 25274c9ab..d887c2661 100644
--- a/Examples/test-suite/template_arg_replace.i
+++ b/Examples/test-suite/template_arg_replace.i
@@ -6,7 +6,7 @@
template <typename T, int r, int c> class test_Matrix {
public:
- void Func(const test_Matrix<T,r,c> &m) { };
+ void Func(const test_Matrix<T,r,c> &m) { }
};
%}
diff --git a/Examples/test-suite/template_construct.i b/Examples/test-suite/template_construct.i
index a6e8c3c33..ac418f8e5 100644
--- a/Examples/test-suite/template_construct.i
+++ b/Examples/test-suite/template_construct.i
@@ -7,7 +7,13 @@ template<class T>
class Foo {
T y;
public:
+#ifdef SWIG
Foo<T>(T x) : y(x) { }
+#else
+ // Modern compilers reject this, so feed the compiler the corrected
+ // version.
+ Foo(T x) : y(x) { }
+#endif
};
%}
diff --git a/Examples/test-suite/template_default_vw.i b/Examples/test-suite/template_default_vw.i
index 429ed301e..ed207125c 100644
--- a/Examples/test-suite/template_default_vw.i
+++ b/Examples/test-suite/template_default_vw.i
@@ -13,7 +13,7 @@ public:
typedef Handle<SomeClass> hSomeClass;
class AnotherClass {
public:
- void someFunc( hSomeClass a = hSomeClass() ) { };
+ void someFunc( hSomeClass a = hSomeClass() ) { }
};
%}
diff --git a/Examples/test-suite/template_typedef_cplx2.h b/Examples/test-suite/template_typedef_cplx2.h
index 17d065252..a23c319c1 100644
--- a/Examples/test-suite/template_typedef_cplx2.h
+++ b/Examples/test-suite/template_typedef_cplx2.h
@@ -1,5 +1,5 @@
-#ifndef ___typedef_import_h__
-#define ___typedef_import_h__
+#ifndef TEMPLATE_TYPEDEF_CPLX2_H
+#define TEMPLATE_TYPEDEF_CPLX2_H
#ifdef SWIG
%module template_typedef_cplx2;
@@ -113,6 +113,8 @@ namespace vfncs {
#ifndef SWIG
// Initialize these static class members
+// XXX Since this is a header file, the following creates the symbols in *each* SWIG _wrap.cxx file. Linking the resulting SWIG modules together may result in
+// duplicate symbol link errors.
const char* const arith_traits< double, double >::arg_type = "double";
const char* const arith_traits< double, double >::res_type = "double";
@@ -172,4 +174,4 @@ namespace vfncs {
#endif
-#endif //___template_typedef_h__
+#endif // TEMPLATE_TYPEDEF_CPLX2_H
diff --git a/Examples/test-suite/template_whitespace.i b/Examples/test-suite/template_whitespace.i
index f00b9e857..063dec6d2 100644
--- a/Examples/test-suite/template_whitespace.i
+++ b/Examples/test-suite/template_whitespace.i
@@ -11,9 +11,9 @@ template<class T, class U> class map {
};
%}
-//%typemap(in) vector<int> "$target = new vector<int>();";
-//%typemap(in) vector<unsigned int> "$target = new vector<unsigned int>();";
-//%typemap(in) map<int,int> "$target = new map<int, int>();";
+//%typemap(in) vector<int> "$target = new vector<int>();"
+//%typemap(in) vector<unsigned int> "$target = new vector<unsigned int>();"
+//%typemap(in) map<int,int> "$target = new map<int, int>();"
%inline %{
void foo(vector<int > v) {}
diff --git a/Examples/test-suite/testdir/inctest/subdir2/hello.i b/Examples/test-suite/testdir/inctest/subdir2/hello.i
index ed172b1fd..e87b43759 100644
--- a/Examples/test-suite/testdir/inctest/subdir2/hello.i
+++ b/Examples/test-suite/testdir/inctest/subdir2/hello.i
@@ -3,6 +3,7 @@
%{
typedef char * TypedefString;
+#include <string.h>
%}
diff --git a/Examples/test-suite/threads.i b/Examples/test-suite/threads.i
index 7c6b09be0..28c55945e 100644
--- a/Examples/test-suite/threads.i
+++ b/Examples/test-suite/threads.i
@@ -9,6 +9,7 @@
%inline %{
#include <string>
+ #include <string.h>
struct Kerfuffle {
std::string StdString(std::string str) {
return str;
diff --git a/Examples/test-suite/threads_exception.i b/Examples/test-suite/threads_exception.i
index 4708633db..776e84231 100644
--- a/Examples/test-suite/threads_exception.i
+++ b/Examples/test-suite/threads_exception.i
@@ -13,6 +13,7 @@
%}
%{
+#include <string.h>
struct A {};
%}
diff --git a/Examples/test-suite/typedef_struct.i b/Examples/test-suite/typedef_struct.i
index 185e81105..b9a670cf5 100644
--- a/Examples/test-suite/typedef_struct.i
+++ b/Examples/test-suite/typedef_struct.i
@@ -31,6 +31,7 @@
#define MS_NOOVERRIDE -1111
+#include <stdlib.h>
%}
diff --git a/Examples/test-suite/typemap_array_qualifiers.i b/Examples/test-suite/typemap_array_qualifiers.i
index c3965ced2..f7cce3c86 100644
--- a/Examples/test-suite/typemap_array_qualifiers.i
+++ b/Examples/test-suite/typemap_array_qualifiers.i
@@ -26,6 +26,12 @@
}
%enddef
+%{
+#if __cplusplus >= 202002L
+#define volatile
+#endif
+%}
+
%inline %{
typedef struct {
int a;
diff --git a/Examples/test-suite/typemap_out_optimal.i b/Examples/test-suite/typemap_out_optimal.i
index d707ed2d5..46809d117 100644
--- a/Examples/test-suite/typemap_out_optimal.i
+++ b/Examples/test-suite/typemap_out_optimal.i
@@ -4,39 +4,40 @@
// Just the following languages tested
#if defined (SWIGCSHARP) || defined (SWIGD)
%typemap(out, optimal="1") SWIGTYPE %{
- $result = new $1_ltype((const $1_ltype &)$1);
+ $result = new $1_ltype($1);
%}
#elif defined (SWIGJAVA)
%typemap(out, optimal="1") SWIGTYPE %{
- *($&1_ltype*)&$result = new $1_ltype((const $1_ltype &)$1);
+ *($&1_ltype*)&$result = new $1_ltype($1);
%}
#elif defined (SWIGUTL)
%typemap(out,noblock="1", optimal="1") SWIGTYPE {
- %set_output(SWIG_NewPointerObj(%new_copy($1, $ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+ %set_output(SWIG_NewPointerObj(new $1_ltype($1), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
}
#endif
%ignore XX::operator=;
-#ifdef SWIGD
-%rename(trace) XX::debug;
-#endif
-
%inline %{
#include <iostream>
using namespace std;
struct XX {
- XX() { if (debug) cout << "XX()" << endl; }
- XX(int i) { if (debug) cout << "XX(" << i << ")" << endl; }
- XX(const XX &other) { if (debug) cout << "XX(const XX &)" << endl; }
- XX& operator =(const XX &other) { if (debug) cout << "operator=(const XX &)" << endl; return *this; }
- ~XX() { if (debug) cout << "~XX()" << endl; }
- static XX create() {
+ XX() { if (trace) cout << "XX()" << endl; }
+ XX(int i) { if (trace) cout << "XX(" << i << ")" << endl; }
+ XX(const XX &other) { if (trace) cout << "XX(const XX &)" << endl; }
+ XX& operator =(const XX &other) { if (trace) cout << "operator=(const XX &)" << endl; return *this; }
+ ~XX() { if (trace) cout << "~XX()" << endl; }
+
+// Note: best observed RVO for C#, Java and Python with g++-6 to g++-10 (just one constructor and one destructor call)
+ static XX create() {
return XX(123);
}
- static bool debug;
+ static const XX createConst() {
+ return XX(456);
+ }
+ static bool trace;
};
-bool XX::debug = true;
+bool XX::trace = true;
%}
diff --git a/Examples/test-suite/typemap_qualifier_strip.i b/Examples/test-suite/typemap_qualifier_strip.i
index 9b9f24cd8..36d524dad 100644
--- a/Examples/test-suite/typemap_qualifier_strip.i
+++ b/Examples/test-suite/typemap_qualifier_strip.i
@@ -4,18 +4,18 @@
%typemap(freearg) int *const ptrConst ""
%typemap(freearg) int const* constPtr ""
-%typemap(in) int *ptr {
- int temp = 1234;
+%typemap(in) int *ptr (int temp) {
+ temp = 1234;
$1 = &temp;
}
-%typemap(in) int *const ptrConst {
- int temp = 5678;
+%typemap(in) int *const ptrConst (int temp) {
+ temp = 5678;
$1 = &temp;
}
-%typemap(in) int const* constPtr {
- int temp = 3456;
+%typemap(in) int const* constPtr (int temp) {
+ temp = 3456;
$1 = &temp;
}
diff --git a/Examples/test-suite/typemap_variables.i b/Examples/test-suite/typemap_variables.i
index b1ae24fdf..af8dd07d2 100644
--- a/Examples/test-suite/typemap_variables.i
+++ b/Examples/test-suite/typemap_variables.i
@@ -68,12 +68,12 @@
%clear int Space::nspace;
%clear int Space::Struct::smember;
%ignore Space::Struct::member;
-%typemap(varin) int globul "TYPEMAP_VARIABLES_FAIL";
-%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int globul "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;";
-%typemap(varin) int Space::nspace "TYPEMAP_VARIABLES_FAIL";
-%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int Space::nspace "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;";
-%typemap(varin) int Space::Struct::smember "TYPEMAP_VARIABLES_FAIL";
-%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int Space::Struct::smember "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;";
+%typemap(varin) int globul "TYPEMAP_VARIABLES_FAIL"
+%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int globul "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;"
+%typemap(varin) int Space::nspace "TYPEMAP_VARIABLES_FAIL"
+%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int Space::nspace "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;"
+%typemap(varin) int Space::Struct::smember "TYPEMAP_VARIABLES_FAIL"
+%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int Space::Struct::smember "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;"
#endif
%inline %{
diff --git a/Examples/test-suite/typemap_various.i b/Examples/test-suite/typemap_various.i
index 2caff97dc..d619aabaa 100644
--- a/Examples/test-suite/typemap_various.i
+++ b/Examples/test-suite/typemap_various.i
@@ -58,6 +58,10 @@ void CheckRetTypemapUsed() {
/* hello */ delete[] result;
}
+%{
+#include <string.h>
+%}
+
%inline {
class FFoo {
public:
diff --git a/Examples/test-suite/using2.i b/Examples/test-suite/using2.i
index 1f3dc46f5..1c471c1e5 100644
--- a/Examples/test-suite/using2.i
+++ b/Examples/test-suite/using2.i
@@ -1,6 +1,6 @@
%module using2
-%warnfilter(SWIGWARN_PARSE_USING_UNDEF);
+%warnfilter(SWIGWARN_PARSE_USING_UNDEF) ::baz;
using ::baz;
diff --git a/Examples/test-suite/using_member.i b/Examples/test-suite/using_member.i
new file mode 100644
index 000000000..c80a83a50
--- /dev/null
+++ b/Examples/test-suite/using_member.i
@@ -0,0 +1,71 @@
+%module using_member
+
+/* using declaration tests, including renaming */
+%warnfilter(SWIGWARN_LANG_USING_NAME_DIFFERENT) one::twotwo::threetwo::BB::great;
+
+%rename(greater) one::two::three::interface1::AA::great(int);
+%rename(greater) one::two::three::interface1::AA::great(float);
+%rename(greater) one::CC::great;
+%rename(greater) one::DD::great;
+%rename(greaterstill) one::DD::great(bool);
+
+%inline %{
+namespace interface1
+{
+ struct A
+ {
+ int get(int) {return 10;}
+ };
+}
+using interface1::A;
+
+struct B : public A
+{
+ using A::get;
+ int get(double) {return 20;}
+};
+
+
+namespace one {
+ namespace two {
+ namespace three {
+ namespace interface1
+ {
+ class AA
+ {
+ public:
+ int great(int) {return 0;}
+ int great(float) {return 1;}
+ };
+ }
+ using interface1::AA;
+ }
+ }
+ namespace twotwo {
+ namespace threetwo {
+ class BB : public two::three::AA
+ {
+ public:
+// TODO: two::three::AA::great not introduced
+ using two::three::AA::great;
+ int great(bool) {return 2;}
+ int jj() {return 3;}
+ };
+ }
+ }
+
+ class CC : public two::three::AA
+ {
+ public:
+ using two::three::AA::great;
+ int great(bool) {return 20;}
+ };
+
+ class DD : public two::three::AA
+ {
+ public:
+ using two::three::AA::great;
+ int great(bool) {return 30;}
+ };
+}
+%}
diff --git a/Examples/test-suite/using_member_scopes.i b/Examples/test-suite/using_member_scopes.i
new file mode 100644
index 000000000..3245c9cc7
--- /dev/null
+++ b/Examples/test-suite/using_member_scopes.i
@@ -0,0 +1,85 @@
+%module using_member_scopes
+
+// Fully qualifying parameter types in a method declared after the using declaration caused
+// a method being incorrectly added by the using declaration even though the declaration already existed
+
+%inline %{
+namespace OgreBites
+{
+ struct NativeWindowType {};
+ class ApplicationContextBase {
+ public:
+ virtual ~ApplicationContextBase() {}
+ virtual void setWindowGrab(NativeWindowType* win, bool grab = true) {}
+ void setWindowGrab(bool grab = true) {}
+ };
+ class ApplicationContextSDL : public ApplicationContextBase {
+ public:
+ using ApplicationContextBase::setWindowGrab;
+ void setWindowGrab(NativeWindowType* win, bool grab = true) {} // This should not be added again as it exists in base class
+ };
+/*
+typedef not working yet
+ class ApplicationContextSDL2 : public ApplicationContextBase {
+ public:
+ using ApplicationContextBase::setWindowGrab;
+ typedef NativeWindowType* pNWT;
+ void setWindowGrab(pNWT win, bool grab) {} // This should not be added again as it exists in base class
+ };
+*/
+}
+%}
+
+
+%inline %{
+// Test using declaration in various positions before and after overloaded methods
+// Testing where the derived class overrides all the base class methods (and more)
+namespace Bites
+{
+ struct Base
+ {
+ virtual ~Base() {}
+ virtual void grab() {}
+ virtual void grab(int i) {}
+ };
+ struct Derived1 : public Base
+ {
+ using Base::grab;
+ virtual void grab() {}
+ virtual void grab(int i) {}
+ };
+ struct Derived2 : public Base
+ {
+ using Base::grab;
+ virtual void grab() {}
+ virtual void grab(int i) {}
+ virtual void grab(int i, double d) {}
+ };
+ struct Derived3 : public Base
+ {
+ virtual void grab() {}
+ using Base::grab;
+ virtual void grab(int i) {}
+ };
+ struct Derived4 : public Base
+ {
+ virtual void grab() {}
+ using Base::grab;
+ virtual void grab(int i) {}
+ virtual void grab(int i, double d) {}
+ };
+ struct Derived5 : public Base
+ {
+ virtual void grab() {}
+ virtual void grab(int i) {}
+ using Base::grab;
+ };
+ struct Derived6 : public Base
+ {
+ virtual void grab() {}
+ virtual void grab(int i) {}
+ virtual void grab(int i, double d) {}
+ using Base::grab;
+ };
+}
+%}
diff --git a/Examples/test-suite/valuewrapper_base.i b/Examples/test-suite/valuewrapper_base.i
index 63471bbc8..5107a3c9b 100644
--- a/Examples/test-suite/valuewrapper_base.i
+++ b/Examples/test-suite/valuewrapper_base.i
@@ -12,7 +12,7 @@
template <Polarization P>
struct Interface_ : Base
{
- Interface_(const Base& b) { };
+ Interface_(const Base& b) { }
};
template <class Result>
diff --git a/Examples/test-suite/valuewrapper_opaque.i b/Examples/test-suite/valuewrapper_opaque.i
index bc7ba8683..962bd2f81 100644
--- a/Examples/test-suite/valuewrapper_opaque.i
+++ b/Examples/test-suite/valuewrapper_opaque.i
@@ -14,7 +14,7 @@ class C;
%{
template<typename T> class TemplateClass {
public:
-TemplateClass<T>(T a) {}
+TemplateClass(T a) {}
};
struct B
diff --git a/Examples/test-suite/varargs.i b/Examples/test-suite/varargs.i
index 68c7a1714..c1aee229e 100644
--- a/Examples/test-suite/varargs.i
+++ b/Examples/test-suite/varargs.i
@@ -4,6 +4,10 @@
// Default handling of varargs
+%{
+#include <string.h>
+%}
+
%inline %{
char *test(const char *fmt, ...) {
return (char *) fmt;
diff --git a/Examples/test-suite/voidtest.i b/Examples/test-suite/voidtest.i
index f0e649373..d792f4151 100644
--- a/Examples/test-suite/voidtest.i
+++ b/Examples/test-suite/voidtest.i
@@ -9,6 +9,7 @@ class Foo {
public:
Foo(void) { }
void memberfunc(void) { }
+ void* get_this() { return this; }
static void staticmemberfunc(void) { }
};
@@ -18,4 +19,6 @@ void *vfunc2(Foo *f) { return f; }
Foo *vfunc3(void *f) { return (Foo *) f; }
Foo *vfunc4(Foo *f) { return f; }
+bool test_pointers_equal(void *a, void *b) { return a == b; }
+
%}
diff --git a/Examples/xml/example_apply.expected-xml b/Examples/xml/example_apply.expected-xml
index 6118ef1f2..26cf5df2f 100644
--- a/Examples/xml/example_apply.expected-xml
+++ b/Examples/xml/example_apply.expected-xml
@@ -409,7 +409,7 @@ static void _ptrset(SV *_PTRVALUE, SV *value, int index, char *type) {
} else if (strcmp(type,"char *") == 0) {
char *c = SvPV(value,PL_na);
char **ca = (char **) ptr;
- if (ca[index]) free(ca[index]);
+ free(ca[index]);
if (strcmp(c,"NULL") == 0) {
ca[index] = 0;
} else {
@@ -500,8 +500,7 @@ void _ptrfree(SV *_PTRVALUE) {
}
}
}
- if (ptr)
- free((char *) ptr);
+ free((char *) ptr);
}
</swigxml:code>
diff --git a/Examples/xml/example_xml.expected-xml b/Examples/xml/example_xml.expected-xml
index 4d08b206a..e13bcf24b 100644
--- a/Examples/xml/example_xml.expected-xml
+++ b/Examples/xml/example_xml.expected-xml
@@ -441,7 +441,7 @@ static void _ptrset(SV *_PTRVALUE, SV *value, int index, char *type) {
} else if (strcmp(type,"char *") == 0) {
char *c = SvPV(value,PL_na);
char **ca = (char **) ptr;
- if (ca[index]) free(ca[index]);
+ free(ca[index]);
if (strcmp(c,"NULL") == 0) {
ca[index] = 0;
} else {
@@ -532,8 +532,7 @@ void _ptrfree(SV *_PTRVALUE) {
}
}
}
- if (ptr)
- free((char *) ptr);
+ free((char *) ptr);
}
</swigxml:code>
diff --git a/Lib/allkw.swg b/Lib/allkw.swg
index 2d3cf6ea9..5e4cb8308 100644
--- a/Lib/allkw.swg
+++ b/Lib/allkw.swg
@@ -1,5 +1,5 @@
-#ifndef __Lib_allkw_swg__
-#define __Lib_allkw_swg__
+#ifndef SWIG_INCLUDED_LIB_ALLKW_SWG
+#define SWIG_INCLUDED_LIB_ALLKW_SWG
/*
@@ -30,4 +30,4 @@
%include <tcl/tclkw.swg>
-#endif //__Lib_allkw_swg__
+#endif // SWIG_INCLUDED_LIB_ALLKW_SWG
diff --git a/Lib/carrays.i b/Lib/carrays.i
index 3a9c3cfee..0aa3eee89 100644
--- a/Lib/carrays.i
+++ b/Lib/carrays.i
@@ -5,6 +5,12 @@
* pointers as arrays.
* ----------------------------------------------------------------------------- */
+#ifndef __cplusplus
+// C uses free/calloc/malloc
+%include "swigfragments.swg"
+%fragment("<stdlib.h>");
+#endif
+
/* -----------------------------------------------------------------------------
* %array_functions(TYPE,NAME)
*
diff --git a/Lib/cdata.i b/Lib/cdata.i
index cd1526643..8736de1c2 100644
--- a/Lib/cdata.i
+++ b/Lib/cdata.i
@@ -4,6 +4,8 @@
* SWIG library file containing macros for manipulating raw C data as strings.
* ----------------------------------------------------------------------------- */
+%include <swigfragments.swg>
+
%{
typedef struct SWIGCDATA {
char *data;
@@ -60,7 +62,7 @@ static jbyteArray SWIG_JavaArrayOutCDATA(JNIEnv *jenv, char *result, jsize sz) {
/* -----------------------------------------------------------------------------
- * %cdata(TYPE [, NAME])
+ * %cdata(TYPE [, NAME])
*
* Convert raw C data to a binary string.
* ----------------------------------------------------------------------------- */
@@ -99,6 +101,8 @@ SWIGCDATA cdata_##NAME(TYPE *ptr, int nelements);
%cdata(void);
+%fragment("<string.h>");
+
/* Memory move function. Due to multi-argument typemaps this appears to be wrapped as
void memmove(void *data, const char *s); */
void memmove(void *data, const void *indata, int inlen);
diff --git a/Lib/cffi/cffi.swg b/Lib/cffi/cffi.swg
deleted file mode 100644
index f7294956f..000000000
--- a/Lib/cffi/cffi.swg
+++ /dev/null
@@ -1,294 +0,0 @@
-/* Define a C preprocessor symbol that can be used in interface files
- to distinguish between the SWIG language modules. */
-
-#define SWIG_CFFI
-
-/* Typespecs for basic types. */
-
-%typemap(cin) void ":void";
-
-%typemap(cin) char ":char";
-%typemap(cin) char * ":string";
-%typemap(cin) unsigned char ":unsigned-char";
-%typemap(cin) signed char ":char";
-
-%typemap(cin) short ":short";
-%typemap(cin) signed short ":short";
-%typemap(cin) unsigned short ":unsigned-short";
-
-%typemap(cin) int ":int";
-%typemap(cin) signed int ":int";
-%typemap(cin) unsigned int ":unsigned-int";
-
-%typemap(cin) long ":long";
-%typemap(cin) signed long ":long";
-%typemap(cin) unsigned long ":unsigned-long";
-
-%typemap(cin) long long ":long-long";
-%typemap(cin) signed long long ":long-long";
-%typemap(cin) unsigned long long ":unsigned-long-long";
-
-%typemap(cin) float ":float";
-%typemap(cin) double ":double";
-%typemap(cin) SWIGTYPE ":pointer";
-
-%typemap(cout) void ":void";
-
-%typemap(cout) char ":char";
-%typemap(cout) char * ":string";
-%typemap(cout) unsigned char ":unsigned-char";
-%typemap(cout) signed char ":char";
-
-%typemap(cout) short ":short";
-%typemap(cout) signed short ":short";
-%typemap(cout) unsigned short ":unsigned-short";
-
-%typemap(cout) int ":int";
-%typemap(cout) signed int ":int";
-%typemap(cout) unsigned int ":unsigned-int";
-
-%typemap(cout) long ":long";
-%typemap(cout) signed long ":long";
-%typemap(cout) unsigned long ":unsigned-long";
-
-%typemap(cout) long long ":long-long";
-%typemap(cout) signed long long ":long-long";
-%typemap(cout) unsigned long long ":unsigned-long-long";
-
-%typemap(cout) float ":float";
-%typemap(cout) double ":double";
-%typemap(cout) SWIGTYPE ":pointer";
-
-
-%typemap(ctype) bool "int";
-%typemap(ctype) char, unsigned char, signed char,
- short, signed short, unsigned short,
- int, signed int, unsigned int,
- long, signed long, unsigned long,
- float, double, long double, char *, void *, void,
- enum SWIGTYPE, SWIGTYPE *,
- SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE && "$1_ltype";
-%typemap(ctype) SWIGTYPE "$&1_type";
-
-%typemap(in) bool "$1 = (bool)$input;";
-%typemap(in) char, unsigned char, signed char,
- short, signed short, unsigned short,
- int, signed int, unsigned int,
- long, signed long, unsigned long,
- float, double, long double, char *, void *, void,
- enum SWIGTYPE, SWIGTYPE *,
- SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE && "$1 = $input;";
-%typemap(in) SWIGTYPE "$1 = *$input;";
-
-%typemap(out) void "";
-%typemap(out) bool "$result = (int)$1;";
-%typemap(out) char, unsigned char, signed char,
- short, signed short, unsigned short,
- int, signed int, unsigned int,
- long, signed long, unsigned long,
- float, double, long double, char *, void *,
- enum SWIGTYPE, SWIGTYPE *,
- SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE && "$result = $1;";
-#ifdef __cplusplus
-%typemap(out) SWIGTYPE "$result = new $1_type($1);";
-#else
-%typemap(out) SWIGTYPE {
- $result = ($&1_ltype) malloc(sizeof($1_type));
- memmove($result, &$1, sizeof($1_type));
-}
-#endif
-
-%typecheck(SWIG_TYPECHECK_BOOL) bool { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_CHAR) char { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_FLOAT) float { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_DOUBLE) double { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_STRING) char * { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_INTEGER)
- unsigned char, signed char,
- short, signed short, unsigned short,
- int, signed int, unsigned int,
- long, signed long, unsigned long,
- enum SWIGTYPE { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&,
- SWIGTYPE[ANY], SWIGTYPE { $1 = 1; };
-/* This maps C/C++ types to Lisp classes for overload dispatch */
-
-%typemap(lisptype) bool "cl:boolean";
-%typemap(lisptype) char "cl:character";
-%typemap(lisptype) unsigned char "cl:integer";
-%typemap(lisptype) signed char "cl:integer";
-
-%typemap(lispclass) bool "t";
-%typemap(lispclass) char "cl:character";
-%typemap(lispclass) unsigned char, signed char,
- short, signed short, unsigned short,
- int, signed int, unsigned int,
- long, signed long, unsigned long,
- enum SWIGTYPE "cl:integer";
-/* CLOS methods can't be specialized on single-float or double-float */
-%typemap(lispclass) float "cl:number";
-%typemap(lispclass) double "cl:number";
-%typemap(lispclass) char * "cl:string";
-
-/* Array reference typemaps */
-%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
-%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
-
-/* const pointers */
-%apply SWIGTYPE * { SWIGTYPE *const }
-%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) }
-%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) }
-
-%{
-
-#ifdef __cplusplus
-# define EXTERN extern "C"
-#else
-# define EXTERN extern
-#endif
-
-#define EXPORT EXTERN SWIGEXPORT
-
-#include <string.h>
-%}
-
-%insert("swiglisp") %{
-;;;SWIG wrapper code starts here
-
-(cl:defmacro defanonenum (cl:&body enums)
- "Converts anonymous enums to defconstants."
- `(cl:progn ,@(cl:loop for value in enums
- for index = 0 then (cl:1+ index)
- when (cl:listp value) do (cl:setf index (cl:second value)
- value (cl:first value))
- collect `(cl:defconstant ,value ,index))))
-
-(cl:eval-when (:compile-toplevel :load-toplevel)
- (cl:unless (cl:fboundp 'swig-lispify)
- (cl:defun swig-lispify (name flag cl:&optional (package cl:*package*))
- (cl:labels ((helper (lst last rest cl:&aux (c (cl:car lst)))
- (cl:cond
- ((cl:null lst)
- rest)
- ((cl:upper-case-p c)
- (helper (cl:cdr lst) 'upper
- (cl:case last
- ((lower digit) (cl:list* c #\- rest))
- (cl:t (cl:cons c rest)))))
- ((cl:lower-case-p c)
- (helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest)))
- ((cl:digit-char-p c)
- (helper (cl:cdr lst) 'digit
- (cl:case last
- ((upper lower) (cl:list* c #\- rest))
- (cl:t (cl:cons c rest)))))
- ((cl:char-equal c #\_)
- (helper (cl:cdr lst) '_ (cl:cons #\- rest)))
- (cl:t
- (cl:error "Invalid character: ~A" c)))))
- (cl:let ((fix (cl:case flag
- ((constant enumvalue) "+")
- (variable "*")
- (cl:t ""))))
- (cl:intern
- (cl:concatenate
- 'cl:string
- fix
- (cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil))
- fix)
- package))))))
-
-;;;SWIG wrapper code ends here
-%}
-
-#ifdef __cplusplus
-%typemap(out) SWIGTYPE "$result = new $1_type($1);";
-#else
-%typemap(out) SWIGTYPE {
- $result = ($&1_ltype) malloc(sizeof($1_type));
- memmove($result, &$1, sizeof($1_type));
-}
-#endif
-
-//////////////////////////////////////////////////////////////
-
-/* name conversion for overloaded operators. */
-#ifdef __cplusplus
-%rename(__add__) *::operator+;
-%rename(__pos__) *::operator+();
-%rename(__pos__) *::operator+() const;
-
-%rename(__sub__) *::operator-;
-%rename(__neg__) *::operator-() const;
-%rename(__neg__) *::operator-();
-
-%rename(__mul__) *::operator*;
-%rename(__deref__) *::operator*();
-%rename(__deref__) *::operator*() const;
-
-%rename(__div__) *::operator/;
-%rename(__mod__) *::operator%;
-%rename(__logxor__) *::operator^;
-%rename(__logand__) *::operator&;
-%rename(__logior__) *::operator|;
-%rename(__lognot__) *::operator~();
-%rename(__lognot__) *::operator~() const;
-
-%rename(__not__) *::operator!();
-%rename(__not__) *::operator!() const;
-
-%rename(__assign__) *::operator=;
-
-%rename(__add_assign__) *::operator+=;
-%rename(__sub_assign__) *::operator-=;
-%rename(__mul_assign__) *::operator*=;
-%rename(__div_assign__) *::operator/=;
-%rename(__mod_assign__) *::operator%=;
-%rename(__logxor_assign__) *::operator^=;
-%rename(__logand_assign__) *::operator&=;
-%rename(__logior_assign__) *::operator|=;
-
-%rename(__lshift__) *::operator<<;
-%rename(__lshift_assign__) *::operator<<=;
-%rename(__rshift__) *::operator>>;
-%rename(__rshift_assign__) *::operator>>=;
-
-%rename(__eq__) *::operator==;
-%rename(__ne__) *::operator!=;
-%rename(__lt__) *::operator<;
-%rename(__gt__) *::operator>;
-%rename(__lte__) *::operator<=;
-%rename(__gte__) *::operator>=;
-
-%rename(__and__) *::operator&&;
-%rename(__or__) *::operator||;
-
-%rename(__preincr__) *::operator++();
-%rename(__postincr__) *::operator++(int);
-%rename(__predecr__) *::operator--();
-%rename(__postdecr__) *::operator--(int);
-
-%rename(__comma__) *::operator,();
-%rename(__comma__) *::operator,() const;
-
-%rename(__member_ref__) *::operator->;
-%rename(__member_func_ref__) *::operator->*;
-
-%rename(__funcall__) *::operator();
-%rename(__aref__) *::operator[];
-#endif
-
-
-%{
-
-#ifdef __cplusplus
-# define EXTERN extern "C"
-#else
-# define EXTERN extern
-#endif
-
-#define EXPORT EXTERN SWIGEXPORT
-
-#include <string.h>
-#include <stdlib.h>
-%}
diff --git a/Lib/cpointer.i b/Lib/cpointer.i
index 881c511fc..df40c0426 100644
--- a/Lib/cpointer.i
+++ b/Lib/cpointer.i
@@ -5,6 +5,12 @@
* pointer objects.
* ----------------------------------------------------------------------------- */
+#ifndef __cplusplus
+// C uses free/calloc/malloc
+%include "swigfragments.swg"
+%fragment("<stdlib.h>");
+#endif
+
/* -----------------------------------------------------------------------------
* %pointer_class(type,name)
*
@@ -55,14 +61,14 @@ NAME() {
return new TYPE();
}
~NAME() {
- if ($self) delete $self;
+ delete $self;
}
#else
NAME() {
return (TYPE *) calloc(1,sizeof(TYPE));
}
~NAME() {
- if ($self) free($self);
+ free($self);
}
#endif
}
@@ -114,7 +120,7 @@ static NAME * frompointer(TYPE *t) {
%define %pointer_functions(TYPE,NAME)
%{
-static TYPE *new_##NAME() { %}
+static TYPE *new_##NAME(void) { %}
#ifdef __cplusplus
%{ return new TYPE(); %}
#else
@@ -134,9 +140,9 @@ static TYPE *copy_##NAME(TYPE value) { %}
static void delete_##NAME(TYPE *obj) { %}
#ifdef __cplusplus
-%{ if (obj) delete obj; %}
+%{ delete obj; %}
#else
-%{ if (obj) free(obj); %}
+%{ free(obj); %}
#endif
%{}
@@ -149,7 +155,7 @@ static TYPE NAME ##_value(TYPE *obj) {
}
%}
-TYPE *new_##NAME();
+TYPE *new_##NAME(void);
TYPE *copy_##NAME(TYPE value);
void delete_##NAME(TYPE *obj);
void NAME##_assign(TYPE *obj, TYPE value);
diff --git a/Lib/csharp/boost_intrusive_ptr.i b/Lib/csharp/boost_intrusive_ptr.i
index fa3f53a20..355a910cf 100644
--- a/Lib/csharp/boost_intrusive_ptr.i
+++ b/Lib/csharp/boost_intrusive_ptr.i
@@ -32,7 +32,7 @@
%}
%typemap(out, fragment="SWIG_intrusive_deleter") CONST TYPE %{
//plain value(out)
- $1_ltype* resultp = new $1_ltype(($1_ltype &)$1);
+ $1_ltype* resultp = new $1_ltype($1);
intrusive_ptr_add_ref(resultp);
*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(resultp, SWIG_intrusive_deleter< CONST TYPE >());
%}
@@ -372,7 +372,7 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
// plain pointer
%typemap(in) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
diff --git a/Lib/csharp/boost_shared_ptr.i b/Lib/csharp/boost_shared_ptr.i
index 508c0ec14..d47fab558 100644
--- a/Lib/csharp/boost_shared_ptr.i
+++ b/Lib/csharp/boost_shared_ptr.i
@@ -29,10 +29,10 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
%typemap(directorin) CONST TYPE
-%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
%typemap(directorout) CONST TYPE
%{ if (!$input) {
@@ -122,7 +122,7 @@
%typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
%{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
%typemap(out, fragment="SWIG_null_deleter") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
-%{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
+%{ $result = ($1 && *$1) ? new $*1_ltype(*$1) : 0;
if ($owner) delete $1; %}
%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg
index 0e180f576..1f80d12a1 100644
--- a/Lib/csharp/csharp.swg
+++ b/Lib/csharp/csharp.swg
@@ -399,7 +399,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(out) SWIGTYPE
#ifdef __cplusplus
-%{ $result = new $1_ltype((const $1_ltype &)$1); %}
+%{ $result = new $1_ltype($1); %}
#else
{
$&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
@@ -409,7 +409,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
#endif
%typemap(directorin) SWIGTYPE
-%{ $input = (void *)new $1_ltype((const $1_ltype &)$1); %}
+%{ $input = (void *)new $1_ltype(SWIG_STD_MOVE($1)); %}
%typemap(csdirectorin) SWIGTYPE "new $&csclassname($iminput, true)"
%typemap(csdirectorout) SWIGTYPE "$&csclassname.getCPtr($cscall).Handle"
@@ -420,14 +420,15 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%}
%typemap(in, canthrow=1) SWIGTYPE & %{ $1 = ($1_ltype)$input;
if (!$1) {
- SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0);
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type is null", 0);
return $null;
} %}
-%typemap(in, canthrow=1) SWIGTYPE && %{ $1 = ($1_ltype)$input;
+%typemap(in, canthrow=1, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = ($1_ltype)$input;
if (!$1) {
- SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0);
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type is null", 0);
return $null;
- } %}
+ }
+ rvrdeleter.reset($1); %}
%typemap(out) SWIGTYPE * %{ $result = (void *)$1; %}
%typemap(out, fragment="SWIG_PackData") SWIGTYPE (CLASS::*) %{
char buf[128];
@@ -613,7 +614,8 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
"$csinput"
%typemap(csin) char *, char *&, char[ANY], char[] "$csinput"
%typemap(csin) SWIGTYPE "$&csclassname.getCPtr($csinput)"
-%typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "$csclassname.getCPtr($csinput)"
+%typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$csclassname.getCPtr($csinput)"
+%typemap(csin) SWIGTYPE && "$csclassname.swigRelease($csinput)"
%typemap(csin) SWIGTYPE (CLASS::*) "$csclassname.getCMemberPtr($csinput)"
/* The csout typemap is used for converting function return types from the return type
@@ -913,6 +915,19 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef getCPtr($csclassname obj) {
return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
}
+
+ CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef swigRelease($csclassname obj) {
+ if (obj != null) {
+ if (!obj.swigCMemOwn)
+ throw new global::System.ApplicationException("Cannot release ownership as memory is not owned");
+ global::System.Runtime.InteropServices.HandleRef ptr = obj.swigCPtr;
+ obj.swigCMemOwn = false;
+ obj.Dispose();
+ return ptr;
+ } else {
+ return new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
+ }
+ }
%}
// Derived proxy classes
@@ -926,6 +941,19 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef getCPtr($csclassname obj) {
return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
}
+
+ CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef swigRelease($csclassname obj) {
+ if (obj != null) {
+ if (!obj.swigCMemOwn)
+ throw new global::System.ApplicationException("Cannot release ownership as memory is not owned");
+ global::System.Runtime.InteropServices.HandleRef ptr = obj.swigCPtr;
+ obj.swigCMemOwn = false;
+ obj.Dispose();
+ return ptr;
+ } else {
+ return new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
+ }
+ }
%}
%enddef
@@ -945,6 +973,10 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef getCPtr($csclassname obj) {
return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
}
+
+ CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef swigRelease($csclassname obj) {
+ return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
+ }
%}
%typemap(csbody) TYPE (CLASS::*) %{
diff --git a/Lib/csharp/csharphead.swg b/Lib/csharp/csharphead.swg
index 7db4c0e3c..56a019bd5 100644
--- a/Lib/csharp/csharphead.swg
+++ b/Lib/csharp/csharphead.swg
@@ -335,5 +335,5 @@ SWIGEXPORT void SWIGSTDCALL SWIGRegisterStringCallback_$module(SWIG_CSharpString
%insert(runtime) %{
/* Contract support */
-#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, msg, ""); return nullreturn; } else
+#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, msg, ""); return nullreturn; } } while (0)
%}
diff --git a/Lib/csharp/csharpkw.swg b/Lib/csharp/csharpkw.swg
index 824f61874..1904fce94 100644
--- a/Lib/csharp/csharpkw.swg
+++ b/Lib/csharp/csharpkw.swg
@@ -2,9 +2,9 @@
#define CSHARP_CSHARPKW_SWG_
/* Warnings for C# keywords */
-#define CSHARPKW(x) %keywordwarn("'" `x` "' is a C# keyword, renaming to '" `x` "_'",rename="%s_") `x`
+#define CSHARPKW(x) %keywordwarn("'" `x` "' is a C# keyword",rename="%s_") `x`
-#define CSHARPCLASSKW(x) %keywordwarn("'" `x` "' is a special method name used in the C# wrapper classes, class renamed to '" `x` "_'",%$isclass,rename="%s_") `x`
+#define CSHARPCLASSKW(x) %keywordwarn("'" `x` "' is a special method name used in the C# wrapper classes",%$isclass,rename="%s_") `x`
/*
from
diff --git a/Lib/csharp/std_array.i b/Lib/csharp/std_array.i
index a4f0f9640..6e7fe9eb4 100644
--- a/Lib/csharp/std_array.i
+++ b/Lib/csharp/std_array.i
@@ -16,7 +16,7 @@
%define SWIG_STD_ARRAY_INTERNAL(T, N)
-%typemap(csinterfaces) std::array< T, N > "global::System.IDisposable, global::System.Collections.IEnumerable\n , global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>\n";
+%typemap(csinterfaces) std::array< T, N > "global::System.IDisposable, global::System.Collections.IEnumerable\n , global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>\n"
%proxycode %{
public $csclassname(global::System.Collections.ICollection c) : this() {
if (c == null)
diff --git a/Lib/csharp/std_auto_ptr.i b/Lib/csharp/std_auto_ptr.i
index 1d91c9872..da15df3e9 100644
--- a/Lib/csharp/std_auto_ptr.i
+++ b/Lib/csharp/std_auto_ptr.i
@@ -1,25 +1,38 @@
-/*
- The typemaps here allow handling functions returning std::auto_ptr<>,
- which is the most common use of this type. If you have functions taking it
- as parameter, these typemaps can't be used for them and you need to do
- something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
%define %auto_ptr(TYPE)
-%typemap (ctype) std::auto_ptr<TYPE > "void *"
-%typemap (imtype, out="System.IntPtr") std::auto_ptr<TYPE > "HandleRef"
-%typemap (cstype) std::auto_ptr<TYPE > "$typemap(cstype, TYPE)"
-%typemap (out) std::auto_ptr<TYPE > %{
- $result = (void *)$1.release();
+%typemap (ctype) std::auto_ptr< TYPE > "void *"
+%typemap (imtype, out="System.IntPtr") std::auto_ptr< TYPE > "global::System.Runtime.InteropServices.HandleRef"
+%typemap (cstype) std::auto_ptr< TYPE > "$typemap(cstype, TYPE)"
+
+%typemap(in) std::auto_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(csin) std::auto_ptr< TYPE > "$typemap(cstype, TYPE).swigRelease($csinput)"
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ $result = (void *)$1.release();
%}
-%typemap(csout, excode=SWIGEXCODE) std::auto_ptr<TYPE > {
- System.IntPtr cPtr = $imcall;
- $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
- return ret;
- }
-%template() std::auto_ptr<TYPE >;
+
+%typemap(csout, excode=SWIGEXCODE) std::auto_ptr< TYPE > {
+ System.IntPtr cPtr = $imcall;
+ $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
+ return ret;
+ }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::auto_ptr< TYPE > ""
+
+%template() std::auto_ptr< TYPE >;
%enddef
namespace std {
- template <class T> class auto_ptr {};
-}
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/csharp/std_list.i b/Lib/csharp/std_list.i
index 674aba0ab..cf6f20238 100644
--- a/Lib/csharp/std_list.i
+++ b/Lib/csharp/std_list.i
@@ -19,7 +19,7 @@
// MACRO for use within the std::list class body
%define SWIG_STD_LIST_MINIMUM_INTERNAL(CSINTERFACE, CTYPE...)
-%typemap(csinterfaces) std::list< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n";
+%typemap(csinterfaces) std::list< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n"
%apply void *VOID_INT_PTR { std::list< CTYPE >::iterator * };
diff --git a/Lib/csharp/std_map.i b/Lib/csharp/std_map.i
index e538a03a1..7a118569a 100644
--- a/Lib/csharp/std_map.i
+++ b/Lib/csharp/std_map.i
@@ -26,7 +26,7 @@
/* K is the C++ key type, T is the C++ value type */
%define SWIG_STD_MAP_INTERNAL(K, T, C)
-%typemap(csinterfaces) std::map< K, T, C > "global::System.IDisposable \n , global::System.Collections.Generic.IDictionary<$typemap(cstype, K), $typemap(cstype, T)>\n";
+%typemap(csinterfaces) std::map< K, T, C > "global::System.IDisposable \n , global::System.Collections.Generic.IDictionary<$typemap(cstype, K), $typemap(cstype, T)>\n"
%proxycode %{
public $typemap(cstype, T) this[$typemap(cstype, K) key] {
diff --git a/Lib/csharp/std_set.i b/Lib/csharp/std_set.i
index 82f010aff..012152260 100644
--- a/Lib/csharp/std_set.i
+++ b/Lib/csharp/std_set.i
@@ -28,7 +28,7 @@ namespace std {
template <class T>
class set {
-%typemap(csinterfaces) std::set<T> "global::System.IDisposable, global::System.Collections.Generic.ISet<$typemap(cstype, T)>\n";
+%typemap(csinterfaces) std::set<T> "global::System.IDisposable, global::System.Collections.Generic.ISet<$typemap(cstype, T)>\n"
%proxycode %{
void global::System.Collections.Generic.ICollection<$typemap(cstype, T)>.Add($typemap(cstype, T) item) {
((global::System.Collections.Generic.ISet<$typemap(cstype, T)>)this).Add(item);
diff --git a/Lib/csharp/std_string.i b/Lib/csharp/std_string.i
index 5f8fa44cb..c8920c09e 100644
--- a/Lib/csharp/std_string.i
+++ b/Lib/csharp/std_string.i
@@ -20,7 +20,7 @@ namespace std {
class string;
// string
-%typemap(ctype) string "char *"
+%typemap(ctype) string "const char *"
%typemap(imtype) string "string"
%typemap(cstype) string "string"
@@ -42,7 +42,7 @@ class string;
}
$result.assign($input); %}
-%typemap(directorin) string %{ $input = SWIG_csharp_string_callback($1.c_str()); %}
+%typemap(directorin) string %{ $input = $1.c_str(); %}
%typemap(csin) string "$csinput"
%typemap(csout, excode=SWIGEXCODE) string {
@@ -57,7 +57,7 @@ class string;
return $null; %}
// const string &
-%typemap(ctype) const string & "char *"
+%typemap(ctype) const string & "const char *"
%typemap(imtype) const string & "string"
%typemap(cstype) const string & "string"
@@ -89,7 +89,7 @@ class string;
$1_str = $input;
$result = &$1_str; %}
-%typemap(directorin) const string & %{ $input = SWIG_csharp_string_callback($1.c_str()); %}
+%typemap(directorin) const string & %{ $input = $1.c_str(); %}
%typemap(csvarin, excode=SWIGEXCODE2) const string & %{
set {
diff --git a/Lib/csharp/std_unique_ptr.i b/Lib/csharp/std_unique_ptr.i
new file mode 100644
index 000000000..0a4caafbc
--- /dev/null
+++ b/Lib/csharp/std_unique_ptr.i
@@ -0,0 +1,38 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap (ctype) std::unique_ptr< TYPE > "void *"
+%typemap (imtype, out="System.IntPtr") std::unique_ptr< TYPE > "global::System.Runtime.InteropServices.HandleRef"
+%typemap (cstype) std::unique_ptr< TYPE > "$typemap(cstype, TYPE)"
+
+%typemap(in) std::unique_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(csin) std::unique_ptr< TYPE > "$typemap(cstype, TYPE).swigRelease($csinput)"
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ $result = (void *)$1.release();
+%}
+
+%typemap(csout, excode=SWIGEXCODE) std::unique_ptr< TYPE > {
+ System.IntPtr cPtr = $imcall;
+ $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
+ return ret;
+ }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::unique_ptr< TYPE > ""
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/csharp/std_vector.i b/Lib/csharp/std_vector.i
index e2811290c..a2add584d 100644
--- a/Lib/csharp/std_vector.i
+++ b/Lib/csharp/std_vector.i
@@ -19,7 +19,7 @@
// MACRO for use within the std::vector class body
%define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CSINTERFACE, CONST_REFERENCE, CTYPE...)
-%typemap(csinterfaces) std::vector< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n";
+%typemap(csinterfaces) std::vector< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n"
%proxycode %{
public $csclassname(global::System.Collections.IEnumerable c) : this() {
if (c == null)
@@ -63,7 +63,7 @@
return (int)capacity();
}
set {
- if (value < size())
+ if (value < 0 || ($typemap(cstype, size_t))value < size())
throw new global::System.ArgumentOutOfRangeException("Capacity");
reserve(($typemap(cstype, size_t))value);
}
diff --git a/Lib/csharp/std_wstring.i b/Lib/csharp/std_wstring.i
index 162b90e80..1d10ca808 100644
--- a/Lib/csharp/std_wstring.i
+++ b/Lib/csharp/std_wstring.i
@@ -2,7 +2,9 @@
* std_wstring.i
*
* Typemaps for std::wstring and const std::wstring&
- * These are mapped to a C# String and are passed around by value.
+ * std::wstring is mapped to a C# Unicode string (UTF16) and is passed around by value.
+ * std::wstring support includes wchar_t as a 2 byte type (Windows) and a 4 byte type
+ * (most Unix systems).
*
* To use non-const std::wstring references use the following %apply. Note
* that they are passed by value.
@@ -15,6 +17,28 @@
#include <string>
%}
+%fragment("Swig_csharp_UTF16ToWString", "header") %{
+/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */
+static std::wstring Swig_csharp_UTF16ToWString(const unsigned short *str) {
+ if (sizeof(wchar_t) == 2) {
+ return std::wstring((wchar_t *)str);
+ } else {
+ const unsigned short *pBegin(str);
+ const unsigned short *ptr(pBegin);
+
+ while (*ptr != 0)
+ ++ptr;
+
+ std::wstring result;
+ result.reserve(ptr - pBegin);
+ while(pBegin != ptr)
+ result.push_back(*pBegin++);
+
+ return result;
+ }
+}
+%}
+
namespace std {
%naturalvar wstring;
@@ -22,31 +46,33 @@ namespace std {
class wstring;
// wstring
-%typemap(ctype, out="void *") wstring "wchar_t *"
+%typemap(ctype, out="void *") wstring "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
- outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
) wstring "string"
%typemap(cstype) wstring "string"
%typemap(csdirectorin) wstring "$iminput"
%typemap(csdirectorout) wstring "$cscall"
-%typemap(in, canthrow=1) wstring
+%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") wstring
%{ if (!$input) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
- $1.assign($input); %}
-%typemap(out) wstring %{ $result = SWIG_csharp_wstring_callback($1.c_str()); %}
+ $1 = Swig_csharp_UTF16ToWString($input); %}
+%typemap(out) wstring %{ $result = SWIG_csharp_wstring_with_length_callback($1.c_str(), (int)$1.size()); %}
-%typemap(directorout, canthrow=1) wstring
+%typemap(directorout, canthrow=1) wstring
%{ if (!$input) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
- $result.assign($input); %}
+ $result = Swig_csharp_UTF16ToWString($input); %}
-%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %}
+%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_with_length_callback($1.c_str(), (int)$1.size()); %}
%typemap(csin) wstring "$csinput"
%typemap(csout, excode=SWIGEXCODE) wstring {
@@ -57,29 +83,30 @@ class wstring;
%typemap(typecheck) wstring = wchar_t *;
%typemap(throws, canthrow=1) wstring
-%{ std::string message($1.begin(), $1.end());
- SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str());
+%{ SWIG_csharp_ApplicationException_callback($1.c_str(), (int)$1.size());
return $null; %}
// const wstring &
-%typemap(ctype, out="void *") const wstring & "wchar_t *"
+%typemap(ctype, out="void *") const wstring & "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
- outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
) const wstring & "string"
%typemap(cstype) const wstring & "string"
%typemap(csdirectorin) const wstring & "$iminput"
%typemap(csdirectorout) const wstring & "$cscall"
-%typemap(in, canthrow=1) const wstring &
+%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") const wstring &
%{ if (!$input) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
- std::wstring $1_str($input);
+ std::wstring $1_str(Swig_csharp_UTF16ToWString($input));
$1 = &$1_str; %}
-%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_callback($1->c_str()); %}
+%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_with_length_callback($1->c_str(), (int)$1->size()); %}
%typemap(csin) const wstring & "$csinput"
%typemap(csout, excode=SWIGEXCODE) const wstring & {
@@ -94,10 +121,10 @@ class wstring;
}
/* possible thread/reentrant code problem */
static std::wstring $1_str;
- $1_str = $input;
+ $1_str = Swig_csharp_UTF16ToWString($input);
$result = &$1_str; %}
-%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %}
+%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_with_length_callback($1.c_str(), (int)$1.size()); %}
%typemap(csvarin, excode=SWIGEXCODE2) const wstring & %{
set {
@@ -112,8 +139,7 @@ class wstring;
%typemap(typecheck) const wstring & = wchar_t *;
%typemap(throws, canthrow=1) const wstring &
-%{ std::string message($1.begin(), $1.end());
- SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str());
+%{ SWIG_csharp_ApplicationException_callback($1.c_str(), (int)$1.size());
return $null; %}
}
diff --git a/Lib/csharp/swigmove.i b/Lib/csharp/swigmove.i
new file mode 100644
index 000000000..2f21bd6f7
--- /dev/null
+++ b/Lib/csharp/swigmove.i
@@ -0,0 +1,16 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, canthrow=1, fragment="<memory>") SWIGTYPE MOVE ($&1_type argp)
+%{ argp = ($&1_ltype)$input;
+ if (!argp) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null $1_type", 0);
+ return $null;
+ }
+ SwigValueWrapper< $1_ltype >::reset($1, argp); %}
+
+%typemap(csin) SWIGTYPE MOVE "$&csclassname.swigRelease($csinput)"
diff --git a/Lib/csharp/wchar.i b/Lib/csharp/wchar.i
index 1ece767da..f1e0d5a26 100644
--- a/Lib/csharp/wchar.i
+++ b/Lib/csharp/wchar.i
@@ -2,37 +2,58 @@
* wchar.i
*
* Typemaps for the wchar_t type
- * These are mapped to a C# String and are passed around by value.
+ * wchar_t * is mapped to a C# Unicode string (UTF16) and is passed around by value.
+ * wchar_t * support includes wchar_t as a 2 byte type (Windows) and a 4 byte type
+ * (most Unix systems).
*
* Support code for wide strings can be turned off by defining SWIG_CSHARP_NO_WSTRING_HELPER
- *
* ----------------------------------------------------------------------------- */
#if !defined(SWIG_CSHARP_NO_WSTRING_HELPER)
#if !defined(SWIG_CSHARP_WSTRING_HELPER_)
#define SWIG_CSHARP_WSTRING_HELPER_
+
+%fragment("<wchar.h>"); // TODO: %fragment("<wchar.h", "runtime");
+
%insert(runtime) %{
/* Callback for returning strings to C# without leaking memory */
-typedef void * (SWIGSTDCALL* SWIG_CSharpWStringHelperCallback)(const wchar_t *);
-static SWIG_CSharpWStringHelperCallback SWIG_csharp_wstring_callback = NULL;
+typedef void * (SWIGSTDCALL* SWIG_CSharpWStringHelperCallback)(const wchar_t *, int length);
+static SWIG_CSharpWStringHelperCallback SWIG_csharp_wstring_with_length_callback = NULL;
+%}
+
+%insert(header) %{
+static void * SWIG_csharp_wstring_callback(const wchar_t *s) {
+ return SWIG_csharp_wstring_with_length_callback(s, (int)wcslen(s));
+}
%}
+
%pragma(csharp) imclasscode=%{
protected class SWIGWStringHelper {
[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]
- public delegate string SWIGWStringDelegate(global::System.IntPtr message);
- static SWIGWStringDelegate wstringDelegate = new SWIGWStringDelegate(CreateWString);
+ public delegate string SWIGWStringDelegate(global::System.IntPtr message, int length);
+ static SWIGWStringDelegate wstringUTF16Delegate = new SWIGWStringDelegate(CreateWStringFromUTF16);
+ static SWIGWStringDelegate wstringUTF32Delegate = new SWIGWStringDelegate(CreateWStringFromUTF32);
[global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="SWIGRegisterWStringCallback_$module")]
- public static extern void SWIGRegisterWStringCallback_$module(SWIGWStringDelegate wstringDelegate);
+ public static extern void SWIGRegisterWStringCallback_$module(SWIGWStringDelegate wstringUTF16Delegate, SWIGWStringDelegate wstringUTF32Delegate);
- static string CreateWString([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString) {
- return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString);
+ public static string CreateWStringFromUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString, length);
+ }
+
+ public static string CreateWStringFromUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ if (length == 0)
+ return string.Empty;
+
+ byte[] buffer = new byte[length * 4];
+ global::System.Runtime.InteropServices.Marshal.Copy(cString, buffer, 0, buffer.Length);
+ return global::System.Text.Encoding.UTF32.GetString(buffer);
}
static SWIGWStringHelper() {
- SWIGRegisterWStringCallback_$module(wstringDelegate);
+ SWIGRegisterWStringCallback_$module(wstringUTF16Delegate, wstringUTF32Delegate);
}
}
@@ -43,13 +64,76 @@ static SWIG_CSharpWStringHelperCallback SWIG_csharp_wstring_callback = NULL;
#ifdef __cplusplus
extern "C"
#endif
-SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStringHelperCallback callback) {
- SWIG_csharp_wstring_callback = callback;
+SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStringHelperCallback callback_utf16, SWIG_CSharpWStringHelperCallback callback_utf32) {
+ SWIG_csharp_wstring_with_length_callback = sizeof(wchar_t) == 2 ? callback_utf16 : callback_utf32;
}
%}
#endif // SWIG_CSHARP_WSTRING_HELPER_
#endif // SWIG_CSHARP_NO_WSTRING_HELPER
+#if !defined(SWIG_CSHARP_NO_WSTRING_EXCEPTION_HELPER)
+#if !defined(SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_)
+#define SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_
+
+%insert(runtime) %{
+/* Callback for returning strings to C# without leaking memory */
+typedef void (SWIGSTDCALL* SWIG_CSharpWStringExceptionHelperCallback)(const wchar_t *, int length);
+static SWIG_CSharpWStringExceptionHelperCallback SWIG_csharp_ApplicationException_callback = NULL;
+%}
+
+%pragma(csharp) imclasscode=%{
+ protected class SWIGWStringExceptionHelper {
+
+ [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]
+ public delegate void SWIGWStringExceptionDelegate(global::System.IntPtr message, int length);
+ static SWIGWStringExceptionDelegate applicationExceptionUTF16Delegate = new SWIGWStringExceptionDelegate(SetPendingApplicationExceptionUTF16);
+ static SWIGWStringExceptionDelegate applicationExceptionUTF32Delegate = new SWIGWStringExceptionDelegate(SetPendingApplicationExceptionUTF32);
+
+ [global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="SWIGRegisterWStringExceptionCallback_$module")]
+ public static extern void SWIGRegisterWStringExceptionCallback_$module(SWIGWStringExceptionDelegate applicationExceptionUTF16Delegate, SWIGWStringExceptionDelegate applicationExceptionUTF32Delegate);
+
+ static string CreateWStringFromUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString, length);
+ }
+
+ public static string CreateWStringFromUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ if (length == 0)
+ return string.Empty;
+
+ byte[] buffer = new byte[length * 4];
+ return global::System.Text.Encoding.UTF32.GetString(buffer);
+ }
+
+ static void SetPendingApplicationExceptionUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ string message = SWIGWStringHelper.CreateWStringFromUTF16(cString, length);
+ SWIGPendingException.Set(new global::System.ApplicationException(message, SWIGPendingException.Retrieve()));
+ }
+
+ static void SetPendingApplicationExceptionUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ string message = SWIGWStringHelper.CreateWStringFromUTF32(cString, length);
+ SWIGPendingException.Set(new global::System.ApplicationException(message, SWIGPendingException.Retrieve()));
+ }
+
+ static SWIGWStringExceptionHelper() {
+ SWIGRegisterWStringExceptionCallback_$module(applicationExceptionUTF16Delegate, applicationExceptionUTF32Delegate);
+ }
+ }
+
+ static protected SWIGWStringExceptionHelper swigWStringExceptionHelper = new SWIGWStringExceptionHelper();
+%}
+
+%insert(runtime) %{
+#ifdef __cplusplus
+extern "C"
+#endif
+SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringExceptionCallback_$module(SWIG_CSharpWStringExceptionHelperCallback callback_utf16, SWIG_CSharpWStringExceptionHelperCallback callback_utf32) {
+ SWIG_csharp_ApplicationException_callback = sizeof(wchar_t) == 2 ? callback_utf16 : callback_utf32;
+}
+%}
+
+#endif // SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_
+#endif // SWIG_CSHARP_NO_WSTRING_EXCEPTION_HELPER
+
// wchar_t
%typemap(ctype) wchar_t "wchar_t"
@@ -77,13 +161,64 @@ SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStri
%typemap(typecheck) wchar_t = char;
// wchar_t *
-%typemap(ctype) wchar_t * "wchar_t *"
-%typemap(imtype, inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]", out="global::System.IntPtr" ) wchar_t * "string"
+
+%fragment("Swig_csharp_UTF16ToWCharPtr", "header") %{
+/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */
+static wchar_t * Swig_csharp_UTF16ToWCharPtr(const unsigned short *str) {
+ if (sizeof(wchar_t) == 2) {
+ return (wchar_t *)str;
+ } else {
+ wchar_t *result = 0;
+
+ if (str) {
+ const unsigned short *pBegin(str);
+ const unsigned short *pEnd(pBegin);
+ wchar_t *ptr = 0;
+
+ while (*pEnd != 0)
+ ++pEnd;
+
+#ifdef __cplusplus
+ result = ptr = new wchar_t[pEnd - pBegin + 1];
+#else
+ result = ptr = (wchar_t *)malloc(sizeof(wchar_t) * (pEnd - pBegin + 1));
+#endif
+ while(pBegin != pEnd)
+ *ptr++ = *pBegin++;
+ *ptr++ = 0;
+ }
+
+ return result;
+ }
+}
+%}
+
+%fragment("Swig_csharp_UTF16ToWCharPtrFree", "header") %{
+static void Swig_csharp_UTF16ToWCharPtrFree(wchar_t *str) {
+ if (sizeof(wchar_t) != 2) {
+#ifdef __cplusplus
+ delete [] str;
+#else
+ free(str);
+#endif
+ }
+}
+%}
+
+%typemap(ctype, out="void *") wchar_t * "unsigned short *"
+%typemap(imtype,
+ inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ ) wchar_t * "string"
%typemap(cstype) wchar_t * "string"
+%typemap(csdirectorin) wchar_t * "$iminput"
+%typemap(csdirectorout) wchar_t * "$cscall"
%typemap(csin) wchar_t * "$csinput"
%typemap(csout, excode=SWIGEXCODE) wchar_t * {
- string ret = global::System.Runtime.InteropServices.Marshal.PtrToStringUni($imcall);$excode
+ string ret = $imcall;$excode
return ret;
}
%typemap(csvarin, excode=SWIGEXCODE2) wchar_t * %{
@@ -92,12 +227,109 @@ SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStri
} %}
%typemap(csvarout, excode=SWIGEXCODE2) wchar_t * %{
get {
- string ret = global::System.Runtime.InteropServices.Marshal.PtrToStringUni($imcall);$excode
+ string ret = $imcall;$excode
return ret;
} %}
-%typemap(in) wchar_t * %{ $1 = ($1_ltype)$input; %}
-%typemap(out) wchar_t * %{ $result = (wchar_t *)$1; %}
+%typemap(in, fragment="Swig_csharp_UTF16ToWCharPtr") wchar_t *
+%{ $1 = Swig_csharp_UTF16ToWCharPtr($input); %}
+
+%typemap(out) wchar_t * %{ $result = $1 ? SWIG_csharp_wstring_callback($1) : 0; %}
+
+%typemap(freearg, fragment="Swig_csharp_UTF16ToWCharPtrFree") wchar_t *
+%{ Swig_csharp_UTF16ToWCharPtrFree($1); %}
+
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) wchar_t *
+%{ $result = Swig_csharp_UTF16ToWCharPtr($input); %}
+
+%typemap(directorin) wchar_t * %{ $input = SWIG_csharp_wstring_with_length_callback($1, (int)wcslen($1)); %}
%typemap(typecheck) wchar_t * = char *;
+%typemap(throws, canthrow=1, fragment="<wchar.h>") wchar_t *
+%{ SWIG_csharp_ApplicationException_callback($1, (int)wcslen($1));
+ return $null; %}
+
+
+/* Default typemap for handling wchar_t * members (based on char * in swig.swg) */
+
+#ifdef __cplusplus
+%typemap(memberin,fragment="<wchar.h>") wchar_t * {
+ delete [] $1;
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,fragment="<wchar.h>") wchar_t * {
+ delete [] $1;
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+#else
+%typemap(memberin,fragment="<wchar.h>") wchar_t * {
+ free($1);
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,fragment="<wchar.h>") wchar_t * {
+ free($1);
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+
+#endif
diff --git a/Lib/d/boost_shared_ptr.i b/Lib/d/boost_shared_ptr.i
index 4a220a589..6d85c5aef 100644
--- a/Lib/d/boost_shared_ptr.i
+++ b/Lib/d/boost_shared_ptr.i
@@ -23,10 +23,10 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
%typemap(directorin) CONST TYPE
-%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
%typemap(directorout) CONST TYPE
%{ if (!$input) {
@@ -116,7 +116,7 @@
%typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
%{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
%typemap(out, fragment="SWIG_null_deleter") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
-%{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
+%{ $result = ($1 && *$1) ? new $*1_ltype(*$1) : 0;
if ($owner) delete $1; %}
%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
diff --git a/Lib/d/cpointer.i b/Lib/d/cpointer.i
index 75e610f67..da3084b7a 100644
--- a/Lib/d/cpointer.i
+++ b/Lib/d/cpointer.i
@@ -54,14 +54,14 @@ NAME() {
return new TYPE();
}
~NAME() {
- if (self) delete self;
+ delete self;
}
#else
NAME() {
return (TYPE *) calloc(1,sizeof(TYPE));
}
~NAME() {
- if (self) free(self);
+ free(self);
}
#endif
}
@@ -133,9 +133,9 @@ static TYPE *copy_##NAME(TYPE value) { %}
static void delete_##NAME(TYPE *self) { %}
#ifdef __cplusplus
-%{ if (self) delete self; %}
+%{ delete self; %}
#else
-%{ if (self) free(self); %}
+%{ free(self); %}
#endif
%{}
diff --git a/Lib/d/dclassgen.swg b/Lib/d/dclassgen.swg
index 84fa03a0b..e4ff8d5f5 100644
--- a/Lib/d/dclassgen.swg
+++ b/Lib/d/dclassgen.swg
@@ -76,6 +76,19 @@ public static void* swigGetCPtr(typeof(this) obj) {
return (obj is null) ? null : obj.swigCPtr;
}
+public static void* swigRelease(typeof(this) obj) {
+ if (obj !is null) {
+ if (!obj.swigCMemOwn)
+ throw new Exception("Cannot release ownership as memory is not owned");
+ void* ptr = obj.swigCPtr;
+ obj.swigCMemOwn = false;
+ obj.dispose();
+ return ptr;
+ } else {
+ return null;
+ }
+}
+
mixin $imdmodule.SwigOperatorDefinitions;
%}
@@ -92,6 +105,19 @@ public static void* swigGetCPtr(typeof(this) obj) {
return (obj is null) ? null : obj.swigCPtr;
}
+public static void* swigRelease(typeof(this) obj) {
+ if (obj !is null) {
+ if (!obj.swigCMemOwn)
+ throw new Exception("Cannot release ownership as memory is not owned");
+ void* ptr = obj.swigCPtr;
+ obj.swigCMemOwn = false;
+ obj.dispose();
+ return ptr;
+ } else {
+ return null;
+ }
+}
+
mixin $imdmodule.SwigOperatorDefinitions;
%}
@@ -100,7 +126,7 @@ mixin $imdmodule.SwigOperatorDefinitions;
* Type wrapper classes.
*/
-%typemap(dbody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{
+%typemap(dbody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] %{
private void* swigCPtr;
public this(void* cObject, bool futureUse) {
@@ -115,6 +141,10 @@ public static void* swigGetCPtr(typeof(this) obj) {
return (obj is null) ? null : obj.swigCPtr;
}
+public static void* swigRelease(typeof(this) obj) {
+ return (obj is null) ? null : obj.swigCPtr;
+}
+
mixin $imdmodule.SwigOperatorDefinitions;
%}
diff --git a/Lib/d/dhead.swg b/Lib/d/dhead.swg
index 50e9c2e87..1ef1e4164 100644
--- a/Lib/d/dhead.swg
+++ b/Lib/d/dhead.swg
@@ -12,7 +12,7 @@
#include <stdio.h>
/* Contract support. */
-#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_DSetPendingException(SWIG_DException, msg); return nullreturn; } else
+#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_DSetPendingException(SWIG_DException, msg); return nullreturn; } } while (0)
%}
diff --git a/Lib/d/dkw.swg b/Lib/d/dkw.swg
index 581093f96..2a189ed64 100644
--- a/Lib/d/dkw.swg
+++ b/Lib/d/dkw.swg
@@ -2,7 +2,7 @@
#define D_DKW_SWG_
/* Warnings for D keywords */
-#define DKEYWORD(x) %keywordwarn("'" `x` "' is a D keyword, renaming to '_" `x` "'",rename="_%s") `x`
+#define DKEYWORD(x) %keywordwarn("'" `x` "' is a D keyword",rename="_%s") `x`
// Source: http://www.digitalmars.com/d/{1.0,2.0}/lex.html and
DKEYWORD(Error);
diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg
index f0d604b6f..c227519e8 100644
--- a/Lib/d/dswigtype.swg
+++ b/Lib/d/dswigtype.swg
@@ -20,6 +20,10 @@
%typemap(imtype) SWIGTYPE & "void*"
%typemap(dtype, nativepointer="$dtype") SWIGTYPE & "$dclassname"
+%typemap(ctype) SWIGTYPE && "void *"
+%typemap(imtype) SWIGTYPE && "void*"
+%typemap(dtype, nativepointer="$dtype") SWIGTYPE && "$dclassname"
+
%typemap(ctype) SWIGTYPE *const& "void *"
%typemap(imtype) SWIGTYPE *const& "void*"
%typemap(dtype) SWIGTYPE *const& "$*dclassname"
@@ -28,6 +32,7 @@
SWIGTYPE,
SWIGTYPE *,
SWIGTYPE &,
+ SWIGTYPE &&,
SWIGTYPE [],
SWIGTYPE *const&
""
@@ -47,7 +52,7 @@
%typemap(out) SWIGTYPE
#ifdef __cplusplus
-%{ $result = new $1_ltype((const $1_ltype &)$1); %}
+%{ $result = new $1_ltype($1); %}
#else
{
$&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
@@ -57,7 +62,7 @@
#endif
%typemap(directorin) SWIGTYPE
- "$input = (void *)new $1_ltype((const $1_ltype &)$1);"
+ "$input = (void *)new $1_ltype(SWIG_STD_MOVE($1));"
%typemap(directorout) SWIGTYPE
%{ if (!$input) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Unexpected null return for type $1_type");
@@ -117,7 +122,7 @@
%typemap(in, canthrow=1) SWIGTYPE & %{ $1 = ($1_ltype)$input;
if (!$1) {
- SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type type is null");
+ SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type is null");
return $null;
} %}
%typemap(out) SWIGTYPE & "$result = (void *)$1;"
@@ -149,6 +154,44 @@
/*
+ * Rvalue reference conversion typemaps.
+ */
+
+%typemap(in, canthrow=1, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = ($1_ltype)$input;
+ if (!$1) {
+ SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type is null");
+ return $null;
+ }
+ rvrdeleter.reset($1); %}
+%typemap(out) SWIGTYPE && "$result = (void *)$1;"
+
+%typemap(directorin) SWIGTYPE &&
+ "$input = ($1_ltype) &$1;"
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE &&
+%{ if (!$input) {
+ SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Unexpected null return for type $1_type");
+ return $null;
+ }
+ $result = ($1_ltype)$input; %}
+
+%typemap(ddirectorin,
+ nativepointer="cast($dtype)$winput"
+) SWIGTYPE && "new $dclassname($winput, false)"
+%typemap(ddirectorout,
+ nativepointer="cast(void*)$dcall"
+) SWIGTYPE && "$dclassname.swigGetCPtr($dcall)"
+
+%typemap(din,
+ nativepointer="cast(void*)$dinput"
+) SWIGTYPE && "$dclassname.swigRelease($dinput)"
+%typemap(dout, excode=SWIGEXCODE,
+ nativepointer="{\n auto ret = cast($dtype)$imcall;$excode\n return ret;\n}") SWIGTYPE && {
+ $dclassname ret = new $dclassname($imcall, $owner);$excode
+ return ret;
+}
+
+
+/*
* Array conversion typemaps.
*/
@@ -164,6 +207,7 @@
// Treat references to arrays like references to a single element.
%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
+%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
/*
diff --git a/Lib/d/std_auto_ptr.i b/Lib/d/std_auto_ptr.i
new file mode 100644
index 000000000..500b6115a
--- /dev/null
+++ b/Lib/d/std_auto_ptr.i
@@ -0,0 +1,42 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap (ctype) std::auto_ptr< TYPE > "void *"
+%typemap (imtype) std::auto_ptr< TYPE > "void*"
+%typemap (dtype) std::auto_ptr< TYPE > "$typemap(dtype, TYPE)"
+
+%typemap(in) std::auto_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(din,
+ nativepointer="cast(void*)$dinput"
+) std::auto_ptr< TYPE > "$typemap(dtype, TYPE).swigRelease($dinput)"
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ $result = (void *)$1.release();
+%}
+
+%typemap(dout, excode=SWIGEXCODE,
+ nativepointer="{\n auto ret = cast($dtype)$imcall;$excode\n return ret;\n}"
+) std::auto_ptr< TYPE > {
+ void* cPtr = $imcall;
+ $typemap(dtype, TYPE) ret = (cPtr is null) ? null : new $typemap(dtype, TYPE)(cPtr, true);$excode
+ return ret;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::auto_ptr< TYPE > ""
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/d/std_unique_ptr.i b/Lib/d/std_unique_ptr.i
new file mode 100644
index 000000000..9317a7e0e
--- /dev/null
+++ b/Lib/d/std_unique_ptr.i
@@ -0,0 +1,42 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap (ctype) std::unique_ptr< TYPE > "void *"
+%typemap (imtype) std::unique_ptr< TYPE > "void*"
+%typemap (dtype) std::unique_ptr< TYPE > "$typemap(dtype, TYPE)"
+
+%typemap(in) std::unique_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(din,
+ nativepointer="cast(void*)$dinput"
+) std::unique_ptr< TYPE > "$typemap(dtype, TYPE).swigRelease($dinput)"
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ $result = (void *)$1.release();
+%}
+
+%typemap(dout, excode=SWIGEXCODE,
+ nativepointer="{\n auto ret = cast($dtype)$imcall;$excode\n return ret;\n}"
+) std::unique_ptr< TYPE > {
+ void* cPtr = $imcall;
+ $typemap(dtype, TYPE) ret = (cPtr is null) ? null : new $typemap(dtype, TYPE)(cPtr, true);$excode
+ return ret;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::unique_ptr< TYPE > ""
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/d/swigmove.i b/Lib/d/swigmove.i
new file mode 100644
index 000000000..e2eb83406
--- /dev/null
+++ b/Lib/d/swigmove.i
@@ -0,0 +1,16 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, canthrow=1) SWIGTYPE MOVE ($&1_type argp)
+%{ argp = ($&1_ltype)$input;
+ if (!argp) {
+ SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Attempt to dereference null $1_type");
+ return $null;
+ }
+ SwigValueWrapper< $1_ltype >::reset($1, argp); %}
+
+%typemap(din) SWIGTYPE MOVE "$dclassname.swigRelease($dinput)"
diff --git a/Lib/exception.i b/Lib/exception.i
index 7508b409b..5cdea58e8 100644
--- a/Lib/exception.i
+++ b/Lib/exception.i
@@ -14,14 +14,14 @@
#ifdef SWIGPHP
%{
-#if PHP_MAJOR >= 8
-# define SWIG_HANDLE_VALUE_ERROR_FOR_PHP8 code == SWIG_ValueError ? zend_ce_value_error :
+#if PHP_MAJOR_VERSION >= 8
+# define SWIG_HANDLE_VALUE_ERROR_FOR_PHP8(code) code == SWIG_ValueError ? zend_ce_value_error :
#else
-# define SWIG_HANDLE_VALUE_ERROR_FOR_PHP8
+# define SWIG_HANDLE_VALUE_ERROR_FOR_PHP8(code)
#endif
#define SWIG_exception(code, msg) do { zend_throw_exception( \
code == SWIG_TypeError ? zend_ce_type_error : \
- SWIG_HANDLE_VALUE_ERROR_FOR_PHP8 \
+ SWIG_HANDLE_VALUE_ERROR_FOR_PHP8(code) \
code == SWIG_DivisionByZero ? zend_ce_division_by_zero_error : \
code == SWIG_SyntaxError ? zend_ce_parse_error : \
code == SWIG_OverflowError ? zend_ce_arithmetic_error : \
diff --git a/Lib/go/go.swg b/Lib/go/go.swg
index c225ed9ad..348ae5f0d 100644
--- a/Lib/go/go.swg
+++ b/Lib/go/go.swg
@@ -388,8 +388,9 @@
%typemap(gotype) SWIGTYPE &&
%{$gotypename%}
-%typemap(in) SWIGTYPE &&
-%{ $1 = *($&1_ltype)&$input; %}
+%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter)
+%{ $1 = *($&1_ltype)&$input;
+rvrdeleter.reset($1); %}
%typemap(out) SWIGTYPE &&
%{ *($&1_ltype)&$result = $1; %}
@@ -453,9 +454,12 @@
%}
%typemap(freearg)
- char *, char *&, char[ANY], char[]
+ char *, char[ANY], char[]
%{ free($1); %}
+%typemap(freearg) char *&
+%{ free(temp$argnum); %}
+
%typemap(out,fragment="AllocateString")
char *, char *&, char[ANY], char[]
%{ $result = Swig_AllocateString((char*)$1, $1 ? strlen((char*)$1) : 0); %}
@@ -520,6 +524,44 @@
$2 = ($2_ltype)$input.n;
%}
+/* The int & type needs to convert to intgo. */
+
+%typemap(gotype) int & "*int"
+
+%typemap(in) int & (int e)
+%{
+ e = (int)*$input;
+ $1 = &e;
+%}
+
+%typemap(out) int &
+%{ $result = new intgo(*$1); %}
+
+%typemap(argout) int &
+%{ *$input = (intgo)e$argnum; %}
+
+%typemap(goout) int & ""
+
+%typemap(directorin) int & (intgo e)
+%{
+ e = (intgo)$1;
+ $input = &e;
+%}
+
+%typemap(godirectorin) int & ""
+
+%typemap(directorout) int &
+%{
+ $*1_ltype f = ($*1_ltype)*$input;
+ $result = ($1_ltype)&f;
+%}
+
+%typemap(directorargout) int &
+%{ $1 = (int)*$input; %}
+
+%typemap(argout) const int & ""
+%typemap(directorargout) const int & ""
+
/* Enums. We can't do the right thing for enums in typemap(gotype) so
we deliberately don't define them. The right thing would be to
capitalize the name. This is instead done in go.cxx. */
@@ -552,10 +594,7 @@
%typemap(godirectorin) enum SWIGTYPE & ""
%typemap(directorout) enum SWIGTYPE &
-%{
- $*1_ltype f = ($*1_ltype)*$input;
- $result = ($1_ltype)&f;
-%}
+%{ $result = $input; %}
/* Arbitrary type. This is a type passed by value in the C/C++ code.
We convert it to a pointer for the Go code. Note that all basic
@@ -587,7 +626,7 @@
%typemap(goout) SWIGTYPE ""
%typemap(directorin) SWIGTYPE
-%{ $input = new $1_ltype((const $1_ltype &)$1); %}
+%{ $input = new $1_ltype(SWIG_STD_MOVE($1)); %}
%typemap(godirectorin) SWIGTYPE ""
diff --git a/Lib/go/gokw.swg b/Lib/go/gokw.swg
index dd9f35aa3..354283002 100644
--- a/Lib/go/gokw.swg
+++ b/Lib/go/gokw.swg
@@ -1,6 +1,6 @@
/* Rename keywords. */
-#define GOKW(x) %keywordwarn("'" `x` "' is a Go keyword, renaming to 'X"`x`"'",rename="X%s") `x`
+#define GOKW(x) %keywordwarn("'" `x` "' is a Go keyword",rename="X%s") `x`
#define GOBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in Go") "::"`x`
GOKW(break);
diff --git a/Lib/go/goruntime.swg b/Lib/go/goruntime.swg
index c3401b1a8..7bf083bd3 100644
--- a/Lib/go/goruntime.swg
+++ b/Lib/go/goruntime.swg
@@ -24,6 +24,7 @@ static void* Swig_malloc(int c) {
%}
%insert(cgo_comment_typedefs) %{
+#include <stddef.h>
#include <stdint.h>
%}
@@ -149,6 +150,17 @@ type _swig_fnptr *byte
type _swig_memberptr *byte
%}
+/* Convert a Go interface value into a C++ pointer. */
+
+%insert(go_header) %{
+func getSwigcptr(v interface { Swigcptr() uintptr }) uintptr {
+ if v == nil {
+ return 0
+ }
+ return v.Swigcptr()
+}
+%}
+
/* For directors we need C++ to track a Go pointer. Since we can't
pass a Go pointer into C++, we use a map to track the pointers on
the Go side. */
diff --git a/Lib/go/std_array.i b/Lib/go/std_array.i
new file mode 100644
index 000000000..36c790e3c
--- /dev/null
+++ b/Lib/go/std_array.i
@@ -0,0 +1,43 @@
+/* -----------------------------------------------------------------------------
+ * std_array.i
+ * ----------------------------------------------------------------------------- */
+
+%include <std_common.i>
+
+namespace std {
+
+ template<class T, size_t N> class array {
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ array();
+ array(const array& other);
+
+ size_type size() const;
+ %rename(isEmpty) empty;
+ bool empty() const;
+ void fill(const T& u);
+ %extend {
+ const_reference get(int i) throw (std::out_of_range) {
+ int size = int(self->size());
+ if (i>=0 && i<size)
+ return (*self)[i];
+ else
+ throw std::out_of_range("array index out of range");
+ }
+ void set(int i, const value_type& val) throw (std::out_of_range) {
+ int size = int(self->size());
+ if (i>=0 && i<size)
+ (*self)[i] = val;
+ else
+ throw std::out_of_range("array index out of range");
+ }
+ }
+ };
+}
diff --git a/Lib/go/std_string.i b/Lib/go/std_string.i
index 099ae84d4..35b4a5e46 100644
--- a/Lib/go/std_string.i
+++ b/Lib/go/std_string.i
@@ -52,6 +52,9 @@ class string;
%typemap(godirectorin,fragment="CopyString") string
%{ $result = swigCopyString($input) %}
+%typemap(throws) string
+%{ _swig_gopanic($1.c_str()); %}
+
%typemap(in) const string &
%{
$*1_ltype $1_str($input.p, $input.n);
@@ -88,4 +91,72 @@ class string;
%typemap(godirectorin,fragment="CopyString") const string &
%{ $result = swigCopyString($input) %}
+%typemap(throws) const string &
+%{ _swig_gopanic($1.c_str()); %}
+
+
+%typemap(gotype) string * "*string"
+
+%typemap(in) string * (string temp)
+%{
+ if ($input) {
+ temp.assign($input->p, $input->n);
+ $1 = &temp;
+ } else
+ $1 = 0;
+%}
+
+%typemap(godirectorout) string *
+%{
+ if $input != nil {
+ p := Swig_malloc(len(*$input))
+ s := (*[1<<30]byte)(unsafe.Pointer(p))[:len(*$input)]
+ copy(s, *$input)
+ $result = (*string)(unsafe.Pointer(&s))
+ } else {
+ $result = nil
+ }
+%}
+
+%typemap(directorout) string * (string temp)
+%{
+ temp.assign($input->p, $input->n);
+ $result = &temp;
+ free($input.p);
+%}
+
+%typemap(out,fragment="AllocateString") string * (_gostring_ temp)
+%{
+ temp = Swig_AllocateString($1->data(), $1->length());
+ $result = &temp;
+%}
+
+%typemap(goout,fragment="CopyString") string *
+%{ *$result = swigCopyString(*$1) %}
+
+%typemap(directorin,fragment="AllocateString") string * (_gostring_ temp)
+%{
+ if ($1) {
+ temp = Swig_AllocateString($1->data(), $1->length());
+ $input = &temp;
+ } else
+ $input = 0;
+%}
+
+%typemap(godirectorin,fragment="CopyString") string *
+%{ *$result = swigCopyString(*$input); %}
+
+%typemap(argout,fragment="AllocateString") string *
+%{
+ if ($1)
+ *$input = Swig_AllocateString($1->data(), $1->length());
+%}
+
+%typemap(goargout,fragment="CopyString") string *
+%{
+ if $input != nil {
+ *$1 = swigCopyString(*$input)
+ }
+%}
+
}
diff --git a/Lib/go/swigmove.i b/Lib/go/swigmove.i
new file mode 100644
index 000000000..e1984b6ea
--- /dev/null
+++ b/Lib/go/swigmove.i
@@ -0,0 +1,15 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in) SWIGTYPE MOVE ($&1_type argp)
+%{
+ argp = ($&1_ltype)$input;
+ if (argp == NULL) {
+ _swig_gopanic("Attempt to dereference null $1_type");
+ }
+ SwigValueWrapper< $1_ltype >::reset($1, argp);
+%}
diff --git a/Lib/guile/guile_scm_run.swg b/Lib/guile/guile_scm_run.swg
index 86e5c3be0..689a1060f 100644
--- a/Lib/guile/guile_scm_run.swg
+++ b/Lib/guile/guile_scm_run.swg
@@ -2,6 +2,12 @@
* guile_scm_run.swg
* ----------------------------------------------------------------------------- */
+#if __GNUC__ >= 10
+#if defined(__cplusplus)
+#pragma GCC diagnostic ignored "-Wvolatile" /* For 'volatile SCM *' in at least Guile 3.0 and earlier */
+#endif
+#endif
+
#include <libguile.h>
#include <stdio.h>
#include <string.h>
@@ -65,10 +71,12 @@ typedef struct swig_guile_clientdata {
#define SWIG_IsPointer(object) \
SWIG_Guile_IsPointer(object)
#define SWIG_contract_assert(expr, msg) \
- if (!(expr)) \
- scm_error(scm_from_locale_symbol("swig-contract-assertion-failed"), \
- (char *) FUNC_NAME, (char *) msg, \
- SCM_EOL, SCM_BOOL_F); else
+ do { \
+ if (!(expr)) \
+ scm_error(scm_from_locale_symbol("swig-contract-assertion-failed"), \
+ (char *) FUNC_NAME, (char *) msg, \
+ SCM_EOL, SCM_BOOL_F); \
+ } while (0)
/* for C++ member pointers, ie, member methods */
#define SWIG_ConvertMember(obj, ptr, sz, ty) \
@@ -110,6 +118,8 @@ static SCM swig_symbol = SCM_EOL;
( !scm_is_null(x) && SCM_INSTANCEP(x) && scm_is_true(scm_slot_exists_p(x, swig_symbol)) \
? scm_slot_ref(x, swig_symbol) : (x) )
+SWIGINTERN void SWIG_Guile_MarkPointerNoncollectable(SCM s);
+
SWIGINTERN SCM
SWIG_Guile_NewPointerObj(void *ptr, swig_type_info *type, int owner)
{
@@ -123,7 +133,7 @@ SWIG_Guile_NewPointerObj(void *ptr, swig_type_info *type, int owner)
else
SCM_NEWSMOB2(smob, swig_tag, ptr, (void *) type);
- if (!cdata || SCM_NULLP(cdata->goops_class) || swig_make_func == SCM_EOL ) {
+ if (!cdata || scm_is_null(cdata->goops_class) || swig_make_func == SCM_EOL ) {
return smob;
} else {
/* the scm_make() C function only handles the creation of gf,
@@ -143,7 +153,7 @@ SWIGINTERN unsigned long
SWIG_Guile_PointerAddress(SCM object)
{
SCM smob = SWIG_Guile_GetSmob(object);
- if (SCM_NULLP(smob)) return 0;
+ if (scm_is_null(smob)) return 0;
else if (SCM_SMOB_PREDICATE(swig_tag, smob)
|| SCM_SMOB_PREDICATE(swig_collectable_tag, smob)
|| SCM_SMOB_PREDICATE(swig_destroyed_tag, smob)) {
@@ -156,7 +166,7 @@ SWIGINTERN swig_type_info *
SWIG_Guile_PointerType(SCM object)
{
SCM smob = SWIG_Guile_GetSmob(object);
- if (SCM_NULLP(smob)) return NULL;
+ if (scm_is_null(smob)) return NULL;
else if (SCM_SMOB_PREDICATE(swig_tag, smob)
|| SCM_SMOB_PREDICATE(swig_collectable_tag, smob)
|| SCM_SMOB_PREDICATE(swig_destroyed_tag, smob)) {
@@ -183,8 +193,9 @@ SWIG_Guile_ConvertPtr(SCM s, void **result, swig_type_info *type, int flags)
swig_cast_info *cast;
swig_type_info *from;
SCM smob = SWIG_Guile_GetSmob(s);
+ int ret = SWIG_ERROR;
- if (SCM_NULLP(smob)) {
+ if (scm_is_null(smob)) {
*result = NULL;
return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
#if SCM_MAJOR_VERSION >= 2
@@ -195,22 +206,36 @@ SWIG_Guile_ConvertPtr(SCM s, void **result, swig_type_info *type, int flags)
} else if (SWIG_Guile_IsValidSmob(smob)) {
from = (swig_type_info *) SCM_CELL_WORD_2(smob);
if (!from) return SWIG_ERROR;
+
+ if ((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) {
+ if ((SCM_CELL_TYPE(smob) == swig_collectable_tag && SCM_CELL_WORD_1(smob) == 0) || SCM_CELL_TYPE(smob) == swig_tag) {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ }
+ }
+
if (type) {
cast = SWIG_TypeCheckStruct(from, type);
if (cast) {
int newmemory = 0;
*result = SWIG_TypeCast(cast, (void *) SCM_CELL_WORD_1(smob), &newmemory);
assert(!newmemory); /* newmemory handling not yet implemented */
- return SWIG_OK;
+ ret = SWIG_OK;
} else {
return SWIG_ERROR;
}
} else {
*result = (void *) SCM_CELL_WORD_1(smob);
- return SWIG_OK;
+ ret = SWIG_OK;
+ }
+
+ if (flags & SWIG_POINTER_DISOWN) {
+ SWIG_Guile_MarkPointerNoncollectable(smob);
+ }
+ if (flags & SWIG_POINTER_CLEAR) {
+ SCM_SET_CELL_WORD_1(smob, 0);
}
}
- return SWIG_ERROR;
+ return ret;
}
SWIGINTERNINLINE void *
@@ -250,7 +275,7 @@ SWIGINTERN void
SWIG_Guile_MarkPointerNoncollectable(SCM s)
{
SCM smob = SWIG_Guile_GetSmob(s);
- if (!SCM_NULLP(smob)) {
+ if (!scm_is_null(smob)) {
if (SWIG_Guile_IsValidSmob(smob)) {
SCM_SET_CELL_TYPE(smob, swig_tag);
}
@@ -263,7 +288,7 @@ SWIGINTERN void
SWIG_Guile_MarkPointerDestroyed(SCM s)
{
SCM smob = SWIG_Guile_GetSmob(s);
- if (!SCM_NULLP(smob)) {
+ if (!scm_is_null(smob)) {
if (SWIG_Guile_IsValidSmob(smob)) {
SCM_SET_CELL_TYPE(smob, swig_destroyed_tag);
}
@@ -484,20 +509,20 @@ SWIG_Guile_GetArgs (SCM *dest, SCM rest,
int i;
int num_args_passed = 0;
for (i = 0; i<reqargs; i++) {
- if (!SCM_CONSP(rest))
+ if (!scm_is_pair(rest))
scm_wrong_num_args(scm_from_utf8_string(procname ? (char *) procname : "unknown procedure"));
*dest++ = SCM_CAR(rest);
rest = SCM_CDR(rest);
num_args_passed++;
}
- for (i = 0; i<optargs && SCM_CONSP(rest); i++) {
+ for (i = 0; i<optargs && scm_is_pair(rest); i++) {
*dest++ = SCM_CAR(rest);
rest = SCM_CDR(rest);
num_args_passed++;
}
for (; i<optargs; i++)
*dest++ = SCM_UNDEFINED;
- if (!SCM_NULLP(rest))
+ if (!scm_is_null(rest))
scm_wrong_num_args(scm_from_utf8_string(procname ? (char *) procname : "unknown procedure"));
return num_args_passed;
}
diff --git a/Lib/guile/list-vector.i b/Lib/guile/list-vector.i
index 057a1da5b..824052599 100644
--- a/Lib/guile/list-vector.i
+++ b/Lib/guile/list-vector.i
@@ -107,7 +107,7 @@
(size_t VECTORLENINPUT, C_TYPE *VECTORINPUT),
(int LISTLENINPUT, C_TYPE *LISTINPUT),
(size_t LISTLENINPUT, C_TYPE *LISTINPUT)
- {if ($2!=NULL) SWIG_free($2);}
+ {SWIG_free($2);}
%enddef
@@ -173,7 +173,7 @@
(int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT),
(size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT)
{
- if ((*$2)!=NULL) free(*$2);
+ free(*$2);
}
%enddef
@@ -231,7 +231,7 @@ TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, SWIG_str02scm, stri
if ((*$2)!=NULL) {
int i;
for (i = 0; i < *$1; i++) {
- if ((*$2)[i] != NULL) free((*$2)[i]);
+ free((*$2)[i]);
}
free(*$2);
}
@@ -249,7 +249,7 @@ TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, SWIG_str02scm, stri
if (($2)!=NULL) {
int i;
for (i = 0; i< $1; i++)
- if (($2)[i] != NULL) free(($2)[i]);
+ free(($2)[i]);
free($2);
}
}
@@ -360,7 +360,7 @@ TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, SWIG_str02scm, stri
const C_TYPE *PARALLEL_VECTORINPUT,
C_TYPE *PARALLEL_LISTINPUT,
const C_TYPE *PARALLEL_LISTINPUT
- {if ($1!=NULL) SWIG_free($1);}
+ {SWIG_free($1);}
%enddef
@@ -422,7 +422,7 @@ TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, SWIG_str02scm, stri
%typemap(freearg) C_TYPE **PARALLEL_VECTOROUTPUT,
C_TYPE **PARALLEL_LISTOUTPUT
{
- if ((*$1)!=NULL) free(*$1);
+ free(*$1);
}
%enddef
@@ -471,7 +471,7 @@ TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, SWIG_str02
if (($1)!=NULL) {
int i;
for (i = 0; i<*_global_list_length; i++)
- if (($1)[i] != NULL) SWIG_free(($1)[i]);
+ SWIG_free(($1)[i]);
SWIG_free($1);
}
}
@@ -482,7 +482,7 @@ TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, SWIG_str02
if ((*$1)!=NULL) {
int i;
for (i = 0; i<_global_arraylentemp; i++)
- if ((*$1)[i] != NULL) free((*$1)[i]);
+ free((*$1)[i]);
free(*$1);
}
}
diff --git a/Lib/guile/std_auto_ptr.i b/Lib/guile/std_auto_ptr.i
new file mode 100644
index 000000000..59d5c0ed8
--- /dev/null
+++ b/Lib/guile/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ scm_misc_error(FUNC_NAME, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *'", SCM_EOL);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/guile/std_common.i b/Lib/guile/std_common.i
index 5899c5548..979744976 100644
--- a/Lib/guile/std_common.i
+++ b/Lib/guile/std_common.i
@@ -19,7 +19,7 @@ std::string SWIG_scm2string(SCM x) {
char* temp;
temp = SWIG_scm2str(x);
std::string s(temp);
- if (temp) SWIG_free(temp);
+ SWIG_free(temp);
return s;
}
%}
diff --git a/Lib/guile/std_string.i b/Lib/guile/std_string.i
index 6513173ee..c49bfcb07 100644
--- a/Lib/guile/std_string.i
+++ b/Lib/guile/std_string.i
@@ -30,7 +30,7 @@ namespace std {
if (scm_is_string($input)) {
tempptr = SWIG_scm2str($input);
$1.assign(tempptr);
- if (tempptr) SWIG_free(tempptr);
+ SWIG_free(tempptr);
} else {
SWIG_exception(SWIG_TypeError, "string expected");
}
@@ -40,7 +40,7 @@ namespace std {
if (scm_is_string($input)) {
tempptr = SWIG_scm2str($input);
temp.assign(tempptr);
- if (tempptr) SWIG_free(tempptr);
+ SWIG_free(tempptr);
$1 = &temp;
} else {
SWIG_exception(SWIG_TypeError, "string expected");
@@ -51,7 +51,7 @@ namespace std {
if (scm_is_string($input)) {
tempptr = SWIG_scm2str($input);
$1 = new $*1_ltype(tempptr);
- if (tempptr) SWIG_free(tempptr);
+ SWIG_free(tempptr);
} else {
SWIG_exception(SWIG_TypeError, "string expected");
}
@@ -73,7 +73,7 @@ namespace std {
if (scm_is_string($input)) {
char *tempptr = SWIG_scm2str($input);
$1.assign(tempptr);
- if (tempptr) SWIG_free(tempptr);
+ SWIG_free(tempptr);
} else {
SWIG_exception(SWIG_TypeError, "string expected");
}
@@ -83,4 +83,13 @@ namespace std {
$result = SWIG_str02scm($1.c_str());
}
+ %typemap(throws) string {
+ scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+ scm_list_n(SWIG_str02scm($1.c_str()), SCM_UNDEFINED));
+ }
+
+ %typemap(throws) const string & {
+ scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+ scm_list_n(SWIG_str02scm($1.c_str()), SCM_UNDEFINED));
+ }
}
diff --git a/Lib/guile/std_unique_ptr.i b/Lib/guile/std_unique_ptr.i
new file mode 100644
index 000000000..6f907e90c
--- /dev/null
+++ b/Lib/guile/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ scm_misc_error(FUNC_NAME, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *'", SCM_EOL);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/guile/swigmove.i b/Lib/guile/swigmove.i
new file mode 100644
index 000000000..87ab91ead
--- /dev/null
+++ b/Lib/guile/swigmove.i
@@ -0,0 +1,19 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "$1_type", $symname, $argnum);
+ } else {
+ %argument_fail(res, "$1_type", $symname, $argnum);
+ }
+ }
+ if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
+ SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/guile/swigrun.i b/Lib/guile/swigrun.i
index 4b9ea2c79..e4573eb3b 100644
--- a/Lib/guile/swigrun.i
+++ b/Lib/guile/swigrun.i
@@ -4,8 +4,6 @@
#ifdef SWIGGUILE_SCM
-/* Hook the runtime module initialization
- into the shared initialization function SWIG_Guile_Init. */
%runtime %{
/* Hook the runtime module initialization
into the shared initialization function SWIG_Guile_Init. */
diff --git a/Lib/guile/typemaps.i b/Lib/guile/typemaps.i
index 84a754d8b..45a2208f2 100644
--- a/Lib/guile/typemaps.i
+++ b/Lib/guile/typemaps.i
@@ -4,17 +4,43 @@
* Guile-specific typemaps
* ----------------------------------------------------------------------------- */
+/* These are defined with a view to eventually merging with those defined for other target languages in swigtypemaps.swg and exception.swg */
+#define %set_output(obj) $result = obj
+#define %set_varoutput(obj) $result = obj
+#define %argument_fail(_code, _type, _name, _argn) scm_wrong_type_arg((char *) FUNC_NAME, _argn, $input)
+#define %as_voidptr(ptr) (void*)(ptr)
+#define %argument_nullref(_type, _name, _argn) scm_misc_error(FUNC_NAME, "invalid null reference for argument " #_argn " of type '" _type "'", SCM_EOL)
+#define %releasenotowned_fail(_code, _type, _name, _argn) scm_misc_error(FUNC_NAME, "cannot release ownership as memory is not owned for argument " #_argn " of type '" _type "'", SCM_EOL)
+
/* Pointers */
-%typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] {
+%typemap(in) SWIGTYPE *, SWIGTYPE [] {
$1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0);
}
-%typemap(freearg) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "";
+%typemap(in) SWIGTYPE & ($1_ltype argp) {
+ argp = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0);
+ if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
+ $1 = argp;
+}
+%typemap(in, noblock=1, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "$1_type", $symname, $argnum);
+ } else {
+ %argument_fail(res, "$1_type", $symname, $argnum);
+ }
+ }
+ if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
+ $1 = ($1_ltype)argp;
+ rvrdeleter.reset($1);
+}
+%typemap(freearg) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] ""
%typemap(in) void * {
$1 = ($1_ltype)SWIG_MustGetPtr($input, NULL, $argnum, 0);
}
-%typemap(freearg) void * "";
+%typemap(freearg) void * ""
%typemap(varin) SWIGTYPE * {
$1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, 0);
@@ -115,8 +141,9 @@
/* Pass-by-value */
-%typemap(in) SWIGTYPE($&1_ltype argp) {
+%typemap(in) SWIGTYPE ($&1_ltype argp) {
argp = ($&1_ltype)SWIG_MustGetPtr($input, $&1_descriptor, $argnum, 0);
+ if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
$1 = *argp;
}
@@ -130,7 +157,7 @@
#ifdef __cplusplus
{
$&1_ltype resultptr;
- resultptr = new $1_ltype((const $1_ltype &) $1);
+ resultptr = new $1_ltype($1);
$result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 1);
}
#else
@@ -145,8 +172,7 @@
%typemap(varout) SWIGTYPE
#ifdef __cplusplus
{
- $&1_ltype resultptr;
- resultptr = new $1_ltype((const $1_ltype&) $1);
+ $&1_ltype resultptr = ($&1_ltype)&$1;
$result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 0);
}
#else
@@ -322,19 +348,19 @@ SIMPLE_MAP(unsigned long long, scm_to_ulong_long, scm_from_ulong_long, integer);
/* SWIG_scm2str makes a malloc'ed copy of the string, so get rid of it after
the function call. */
-%typemap (freearg) char * "if (must_free$argnum && $1) SWIG_free($1);";
-%typemap (freearg) char **INPUT, char **BOTH "if (must_free$argnum && (*$1)) SWIG_free(*$1);"
+%typemap (freearg) char * "if (must_free$argnum) SWIG_free($1);"
+%typemap (freearg) char **INPUT, char **BOTH "if (must_free$argnum) SWIG_free(*$1);"
%typemap (freearg) char **OUTPUT "SWIG_free(*$1);"
/* But this shall not apply if we try to pass a single char by
reference. */
-%typemap (freearg) char *OUTPUT, char *BOTH "";
+%typemap (freearg) char *OUTPUT, char *BOTH ""
/* If we set a string variable, delete the old result first, unless const. */
%typemap (varin) char * {
- if ($1) free($1);
+ free($1);
$1 = ($1_ltype) SWIG_scm2str($input);
}
@@ -349,13 +375,13 @@ SIMPLE_MAP(unsigned long long, scm_to_ulong_long, scm_from_ulong_long, integer);
/* Void */
-%typemap (out,doc="") void "gswig_result = SCM_UNSPECIFIED;";
+%typemap (out,doc="") void "gswig_result = SCM_UNSPECIFIED;"
/* SCM is passed through */
typedef unsigned long SCM;
-%typemap (in) SCM "$1=$input;";
-%typemap (out) SCM "$result=$1;";
+%typemap (in) SCM "$1=$input;"
+%typemap (out) SCM "$result=$1;"
%typecheck(SWIG_TYPECHECK_POINTER) SCM "$1=1;";
/* ------------------------------------------------------------
@@ -373,11 +399,6 @@ typedef unsigned long SCM;
* taken from typemaps/swigtype.swg
* ------------------------------------------------------------ */
-#define %set_output(obj) $result = obj
-#define %set_varoutput(obj) $result = obj
-#define %argument_fail(code, type, name, argn) scm_wrong_type_arg((char *) FUNC_NAME, argn, $input);
-#define %as_voidptr(ptr) (void*)(ptr)
-
%typemap(in) SWIGTYPE (CLASS::*) {
int res = SWIG_ConvertMember($input, %as_voidptr(&$1), sizeof($1), $descriptor);
if (!SWIG_IsOK(res)) {
@@ -426,7 +447,7 @@ typedef unsigned long SCM;
%typecheck(SWIG_TYPECHECK_BOOL)
bool, bool&, const bool&
{
- $1 = SCM_BOOLP($input) ? 1 : 0;
+ $1 = scm_is_bool($input) ? 1 : 0;
}
%typecheck(SWIG_TYPECHECK_DOUBLE)
diff --git a/Lib/java/boost_intrusive_ptr.i b/Lib/java/boost_intrusive_ptr.i
index 3bc80b467..072a31e8c 100644
--- a/Lib/java/boost_intrusive_ptr.i
+++ b/Lib/java/boost_intrusive_ptr.i
@@ -33,7 +33,7 @@
%}
%typemap(out, fragment="SWIG_intrusive_deleter") CONST TYPE %{
//plain value(out)
- $1_ltype* resultp = new $1_ltype(($1_ltype &)$1);
+ $1_ltype* resultp = new $1_ltype($1);
intrusive_ptr_add_ref(resultp);
*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(resultp, SWIG_intrusive_deleter< CONST TYPE >());
%}
@@ -342,7 +342,7 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
// plain pointer
%typemap(in) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
diff --git a/Lib/java/boost_shared_ptr.i b/Lib/java/boost_shared_ptr.i
index 325a6832d..ce00162da 100644
--- a/Lib/java/boost_shared_ptr.i
+++ b/Lib/java/boost_shared_ptr.i
@@ -29,11 +29,11 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
%typemap(directorin,descriptor="L$packagepath/$&javaclassname;") CONST TYPE
%{ $input = 0;
- *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+ *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
%typemap(directorout) CONST TYPE
%{ if (!$input) {
diff --git a/Lib/java/director.swg b/Lib/java/director.swg
index e911a3da7..536513557 100644
--- a/Lib/java/director.swg
+++ b/Lib/java/director.swg
@@ -51,6 +51,10 @@ SWIGINTERN int Swig::GetThreadName(char *name, size_t len) {
#endif
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+#include <pthread.h>
+#endif
+
namespace Swig {
/* Java object wrapper */
@@ -133,6 +137,19 @@ namespace Swig {
}
}
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+ static void detach(void *jvm) {
+ static_cast<JavaVM *>(jvm)->DetachCurrentThread();
+ }
+
+ static void make_detach_key() {
+ pthread_key_create(&detach_key_, detach);
+ }
+
+ /* thread-local key to register a destructor */
+ static pthread_key_t detach_key_;
+#endif
+
private:
/* pointer to Java object */
jobject jthis_;
@@ -140,6 +157,10 @@ namespace Swig {
bool weak_global_;
};
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+ pthread_key_t JObjectWrapper::detach_key_;
+#endif
+
/* Local JNI reference deleter */
class LocalRefGuard {
JNIEnv *jenv_;
@@ -201,9 +222,19 @@ namespace Swig {
#else
director_->swig_jvm_->AttachCurrentThread(jenv, &args);
#endif
+
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+ // At least on Android 6, detaching after every call causes a memory leak.
+ // Instead, register a thread desructor and detach only when the thread ends.
+ // See https://developer.android.com/training/articles/perf-jni#threads
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+
+ pthread_once(&once, JObjectWrapper::make_detach_key);
+ pthread_setspecific(JObjectWrapper::detach_key_, director->swig_jvm_);
+#endif
}
~JNIEnvWrapper() {
-#if !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
+#if !defined(SWIG_JAVA_DETACH_ON_THREAD_END) && !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
// Some JVMs, eg jdk-1.4.2 and lower on Solaris have a bug and crash with the DetachCurrentThread call.
// However, without this call, the JVM hangs on exit when the thread was not created by the JVM and creates a memory leak.
if (env_status == JNI_EDETACHED)
diff --git a/Lib/java/java.swg b/Lib/java/java.swg
index 8f95f3a3b..8719818bb 100644
--- a/Lib/java/java.swg
+++ b/Lib/java/java.swg
@@ -665,7 +665,7 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
%typemap(out) SWIGTYPE
#ifdef __cplusplus
-%{ *($&1_ltype*)&$result = new $1_ltype((const $1_ltype &)$1); %}
+%{ *($&1_ltype*)&$result = new $1_ltype($1); %}
#else
{
$&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
@@ -676,7 +676,7 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
%typemap(directorin,descriptor="L$packagepath/$&javaclassname;") SWIGTYPE
%{ $input = 0;
- *(($&1_ltype*)&$input) = new $1_ltype((const $1_ltype &)$1); %}
+ *(($&1_ltype*)&$input) = new $1_ltype(SWIG_STD_MOVE($1)); %}
%typemap(javadirectorin) SWIGTYPE "new $&javaclassname($jniinput, true)"
%typemap(javadirectorout) SWIGTYPE "$&javaclassname.getCPtr($javacall)"
@@ -692,14 +692,15 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
}
%typemap(in) SWIGTYPE & %{ $1 = *($&1_ltype)&$input;
if (!$1) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null");
+ SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null");
return $null;
} %}
-%typemap(in) SWIGTYPE && %{ $1 = *($&1_ltype)&$input;
+%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = *($&1_ltype)&$input;
if (!$1) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null");
+ SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null");
return $null;
- } %}
+ }
+ rvrdeleter.reset($1); %}
%typemap(out) SWIGTYPE *
%{ *($&1_ltype)&$result = $1; %}
%typemap(out, fragment="SWIG_PackData", noblock=1) SWIGTYPE (CLASS::*) {
@@ -1101,7 +1102,8 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
jobjectArray
"$javainput"
%typemap(javain) SWIGTYPE "$&javaclassname.getCPtr($javainput)"
-%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "$javaclassname.getCPtr($javainput)"
+%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$javaclassname.getCPtr($javainput)"
+%typemap(javain) SWIGTYPE && "$javaclassname.swigRelease($javainput)"
%typemap(javain) SWIGTYPE (CLASS::*) "$javaclassname.getCMemberPtr($javainput)"
/* The javaout typemap is used for converting function return types from the return type
@@ -1216,6 +1218,18 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
+
+ CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
+ long ptr = 0;
+ if (obj != null) {
+ if (!obj.swigCMemOwn)
+ throw new RuntimeException("Cannot release ownership as memory is not owned");
+ ptr = obj.swigCPtr;
+ obj.swigCMemOwn = false;
+ obj.delete();
+ }
+ return ptr;
+ }
%}
// Derived proxy classes
@@ -1230,6 +1244,18 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
+
+ CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
+ long ptr = 0;
+ if (obj != null) {
+ if (!obj.swigCMemOwn)
+ throw new RuntimeException("Cannot release ownership as memory is not owned");
+ ptr = obj.swigCPtr;
+ obj.swigCMemOwn = false;
+ obj.delete();
+ }
+ return ptr;
+ }
%}
%enddef
@@ -1249,6 +1275,10 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
+
+ CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
+ return (obj == null) ? 0 : obj.swigCPtr;
+ }
%}
%typemap(javabody) TYPE (CLASS::*) %{
diff --git a/Lib/java/javahead.swg b/Lib/java/javahead.swg
index 1fc327909..758a037d1 100644
--- a/Lib/java/javahead.swg
+++ b/Lib/java/javahead.swg
@@ -87,5 +87,5 @@ static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionC
%insert(runtime) %{
/* Contract support */
-#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else
+#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } } while (0)
%}
diff --git a/Lib/java/javakw.swg b/Lib/java/javakw.swg
index 99cd54770..8a5b76eef 100644
--- a/Lib/java/javakw.swg
+++ b/Lib/java/javakw.swg
@@ -2,7 +2,7 @@
#define JAVA_JAVAKW_SWG_
/* Warnings for Java keywords */
-#define JAVAKW(x) %keywordwarn("'" `x` "' is a java keyword, renaming to '_"`x`"'",rename="_%s") `x`
+#define JAVAKW(x) %keywordwarn("'" `x` "' is a java keyword",rename="_%s") `x`
/*
from
diff --git a/Lib/java/std_auto_ptr.i b/Lib/java/std_auto_ptr.i
index 69ac2841f..aee9b4828 100644
--- a/Lib/java/std_auto_ptr.i
+++ b/Lib/java/std_auto_ptr.i
@@ -1,27 +1,41 @@
-/*
- The typemaps here allow handling functions returning std::auto_ptr<>,
- which is the most common use of this type. If you have functions taking it
- as parameter, these typemaps can't be used for them and you need to do
- something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
%define %auto_ptr(TYPE)
-%typemap (jni) std::auto_ptr<TYPE > "jlong"
-%typemap (jtype) std::auto_ptr<TYPE > "long"
-%typemap (jstype) std::auto_ptr<TYPE > "$typemap(jstype, TYPE)"
-
-%typemap (out) std::auto_ptr<TYPE > %{
- jlong lpp = 0;
- *(TYPE**) &lpp = $1.release();
- $result = lpp;
+
+%typemap (jni) std::auto_ptr< TYPE > "jlong"
+%typemap (jtype) std::auto_ptr< TYPE > "long"
+%typemap (jstype) std::auto_ptr< TYPE > "$typemap(jstype, TYPE)"
+
+%typemap(in) std::auto_ptr< TYPE > (TYPE *auto_temp)
+%{ auto_temp = *(TYPE **)&$input;
+ $1.reset(auto_temp); %}
+
+%typemap(javain) std::auto_ptr< TYPE > "$typemap(jstype, TYPE).swigRelease($javainput)"
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ jlong lpp = 0;
+ *(TYPE **) &lpp = $1.release();
+ $result = lpp;
%}
-%typemap(javaout) std::auto_ptr<TYPE > {
- long cPtr = $jnicall;
- return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
- }
-%template() std::auto_ptr<TYPE >;
+
+%typemap(javaout) std::auto_ptr< TYPE > {
+ long cPtr = $jnicall;
+ return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
+ }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::auto_ptr< TYPE > ""
+
+%template() std::auto_ptr< TYPE >;
%enddef
namespace std {
- template <class T> class auto_ptr {};
-}
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/java/std_unique_ptr.i b/Lib/java/std_unique_ptr.i
new file mode 100644
index 000000000..838ca495a
--- /dev/null
+++ b/Lib/java/std_unique_ptr.i
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+
+%typemap (jni) std::unique_ptr< TYPE > "jlong"
+%typemap (jtype) std::unique_ptr< TYPE > "long"
+%typemap (jstype) std::unique_ptr< TYPE > "$typemap(jstype, TYPE)"
+
+%typemap(in) std::unique_ptr< TYPE > (TYPE *unique_temp)
+%{ unique_temp = *(TYPE **)&$input;
+ $1.reset(unique_temp); %}
+
+%typemap(javain) std::unique_ptr< TYPE > "$typemap(jstype, TYPE).swigRelease($javainput)"
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ jlong lpp = 0;
+ *(TYPE **) &lpp = $1.release();
+ $result = lpp;
+%}
+
+%typemap(javaout) std::unique_ptr< TYPE > {
+ long cPtr = $jnicall;
+ return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
+ }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::unique_ptr< TYPE > ""
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/java/std_wstring.i b/Lib/java/std_wstring.i
index dd0b2f5ff..efa9e63b8 100644
--- a/Lib/java/std_wstring.i
+++ b/Lib/java/std_wstring.i
@@ -60,7 +60,7 @@ class wstring;
%}
%typemap(directorin,descriptor="Ljava/lang/String;") wstring %{
- jsize $1_len = $1.length();
+ jsize $1_len = (jsize)$1.length();
jchar *$1_conv_buf = new jchar[$1_len];
for (jsize i = 0; i < $1_len; ++i) {
$1_conv_buf[i] = (jchar)$1[i];
@@ -71,7 +71,7 @@ class wstring;
%}
%typemap(out) wstring
-%{jsize $1_len = $1.length();
+%{jsize $1_len = (jsize)$1.length();
jchar *conv_buf = new jchar[$1_len];
for (jsize i = 0; i < $1_len; ++i) {
conv_buf[i] = (jchar)$1[i];
@@ -88,9 +88,12 @@ class wstring;
//%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"
@@ -138,7 +141,7 @@ class wstring;
jenv->ReleaseStringChars($input, $1_pstr); %}
%typemap(directorin,descriptor="Ljava/lang/String;") const wstring & %{
- jsize $1_len = $1.length();
+ jsize $1_len = (jsize)$1.length();
jchar *$1_conv_buf = new jchar[$1_len];
for (jsize i = 0; i < $1_len; ++i) {
$1_conv_buf[i] = (jchar)($1)[i];
@@ -149,7 +152,7 @@ class wstring;
%}
%typemap(out) const wstring &
-%{jsize $1_len = $1->length();
+%{jsize $1_len = (jsize)$1->length();
jchar *conv_buf = new jchar[$1_len];
for (jsize i = 0; i < $1_len; ++i) {
conv_buf[i] = (jchar)(*$1)[i];
@@ -166,9 +169,12 @@ class wstring;
//%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/java/swiginterface.i b/Lib/java/swiginterface.i
index 0a0f7806a..c3ca97d36 100644
--- a/Lib/java/swiginterface.i
+++ b/Lib/java/swiginterface.i
@@ -40,7 +40,7 @@
%typemap(javadirectorout) CTYPE *const& "$javacall.$*interfacename_GetInterfaceCPtr()"
%typemap(directorin,descriptor="L$packagepath/$&javainterfacename;") CTYPE
%{ $input = 0;
- *(($&1_ltype*)&$input) = new $1_ltype((const $1_ltype &)$1); %}
+ *(($&1_ltype*)&$input) = new $1_ltype(SWIG_STD_MOVE($1)); %}
%typemap(directorin,descriptor="L$packagepath/$javainterfacename;") CTYPE *, CTYPE []
%{ *(($&1_ltype)&$input) = ($1_ltype) $1; %}
%typemap(directorin,descriptor="L$packagepath/$javainterfacename;") CTYPE &
diff --git a/Lib/java/swigmove.i b/Lib/java/swigmove.i
new file mode 100644
index 000000000..671b988af
--- /dev/null
+++ b/Lib/java/swigmove.i
@@ -0,0 +1,16 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in) SWIGTYPE MOVE ($&1_type argp)
+%{ argp = *($&1_ltype*)&$input;
+ if (!argp) {
+ SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type");
+ return $null;
+ }
+ SwigValueWrapper< $1_ltype >::reset($1, argp); %}
+
+%typemap(javain) SWIGTYPE MOVE "$&javaclassname.swigRelease($javainput)"
diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg
index d092ea4ab..4d5a9355b 100644
--- a/Lib/javascript/jsc/javascriptrun.swg
+++ b/Lib/javascript/jsc/javascriptrun.swg
@@ -7,23 +7,27 @@
#define SWIG_exception(code, msg) do { SWIG_JSC_exception(context, exception, code, msg); SWIG_fail; } while (0)
#define SWIG_fail goto fail
-SWIGRUNTIME void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) {
- JSStringRef message = JSStringCreateWithUTF8CString(type);
+SWIGRUNTIME void SWIG_Javascript_Raise_ValueRef(JSContextRef context, JSValueRef *exception, JSValueRef valRef) {
JSValueRef error_arguments[1];
JSObjectRef exception_object;
- JSValueRef exception_value;
- exception_value = JSValueMakeString(context, message);
/* Converting the result to an object will let JavascriptCore add
"sourceURL" (file) and "line" (number) and "message" to the exception,
instead of just returning a raw string. This is extremely important for debugging your errors.
Using JSObjectMakeError is better than JSValueToObject because the latter only populates
"sourceURL" and "line", but not "message" or any others I don't know about.
*/
- error_arguments[0] = exception_value;
+ error_arguments[0] = valRef;
exception_object = JSObjectMakeError(context, 1, error_arguments, NULL);
/* Return the exception_object */
*exception = exception_object;
+}
+
+SWIGRUNTIME void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* msg) {
+ JSStringRef message = JSStringCreateWithUTF8CString(msg);
+ JSValueRef exception_value = JSValueMakeString(context, message);
+
+ SWIG_Javascript_Raise_ValueRef(context, exception, exception_value);
JSStringRelease(message);
}
@@ -122,7 +126,7 @@ SWIGRUNTIME int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef ob
}
assert(ptr);
*ptr = NULL;
- if (cdata->info == info) {
+ if (!info || cdata->info == info) {
*ptr = cdata->swigCObject;
} else {
swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info);
@@ -135,8 +139,15 @@ SWIGRUNTIME int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef ob
}
}
- if (flags & SWIG_POINTER_DISOWN) {
- cdata->swigCMemOwn = false;
+ if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !cdata->swigCMemOwn) {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ } else {
+ if (flags & SWIG_POINTER_DISOWN) {
+ cdata->swigCMemOwn = false;
+ }
+ if (flags & SWIG_POINTER_CLEAR) {
+ cdata->swigCObject = 0;
+ }
}
return SWIG_OK;
diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg
index 55c8e4b98..5c8081a82 100644
--- a/Lib/javascript/jsc/javascriptstrings.swg
+++ b/Lib/javascript/jsc/javascriptstrings.swg
@@ -75,6 +75,7 @@ SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t siz
}
%define %_typemap2_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -166,6 +167,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
%_typemap_string(StringCode,
Char,
+ WarningLeakMsg,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
SWIG_CharPtrLen,
diff --git a/Lib/javascript/jsc/javascripttypemaps.swg b/Lib/javascript/jsc/javascripttypemaps.swg
index e8fbbeca8..fd8e7aa2f 100644
--- a/Lib/javascript/jsc/javascripttypemaps.swg
+++ b/Lib/javascript/jsc/javascripttypemaps.swg
@@ -41,7 +41,7 @@
#define SWIG_SetConstant(name, obj)
/* raise */
-#define SWIG_Raise(obj, type, desc) SWIG_Javascript_Raise(context, exception, type)
+#define SWIG_Raise(obj, type, desc) SWIG_Javascript_Raise_ValueRef(context, exception, obj)
%insert("runtime") %{
#define SWIG_JSC_FROM_DECL_ARGS(arg1) (JSContextRef context, arg1)
diff --git a/Lib/javascript/jsc/std_auto_ptr.i b/Lib/javascript/jsc/std_auto_ptr.i
new file mode 100644
index 000000000..3d7ae8ba1
--- /dev/null
+++ b/Lib/javascript/jsc/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/javascript/jsc/std_unique_ptr.i b/Lib/javascript/jsc/std_unique_ptr.i
new file mode 100644
index 000000000..f988714df
--- /dev/null
+++ b/Lib/javascript/jsc/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/javascript/jsc/swigmove.i b/Lib/javascript/jsc/swigmove.i
new file mode 100644
index 000000000..62ecca768
--- /dev/null
+++ b/Lib/javascript/jsc/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/javascript/jsc/typemaps.i b/Lib/javascript/jsc/typemaps.i
index d3d8afb19..b5b441bc7 100644
--- a/Lib/javascript/jsc/typemaps.i
+++ b/Lib/javascript/jsc/typemaps.i
@@ -72,7 +72,7 @@ multiple output values, they are returned in the form of a Python tuple.
For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
+returns the integer part in one of its parameters) :
double modf(double x, double *ip);
diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg
index 2abed9488..dcda0ee63 100644
--- a/Lib/javascript/v8/javascriptcode.swg
+++ b/Lib/javascript/v8/javascriptcode.swg
@@ -105,17 +105,10 @@ fail:
%{
if(args.Length() == $jsargcount) {
errorHandler.err.Clear();
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
- self = $jswrapper(args, errorHandler);
- if(errorHandler.err.IsEmpty()) {
- SWIGV8_ESCAPE(self);
- }
-#else
$jswrapper(args, errorHandler);
if(errorHandler.err.IsEmpty()) {
return;
}
-#endif
}
%}
@@ -127,22 +120,8 @@ fail:
%fragment ("js_dtor", "templates")
%{
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-static void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) {
- SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-static void $jswrapper(v8::Isolate *isolate, v8::Persistent<v8::Value> object, void *parameter) {
- SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-static void $jswrapper(v8::Isolate *isolate, v8::Persistent<v8::Object> *object, SWIGV8_Proxy *proxy) {
-#elif (V8_MAJOR_VERSION-0) < 5
-static void $jswrapper(const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &data) {
- v8::Local<v8::Object> object = data.GetValue();
- SWIGV8_Proxy *proxy = data.GetParameter();
-#else
- static void $jswrapper(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
+static void $jswrapper(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
SWIGV8_Proxy *proxy = data.GetParameter();
-#endif
if(proxy->swigCMemOwn && proxy->swigCObject) {
#ifdef SWIGRUNTIME_DEBUG
@@ -151,20 +130,6 @@ static void $jswrapper(const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &dat
$jsfree proxy->swigCObject;
}
delete proxy;
-
-#if (V8_MAJOR_VERSION-0) < 5
- object.Clear();
-#endif
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- object.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
- object.Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
- object->Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 5
- object->Dispose();
-#endif
}
%}
@@ -176,40 +141,14 @@ static void $jswrapper(const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &dat
* ----------------------------------------------------------------------------- */
%fragment ("js_dtoroverride", "templates")
%{
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-static void $jswrapper(v8::Persistent<v8::Value> object, void *parameter) {
- SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-static void $jswrapper(v8::Isolate *isolate, v8::Persistent<v8::Value> object, void *parameter) {
- SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-static void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object> *object, SWIGV8_Proxy *proxy) {
-#elif (V8_MAJOR_VERSION-0) < 5
-static void $jswrapper(const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &data) {
- v8::Local<v8::Object> object = data.GetValue();
- SWIGV8_Proxy *proxy = data.GetParameter();
-#else
static void $jswrapper(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
SWIGV8_Proxy *proxy = data.GetParameter();
-#endif
if(proxy->swigCMemOwn && proxy->swigCObject) {
$jstype arg1 = ($jstype)proxy->swigCObject;
${destructor_action}
}
delete proxy;
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- object.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
- object.Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
- object->Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
- object->Dispose();
-#elif (V8_MAJOR_VERSION-0) < 5
- object.Clear();
-#endif
}
%}
@@ -221,11 +160,7 @@ static void $jswrapper(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
* ----------------------------------------------------------------------------- */
%fragment("js_getter", "templates")
%{
-#if (V8_MAJOR_VERSION-0) < 5
-static SwigV8ReturnValue $jswrapper(v8::Local<v8::String> property, const SwigV8PropertyCallbackInfo &info) {
-#else
static SwigV8ReturnValue $jswrapper(v8::Local<v8::Name> property, const SwigV8PropertyCallbackInfo &info) {
-#endif
SWIGV8_HANDLESCOPE();
SWIGV8_VALUE jsresult;
@@ -247,11 +182,7 @@ fail:
* ----------------------------------------------------------------------------- */
%fragment("js_setter", "templates")
%{
-#if (V8_MAJOR_VERSION-0) < 5
-static void $jswrapper(v8::Local<v8::String> property, v8::Local<v8::Value> value, const SwigV8PropertyCallbackInfoVoid &info) {
-#else
static void $jswrapper(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const SwigV8PropertyCallbackInfoVoid &info) {
-#endif
SWIGV8_HANDLESCOPE();
$jslocals
@@ -344,17 +275,10 @@ fail:
if(args.Length() == $jsargcount) {
errorHandler.err.Clear();
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
- jsresult = $jswrapper(args, errorHandler);
- if(errorHandler.err.IsEmpty()) {
- SWIGV8_ESCAPE(jsresult);
- }
-#else
$jswrapper(args, errorHandler);
if(errorHandler.err.IsEmpty()) {
return;
}
-#endif
}
%}
@@ -394,15 +318,11 @@ fail:
%{
if (SWIGTYPE_p$jsbaseclass->clientdata && !(static_cast<SWIGV8_ClientData *>(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ.IsEmpty()))
{
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
- $jsmangledname_class->Inherit(static_cast<SWIGV8_ClientData *>(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ);
-#else
$jsmangledname_class->Inherit(
v8::Local<v8::FunctionTemplate>::New(
v8::Isolate::GetCurrent(),
static_cast<SWIGV8_ClientData *>(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ)
);
-#endif
#ifdef SWIGRUNTIME_DEBUG
printf("Inheritance successful $jsmangledname $jsbaseclass\n");
@@ -425,10 +345,7 @@ fail:
SWIGV8_FUNCTION_TEMPLATE $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname");
$jsmangledname_class_0->SetCallHandler($jsctor);
$jsmangledname_class_0->Inherit($jsmangledname_class);
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
- $jsmangledname_class_0->SetHiddenPrototype(true);
- v8::Handle<v8::Object> $jsmangledname_obj = $jsmangledname_class_0->GetFunction();
-#elif (SWIG_V8_VERSION < 0x0704)
+#if (SWIG_V8_VERSION < 0x0704)
$jsmangledname_class_0->SetHiddenPrototype(true);
v8::Local<v8::Object> $jsmangledname_obj = $jsmangledname_class_0->GetFunction();
#else
@@ -444,12 +361,7 @@ fail:
* ----------------------------------------------------------------------------- */
%fragment("jsv8_register_class", "templates")
%{
-#if (V8_MAJOR_VERSION-0) < 5
- $jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj);
-#else
SWIGV8_MAYBE_CHECK($jsparent_obj->Set(context, SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj));
-#endif
-
%}
/* -----------------------------------------------------------------------------
@@ -469,11 +381,7 @@ fail:
* ----------------------------------------------------------------------------- */
%fragment("jsv8_register_namespace", "templates")
%{
-#if (V8_MAJOR_VERSION-0) < 5
- $jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj);
-#else
SWIGV8_MAYBE_CHECK($jsparent_obj->Set(context, SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj));
-#endif
%}
/* -----------------------------------------------------------------------------
diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg
index fdbff000e..ea303fa3d 100644
--- a/Lib/javascript/v8/javascripthelpers.swg
+++ b/Lib/javascript/v8/javascripthelpers.swg
@@ -1,22 +1,9 @@
%insert(runtime) %{
-// Note: since 3.19 there are new CallBack types, since 03.21.9 the old ones have been removed
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-typedef v8::InvocationCallback SwigV8FunctionCallback;
-typedef v8::AccessorGetter SwigV8AccessorGetterCallback;
-typedef v8::AccessorSetter SwigV8AccessorSetterCallback;
-typedef v8::AccessorInfo SwigV8PropertyCallbackInfoVoid;
-#elif (V8_MAJOR_VERSION-0) < 5
-typedef v8::FunctionCallback SwigV8FunctionCallback;
-typedef v8::AccessorGetterCallback SwigV8AccessorGetterCallback;
-typedef v8::AccessorSetterCallback SwigV8AccessorSetterCallback;
-typedef v8::PropertyCallbackInfo<void> SwigV8PropertyCallbackInfoVoid;
-#else
typedef v8::FunctionCallback SwigV8FunctionCallback;
typedef v8::AccessorNameGetterCallback SwigV8AccessorGetterCallback;
typedef v8::AccessorNameSetterCallback SwigV8AccessorSetterCallback;
typedef v8::PropertyCallbackInfo<void> SwigV8PropertyCallbackInfoVoid;
-#endif
/**
* Creates a class template for a class with specified initialization function.
@@ -62,11 +49,7 @@ SWIGRUNTIME void SWIGV8_AddMemberVariable(SWIGV8_FUNCTION_TEMPLATE class_templ,
*/
SWIGRUNTIME void SWIGV8_AddStaticFunction(SWIGV8_OBJECT obj, const char* symbol,
const SwigV8FunctionCallback& _func, v8::Local<v8::Context> context) {
-#if (V8_MAJOR_VERSION-0) < 5
- obj->Set(SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction());
-#else
SWIGV8_MAYBE_CHECK(obj->Set(context, SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction(context).ToLocalChecked()));
-#endif
}
/**
@@ -75,27 +58,15 @@ SWIGRUNTIME void SWIGV8_AddStaticFunction(SWIGV8_OBJECT obj, const char* symbol,
SWIGRUNTIME void SWIGV8_AddStaticVariable(SWIGV8_OBJECT obj, const char* symbol,
SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter,
v8::Local<v8::Context> context) {
-#if (V8_MAJOR_VERSION-0) < 5
- obj->SetAccessor(SWIGV8_SYMBOL_NEW(symbol), getter, setter);
-#else
SWIGV8_MAYBE_CHECK(obj->SetAccessor(context, SWIGV8_SYMBOL_NEW(symbol), getter, setter));
-#endif
}
-#if (V8_MAJOR_VERSION-0) < 5
-SWIGRUNTIME void JS_veto_set_variable(v8::Local<v8::String> property, v8::Local<v8::Value> value, const SwigV8PropertyCallbackInfoVoid& info)
-#else
SWIGRUNTIME void JS_veto_set_variable(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const SwigV8PropertyCallbackInfoVoid& info)
-#endif
{
char buffer[256];
char msg[512];
int res;
-#if (V8_MAJOR_VERSION-0) < 5
- property->WriteUtf8(buffer, 256);
- res = sprintf(msg, "Tried to write read-only variable: %s.", buffer);
-#else
v8::Local<v8::String> sproperty;
if (property->ToString(SWIGV8_CURRENT_CONTEXT()).ToLocal(&sproperty)) {
SWIGV8_WRITE_UTF8(sproperty, buffer, 256);
@@ -104,7 +75,6 @@ SWIGRUNTIME void JS_veto_set_variable(v8::Local<v8::Name> property, v8::Local<v8
else {
res = -1;
}
-#endif
if(res<0) {
SWIG_exception(SWIG_ERROR, "Tried to write read-only variable.");
diff --git a/Lib/javascript/v8/javascriptinit.swg b/Lib/javascript/v8/javascriptinit.swg
index 772189787..3bf8c416c 100644
--- a/Lib/javascript/v8/javascriptinit.swg
+++ b/Lib/javascript/v8/javascriptinit.swg
@@ -9,25 +9,17 @@ SWIG_V8_SetModule(v8::Local<v8::Context> context, swig_module_info *swig_module)
v8::Local<v8::Object> global_obj = context->Global();
v8::Local<v8::External> mod = SWIGV8_EXTERNAL_NEW(swig_module);
assert(!mod.IsEmpty());
-#if (V8_MAJOR_VERSION-0) < 5
- global_obj->SetHiddenValue(SWIGV8_STRING_NEW("swig_module_info_data"), mod);
-#else
v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("swig_module_info_data"));
global_obj->SetPrivate(context, privateKey, mod);
-#endif
}
SWIGRUNTIME swig_module_info *
SWIG_V8_GetModule(v8::Local<v8::Context> context) {
v8::Local<v8::Object> global_obj = context->Global();
-#if (V8_MAJOR_VERSION-0) < 5
- v8::Local<v8::Value> moduleinfo = global_obj->GetHiddenValue(SWIGV8_STRING_NEW("swig_module_info_data"));
-#else
v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("swig_module_info_data"));
v8::Local<v8::Value> moduleinfo;
if (!global_obj->GetPrivate(context, privateKey).ToLocal(&moduleinfo))
return 0;
-#endif
if (moduleinfo.IsEmpty() || moduleinfo->IsNull() || moduleinfo->IsUndefined())
{
diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg
index 2df342416..f76270855 100644
--- a/Lib/javascript/v8/javascriptrun.swg
+++ b/Lib/javascript/v8/javascriptrun.swg
@@ -4,56 +4,26 @@
* Useful table of versions: https://nodejs.org/en/download/releases/
* ---------------------------------------------------------------------------*/
-// First v8 version that uses "SetWeak" and not "MakeWeak"
-
-#define SWIGV8_SETWEAK_VERSION 0x032224
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031803)
-#define SWIGV8_STRING_NEW2(cstr, len) v8::String::New(cstr, len)
-#elif (SWIG_V8_VERSION < 0x0704)
+#if (SWIG_V8_VERSION < 0x0704)
#define SWIGV8_STRING_NEW2(cstr, len) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), cstr, v8::String::kNormalString, len)
#else
#define SWIGV8_STRING_NEW2(cstr, len) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), cstr, v8::NewStringType::kNormal, len)).ToLocalChecked()
#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-typedef v8::Handle<v8::Value> SwigV8ReturnValue;
-typedef v8::Arguments SwigV8Arguments;
-typedef v8::AccessorInfo SwigV8PropertyCallbackInfo;
-#define SWIGV8_RETURN(val) return scope.Close(val)
-#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val)
-#else
typedef void SwigV8ReturnValue;
typedef v8::FunctionCallbackInfo<v8::Value> SwigV8Arguments;
typedef v8::PropertyCallbackInfo<v8::Value> SwigV8PropertyCallbackInfo;
#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return
#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032117)
-#define SWIGV8_HANDLESCOPE() v8::HandleScope scope
-#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope
-#define SWIGV8_ESCAPE(val) return scope.Close(val)
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032224)
-#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent());
-#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope(v8::Isolate::GetCurrent());
-#define SWIGV8_ESCAPE(val) return scope.Close(val)
-#else
#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent());
#define SWIGV8_HANDLESCOPE_ESC() v8::EscapableHandleScope scope(v8::Isolate::GetCurrent());
#define SWIGV8_ESCAPE(val) return scope.Escape(val)
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032224)
-#define SWIGV8_ADJUST_MEMORY(size) v8::V8::AdjustAmountOfExternalAllocatedMemory(size)
-#define SWIGV8_CURRENT_CONTEXT() v8::Context::GetCurrent()
-#define SWIGV8_THROW_EXCEPTION(err) v8::ThrowException(err)
-#define SWIGV8_STRING_NEW(str) v8::String::New(str)
-#define SWIGV8_SYMBOL_NEW(sym) v8::String::NewSymbol(sym)
-#else
#define SWIGV8_ADJUST_MEMORY(size) v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size)
#define SWIGV8_CURRENT_CONTEXT() v8::Isolate::GetCurrent()->GetCurrentContext()
#define SWIGV8_THROW_EXCEPTION(err) v8::Isolate::GetCurrent()->ThrowException(err)
+
#if (SWIG_V8_VERSION < 0x0704)
#define SWIGV8_STRING_NEW(str) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str, v8::String::kNormalString)
#define SWIGV8_SYMBOL_NEW(sym) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sym, v8::String::kNormalString)
@@ -61,37 +31,13 @@ typedef v8::PropertyCallbackInfo<v8::Value> SwigV8PropertyCallbackInfo;
#define SWIGV8_STRING_NEW(str) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str, v8::NewStringType::kNormal)).ToLocalChecked()
#define SWIGV8_SYMBOL_NEW(sym) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sym, v8::NewStringType::kNormal)).ToLocalChecked()
#endif
-#endif
-#if (V8_MAJOR_VERSION-0) < 5
-#define SWIGV8_MAYBE_CHECK(maybe) maybe
-#elif (SWIG_V8_VERSION < 0x0704)
+#if (SWIG_V8_VERSION < 0x0704)
#define SWIGV8_MAYBE_CHECK(maybe) maybe.FromJust()
#else
#define SWIGV8_MAYBE_CHECK(maybe) maybe.Check()
#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318)
-#define SWIGV8_ARRAY_NEW(size) v8::Array::New(size)
-#define SWIGV8_BOOLEAN_NEW(bool) v8::Boolean::New(bool)
-#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(val)
-#define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(func)
-#define SWIGV8_FUNCTEMPLATE_NEW_VOID() v8::FunctionTemplate::New()
-#define SWIGV8_INT32_NEW(num) v8::Int32::New(num)
-#define SWIGV8_INTEGER_NEW(num) v8::Integer::New(num)
-#define SWIGV8_INTEGER_NEW_UNS(num) v8::Integer::NewFromUnsigned(num)
-#define SWIGV8_NUMBER_NEW(num) v8::Number::New(num)
-#define SWIGV8_OBJECT_NEW() v8::Object::New()
-#define SWIGV8_UNDEFINED() v8::Undefined()
-#define SWIGV8_ARRAY v8::Handle<v8::Array>
-#define SWIGV8_FUNCTION_TEMPLATE v8::Handle<v8::FunctionTemplate>
-#define SWIGV8_OBJECT v8::Handle<v8::Object>
-#define SWIGV8_OBJECT_TEMPLATE v8::Handle<v8::ObjectTemplate>
-#define SWIGV8_VALUE v8::Handle<v8::Value>
-#define SWIGV8_NULL() v8::Null()
-#define SWIGV8_ARRAY_GET(array, index) (array)->Get(index)
-#define SWIGV8_ARRAY_SET(array, index, value) (array)->Set(index, value)
-#else
#define SWIGV8_ARRAY_NEW(size) v8::Array::New(v8::Isolate::GetCurrent(), size)
#define SWIGV8_BOOLEAN_NEW(bool) v8::Boolean::New(v8::Isolate::GetCurrent(), bool)
#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(v8::Isolate::GetCurrent(), val)
@@ -111,17 +57,10 @@ typedef v8::PropertyCallbackInfo<v8::Value> SwigV8PropertyCallbackInfo;
#define SWIGV8_NULL() v8::Null(v8::Isolate::GetCurrent())
#define SWIGV8_ARRAY_GET(array, index) (array)->Get(SWIGV8_CURRENT_CONTEXT(), index).ToLocalChecked()
#define SWIGV8_ARRAY_SET(array, index, value) SWIGV8_MAYBE_CHECK((array)->Set(SWIGV8_CURRENT_CONTEXT(), index, value))
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-#define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ = v8::Persistent<v8::FunctionTemplate>::New(class);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-#define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), class);
-#else
#define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ.Reset(v8::Isolate::GetCurrent(), class);
-#endif
-#if (V8_MAJOR_VERSION-0) < 6 || (SWIG_V8_VERSION < 0x0608)
+#if SWIG_V8_VERSION < 0x0608
#define SWIGV8_TO_OBJECT(handle) (handle)->ToObject()
#define SWIGV8_TO_STRING(handle) (handle)->ToString()
#define SWIGV8_NUMBER_VALUE(handle) (handle)->NumberValue()
@@ -157,6 +96,11 @@ SWIGINTERN void SWIG_V8_Raise(const char *msg) {
SWIGV8_THROW_EXCEPTION(v8::Exception::Error(SWIGV8_STRING_NEW(msg)));
}
+SWIGINTERN void SWIG_V8_Raise(SWIGV8_VALUE obj, const char *msg) {
+ SWIGV8_THROW_EXCEPTION(v8::Exception::Error(SWIGV8_TO_STRING(obj)));
+}
+
+
/*
Note: There are two contexts for handling errors.
A static V8ErrorHandler is used in not overloaded methods.
@@ -208,23 +152,8 @@ public:
};
~SWIGV8_Proxy() {
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- handle.ClearWeak();
- handle.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
- handle.ClearWeak(v8::Isolate::GetCurrent());
- handle.Dispose(v8::Isolate::GetCurrent());
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
- handle.ClearWeak();
- handle.Dispose();
-#else
handle.ClearWeak();
handle.Reset();
-#endif
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
- handle.Clear();
-#endif
SWIGV8_ADJUST_MEMORY(-SWIGV8_AVG_OBJ_SIZE);
}
@@ -239,17 +168,7 @@ class SWIGV8_ClientData {
public:
v8::Persistent<v8::FunctionTemplate> class_templ;
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- void (*dtor) (v8::Persistent< v8::Value> object, void *parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
- void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Value> object, void *parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
- void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy);
-#elif (V8_MAJOR_VERSION-0) < 5
- void (*dtor) (const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &data);
-#else
void (*dtor) (const v8::WeakCallbackInfo<SWIGV8_Proxy> &data);
-#endif
};
SWIGRUNTIME v8::Persistent<v8::FunctionTemplate> SWIGV8_SWIGTYPE_Proxy_class_templ;
@@ -259,17 +178,12 @@ SWIGRUNTIME int SWIG_V8_ConvertInstancePtr(SWIGV8_OBJECT objRef, void **ptr, swi
if(objRef->InternalFieldCount() < 1) return SWIG_ERROR;
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
- v8::Handle<v8::Value> cdataRef = objRef->GetInternalField(0);
- SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(v8::External::Unwrap(cdataRef));
-#else
SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(objRef->GetAlignedPointerFromInternalField(0));
-#endif
if(cdata == NULL) {
return SWIG_ERROR;
}
- if(cdata->info != info) {
+ if(info && cdata->info != info) {
swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info);
if (!tc && cdata->info->name) {
tc = SWIG_TypeCheck(cdata->info->name, info);
@@ -285,29 +199,22 @@ SWIGRUNTIME int SWIG_V8_ConvertInstancePtr(SWIGV8_OBJECT objRef, void **ptr, swi
*ptr = cdata->swigCObject;
}
- if(flags & SWIG_POINTER_DISOWN) {
- cdata->swigCMemOwn = false;
+ if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !cdata->swigCMemOwn) {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ } else {
+ if (flags & SWIG_POINTER_DISOWN) {
+ cdata->swigCMemOwn = false;
+ }
+ if (flags & SWIG_POINTER_CLEAR) {
+ cdata->swigCObject = 0;
+ }
}
return SWIG_OK;
}
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) {
- SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Value > object, void *parameter) {
- SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) {
-#elif (V8_MAJOR_VERSION-0) < 5
-SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &data) {
- SWIGV8_Proxy *proxy = data.GetParameter();
-#else
SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
SWIGV8_Proxy *proxy = data.GetParameter();
-#endif
-
delete proxy;
}
@@ -319,12 +226,7 @@ SWIGRUNTIME int SWIG_V8_GetInstancePtr(SWIGV8_VALUE valRef, void **ptr) {
if(objRef->InternalFieldCount() < 1) return SWIG_ERROR;
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
- v8::Handle<v8::Value> cdataRef = objRef->GetInternalField(0);
- SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(v8::External::Unwrap(cdataRef));
-#else
SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(objRef->GetAlignedPointerFromInternalField(0));
-#endif
if(cdata == NULL) {
return SWIG_ERROR;
@@ -341,58 +243,17 @@ SWIGRUNTIME void SWIGV8_SetPrivateData(SWIGV8_OBJECT obj, void *ptr, swig_type_i
cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0;
cdata->info = info;
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
- obj->SetPointerInInternalField(0, cdata);
-#else
obj->SetAlignedPointerInInternalField(0, cdata);
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- cdata->handle = v8::Persistent<v8::Object>::New(obj);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
- cdata->handle = v8::Persistent<v8::Object>::New(v8::Isolate::GetCurrent(), obj);
-#else
cdata->handle.Reset(v8::Isolate::GetCurrent(), obj);
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- // clientdata must be set for owned data as we need to register the dtor
- if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
- cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
- } else {
- cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor);
- }
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031918)
- if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
- cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
- } else {
- cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor);
- }
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
- if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
- cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
- } else {
- cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor);
- }
-#elif (V8_MAJOR_VERSION-0) < 5
- if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
- cdata->handle.SetWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
- } else {
- cdata->handle.SetWeak(cdata, SWIGV8_Proxy_DefaultDtor);
- }
-#else
if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
cdata->handle.SetWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor, v8::WeakCallbackType::kParameter);
} else {
cdata->handle.SetWeak(cdata, SWIGV8_Proxy_DefaultDtor, v8::WeakCallbackType::kParameter);
}
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- cdata->handle.MarkIndependent();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
- cdata->handle.MarkIndependent(v8::Isolate::GetCurrent());
-#elif (SWIG_V8_VERSION < 0x0704)
+#if (SWIG_V8_VERSION < 0x0704)
cdata->handle.MarkIndependent();
// Looks like future versions do not require that anymore:
// https://monorail-prod.appspot.com/p/chromium/issues/detail?id=923361#c11
@@ -420,21 +281,10 @@ SWIGRUNTIME SWIGV8_VALUE SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info,
SWIGV8_FUNCTION_TEMPLATE class_templ;
if (ptr == NULL) {
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
- SWIGV8_ESCAPE(SWIGV8_NULL());
-#else
v8::Local<v8::Primitive> result = SWIGV8_NULL();
SWIGV8_ESCAPE(result);
-#endif
}
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
- if(info->clientdata != 0) {
- class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ;
- } else {
- class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ;
- }
-#else
v8::Isolate *isolate = v8::Isolate::GetCurrent();
if(info->clientdata != 0) {
@@ -442,13 +292,8 @@ SWIGRUNTIME SWIGV8_VALUE SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info,
} else {
class_templ = v8::Local<v8::FunctionTemplate>::New(isolate, SWIGV8_SWIGTYPE_Proxy_class_templ);
}
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
- v8::Local<v8::Object> result = class_templ->InstanceTemplate()->NewInstance();
-#else
v8::Local<v8::Object> result = class_templ->InstanceTemplate()->NewInstance(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked();
-#endif
SWIGV8_SetPrivateData(result, ptr, info, flags);
@@ -543,14 +388,10 @@ int SwigV8Packed_Check(SWIGV8_VALUE valRef) {
SWIGV8_OBJECT objRef = SWIGV8_TO_OBJECT(valRef);
if(objRef->InternalFieldCount() < 1) return false;
-#if (V8_MAJOR_VERSION-0) < 5
- v8::Handle<v8::Value> flag = objRef->GetHiddenValue(SWIGV8_STRING_NEW("__swig__packed_data__"));
-#else
v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("__swig__packed_data__"));
v8::Local<v8::Value> flag;
if (!objRef->GetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey).ToLocal(&flag))
return false;
-#endif
return (flag->IsBoolean() && SWIGV8_BOOLEAN_VALUE(flag));
}
@@ -563,12 +404,7 @@ swig_type_info *SwigV8Packed_UnpackData(SWIGV8_VALUE valRef, void *ptr, size_t s
SWIGV8_OBJECT objRef = SWIGV8_TO_OBJECT(valRef);
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
- v8::Handle<v8::Value> cdataRef = objRef->GetInternalField(0);
- sobj = static_cast<SwigV8PackedData*>(v8::External::Unwrap(cdataRef));
-#else
sobj = static_cast<SwigV8PackedData*>(objRef->GetAlignedPointerFromInternalField(0));
-#endif
if (sobj == NULL || sobj->size != size) return 0;
memcpy(ptr, sobj->data, size);
return sobj->type;
@@ -591,38 +427,9 @@ int SWIGV8_ConvertPacked(SWIGV8_VALUE valRef, void *ptr, size_t sz, swig_type_in
return SWIG_OK;
}
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-SWIGRUNTIME void _wrap_SwigV8PackedData_delete(v8::Persistent< v8::Value > object, void *parameter) {
- SwigV8PackedData *cdata = static_cast<SwigV8PackedData *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-SWIGRUNTIME void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent<v8::Value> object, void *parameter) {
- SwigV8PackedData *cdata = static_cast<SwigV8PackedData *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-SWIGRUNTIME void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent<v8::Object> *object, SwigV8PackedData *cdata) {
-#elif (V8_MAJOR_VERSION-0) < 5
-SWIGRUNTIME void _wrap_SwigV8PackedData_delete(const v8::WeakCallbackData<v8::Object, SwigV8PackedData> &data) {
- v8::Local<v8::Object> object = data.GetValue();
- SwigV8PackedData *cdata = data.GetParameter();
-#else
SWIGRUNTIME void _wrap_SwigV8PackedData_delete(const v8::WeakCallbackInfo<SwigV8PackedData> &data) {
SwigV8PackedData *cdata = data.GetParameter();
-#endif
-
delete cdata;
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- object.Clear();
- object.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
- object.Clear();
- object.Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
- object->Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
- object->Dispose();
-#elif (V8_MAJOR_VERSION-0) < 5
- object.Clear();
-#endif
}
SWIGRUNTIME
@@ -633,46 +440,16 @@ SWIGV8_VALUE SWIGV8_NewPackedObj(void *data, size_t size, swig_type_info *type)
// v8::Handle<v8::Object> obj = SWIGV8_OBJECT_NEW();
v8::Local<v8::Object> obj = SWIGV8_OBJECT_NEW();
-#if (V8_MAJOR_VERSION-0) < 5
- obj->SetHiddenValue(SWIGV8_STRING_NEW("__swig__packed_data__"), SWIGV8_BOOLEAN_NEW(true));
-#else
v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("__swig__packed_data__"));
obj->SetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey, SWIGV8_BOOLEAN_NEW(true));
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
- obj->SetPointerInInternalField(0, cdata);
-#else
obj->SetAlignedPointerInInternalField(0, cdata);
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- cdata->handle = v8::Persistent<v8::Object>::New(obj);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
- cdata->handle = v8::Persistent<v8::Object>::New(v8::Isolate::GetCurrent(), obj);
-#else
cdata->handle.Reset(v8::Isolate::GetCurrent(), obj);
-#endif
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- cdata->handle.MakeWeak(cdata, _wrap_SwigV8PackedData_delete);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031918)
- cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, _wrap_SwigV8PackedData_delete);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
- cdata->handle.MakeWeak(cdata, _wrap_SwigV8PackedData_delete);
-#elif (V8_MAJOR_VERSION-0) < 5
- cdata->handle.SetWeak(cdata, _wrap_SwigV8PackedData_delete);
-// v8::V8::SetWeak(&cdata->handle, cdata, _wrap_SwigV8PackedData_delete);
-#else
cdata->handle.SetWeak(cdata, _wrap_SwigV8PackedData_delete, v8::WeakCallbackType::kParameter);
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- cdata->handle.MarkIndependent();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
- cdata->handle.MarkIndependent(v8::Isolate::GetCurrent());
-#elif (SWIG_V8_VERSION < 0x0704)
+#if (SWIG_V8_VERSION < 0x0704)
cdata->handle.MarkIndependent();
// Looks like future versions do not require that anymore:
// https://monorail-prod.appspot.com/p/chromium/issues/detail?id=923361#c11
diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg
index 115554a5a..4e93fc4c1 100644
--- a/Lib/javascript/v8/javascriptruntime.swg
+++ b/Lib/javascript/v8/javascriptruntime.swg
@@ -7,36 +7,8 @@
// ----------------
//
// v8 added version macros V8_MAJOR_VERSION, V8_MINOR_VERSION, V8_BUILD_NUMBER
-// and V8_PATCH_LEVEL in version 4.3.0. SWIG generated code uses these if
-// they are defined - to support earlier versions you can specify the V8 version
-// in use via the command line when you run SWIG:
-//
-// swig -c++ -javascript -v8 -DV8_VERSION=0x032530 example.i
-//
-// Or code in the interface file using SWIG_V8_VERSION:
-//
-// %begin %{#define SWIG_V8_VERSION 0x031110%}
-//
-// This is specified as a hex constant, but the constant is read as pairs of
-// decimal digits, so for V8 3.25.30 use constant 0x032530. This scheme can't
-// represent components > 99, but this constant is only useful for V8 < 4.3.0,
-// and no V8 versions from that era had a component > 99.
-
-%define %swig_v8_define_version(version)
-%insert("runtime") %{
-#ifndef SWIG_V8_VERSION
-#define SWIG_V8_VERSION version
-#endif
-%}
-%enddef
-
-#ifdef V8_VERSION
-%swig_v8_define_version(V8_VERSION)
-#else
-// HACK: defining a default version
-%swig_v8_define_version(0x031110)
-#endif
-
+// and V8_PATCH_LEVEL in version 4.3.0. SWIG doesn't support anything that
+// old so SWIG generated code can rely on these.
// Node support
// ------------
@@ -56,10 +28,11 @@
%insert(runtime) %{
#include <v8.h>
-#if defined(V8_MAJOR_VERSION) && defined(V8_MINOR_VERSION)
#undef SWIG_V8_VERSION
-#define SWIG_V8_VERSION (V8_MAJOR_VERSION * 256 + V8_MINOR_VERSION)
-#endif
+#define SWIG_V8_VERSION ((V8_MAJOR_VERSION / 10) * 4096 + \
+ (V8_MAJOR_VERSION % 10) * 256 + \
+ (V8_MINOR_VERSION / 10) * 16 + \
+ (V8_MINOR_VERSION % 10))
#include <errno.h>
#include <limits.h>
diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg
index aaf1b9302..8dc2d945e 100644
--- a/Lib/javascript/v8/javascriptstrings.swg
+++ b/Lib/javascript/v8/javascriptstrings.swg
@@ -7,11 +7,7 @@ SWIGINTERN int
SWIG_AsCharPtrAndSize(SWIGV8_VALUE valRef, char** cptr, size_t* psize, int *alloc)
{
if(valRef->IsString()) {
-%#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
- v8::Handle<v8::String> js_str = v8::Handle<v8::String>::Cast(valRef);
-%#else
v8::Local<v8::String> js_str = v8::Local<v8::String>::Cast(valRef);
-%#endif
size_t len = SWIGV8_UTF8_LENGTH(js_str) + 1;
char* cstr = (char*) %new_array(len, char);
@@ -53,11 +49,7 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size)
// TODO: handle extra long strings
return SWIGV8_UNDEFINED();
} else {
-%#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
- v8::Handle<v8::String> js_str = SWIGV8_STRING_NEW2(carray, size);
-%#else
v8::Local<v8::String> js_str = SWIGV8_STRING_NEW2(carray, size);
-%#endif
return js_str;
}
} else {
diff --git a/Lib/javascript/v8/javascripttypemaps.swg b/Lib/javascript/v8/javascripttypemaps.swg
index cb31100c5..c4d341be5 100644
--- a/Lib/javascript/v8/javascripttypemaps.swg
+++ b/Lib/javascript/v8/javascripttypemaps.swg
@@ -37,7 +37,7 @@
#define SWIG_SetConstant(name, obj)
/* raise */
-#define SWIG_Raise(obj, type, desc) SWIG_V8_Raise(type)
+#define SWIG_Raise(obj, type, desc) SWIG_V8_Raise(obj, type)
/* Include the unified typemap library */
%include <typemaps/swigtypemaps.swg>
diff --git a/Lib/javascript/v8/std_auto_ptr.i b/Lib/javascript/v8/std_auto_ptr.i
new file mode 100644
index 000000000..3d7ae8ba1
--- /dev/null
+++ b/Lib/javascript/v8/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/javascript/v8/std_unique_ptr.i b/Lib/javascript/v8/std_unique_ptr.i
new file mode 100644
index 000000000..f988714df
--- /dev/null
+++ b/Lib/javascript/v8/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/javascript/v8/swigmove.i b/Lib/javascript/v8/swigmove.i
new file mode 100644
index 000000000..62ecca768
--- /dev/null
+++ b/Lib/javascript/v8/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/javascript/v8/typemaps.i b/Lib/javascript/v8/typemaps.i
index e68b6654a..e88f0019e 100644
--- a/Lib/javascript/v8/typemaps.i
+++ b/Lib/javascript/v8/typemaps.i
@@ -72,7 +72,7 @@ multiple output values, they are returned in the form of a Python tuple.
For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
+returns the integer part in one of its parameters) :
double modf(double x, double *ip);
diff --git a/Lib/lua/argcargv.i b/Lib/lua/argcargv.i
new file mode 100644
index 000000000..94cc8ed42
--- /dev/null
+++ b/Lib/lua/argcargv.i
@@ -0,0 +1,57 @@
+/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+
+ Use it as follows:
+
+ %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+ extern int mainApp(size_t argc, const char **argv);
+
+ then from lua:
+
+ args = { "arg0", "arg1" }
+ mainApp(args)
+
+ * ------------------------------------------------------------ */
+
+%{
+SWIGINTERN int SWIG_argv_size(lua_State* L, int index) {
+ int n=0;
+ while(1){
+ lua_rawgeti(L,index,n+1);
+ if (lua_isnil(L,-1))
+ break;
+ ++n;
+ lua_pop(L,1);
+ }
+ lua_pop(L,1);
+ return n;
+}
+%}
+
+%typemap(in) (int ARGC, char **ARGV) {
+ if (lua_istable(L,$input)) {
+ int i, size = SWIG_argv_size(L,$input);
+ $1 = ($1_ltype) size;
+ $2 = (char **) malloc((size+1)*sizeof(char *));
+ for (i = 0; i < size; i++) {
+ lua_rawgeti(L,$input,i+1);
+ if (lua_isnil(L,-1))
+ break;
+ $2[i] = (char *)lua_tostring(L, -1);
+ lua_pop(L,1);
+ }
+ $2[i]=NULL;
+ } else {
+ $1 = 0; $2 = 0;
+ lua_pushstring(L,"Expecting argv array");
+ lua_error(L);
+ }
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ $1 = lua_istable(L,$input);
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ free((char *) $2);
+}
diff --git a/Lib/lua/lua.swg b/Lib/lua/lua.swg
index 6db3add6e..12c635d77 100644
--- a/Lib/lua/lua.swg
+++ b/Lib/lua/lua.swg
@@ -151,7 +151,7 @@ The python/lua ones are great, but C++ ones I don't like
(mainly because I cannot get the stack trace out of it)
Therefore I have not bothered to try doing much in this
-Therefore currently its just enough to get a few test cases running ok
+Therefore currently it's just enough to get a few test cases running ok
note: if you wish to throw anything related to std::exception
use %include <std_except.i> instead
@@ -191,7 +191,7 @@ use %include <std_except.i> instead
Throwing object is a serious problem:
Assuming some code throws a 'FooBar'
There are a few options:
-- return a pointer to it: but its unclear how long this will last for.
+- return a pointer to it: but it's unclear how long this will last for.
- return a copy of it: but not all objects are copyable
(see exception_partial_info in the test suite for a case where you cannot do this)
- convert to a string & throw that
@@ -213,7 +213,7 @@ SWIG_fail;%}
// %apply SWIGTYPE EXCEPTION_BY_VAL {FooBar};
// %apply SWIGTYPE& EXCEPTION_BY_VAL {FooBar&}; // note: need & twice
%typemap(throws) SWIGTYPE EXCEPTION_BY_VAL
-%{SWIG_NewPointerObj(L,(void *)new $1_ltype(($1_ltype &) $1),$&1_descriptor,1);
+%{SWIG_NewPointerObj(L,(void *)new $1_ltype($1),$&1_descriptor,1);
SWIG_fail;%}
// similar for object reference
@@ -224,7 +224,7 @@ SWIG_fail;%}
// note: no support for object pointers
-// its not clear how long the pointer is valid for, therefore not supporting it
+// it's not clear how long the pointer is valid for, therefore not supporting it
/* -----------------------------------------------------------------------------
* extras
diff --git a/Lib/lua/lua_fnptr.i b/Lib/lua/lua_fnptr.i
index 481cfafa6..81fa54bd2 100644
--- a/Lib/lua/lua_fnptr.i
+++ b/Lib/lua/lua_fnptr.i
@@ -17,7 +17,7 @@ note: it should be passed by value, not byref or as a pointer.
The SWIGLUA_FN holds a pointer to the lua_State, and the stack index where the function is held.
The macro SWIGLUA_FN_GET() will put a copy of the lua function at the top of the stack.
-After that its fairly simple to write the rest of the code (assuming know how to use lua),
+After that it's fairly simple to write the rest of the code (assuming know how to use lua),
just push the parameters, call the function and return the result.
int my_func(int a, int b, SWIGLUA_FN fn)
diff --git a/Lib/lua/luakw.swg b/Lib/lua/luakw.swg
index fc2f92bfe..394e40053 100644
--- a/Lib/lua/luakw.swg
+++ b/Lib/lua/luakw.swg
@@ -2,7 +2,7 @@
Warnings for Lua keywords, built-in names and bad names.
*/
-#define LUAKW(x) %keywordwarn("'" `x` "' is a Lua keyword, renaming to 'c_" `x` "'", rename="c_%s") `x`
+#define LUAKW(x) %keywordwarn("'" `x` "' is a Lua keyword", rename="c_%s") `x`
#define LUABN(x) %namewarn(%warningmsg(SWIGWARN_PARSE_BUILTIN_NAME, "'" `x` "' conflicts with a basic function in Lua"), %$not %$ismember) `x`
/*
diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg
index 6ef2c6f15..909a5229c 100644
--- a/Lib/lua/luarun.swg
+++ b/Lib/lua/luarun.swg
@@ -307,7 +307,7 @@ typedef struct {
/* Contract support */
#define SWIG_contract_assert(expr, msg) \
- if (!(expr)) { SWIG_Lua_pusherrstring(L, (char *) msg); goto fail; } else
+ do { if (!(expr)) { SWIG_Lua_pusherrstring(L, (char *) msg); goto fail; } } while (0)
/* helper #defines */
@@ -826,7 +826,7 @@ SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, i
/* NEW: looks for the __getitem() fn
this is a user provided get fn */
SWIG_Lua_get_table(L,"__getitem"); /* find the __getitem fn */
- if (lua_iscfunction(L,-1)) /* if its there */
+ if (lua_iscfunction(L,-1)) /* if it's there */
{ /* found it so call the fn & return its value */
lua_pushvalue(L,substack_start+1); /* the userdata */
lua_pushvalue(L,substack_start+2); /* the parameter */
@@ -883,7 +883,7 @@ SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SW
lua_pushvalue(L,substack_start+2); /* key */
lua_rawget(L,-2); /* look for the fn */
lua_remove(L,-2); /* stack tidy, remove .fn table */
- if (lua_isfunction(L,-1)) /* note: if its a C function or lua function */
+ if (lua_isfunction(L,-1)) /* note: if it's a C function or lua function */
{ /* found it so return the fn & let lua call it */
lua_remove(L,-2); /* stack tidy, remove metatable */
if(ret)
@@ -966,7 +966,7 @@ SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int fi
/* NEW: looks for the __setitem() fn
this is a user provided set fn */
SWIG_Lua_get_table(L,"__setitem"); /* find the fn */
- if (lua_iscfunction(L,-1)) /* if its there */
+ if (lua_iscfunction(L,-1)) /* if it's there */
{ /* found it so call the fn & return its value */
lua_pushvalue(L,substack_start+1); /* the userdata */
lua_pushvalue(L,substack_start+2); /* the parameter */
@@ -1343,7 +1343,7 @@ SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State *L, swig_lua_clas
SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L); /*forward declaration*/
/* The real function that resolves a metamethod.
- * Function searches given class and all it's bases(recursively) for first instance of something that is
+ * Function searches given class and all its bases (recursively) for first instance of something that is
* not equal to SWIG_Lua_resolve_metamethod. (Almost always this 'something' is actual metamethod implementation
* and it is a SWIG-generated C function.). It returns value on the top of the L and there is no garbage below the
* answer.
@@ -1757,6 +1757,7 @@ SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L,void *ptr,swig_type_info *t
(if possible) */
SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State *L,int index,void **ptr,swig_type_info *type,int flags)
{
+ int ret = SWIG_ERROR;
swig_lua_userdata *usr;
swig_cast_info *cast;
/* special case: lua nil => NULL pointer */
@@ -1773,30 +1774,41 @@ SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State *L,int index,void **ptr,swig_type
usr=(swig_lua_userdata*)lua_touserdata(L,index); /* get data */
if (usr)
{
+ if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !usr->own)
+ {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ }
if (flags & SWIG_POINTER_DISOWN) /* must disown the object */
{
- usr->own=0;
+ usr->own = 0;
}
if (!type) /* special cast void*, no casting fn */
{
*ptr=usr->ptr;
- return SWIG_OK; /* ok */
+ ret = SWIG_OK;
}
- cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */
- if (cast)
+ else
{
- int newmemory = 0;
- *ptr=SWIG_TypeCast(cast,usr->ptr,&newmemory);
- assert(!newmemory); /* newmemory handling not yet implemented */
- return SWIG_OK; /* ok */
+ cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */
+ if (cast)
+ {
+ int newmemory = 0;
+ *ptr=SWIG_TypeCast(cast,usr->ptr,&newmemory);
+ assert(!newmemory); /* newmemory handling not yet implemented */
+ ret = SWIG_OK;
+ }
+ }
+ if ((ret == SWIG_OK) && (flags & SWIG_POINTER_CLEAR))
+ {
+ usr->ptr = 0;
}
}
- return SWIG_ERROR; /* error */
+ return ret;
}
SWIGRUNTIME void* SWIG_Lua_MustGetPtr(lua_State *L,int index,swig_type_info *type,int flags,
int argnum,const char *func_name){
- void *result;
+ void *result = 0;
if (!SWIG_IsOK(SWIG_ConvertPtr(L,index,&result,type,flags))){
luaL_error (L,"Error in %s, expected a %s at argument number %d\n",
func_name,(type && type->str)?type->str:"void*",argnum);
diff --git a/Lib/lua/luatypemaps.swg b/Lib/lua/luatypemaps.swg
index 3f531bd05..7d23917ee 100644
--- a/Lib/lua/luatypemaps.swg
+++ b/Lib/lua/luatypemaps.swg
@@ -24,7 +24,7 @@
// additional check for unsigned numbers, to not permit negative input
%typemap(in,checkfn="lua_isnumber") unsigned int,
unsigned short, unsigned long, unsigned char
-%{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative")
+%{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative");
$1 = ($type)lua_tonumber(L, $input);%}
%typemap(out) int,short,long,
@@ -43,7 +43,7 @@ $1 = ($type)lua_tonumber(L, $input);%}
%{ temp=($*1_ltype)lua_tonumber(L,$input); $1=&temp;%}
%typemap(in,checkfn="lua_isnumber") const unsigned int&($*1_ltype temp)
-%{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative")
+%{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative");
temp=($*1_ltype)lua_tonumber(L,$input); $1=&temp;%}
%typemap(out) const int&, const unsigned int&
@@ -151,11 +151,17 @@ SWIGINTERN int SWIG_lua_isnilstring(lua_State *L, int idx) {
}
%}
-%typemap(in,checkfn="lua_isuserdata") SWIGTYPE&&
-%{
- if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,$disown))){
- SWIG_fail_ptr("$symname",$argnum,$descriptor);
+%typemap(in,checkfn="lua_isuserdata",fragment="<memory>") SWIGTYPE&& (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) %{
+ res = SWIG_ConvertPtr(L, $input, &argp, $descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type '$1_type' in $symname"); SWIG_fail;
+ } else {
+ SWIG_fail_ptr("$symname", $argnum, $descriptor);
+ }
}
+ $1 = ($1_ltype)argp;
+ rvrdeleter.reset($1);
%}
// out is simple
@@ -217,7 +223,7 @@ $1=($1_ltype)&temp;%}
#ifdef __cplusplus
%typemap(out) SWIGTYPE
{
- $&1_ltype resultptr = new $1_ltype((const $1_ltype &) $1);
+ $&1_ltype resultptr = new $1_ltype($1);
SWIG_NewPointerObj(L,(void *) resultptr,$&1_descriptor,1); SWIG_arg++;
}
#else
@@ -248,11 +254,11 @@ $1=($1_ltype)&temp;%}
// void (must be empty without the SWIG_arg++)
-%typemap(out) void "";
+%typemap(out) void ""
/* void* is a special case
A function void fn(void*) should take any kind of pointer as a parameter (just like C/C++ does)
-but if its an output, then it should be wrapped like any other SWIG object (using default typemap)
+but if it's an output, then it should be wrapped like any other SWIG object (using default typemap)
*/
%typemap(in,checkfn="SWIG_isptrtype") void*
%{$1=($1_ltype)SWIG_MustGetPtr(L,$input,0,0,$argnum,"$symname");%}
@@ -285,7 +291,7 @@ parameters match which function
// unfortunately lua only considers one type of number
// so all numbers (int,float,double) match
-// you could add an advanced fn to get type & check if its integral
+// you could add an advanced fn to get type & check if it's integral
%typecheck(SWIG_TYPECHECK_INTEGER)
int, short, long,
unsigned int, unsigned short, unsigned long,
@@ -396,7 +402,7 @@ parameters match which function
* Specials
* ----------------------------------------------------------------------------- */
// swig::LANGUAGE_OBJ was added to allow containers of native objects
-// however its rather difficult to do this in lua, as you cannot hold pointers
+// however it's rather difficult to do this in lua, as you cannot hold pointers
// to native objects (they are held in the interpreter)
// therefore for now: just ignoring this feature
#ifdef __cplusplus
diff --git a/Lib/lua/std_auto_ptr.i b/Lib/lua/std_auto_ptr.i
new file mode 100644
index 000000000..b3b71d0f2
--- /dev/null
+++ b/Lib/lua/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, checkfn="SWIG_isptrtype", noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr(L, $input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *' in $symname"); SWIG_fail;
+ } else {
+ SWIG_fail_ptr("$symname", $argnum, $descriptor(TYPE *));
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ SWIG_NewPointerObj(L, $1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN); SWIG_arg++;
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(L, $input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/lua/std_unique_ptr.i b/Lib/lua/std_unique_ptr.i
new file mode 100644
index 000000000..ad08f3b0e
--- /dev/null
+++ b/Lib/lua/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, checkfn="SWIG_isptrtype", noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr(L, $input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *' in $symname"); SWIG_fail;
+ } else {
+ SWIG_fail_ptr("$symname", $argnum, $descriptor(TYPE *));
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ SWIG_NewPointerObj(L, $1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN); SWIG_arg++;
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(L, $input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/lua/swigmove.i b/Lib/lua/swigmove.i
new file mode 100644
index 000000000..d130e797a
--- /dev/null
+++ b/Lib/lua/swigmove.i
@@ -0,0 +1,18 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, checkfn="lua_isuserdata", noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr(L, $input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type '$1_type' in $symname"); SWIG_fail;
+ } else {
+ SWIG_fail_ptr("$symname", $argnum, $&1_descriptor);
+ }
+ }
+ SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/lua/typemaps.i b/Lib/lua/typemaps.i
index 8392e5bfa..68f6f6cca 100644
--- a/Lib/lua/typemaps.i
+++ b/Lib/lua/typemaps.i
@@ -28,7 +28,7 @@ The basic code looks like this:
However the code below is a mixture of #defines & such, so nowhere as easy to read
-To make you code work correctly its not just a matter of %including this file
+To make you code work correctly it's not just a matter of %including this file
You also have to give SWIG the hints on which to use where
eg
@@ -77,7 +77,7 @@ SWIG_NUMBER_TYPEMAP(enum SWIGTYPE);
// also for long longs's
SWIG_NUMBER_TYPEMAP(long long); SWIG_NUMBER_TYPEMAP(unsigned long long); SWIG_NUMBER_TYPEMAP(signed long long);
-// note we dont do char, as a char* is probably a string not a ptr to a single char
+// note we don't do char, as a char* is probably a string not a ptr to a single char
// similar for booleans
%typemap(in,checkfn="lua_isboolean") bool *INPUT(bool temp), bool &INPUT(bool temp)
@@ -188,16 +188,6 @@ int SWIG_read_NAME_num_array(lua_State* L,int index,TYPE *array,int size);
*/
-/* Reported that you don't need to check for NULL for delete & free
-There probably is some compiler that its not true for, so the code is left here just in case.
-#ifdef __cplusplus
-#define SWIG_ALLOC_ARRAY(TYPE,LEN) new TYPE[LEN]
-#define SWIG_FREE_ARRAY(PTR) if(PTR){delete[] PTR;}
-#else
-#define SWIG_ALLOC_ARRAY(TYPE,LEN) (TYPE *)malloc(LEN*sizeof(TYPE))
-#define SWIG_FREE_ARRAY(PTR) if(PTR){free(PTR);}
-#endif
-*/
%{
#ifdef __cplusplus /* generic alloc/dealloc fns*/
#define SWIG_ALLOC_ARRAY(TYPE,LEN) new TYPE[LEN]
diff --git a/Lib/mzscheme/mzrun.swg b/Lib/mzscheme/mzrun.swg
index c438c9ce8..57d040812 100644
--- a/Lib/mzscheme/mzrun.swg
+++ b/Lib/mzscheme/mzrun.swg
@@ -23,12 +23,14 @@ extern "C" {
SWIG_MzScheme_MustGetPtr(s, type, argnum, flags, FUNC_NAME, argc, argv)
#define SWIG_contract_assert(expr,msg) \
- if (!(expr)) { \
- char *m=(char *) scheme_malloc(strlen(msg)+1000); \
- sprintf(m,"SWIG contract, assertion failed: function=%s, message=%s", \
- (char *) FUNC_NAME,(char *) msg); \
- scheme_signal_error(m); \
- }
+ do { \
+ if (!(expr)) { \
+ char *m=(char *) scheme_malloc(strlen(msg)+1000); \
+ sprintf(m,"SWIG contract, assertion failed: function=%s, message=%s", \
+ (char *) FUNC_NAME,(char *) msg); \
+ scheme_signal_error(m); \
+ } \
+ } while (0)
/* Runtime API */
#define SWIG_GetModule(clientdata) SWIG_MzScheme_GetModule((Scheme_Env *)(clientdata))
@@ -123,6 +125,7 @@ struct swig_mz_proxy {
Scheme_Type mztype;
swig_type_info *type;
void *object;
+ int own;
};
static Scheme_Type swig_type;
@@ -133,7 +136,7 @@ mz_free_swig(void *p, void *data) {
if (SCHEME_NULLP((Scheme_Object*)p) || SCHEME_TYPE((Scheme_Object*)p) != swig_type)
return;
if (proxy->type) {
- if (proxy->type->clientdata) {
+ if (proxy->type->clientdata && proxy->own) {
((Scheme_Prim *)proxy->type->clientdata)(1, (Scheme_Object **)&proxy);
}
}
@@ -141,42 +144,61 @@ mz_free_swig(void *p, void *data) {
static Scheme_Object *
SWIG_MzScheme_NewPointerObj(void *ptr, swig_type_info *type, int owner) {
- struct swig_mz_proxy *new_proxy;
- new_proxy = (struct swig_mz_proxy *) scheme_malloc(sizeof(struct swig_mz_proxy));
- new_proxy->mztype = swig_type;
- new_proxy->type = type;
- new_proxy->object = ptr;
- if (owner) {
- scheme_add_finalizer(new_proxy, mz_free_swig, NULL);
+ if (ptr) {
+ struct swig_mz_proxy *new_proxy;
+ new_proxy = (struct swig_mz_proxy *) scheme_malloc(sizeof(struct swig_mz_proxy));
+ new_proxy->mztype = swig_type;
+ new_proxy->type = type;
+ new_proxy->object = ptr;
+ new_proxy->own = owner & SWIG_POINTER_OWN;
+ if (new_proxy->own) {
+ scheme_add_finalizer(new_proxy, mz_free_swig, NULL);
+ }
+ return (Scheme_Object *) new_proxy;
+ } else {
+ return scheme_make_null();
}
- return (Scheme_Object *) new_proxy;
}
static int
SWIG_MzScheme_ConvertPtr(Scheme_Object *s, void **result, swig_type_info *type, int flags) {
swig_cast_info *cast;
+ int ret = SWIG_ERROR;
if (SCHEME_NULLP(s)) {
*result = NULL;
return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
} else if (SCHEME_TYPE(s) == swig_type) {
struct swig_mz_proxy *proxy = (struct swig_mz_proxy *) s;
+
+ if ((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE && !proxy->own) {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ }
+
if (type) {
cast = SWIG_TypeCheckStruct(proxy->type, type);
if (cast) {
int newmemory = 0;
*result = SWIG_TypeCast(cast, proxy->object, &newmemory);
assert(!newmemory); /* newmemory handling not yet implemented */
- return 0;
+ ret = SWIG_OK;
} else {
- return 1;
+ return SWIG_ERROR;
}
} else {
*result = proxy->object;
- return 0;
+ ret = SWIG_OK;
+ }
+
+ if (flags & SWIG_POINTER_DISOWN) {
+ scheme_subtract_finalizer(proxy, mz_free_swig, NULL);
+ proxy->own = 0;
+ }
+ if (flags & SWIG_POINTER_CLEAR) {
+ proxy->object = 0;
}
}
- return 1;
+ return ret;
}
static SWIGINLINE void *
diff --git a/Lib/mzscheme/std_auto_ptr.i b/Lib/mzscheme/std_auto_ptr.i
new file mode 100644
index 000000000..c61bc8b26
--- /dev/null
+++ b/Lib/mzscheme/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ scheme_signal_error(FUNC_NAME ": cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *'");
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/mzscheme/std_string.i b/Lib/mzscheme/std_string.i
index b19e8567a..70673eadf 100644
--- a/Lib/mzscheme/std_string.i
+++ b/Lib/mzscheme/std_string.i
@@ -52,6 +52,13 @@ namespace std {
$result = scheme_make_string($1->c_str());
}
+ %typemap(throws) string {
+ scheme_signal_error("%s: %s", FUNC_NAME, $1.c_str());
+ }
+
+ %typemap(throws) const string & {
+ scheme_signal_error("%s: %s", FUNC_NAME, $1.c_str());
+ }
}
diff --git a/Lib/mzscheme/std_unique_ptr.i b/Lib/mzscheme/std_unique_ptr.i
new file mode 100644
index 000000000..53cf46694
--- /dev/null
+++ b/Lib/mzscheme/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ scheme_signal_error(FUNC_NAME ": cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *'");
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/mzscheme/swigmove.i b/Lib/mzscheme/swigmove.i
new file mode 100644
index 000000000..bbfcdcb16
--- /dev/null
+++ b/Lib/mzscheme/swigmove.i
@@ -0,0 +1,19 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ scheme_signal_error(FUNC_NAME ": cannot release ownership as memory is not owned for argument $argnum of type '$1_type'");
+ } else {
+ %argument_fail(res, "$1_type", $symname, $argnum);
+ }
+ }
+ if (argp == NULL) scheme_signal_error(FUNC_NAME ": swig-type-error (null reference)");
+ SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/mzscheme/typemaps.i b/Lib/mzscheme/typemaps.i
index 09bda2cca..6c31aea52 100644
--- a/Lib/mzscheme/typemaps.i
+++ b/Lib/mzscheme/typemaps.i
@@ -2,6 +2,12 @@
* typemaps.i
* ----------------------------------------------------------------------------- */
+#define %set_output(obj) $result = obj
+#define %set_varoutput(obj) $result = obj
+#define %argument_fail(code, type, name, argn) scheme_wrong_type(FUNC_NAME, type, argn, argc, argv)
+#define %as_voidptr(ptr) (void*)(ptr)
+
+
/* The MzScheme module handles all types uniformly via typemaps. Here
are the definitions. */
@@ -66,9 +72,23 @@
#ifdef __cplusplus
-%typemap(in) SWIGTYPE &, SWIGTYPE && {
+%typemap(in) SWIGTYPE & {
$1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, $argnum, 0);
- if ($1 == NULL) scheme_signal_error("swig-type-error (null reference)");
+ if ($1 == NULL) scheme_signal_error(FUNC_NAME ": swig-type-error (null reference)");
+}
+
+%typemap(in, noblock=1, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ scheme_signal_error(FUNC_NAME ": cannot release ownership as memory is not owned for argument $argnum of type '$1_type'");
+ } else {
+ %argument_fail(res, "$1_type", $symname, $argnum);
+ }
+ }
+ if (argp == NULL) scheme_signal_error(FUNC_NAME ": swig-type-error (null reference)");
+ $1 = ($1_ltype)argp;
+ rvrdeleter.reset($1);
}
%typemap(out) SWIGTYPE &, SWIGTYPE && {
@@ -105,8 +125,8 @@
$1 = ($1_type) SWIG_convert_int($input);
}
-%typemap(out) enum SWIGTYPE "$result = scheme_make_integer_value($1);";
-%typemap(varout) enum SWIGTYPE "$result = scheme_make_integer_value($1);";
+%typemap(out) enum SWIGTYPE "$result = scheme_make_integer_value($1);"
+%typemap(varout) enum SWIGTYPE "$result = scheme_make_integer_value($1);"
/* Pass-by-value */
@@ -127,7 +147,7 @@
#ifdef __cplusplus
{
$&1_ltype resultptr;
- resultptr = new $1_ltype(($1_ltype &) $1);
+ resultptr = new $1_ltype($1);
$result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 1);
}
#else
@@ -143,7 +163,7 @@
#ifdef __cplusplus
{
$&1_ltype resultptr;
- resultptr = new $1_ltype(($1_ltype &) $1);
+ resultptr = new $1_ltype($1);
$result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 0);
}
#else
@@ -270,14 +290,18 @@ REF_MAP(float, SCHEME_REALP, scheme_real_to_double,
REF_MAP(double, SCHEME_REALP, scheme_real_to_double,
scheme_make_double, real);
+%typemap(throws) char * {
+ scheme_signal_error("%s: %s", FUNC_NAME, $1);
+}
+
/* Void */
-%typemap(out) void "$result = scheme_void;";
+%typemap(out) void "$result = scheme_void;"
/* Pass through Scheme_Object * */
-%typemap (in) Scheme_Object * "$1=$input;";
-%typemap (out) Scheme_Object * "$result=$1;";
+%typemap (in) Scheme_Object * "$1=$input;"
+%typemap (out) Scheme_Object * "$result=$1;"
%typecheck(SWIG_TYPECHECK_POINTER) Scheme_Object * "$1=1;";
@@ -291,7 +315,6 @@ REF_MAP(double, SCHEME_REALP, scheme_real_to_double,
// $2 = ($2_ltype) temp;
//}
-
/* ------------------------------------------------------------
* Typechecking rules
* ------------------------------------------------------------ */
diff --git a/Lib/ocaml/ocaml.swg b/Lib/ocaml/ocaml.swg
index afb01daea..703b7e448 100644
--- a/Lib/ocaml/ocaml.swg
+++ b/Lib/ocaml/ocaml.swg
@@ -40,9 +40,10 @@
$1 = ($ltype) caml_ptr_val($input,$1_descriptor);
}
-%typemap(in) SWIGTYPE && {
+%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{
$1 = ($ltype) caml_ptr_val($input,$1_descriptor);
-}
+ rvrdeleter.reset($1);
+%}
%typemap(varin) SWIGTYPE & {
$1 = *(($ltype) caml_ptr_val($input,$1_descriptor));
@@ -93,10 +94,14 @@
$1 = *(($&1_ltype) caml_ptr_val($input,$&1_descriptor)) ;
}
+%typemap(varout) SWIGTYPE {
+ $result = SWIG_Ocaml_ptr_to_val("create_$ntype_from_ptr", (void *)&$1, $&1_descriptor);
+}
+
#ifdef __cplusplus
%typemap(out) SWIGTYPE {
- $&1_ltype temp = new $ltype((const $1_ltype &) $1);
+ $&1_ltype temp = new $1_ltype($1);
$result = SWIG_Ocaml_ptr_to_val("create_$ntype_from_ptr", (void *)temp, $&1_descriptor);
}
@@ -110,8 +115,12 @@
#endif
+%typemap(varout) SWIGTYPE * {
+ $result = SWIG_Ocaml_ptr_to_val("create_$ntype_from_ptr", (void *)$1, $1_descriptor);
+}
+
%typemap(directorin) SWIGTYPE {
- $&ltype temp = new $ltype((const $ltype &)$1);
+ $&ltype temp = new $1_ltype(SWIG_STD_MOVE($1));
swig_result = SWIG_Ocaml_ptr_to_val("create_$ltype_from_ptr", (void *)temp, $&1_descriptor);
args = caml_list_append(args, swig_result);
}
@@ -180,12 +189,12 @@ SIMPLE_MAP(unsigned long long,caml_val_ulong,caml_long_val);
/* Void */
-%typemap(out) void "$result = Val_unit;";
+%typemap(out) void "$result = Val_unit;"
/* Pass through value */
-%typemap (in) CAML_VALUE "$1=$input;";
-%typemap (out) CAML_VALUE "$result=$1;";
+%typemap (in) CAML_VALUE "$1=$input;"
+%typemap (out) CAML_VALUE "$result=$1;"
#if 0
%include <carray.i>
@@ -302,7 +311,7 @@ SIMPLE_MAP(unsigned long long,caml_val_ulong,caml_long_val);
/* Array reference typemaps */
%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
-%apply SWIGTYPE && { SWIGTYPE ((&)[ANY]) }
+%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
/* const pointers */
%apply SWIGTYPE * { SWIGTYPE *const }
diff --git a/Lib/ocaml/ocamlrun.swg b/Lib/ocaml/ocamlrun.swg
index 5a923c5fe..53ad952fb 100644
--- a/Lib/ocaml/ocamlrun.swg
+++ b/Lib/ocaml/ocamlrun.swg
@@ -369,7 +369,7 @@ extern "C" {
if( !p || len < 0 ) CAMLreturn(caml_val_ptr( (void *)p, 0 ));
vv = caml_swig_alloc(1,C_string);
SWIG_Store_field(vv,0,caml_alloc_string(len));
- memcpy(String_val(SWIG_Field(vv,0)),p,len);
+ memcpy(Bp_val(SWIG_Field(vv,0)),p,len);
CAMLreturn(vv);
}
diff --git a/Lib/ocaml/ocamlrundec.swg b/Lib/ocaml/ocamlrundec.swg
index 555f9a44f..dde0b8e5c 100644
--- a/Lib/ocaml/ocamlrundec.swg
+++ b/Lib/ocaml/ocamlrundec.swg
@@ -164,7 +164,7 @@ SWIGINTERN void SWIG_OCamlThrowException(SWIG_OCamlExceptionCodes code, const ch
CAMLreturn0;
}
-#define SWIG_contract_assert(expr, msg) if(!(expr)) {SWIG_OCamlThrowException(SWIG_OCamlRuntimeException, msg);}
+#define SWIG_contract_assert(expr, msg) do { if(!(expr)) {SWIG_OCamlThrowException(SWIG_OCamlRuntimeException, msg);} } while (0)
SWIGINTERN int
SWIG_GetPtr(void *source, void **result, swig_type_info *type, swig_type_info *result_type);
diff --git a/Lib/ocaml/std_string.i b/Lib/ocaml/std_string.i
index 712c3bb73..2564cfb38 100644
--- a/Lib/ocaml/std_string.i
+++ b/Lib/ocaml/std_string.i
@@ -83,10 +83,22 @@ class wstring;
$result = caml_val_string_len($1.c_str(),$1.size());
}
+%typemap(varout) string {
+ $result = caml_val_string_len($1.c_str(),$1.size());
+}
+
%typemap(out) string * {
$result = caml_val_string_len((*$1).c_str(),(*$1).size());
}
+
+%typemap(varout) string * {
+ $result = caml_val_string_len((*$1).c_str(),(*$1).size());
+}
+
%typemap(typecheck) string, const string & = char *;
+
+%typemap(throws) string, const string & "SWIG_OCamlThrowException(SWIG_OCamlRuntimeException, $1.c_str());"
+
}
#ifdef ENABLE_CHARPTR_ARRAY
diff --git a/Lib/ocaml/swigmove.i b/Lib/ocaml/swigmove.i
new file mode 100644
index 000000000..32f9903bd
--- /dev/null
+++ b/Lib/ocaml/swigmove.i
@@ -0,0 +1,11 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0) {
+ argp1 = ($&1_ltype) caml_ptr_val($input,$&1_descriptor);
+ SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/octave/argcargv.i b/Lib/octave/argcargv.i
new file mode 100644
index 000000000..8d455e586
--- /dev/null
+++ b/Lib/octave/argcargv.i
@@ -0,0 +1,44 @@
+/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------ */
+
+%typemap(in) (int ARGC, char **ARGV) {
+ if ($input.is_scalar_type()) {
+ $1 = 0; $2 = NULL;
+ %argument_fail(SWIG_TypeError, "'int ARGC, char **ARGV' is not a list", $symname, $argnum);
+ }
+ octave_value_list list = $input.list_value();
+ int i, len = list.length();
+ $1 = ($1_ltype) len;
+ $2 = (char **) malloc((len+1)*sizeof(char *));
+ for (i = 0; i < len; i++) {
+ if (!list(i).is_string()) {
+ $1 = 0;
+ %argument_fail(SWIG_TypeError, "'int ARGC, char **ARGV' use a non-string", $symname, $argnum);
+ }
+ $2[i] = (char *)list(i).string_value().c_str();
+ }
+ $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ $1 = 0;
+ const octave_value& ov = $input;
+ if (!ov.is_scalar_type()) {
+ octave_value_list list = ov.list_value();
+ int i, len = list.length();
+ $1 = 1;
+ for (i = 0; i < len; i++) {
+ if (!list(i).is_string()) {
+ $1 = 0;
+ break;
+ }
+ }
+ }
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ if ($2 != NULL) {
+ free((void *)$2);
+ }
+}
diff --git a/Lib/octave/boost_shared_ptr.i b/Lib/octave/boost_shared_ptr.i
index 668bf4354..87c89b5f9 100644
--- a/Lib/octave/boost_shared_ptr.i
+++ b/Lib/octave/boost_shared_ptr.i
@@ -35,7 +35,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -54,12 +54,12 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/octave/octcontainer.swg b/Lib/octave/octcontainer.swg
index 80d593f4f..394c90bac 100644
--- a/Lib/octave/octcontainer.swg
+++ b/Lib/octave/octcontainer.swg
@@ -569,8 +569,17 @@ namespace swig {
} else {
return octseq.check() ? SWIG_OK : SWIG_ERROR;
}
- } catch (std::exception& e) {
+ }
+%#if SWIG_OCTAVE_PREREQ(6,0,0)
+ catch (octave::execution_exception& exec) {
+ }
+%#endif
+ catch (std::exception& e) {
+%#if SWIG_OCTAVE_PREREQ(6,0,0)
+ if (seq) // Know that octave is not in an error state
+%#else
if (seq&&!error_state)
+%#endif
error("swig type error: %s",e.what());
return SWIG_ERROR;
}
diff --git a/Lib/octave/octheaders.hpp b/Lib/octave/octheaders.hpp
index abf6428e7..26e5564d4 100644
--- a/Lib/octave/octheaders.hpp
+++ b/Lib/octave/octheaders.hpp
@@ -9,8 +9,8 @@
// g++ -c -include octheaders.hpp ...
//
-#if !defined(_SWIG_OCTAVE_OCTHEADERS_HPP)
-#define _SWIG_OCTAVE_OCTHEADERS_HPP
+#if !defined(SWIG_OCTAVE_OCTHEADERS_HPP)
+#define SWIG_OCTAVE_OCTHEADERS_HPP
// Required C++ headers
#include <cstdlib>
@@ -127,4 +127,4 @@
#include <octave/call-stack.h>
#endif
-#endif // !defined(_SWIG_OCTAVE_OCTHEADERS_HPP)
+#endif // !defined(SWIG_OCTAVE_OCTHEADERS_HPP)
diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg
index 1069e0e54..2973318c4 100644
--- a/Lib/octave/octrun.swg
+++ b/Lib/octave/octrun.swg
@@ -171,7 +171,16 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
octave_function* function_value(bool = false) { return this; }
+#if SWIG_OCTAVE_PREREQ(6,0,0)
octave_value_list call(octave::tree_evaluator& tw, int nargout = 0, const octave_value_list& args = octave_value_list()) {
+ return execute(tw,nargout,args);
+ }
+#endif
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ octave_value_list execute(octave::tree_evaluator& tw, int nargout = 0, const octave_value_list& args = octave_value_list()) {
+#else
+ octave_value_list call(octave::tree_evaluator& tw, int nargout = 0, const octave_value_list& args = octave_value_list()) {
+#endif
octave_value_list all_args;
all_args.append(first_args);
all_args.append(args);
@@ -223,7 +232,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
const swig_type_info *construct_type; // type of special type object
std::vector < type_ptr_pair > types; // our c++ base classes
- int own; // whether we call c++ destructors when we die
+ int thisown; // whether we call c++ destructors when we die
typedef std::pair < const swig_octave_member *, octave_value > member_value_pair;
typedef std::map < std::string, member_value_pair > member_map;
@@ -403,7 +412,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
octave_swig_type(void *_ptr = 0, const swig_type_info *_type = 0, int _own = 0,
bool _always_static = false)
- : module(0), construct_type(_ptr ? 0 : _type), own(_own),
+ : module(0), construct_type(_ptr ? 0 : _type), thisown(_own),
always_static(_always_static) {
if (_type || _ptr)
types.push_back(std::make_pair(_type, _ptr));
@@ -417,7 +426,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
}
~octave_swig_type() {
- if (own) {
+ if (thisown) {
++count;
for (unsigned int j = 0; j < types.size(); ++j) {
if (!types[j].first || !types[j].first->clientdata)
@@ -456,10 +465,20 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
// Fill in dim_vector
for (int k=0;k<ndim;k++) {
const octave_value& obj = c(k);
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ try {
+ d.elem(k) = obj.int_value();
+ }
+ catch (octave::execution_exception& oee) {
+ // __dims__ should return a cell filled with integers
+ return dim_vector(1,1);
+ }
+#else
d.elem(k) = obj.int_value();
// __dims__ should return a cell filled with integers
if (error_state) return dim_vector(1,1);
+#endif
}
return d;
#if SWIG_OCTAVE_PREREQ(4,4,0)
@@ -468,8 +487,18 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
} else if (out.is_matrix_type() || out.is_numeric_type() ) {
#endif
if (out.rows()==1 || out.columns()==1) {
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ Array<int> a;
+ try {
+ a = out.int_vector_value();
+ }
+ catch (octave::execution_exception& oee) {
+ return dim_vector(1,1);
+ }
+#else
Array<int> a = out.int_vector_value();
if (error_state) return dim_vector(1,1);
+#endif
dim_vector d;
d.resize(a.numel() < 2 ? 2 : a.numel());
d(0) = d(1) = 1;
@@ -530,7 +559,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
}
void merge(octave_swig_type &rhs) {
- rhs.own = 0;
+ rhs.thisown = 0;
for (unsigned int j = 0; j < rhs.types.size(); ++j) {
assert(!rhs.types[j].second.destroyed);
#ifdef SWIG_DIRECTORS
@@ -553,35 +582,56 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
swig_member_const_iterator swig_members_begin() { return members.begin(); }
swig_member_const_iterator swig_members_end() { return members.end(); }
- int cast(void **vptr, swig_type_info *type, int *_own, int flags) {
+ int cast(void **vptr, swig_type_info *type, int *own, int flags) {
int res = SWIG_ERROR;
- if (_own)
- *_own = own;
- if (flags &SWIG_POINTER_DISOWN)
- own = 0;
+ int clear_pointer = 0;
+
+ if (own)
+ *own = 0;
+ if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !thisown) {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ } else {
+ if (own)
+ *own = *own | thisown;
+ if (flags & SWIG_POINTER_DISOWN) {
+ thisown = 0;
+ }
+ if (flags & SWIG_POINTER_CLEAR) {
+ clear_pointer = 1;
+ }
+ }
+
if (!type && types.size()) {
- if(vptr)
+ if (vptr) {
*vptr = types[0].second.ptr;
+ if (clear_pointer)
+ types[0].second.ptr = 0;
+ }
return SWIG_OK;
}
for (unsigned int j = 0; j < types.size(); ++j)
if (type == types[j].first) {
- if(vptr)
+ if (vptr) {
*vptr = types[j].second.ptr;
+ if (clear_pointer)
+ types[j].second.ptr = 0;
+ }
return SWIG_OK;
}
for (unsigned int j = 0; j < types.size(); ++j) {
swig_cast_info *tc = SWIG_TypeCheck(types[j].first->name, type);
if (!tc)
continue;
- if(vptr) {
+ if (vptr) {
int newmemory = 0;
*vptr = SWIG_TypeCast(tc, types[j].second.ptr, &newmemory);
- if (newmemory == SWIG_CAST_NEW_MEMORY) {
- assert(_own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
- if (_own)
- *_own = *_own | SWIG_CAST_NEW_MEMORY;
- }
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
+ if (own)
+ *own = *own | SWIG_CAST_NEW_MEMORY;
+ }
+ if (clear_pointer)
+ types[j].second.ptr = 0;
}
res = SWIG_OK;
break;
@@ -590,7 +640,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
}
bool is_owned() const {
- return own;
+ return thisown;
}
#ifdef SWIG_DIRECTORS
@@ -631,7 +681,11 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
return true;
}
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ virtual bool isstruct() const {
+#else
virtual bool is_map() const {
+#endif
return true;
}
@@ -779,7 +833,11 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
return as_value();
}
+#if SWIG_OCTAVE_PREREQ(4,4,0)
+ virtual bool isobject() const {
+#else
virtual bool is_object() const {
+#endif
return true;
}
@@ -874,7 +932,11 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
}
virtual bool load_binary (std::istream& is, bool swap,
- oct_mach_info::float_format fmt) {
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ octave::mach_info::float_format fmt) {
+#else
+ oct_mach_info::float_format fmt) {
+#endif
return true;
}
@@ -1084,8 +1146,13 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
bool is_defined() const
{ return ptr->is_defined(); }
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ virtual bool isstruct() const
+ { return ptr->isstruct(); }
+#else
virtual bool is_map() const
{ return ptr->is_map(); }
+#endif
virtual octave_value subsref(const std::string &ops, const std::list < octave_value_list > &idx)
{ return ptr->subsref(ops, idx); }
@@ -1096,8 +1163,13 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
octave_value subsasgn(const std::string &ops, const std::list < octave_value_list > &idx, const octave_value &rhs)
{ return ptr->subsasgn(ops, idx, rhs); }
+#if SWIG_OCTAVE_PREREQ(4,4,0)
+ virtual bool isobject() const
+ { return ptr->isobject(); }
+#else
virtual bool is_object() const
{ return ptr->is_object(); }
+#endif
virtual bool is_string() const
{ return ptr->is_string(); }
@@ -1142,7 +1214,11 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
{ return ptr->save_binary(os, save_as_floats); }
virtual bool load_binary (std::istream& is, bool swap,
- oct_mach_info::float_format fmt)
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ octave::mach_info::float_format fmt)
+#else
+ oct_mach_info::float_format fmt)
+#endif
{ return ptr->load_binary(is, swap, fmt); }
#if defined (HAVE_HDF5)
@@ -1178,6 +1254,10 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
#endif
{ return ptr->print(os, pr_as_read_syntax); }
+#if SWIG_OCTAVE_PREREQ(4,4,0)
+ static void set_type_id(int type_id) { t_id=type_id; }
+#endif
+
virtual type_conv_info numeric_conversion_function(void) const {
return octave_base_value::type_conv_info (default_numeric_conversion_function,
octave_scalar::static_type_id ());
@@ -1257,7 +1337,11 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
}
virtual bool load_binary (std::istream& is, bool swap,
- oct_mach_info::float_format fmt) {
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ octave::mach_info::float_format fmt) {
+#else
+ oct_mach_info::float_format fmt) {
+#endif
return true;
}
@@ -1285,6 +1369,10 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
# endif
#endif
+#if SWIG_OCTAVE_PREREQ(4,4,0)
+ static void set_type_id(int type_id) { t_id=type_id; }
+#endif
+
private:
#if !SWIG_OCTAVE_PREREQ(4,0,0)
DECLARE_OCTAVE_ALLOCATOR;
@@ -1459,12 +1547,15 @@ octave_value_typeinfo::register_binary_op(octave_value::op_##name,tid1,tid2,swig
SWIGRUNTIME octave_value SWIG_Octave_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
int own = (flags &SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
+ if (ptr) {
#ifdef SWIG_DIRECTORS
- Swig::Director *d = Swig::get_rtdir(ptr);
- if (d && Swig::swig_director_get_self(d))
- return Swig::swig_director_get_self(d)->as_value();
+ Swig::Director *d = Swig::get_rtdir(ptr);
+ if (d && Swig::swig_director_get_self(d))
+ return Swig::swig_director_get_self(d)->as_value();
#endif
- return Swig::swig_value_ref(new octave_swig_type(ptr, type, own));
+ return Swig::swig_value_ref(new octave_swig_type(ptr, type, own));
+ }
+ return octave_value(Matrix()); // null matrix
}
SWIGRUNTIME int SWIG_Octave_ConvertPtrAndOwn(octave_value ov, void **ptr, swig_type_info *type, int flags, int *own) {
@@ -1507,16 +1598,24 @@ SWIGRUNTIMEINLINE void SWIG_Octave_SetConstant(octave_swig_type *module_ns, cons
}
SWIGRUNTIMEINLINE octave_value SWIG_Octave_GetGlobalValue(std::string name) {
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ octave::interpreter *interp = octave::interpreter::the_interpreter ();
+ return interp->global_varval(name);
+#else
#if SWIG_OCTAVE_PREREQ(4,4,0)
octave::symbol_table& symtab = octave::interpreter::the_interpreter()->get_symbol_table();
return symtab.global_varval(name);
#else
return get_global_value(name, true);
#endif
+#endif
}
SWIGRUNTIME void SWIG_Octave_SetGlobalValue(std::string name, const octave_value& value) {
-#if SWIG_OCTAVE_PREREQ(4,4,0)
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ octave::interpreter *interp = octave::interpreter::the_interpreter ();
+ interp->global_assign(name, value);
+#elif SWIG_OCTAVE_PREREQ(4,4,0)
octave::symbol_table& symtab = octave::interpreter::the_interpreter()->get_symbol_table();
symtab.global_assign(name, value);
#else
@@ -1526,10 +1625,20 @@ SWIGRUNTIME void SWIG_Octave_SetGlobalValue(std::string name, const octave_value
SWIGRUNTIME void SWIG_Octave_LinkGlobalValue(std::string name) {
#if SWIG_OCTAVE_PREREQ(4,4,0)
- octave::symbol_table& symtab = octave::interpreter::the_interpreter()->get_symbol_table();
octave::symbol_scope symscope = octave::interpreter::the_interpreter()->get_current_scope();
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ octave::interpreter *interp = octave::interpreter::the_interpreter ();
+ interp->assign(name, interp->global_varval(name));
+ octave::tree_evaluator& tree_eval = interp->get_evaluator();
+ octave::call_stack& callStack = tree_eval.get_call_stack();
+ std::shared_ptr<octave::stack_frame> stackFrame = callStack.get_current_stack_frame();
+ octave::symbol_record sym=symscope.lookup_symbol(name);
+ stackFrame->mark_global(sym);
+#else
+ octave::symbol_table& symtab = octave::interpreter::the_interpreter()->get_symbol_table();
symscope.assign(name, symtab.global_varval(name));
symscope.mark_global(name);
+#endif
#else
#if !SWIG_OCTAVE_PREREQ(3,2,0)
link_to_global_variable(curr_sym_tab->lookup(name, true));
diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg
index a397fb7c1..e76151f14 100644
--- a/Lib/octave/octruntime.swg
+++ b/Lib/octave/octruntime.swg
@@ -19,7 +19,8 @@ static bool SWIG_init_user(octave_swig_type* module_ns);
SWIGINTERN bool SWIG_Octave_LoadModule(std::string name) {
bool retn = false;
{
-#if SWIG_OCTAVE_PREREQ(4,2,0)
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+#elif SWIG_OCTAVE_PREREQ(4,2,0)
octave::unwind_protect frame;
frame.protect_var(discard_error_messages); discard_error_messages = true;
frame.protect_var(discard_warning_messages); discard_warning_messages = true;
@@ -62,7 +63,8 @@ SWIGINTERN bool SWIG_Octave_LoadModule(std::string name) {
SWIGINTERN bool SWIG_Octave_InstallFunction(octave_function *octloadfcn, std::string name) {
bool retn = false;
{
-#if SWIG_OCTAVE_PREREQ(4,2,0)
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+#elif SWIG_OCTAVE_PREREQ(4,2,0)
octave::unwind_protect frame;
frame.protect_var(discard_error_messages); discard_error_messages = true;
frame.protect_var(discard_warning_messages); discard_warning_messages = true;
@@ -295,9 +297,11 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
for (int i = 0; i < types.numel(); ++i) {
if (types(i) == octave_swig_ref::static_type_name()) {
register_octave_swig_ref = false;
+ octave_swig_ref::set_type_id(i);
}
if (types(i) == octave_swig_packed::static_type_name()) {
register_octave_swig_packed = false;
+ octave_swig_packed::set_type_id(i);
}
}
if (register_octave_swig_ref) {
@@ -314,7 +318,11 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
SWIG_InitializeModule(0);
SWIG_PropagateClientData();
-#if SWIG_OCTAVE_PREREQ(4,4,0)
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+ octave::tree_evaluator& tree_eval = octave::interpreter::the_interpreter()->get_evaluator();
+ octave::call_stack& stack = tree_eval.get_call_stack();
+ octave_function *me = stack.current_function();
+#elif SWIG_OCTAVE_PREREQ(4,4,0)
octave::call_stack& stack = octave::interpreter::the_interpreter()->get_call_stack();
octave_function *me = stack.current();
#else
diff --git a/Lib/octave/octtypemaps.swg b/Lib/octave/octtypemaps.swg
index 4acf8e076..652112312 100644
--- a/Lib/octave/octtypemaps.swg
+++ b/Lib/octave/octtypemaps.swg
@@ -32,8 +32,15 @@
#define SWIG_SetConstant(name, obj) SWIG_Octave_SetConstant(module_ns,name,obj)
// raise
-#define SWIG_Octave_Raise(OBJ, TYPE, DESC) error("C++ side threw an exception of type " TYPE)
-#define SWIG_Raise(obj, type, desc) SWIG_Octave_Raise(obj, type, desc)
+%runtime %{
+void SWIG_Octave_Raise(const octave_value &obj, const char *type) {
+ if (obj.is_string())
+ error("%s", obj.string_value().c_str());
+ else
+ error("C++ side threw an exception of type %s", type);
+}
+%}
+#define SWIG_Raise(obj, type, desc) SWIG_Octave_Raise(obj, type)
// Include the unified typemap library
%include <typemaps/swigtypemaps.swg>
diff --git a/Lib/octave/std_auto_ptr.i b/Lib/octave/std_auto_ptr.i
new file mode 100644
index 000000000..3d7ae8ba1
--- /dev/null
+++ b/Lib/octave/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/octave/std_unique_ptr.i b/Lib/octave/std_unique_ptr.i
new file mode 100644
index 000000000..f988714df
--- /dev/null
+++ b/Lib/octave/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/octave/swigmove.i b/Lib/octave/swigmove.i
new file mode 100644
index 000000000..62ecca768
--- /dev/null
+++ b/Lib/octave/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/perl5/argcargv.i b/Lib/perl5/argcargv.i
new file mode 100644
index 000000000..48a6047b8
--- /dev/null
+++ b/Lib/perl5/argcargv.i
@@ -0,0 +1,32 @@
+/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------ */
+
+%typemap(in) (int ARGC, char **ARGV) {
+ int i;
+ I32 len;
+ AV *av = (AV *)SvRV($input);
+ if (SvTYPE(av) != SVt_PVAV) {
+ SWIG_croak("in method '$symname', Expecting reference to argv array");
+ goto fail;
+ }
+ len = av_len(av) + 1;
+ $1 = ($1_ltype) len;
+ $2 = (char **) malloc((len+1)*sizeof(char *));
+ for (i = 0; i < len; i++) {
+ SV **tv = av_fetch(av, i, 0);
+ $2[i] = SvPV_nolen(*tv);
+ }
+ $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ AV *av = (AV *)SvRV($input);
+ $1 = SvTYPE(av) == SVt_PVAV;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ if ($2 != NULL) {
+ free((void *)$2);
+ }
+}
diff --git a/Lib/perl5/perlhead.swg b/Lib/perl5/perlhead.swg
index 5437af5a5..773adee92 100644
--- a/Lib/perl5/perlhead.swg
+++ b/Lib/perl5/perlhead.swg
@@ -4,26 +4,24 @@
#include <stdlib.h>
extern "C" {
#endif
+
+#if __GNUC__ >= 10
+#if defined(__cplusplus)
+#pragma GCC diagnostic ignored "-Wvolatile"
+#endif
+#endif
+
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
-/* Add in functionality missing in older versions of Perl. Much of this is based on Devel-PPPort on cpan. */
+#if __GNUC__ >= 10
+#pragma GCC diagnostic pop
+#endif
-/* Add PERL_REVISION, PERL_VERSION, PERL_SUBVERSION if missing */
-#ifndef PERL_REVISION
-# if !defined(__PATCHLEVEL_H_INCLUDED__) && !(defined(PATCHLEVEL) && defined(SUBVERSION))
-# define PERL_PATCHLEVEL_H_IMPLICIT
-# include <patchlevel.h>
-# endif
-# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL)))
-# include <could_not_find_Perl_patchlevel.h>
-# endif
-# ifndef PERL_REVISION
-# define PERL_REVISION (5)
-# define PERL_VERSION PATCHLEVEL
-# define PERL_SUBVERSION SUBVERSION
-# endif
+/* PERL_REVISION was added in Perl 5.6. */
+#if !defined PERL_REVISION || (PERL_REVISION-0 == 5 && PERL_VERSION-0 < 8)
+# error SWIG requires Perl >= 5.8.0
#endif
#if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE)
@@ -38,15 +36,6 @@ extern "C" {
# define SvUOK(sv) SvIOK_UV(sv)
#endif
-#if ((PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5)))
-# define PL_sv_undef sv_undef
-# define PL_na na
-# define PL_errgv errgv
-# define PL_sv_no sv_no
-# define PL_sv_yes sv_yes
-# define PL_markstack_ptr markstack_ptr
-#endif
-
#ifndef IVSIZE
# ifdef LONGSIZE
# define IVSIZE LONGSIZE
diff --git a/Lib/perl5/perlinit.swg b/Lib/perl5/perlinit.swg
index b49040d26..c26b93fad 100644
--- a/Lib/perl5/perlinit.swg
+++ b/Lib/perl5/perlinit.swg
@@ -4,15 +4,11 @@
#ifdef __cplusplus
extern "C"
#endif
-#ifndef PERL_OBJECT
#ifndef MULTIPLICITY
SWIGEXPORT void SWIG_init (CV* cv);
#else
SWIGEXPORT void SWIG_init (pTHXo_ CV* cv);
#endif
-#else
-SWIGEXPORT void SWIG_init (CV *cv, CPerlObj *);
-#endif
%}
/* Module initialization function */
diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg
index b04002f5d..71f19cbf8 100644
--- a/Lib/perl5/perlrun.swg
+++ b/Lib/perl5/perlrun.swg
@@ -6,13 +6,8 @@
* type checking.
* ----------------------------------------------------------------------------- */
-#ifdef PERL_OBJECT
-#define SWIG_PERL_OBJECT_DECL CPerlObj *SWIGUNUSEDPARM(pPerl),
-#define SWIG_PERL_OBJECT_CALL pPerl,
-#else
#define SWIG_PERL_OBJECT_DECL
#define SWIG_PERL_OBJECT_CALL
-#endif
/* Common SWIG API */
@@ -88,32 +83,12 @@ extern "C" {
#endif
/* Macro to call an XS function */
-#ifdef PERL_OBJECT
-# define SWIG_CALLXS(_name) _name(cv,pPerl)
-#else
-# ifndef MULTIPLICITY
-# define SWIG_CALLXS(_name) _name(cv)
-# else
-# define SWIG_CALLXS(_name) _name(PERL_GET_THX, cv)
-# endif
-#endif
-
-#ifdef PERL_OBJECT
-#define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-typedef int (CPerlObj::*SwigMagicFunc)(SV *, MAGIC *);
-#ifdef __cplusplus
-}
+#ifndef MULTIPLICITY
+# define SWIG_CALLXS(_name) _name(cv)
+#else
+# define SWIG_CALLXS(_name) _name(PERL_GET_THX, cv)
#endif
-#define SWIG_MAGIC(a,b) (SV *a, MAGIC *b)
-#define SWIGCLASS_STATIC
-
-#else /* PERL_OBJECT */
-
#define MAGIC_PPERL
#define SWIGCLASS_STATIC static SWIGUNUSED
@@ -141,24 +116,14 @@ typedef int (*SwigMagicFunc)(struct interpreter *, SV *, MAGIC *);
#endif
#endif /* MULTIPLICITY */
-#endif /* PERL_OBJECT */
-# ifdef PERL_OBJECT
-# define SWIG_croak_null() SWIG_Perl_croak_null(pPerl)
-static void SWIGUNUSED SWIG_Perl_croak_null(CPerlObj *pPerl)
-# else
static void SWIGUNUSED SWIG_croak_null()
-# endif
{
SV *err = get_sv("@", GV_ADD);
-# if (PERL_VERSION < 6)
- croak("%_", err);
-# else
if (sv_isobject(err))
croak(0);
else
croak("%s", SvPV_nolen(err));
-# endif
}
@@ -245,6 +210,7 @@ SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_
swig_cast_info *tc;
void *voidptr = (void *)0;
SV *tsv = 0;
+ int check_owned_pointer_release = (flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE;
if (own)
*own = 0;
@@ -321,13 +287,14 @@ SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_
/*
* DISOWN implementation: we need a perl guru to check this one.
*/
- if (tsv && (flags & SWIG_POINTER_DISOWN)) {
+ if (tsv && ((flags & SWIG_POINTER_DISOWN) || check_owned_pointer_release)) {
/*
* almost copy paste code from below SWIG_POINTER_OWN setting
*/
SV *obj = sv;
HV *stash = SvSTASH(SvRV(obj));
GV *gv = *(GV**)hv_fetch(stash, "OWNER", 5, TRUE);
+ int owned = 0;
if (isGV(gv)) {
HV *hv = GvHVn(gv);
/*
@@ -335,10 +302,21 @@ SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_
* Hence, to remove ownership, we delete the entry.
*/
if (hv_exists_ent(hv, obj, 0)) {
- hv_delete_ent(hv, obj, 0, 0);
+ owned = 1;
+ if (flags & SWIG_POINTER_DISOWN) {
+ hv_delete_ent(hv, obj, 0, 0);
+ }
}
}
+ if (check_owned_pointer_release && !owned) {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ }
}
+
+ if (tsv && (flags & SWIG_POINTER_CLEAR)) {
+ SvIV_set(tsv, 0);
+ }
+
return SWIG_OK;
}
@@ -462,20 +440,15 @@ typedef struct {
} swig_variable_info;
/* Magic variable code */
-#ifndef PERL_OBJECT
-# ifdef __cplusplus
+#ifdef __cplusplus
# define swig_create_magic(s,a,b,c) _swig_create_magic(s,const_cast<char*>(a),b,c)
-# else
+#else
# define swig_create_magic(s,a,b,c) _swig_create_magic(s,(char*)(a),b,c)
-# endif
-# ifndef MULTIPLICITY
-SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int (*get)(SV *,MAGIC *))
-# else
-SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(struct interpreter*, SV *, MAGIC *), int (*get)(struct interpreter*, SV *,MAGIC *))
-# endif
+#endif
+#ifndef MULTIPLICITY
+SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int (*get)(SV *,MAGIC *))
#else
-# define swig_create_magic(s,a,b,c) _swig_create_magic(pPerl,s,a,b,c)
-SWIGRUNTIME void _swig_create_magic(CPerlObj *pPerl, SV *sv, const char *name, int (CPerlObj::*set)(SV *, MAGIC *), int (CPerlObj::*get)(SV *, MAGIC *))
+SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(struct interpreter*, SV *, MAGIC *), int (*get)(struct interpreter*, SV *,MAGIC *))
#endif
{
MAGIC *mg;
diff --git a/Lib/perl5/std_auto_ptr.i b/Lib/perl5/std_auto_ptr.i
new file mode 100644
index 000000000..3d7ae8ba1
--- /dev/null
+++ b/Lib/perl5/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/perl5/std_unique_ptr.i b/Lib/perl5/std_unique_ptr.i
new file mode 100644
index 000000000..f988714df
--- /dev/null
+++ b/Lib/perl5/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/perl5/swigmove.i b/Lib/perl5/swigmove.i
new file mode 100644
index 000000000..62ecca768
--- /dev/null
+++ b/Lib/perl5/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/php/argcargv.i b/Lib/php/argcargv.i
new file mode 100644
index 000000000..e0093c214
--- /dev/null
+++ b/Lib/php/argcargv.i
@@ -0,0 +1,40 @@
+/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------ */
+
+%typemap(in) (int ARGC, char **ARGV) {
+ int len, i;
+ zval *val;
+ zend_array *ar;
+ if (Z_TYPE($input) != IS_ARRAY) {
+ SWIG_PHP_Error(E_ERROR, "Type error in '$symname'. Expected array");
+ goto fail;
+ }
+ ar = Z_ARR($input);
+ len = zend_array_count(ar);
+ $1 = ($1_ltype) len;
+ $2 = (char **) malloc((len+1)*sizeof(char *));
+ i = 0;
+ ZEND_HASH_FOREACH_VAL(ar, val) {
+ if (Z_TYPE(*val) != IS_STRING) {
+ SWIG_PHP_Error(E_ERROR, "Array must use strings only, in '$symname'.");
+ goto fail;
+ }
+ if (i == len) {
+ SWIG_PHP_Error(E_ERROR, "Array is bigger than zend report in '$symname'.");
+ goto fail;
+ }
+ $2[i++] = Z_STRVAL(*val);
+ } ZEND_HASH_FOREACH_END();
+ $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ $1 = Z_TYPE($input) == IS_ARRAY;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ if ($2 != NULL) {
+ free((void *)$2);
+ }
+}
diff --git a/Lib/php/const.i b/Lib/php/const.i
index 3b40c2c7f..a74af0d78 100644
--- a/Lib/php/const.i
+++ b/Lib/php/const.i
@@ -12,22 +12,22 @@
unsigned char,
signed char,
enum SWIGTYPE %{
- zend_declare_class_constant_long(SWIGTYPE_$class_ce, "$const_name", sizeof("$const_name") - 1, ($1_type)$value);
+ zend_declare_class_constant_long(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, ($1_type)($value));
%}
%typemap(classconsttab) bool %{
- zend_declare_class_constant_bool(SWIGTYPE_$class_ce, "$const_name", sizeof("$const_name") - 1, ($1_type)$value);
+ zend_declare_class_constant_bool(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, ($1_type)($value));
%}
%typemap(classconsttab) float,
double %{
- zend_declare_class_constant_double(SWIGTYPE_$class_ce, "$const_name", sizeof("$const_name") - 1, $value);
+ zend_declare_class_constant_double(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, $value);
%}
%typemap(classconsttab) char %{
{
char swig_char = $value;
- zend_declare_class_constant_stringl(SWIGTYPE_$class_ce, "$const_name", sizeof("$const_name") - 1, &swig_char, 1);
+ zend_declare_class_constant_stringl(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, &swig_char, 1);
}
%}
@@ -35,7 +35,7 @@
const char *,
char [],
const char [] %{
- zend_declare_class_constant_string(SWIGTYPE_$class_ce, "$const_name", sizeof("$const_name") - 1, $value);
+ zend_declare_class_constant_string(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, $value);
%}
// This creates a zend_object to wrap the pointer, and we can't do that
@@ -48,13 +48,13 @@
{
zval z;
ZVAL_UNDEF(&z);
- SWIG_SetPointerZval(&z, (void*)$value, $1_descriptor, 0);
+ SWIG_SetPointerZval(&z, (void*)($value), $1_descriptor, 0);
zval_copy_ctor(&z);
- zend_declare_class_constant(SWIGTYPE_$class_ce, "$const_name", sizeof("$const_name") - 1, &z);
+ zend_declare_class_constant(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, &z);
}
%}
-%typemap(classconsttab) SWIGTYPE (CLASS::*) "";
+%typemap(classconsttab) SWIGTYPE (CLASS::*) ""
%typemap(consttab) int,
unsigned int,
@@ -65,10 +65,10 @@
unsigned char,
signed char,
enum SWIGTYPE
- "SWIG_LONG_CONSTANT($symname, ($1_type)$value);";
+ "SWIG_LONG_CONSTANT($symname, ($1_type)($value));";
%typemap(consttab) bool
- "SWIG_BOOL_CONSTANT($symname, ($1_type)$value);";
+ "SWIG_BOOL_CONSTANT($symname, ($1_type)($value));";
%typemap(consttab) float,
double
@@ -92,7 +92,7 @@
SWIGTYPE [] {
zend_constant c;
ZVAL_UNDEF(&c.value);
- SWIG_SetPointerZval(&c.value, (void*)$value, $1_descriptor, 0);
+ SWIG_SetPointerZval(&c.value, (void*)($value), $1_descriptor, 0);
zval_copy_ctor(&c.value);
c.name = zend_string_init("$symname", sizeof("$symname") - 1, 0);
SWIG_ZEND_CONSTANT_SET_FLAGS(&c, CONST_CS, module_number);
@@ -100,4 +100,4 @@
}
/* Handled as a global variable. */
-%typemap(consttab) SWIGTYPE (CLASS::*) "";
+%typemap(consttab) SWIGTYPE (CLASS::*) ""
diff --git a/Lib/php/director.swg b/Lib/php/director.swg
index 68be6a3ba..55ffff516 100644
--- a/Lib/php/director.swg
+++ b/Lib/php/director.swg
@@ -99,6 +99,8 @@ namespace Swig {
}
}
+ zend_object *swig_get_self() const { return Z_OBJ(swig_self); }
+
void swig_disown() const {
if (!swig_disown_flag) {
swig_disown_flag = true;
@@ -106,13 +108,6 @@ namespace Swig {
}
}
- static bool swig_is_overridden_method(const char *cname, zval *z) {
- zend_string * cname_str = zend_string_init(cname, strlen(cname), 0);
- zend_class_entry *ce = zend_lookup_class(cname_str);
- zend_string_release(cname_str);
- return ce == Z_OBJCE_P(z);
- }
-
template <typename Type>
void swig_acquire_ownership(Type *vptr) const {
if (vptr) {
diff --git a/Lib/php/factory.i b/Lib/php/factory.i
index 5a1f9dc06..5f2b397ec 100644
--- a/Lib/php/factory.i
+++ b/Lib/php/factory.i
@@ -100,7 +100,7 @@ if (!dcast) {
}%enddef
%define %factory(Method,Types...)
-%typemap(out) Method {
+%typemap(out, phptype="?SWIGTYPE") Method {
int dcast = 0;
%formacro(%_factory_dispatch, Types)
if (!dcast) {
diff --git a/Lib/php/php.swg b/Lib/php/php.swg
index 6e4ee2d2f..fd0928076 100644
--- a/Lib/php/php.swg
+++ b/Lib/php/php.swg
@@ -4,6 +4,11 @@
* PHP configuration file
* ----------------------------------------------------------------------------- */
+// Default to generating PHP type declarations (for PHP >= 8) except for
+// cases which are liable to cause compatibility issues with existing
+// bindings.
+%feature("php:type", "compat");
+
%runtime "swigrun.swg" // Common C API type-checking code
%runtime "swigerrors.swg" // SWIG errors
%runtime "phprun.swg" // PHP runtime functions
@@ -34,56 +39,56 @@
%include <utils.i>
-%pass_by_val(bool,CONVERT_BOOL_IN);
+%pass_by_val(bool, "bool", CONVERT_BOOL_IN);
-%pass_by_val(size_t, CONVERT_INT_IN);
+%pass_by_val(size_t, "int", CONVERT_INT_IN);
-%pass_by_val(enum SWIGTYPE, CONVERT_INT_IN);
+%pass_by_val(enum SWIGTYPE, "int", CONVERT_INT_IN);
-%pass_by_val(signed int, CONVERT_INT_IN);
-%pass_by_val(int,CONVERT_INT_IN);
-%pass_by_val(unsigned int,CONVERT_INT_IN);
+%pass_by_val(signed int, "int", CONVERT_INT_IN);
+%pass_by_val(int,"int", CONVERT_INT_IN);
+%pass_by_val(unsigned int,"int", CONVERT_INT_IN);
-%pass_by_val(signed short, CONVERT_INT_IN);
-%pass_by_val(short,CONVERT_INT_IN);
-%pass_by_val(unsigned short, CONVERT_INT_IN);
+%pass_by_val(signed short, "int", CONVERT_INT_IN);
+%pass_by_val(short,"int", CONVERT_INT_IN);
+%pass_by_val(unsigned short, "int", CONVERT_INT_IN);
-%pass_by_val(signed long, CONVERT_INT_IN);
-%pass_by_val(long, CONVERT_INT_IN);
-%pass_by_val(unsigned long, CONVERT_INT_IN);
+%pass_by_val(signed long, "int", CONVERT_INT_IN);
+%pass_by_val(long, "int", CONVERT_INT_IN);
+%pass_by_val(unsigned long, "int", CONVERT_INT_IN);
-%pass_by_val(signed long long, CONVERT_LONG_LONG_IN);
-%pass_by_val(long long, CONVERT_LONG_LONG_IN);
-%pass_by_val(unsigned long long, CONVERT_UNSIGNED_LONG_LONG_IN);
+%pass_by_val(signed long long, "int|string", CONVERT_LONG_LONG_IN);
+%pass_by_val(long long, "int|string", CONVERT_LONG_LONG_IN);
+%pass_by_val(unsigned long long, "int|string", CONVERT_UNSIGNED_LONG_LONG_IN);
-%pass_by_val(signed char, CONVERT_INT_IN);
-%pass_by_val(char, CONVERT_CHAR_IN);
-%pass_by_val(unsigned char, CONVERT_INT_IN);
+%pass_by_val(signed char, "int", CONVERT_INT_IN);
+%pass_by_val(char, "string", CONVERT_CHAR_IN);
+%pass_by_val(unsigned char, "int", CONVERT_INT_IN);
-%pass_by_val(float, CONVERT_FLOAT_IN);
+%pass_by_val(float, "float", CONVERT_FLOAT_IN);
-%pass_by_val(double, CONVERT_FLOAT_IN);
+%pass_by_val(double, "float", CONVERT_FLOAT_IN);
-%pass_by_val(char *, CONVERT_STRING_IN);
+%pass_by_val(char *, "string", CONVERT_STRING_IN);
%typemap(in) char *& = const char *&;
%typemap(directorout) char *& = const char *&;
// char array can be in/out, though the passed string may not be big enough...
// so we have to size it
-%typemap(in) char[ANY]
+%typemap(in, phptype="string") char[ANY]
%{
convert_to_string(&$input);
$1 = ($1_ltype) Z_STRVAL($input);
%}
-%typemap(in) (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) %{
+%typemap(in, phptype="string") (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) %{
convert_to_string(&$input);
$1 = ($1_ltype) Z_STRVAL($input);
$2 = ($2_ltype) Z_STRLEN($input);
%}
/* Object passed by value. Convert to a pointer */
-%typemap(in) SWIGTYPE ($&1_ltype tmp)
+%typemap(in, phptype="SWIGTYPE") SWIGTYPE ($&1_ltype tmp)
%{
if (SWIG_ConvertPtr(&$input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) {
zend_type_error("Expected $&1_descriptor for argument $argnum of $symname");
@@ -101,7 +106,7 @@
$result = *tmp;
%}
-%typemap(in) SWIGTYPE *,
+%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *,
SWIGTYPE []
%{
if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0) {
@@ -120,14 +125,31 @@
swig_acquire_ownership_obj((void*)$result, own);
%}
-%typemap(in) SWIGTYPE &,
- SWIGTYPE &&
+%typemap(in, phptype="SWIGTYPE") SWIGTYPE &
%{
if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) {
zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
return;
}
%}
+%typemap(in, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) %{
+ res = SWIG_ConvertPtr(&$input, &argp, $descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $1_descriptor of $symname");
+ return;
+ } else {
+ zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+ return;
+ }
+ }
+ if (!argp) {
+ zend_type_error("Invalid null reference for argument $argnum of $1_descriptor of $symname");
+ return;
+ }
+ $1 = ($1_ltype)argp;
+ rvrdeleter.reset($1);
+%}
%typemap(directorout) SWIGTYPE & ($1_ltype tmp),
SWIGTYPE && ($1_ltype tmp)
@@ -139,7 +161,7 @@
$result = tmp;
%}
-%typemap(in) SWIGTYPE *const& ($*ltype temp)
+%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *const& ($*ltype temp)
%{
if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) {
zend_type_error("Expected $*1_descriptor for argument $argnum of $symname");
@@ -148,7 +170,7 @@
$1 = ($1_ltype)&temp;
%}
-%typemap(in) SWIGTYPE *DISOWN
+%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *DISOWN
%{
if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN) < 0) {
zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
@@ -161,7 +183,7 @@
SWIGTYPE &,
SWIGTYPE &&;
-%typemap(in) void *
+%typemap(in, phptype="?SWIGTYPE") void *
%{
if (SWIG_ConvertPtr(&$input, (void **) &$1, 0, 0) < 0) {
/* Allow NULL from php for void* */
@@ -176,7 +198,7 @@
/* Special case when void* is passed by reference so it can be made to point
to opaque api structs */
-%typemap(in, byref=1) void ** ($*1_ltype ptr, int force),
+%typemap(in, phptype="?SWIG\\_p_void", byref=1) void ** ($*1_ltype ptr, int force),
void *& ($*1_ltype ptr, int force)
{
/* If they pass NULL by reference, make it into a void*
@@ -186,7 +208,7 @@
if (!(Z_ISREF($input) && Z_ISNULL_P(Z_REFVAL($input)))) {
/* wasn't a pre/ref/thing, OR anything like an int thing */
zend_throw_exception(zend_ce_type_error, "Type error in argument $arg of $symname", 0);
- return;
+ goto fail;
}
}
force=0;
@@ -211,7 +233,8 @@
/* Typemap for output values */
-%typemap(out) int,
+%typemap(out, phptype="int")
+ int,
unsigned int,
short,
unsigned short,
@@ -219,39 +242,35 @@
unsigned long,
signed char,
unsigned char,
- bool,
size_t
%{
RETVAL_LONG($1);
%}
-%typemap(out) enum SWIGTYPE
+%typemap(out, phptype="int") enum SWIGTYPE
%{
RETVAL_LONG((long)$1);
%}
-%typemap(out) long long
+%typemap(out, phptype="int|string") long long
%{
if ((long long)LONG_MIN <= $1 && $1 <= (long long)LONG_MAX) {
RETVAL_LONG((long)($1));
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)$1);
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%lld", (long long)$1));
}
%}
-%typemap(out) unsigned long long
+%typemap(out, phptype="int|string") unsigned long long
%{
if ($1 <= (unsigned long long)LONG_MAX) {
RETVAL_LONG((long)($1));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)$1);
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%llu", (unsigned long long)$1));
}
%}
-%typemap(out) const int &,
+%typemap(out, phptype="int")
+ const int &,
const unsigned int &,
const short &,
const unsigned short &,
@@ -265,34 +284,30 @@
RETVAL_LONG(*$1);
%}
-%typemap(out) const enum SWIGTYPE &
+%typemap(out, phptype="int") const enum SWIGTYPE &
%{
RETVAL_LONG((long)*$1);
%}
-%typemap(out) const enum SWIGTYPE &&
+%typemap(out, phptype="int") const enum SWIGTYPE &&
%{
RETVAL_LONG((long)*$1);
%}
-%typemap(out) const long long &
+%typemap(out, phptype="int|string") const long long &
%{
if ((long long)LONG_MIN <= *$1 && *$1 <= (long long)LONG_MAX) {
RETVAL_LONG((long)(*$1));
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)(*$1));
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%lld", (long long)(*$1)));
}
%}
-%typemap(out) const unsigned long long &
+%typemap(out, phptype="int|string") const unsigned long long &
%{
if (*$1 <= (unsigned long long)LONG_MAX) {
RETVAL_LONG((long)(*$1));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)(*$1));
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%llu", (unsigned long long)(*$1)));
}
%}
@@ -324,12 +339,12 @@
}
%}
-%typemap(out) bool
+%typemap(out, phptype="bool") bool
%{
RETVAL_BOOL(($1) ? 1 : 0);
%}
-%typemap(out) const bool &
+%typemap(out, phptype="bool") const bool &
%{
RETVAL_BOOL((*$1) ? 1 : 0);
%}
@@ -339,13 +354,13 @@
ZVAL_BOOL($input, ($1) ? 1 : 0);
%}
-%typemap(out) float,
+%typemap(out, phptype="float") float,
double
%{
RETVAL_DOUBLE($1);
%}
-%typemap(out) const float &,
+%typemap(out, phptype="float") const float &,
const double &
%{
RETVAL_DOUBLE(*$1);
@@ -357,18 +372,22 @@
ZVAL_DOUBLE($input, $1);
%}
-%typemap(out) char
+%typemap(out, phptype="string") char
%{
RETVAL_STRINGL(&$1, 1);
%}
-%typemap(out) const char &
+%typemap(out, phptype="string") const char &
%{
RETVAL_STRINGL(&*$1, 1);
%}
-%typemap(out) char *,
- char []
+%typemap(out, phptype="string") char []
+%{
+ RETVAL_STRING((const char *)$1);
+%}
+
+%typemap(out, phptype="?string") char *
%{
if (!$1) {
RETVAL_NULL();
@@ -377,7 +396,7 @@
}
%}
-%typemap(out) char *&
+%typemap(out, phptype="?string") char *&
%{
if (!*$1) {
RETVAL_NULL();
@@ -386,7 +405,12 @@
}
%}
-%typemap(out) SWIGTYPE *,
+%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *
+%{
+ SWIG_SetPointerZval($result, (void *)$1, $1_descriptor, $owner);
+%}
+
+%typemap(out, phptype="SWIGTYPE")
SWIGTYPE [],
SWIGTYPE &,
SWIGTYPE &&
@@ -394,7 +418,7 @@
SWIG_SetPointerZval($result, (void *)$1, $1_descriptor, $owner);
%}
-%typemap(out) SWIGTYPE *const&
+%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *const&
%{
SWIG_SetPointerZval($result, (void *)*$1, $*1_descriptor, $owner);
%}
@@ -404,33 +428,39 @@
SWIGTYPE &,
SWIGTYPE &&
%{
+ ZVAL_UNDEF($input);
SWIG_SetPointerZval($input, (void *)&$1, $1_descriptor, $owner);
%}
-%typemap(out) SWIGTYPE (CLASS::*)
+%typemap(out, phptype="SWIGTYPE") SWIGTYPE (CLASS::*)
{
void * p = emalloc(sizeof($1));
memcpy(p, &$1, sizeof($1));
SWIG_SetPointerZval($result, (void *)p, $&1_descriptor, 1);
}
-%typemap(in) SWIGTYPE (CLASS::*)
+%typemap(in, phptype="SWIGTYPE") SWIGTYPE (CLASS::*)
{
void * p = SWIG_Z_FETCH_OBJ_P(&$input)->ptr;
memcpy(&$1, p, sizeof($1));
}
-%typemap(out) SWIGTYPE *DYNAMIC,
- SWIGTYPE &DYNAMIC
+%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *DYNAMIC
+{
+ swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
+ SWIG_SetPointerZval($result, (void *)$1, ty, $owner);
+}
+
+%typemap(out, phptype="SWIGTYPE") SWIGTYPE &DYNAMIC
{
swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
SWIG_SetPointerZval($result, (void *)$1, ty, $owner);
}
-%typemap(out) SWIGTYPE
+%typemap(out, phptype="SWIGTYPE") SWIGTYPE
{
#ifdef __cplusplus
- $&1_ltype resultobj = new $1_ltype((const $1_ltype &) $1);
+ $&1_ltype resultobj = new $1_ltype($1);
#else
$&1_ltype resultobj = ($&1_ltype) malloc(sizeof($1_type));
memcpy(resultobj, &$1, sizeof($1_type));
@@ -440,12 +470,13 @@
%typemap(directorin) SWIGTYPE
%{
- SWIG_SetPointerZval($input, SWIG_as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&1_descriptor, 1);
+ ZVAL_UNDEF($input);
+ SWIG_SetPointerZval($input, (new $1_ltype(SWIG_STD_MOVE($1))), $&1_descriptor, 1);
%}
-%typemap(out) void "";
+%typemap(out, phptype="void") void ""
-%typemap(out) char [ANY]
+%typemap(out, phptype="string") char [ANY]
{
size_t len = 0;
while (len < $1_dim0 && $1[len]) ++len;
@@ -533,18 +564,18 @@
unsigned long,
unsigned short %{
zend_throw_exception(NULL, "C++ $1_type exception thrown", $1);
- return;
+ goto fail;
%}
%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY] %{
(void)$1;
zend_throw_exception(NULL, "C++ $1_type exception thrown", 0);
- return;
+ goto fail;
%}
%typemap(throws) char * %{
zend_throw_exception(NULL, $1, 0);
- return;
+ goto fail;
%}
/* Array reference typemaps */
diff --git a/Lib/php/phpinit.swg b/Lib/php/phpinit.swg
index 40f7b0766..ae72a10ae 100644
--- a/Lib/php/phpinit.swg
+++ b/Lib/php/phpinit.swg
@@ -9,4 +9,8 @@
SWIG_php_minit {
zend_class_entry SWIGUNUSED internal_ce;
SWIG_InitializeModule((void*)&module_number);
+#if PHP_MAJOR_VERSION == 8 && PHP_MINOR_VERSION == 0
+ /* This hack is needed to avoid segfaults. */
+ EG(class_table) = CG(class_table);
+#endif
%}
diff --git a/Lib/php/phpinterfaces.i b/Lib/php/phpinterfaces.i
index dda219d91..5b1da8b79 100644
--- a/Lib/php/phpinterfaces.i
+++ b/Lib/php/phpinterfaces.i
@@ -54,7 +54,7 @@
#define SWIG_PHP_INTERFACE_JsonSerializable_HEADER "ext/json/php_json.h"
// New in PHP 8.0.
-#if PHP_MAJOR >= 8
+#if PHP_MAJOR_VERSION >= 8
# define SWIG_PHP_INTERFACE_Stringable_CE zend_ce_stringable
# define SWIG_PHP_INTERFACE_Stringable_HEADER "zend_interfaces.h"
#endif
diff --git a/Lib/php/phpkw.swg b/Lib/php/phpkw.swg
index e431fc2e4..443ac8bf8 100644
--- a/Lib/php/phpkw.swg
+++ b/Lib/php/phpkw.swg
@@ -3,10 +3,13 @@
* ----------------------------------------------------------------------------- */
/* Keyword (case insensitive) */
-#define PHPKW(x) %keywordwarn("'" `x` "' is a PHP keyword, renaming to 'c_" `x` "'",sourcefmt="%(lower)s",rename="c_%s") `x`
+#define PHPKW(x) %keywordwarn("'" `x` "' is a PHP keyword",sourcefmt="%(lower)s",rename="c_%s") `x`
+
+/* Keyword, except ok as a function */
+#define PHPKW_ok_as_function(x) %keywordwarn("'" `x` "' is a PHP keyword, renaming to 'c_" `x` "'",%$not %$isfunction,sourcefmt="%(lower)s",rename="c_%s") `x`
/* Class (case insensitive) */
-#define PHPCN(x) %keywordwarn("'" `x` "' is a PHP reserved class name, renaming to 'c_" `x` "'",%$isclass,sourcefmt="%(lower)s",rename="c_%s") `x`
+#define PHPCN(x) %keywordwarn("'" `x` "' is a PHP reserved class name",%$isclass,sourcefmt="%(lower)s",rename="c_%s") `x`
/* Constant (case insensitive) */
#define PHPBN1a(x) %namewarn(%warningmsg(SWIGWARN_PARSE_BUILTIN_NAME, "enum conflicts with a built-in constant '"`x`"' in PHP"),%$isenumitem,sourcefmt="%(lower)s") `x`
@@ -22,7 +25,7 @@
PHPBN2a(X); PHPBN2b(X)
%enddef
-#define PHPFN(x) %keywordwarn("'" `x` "' is a PHP built-in function, renaming to 'c_" `x` "'",sourcefmt="%(lower)s",%$isfunction,%$not %$ismember,rename="c_%s") `x`
+#define PHPFN(x) %keywordwarn("'" `x` "' is a PHP built-in function",sourcefmt="%(lower)s",%$isfunction,%$not %$ismember,rename="c_%s") `x`
/* From: http://php.net/manual/en/reserved.keywords.php
* "You cannot use any of the following words as constants, class names,
@@ -84,6 +87,11 @@ PHPKW(while);
PHPKW(xor);
PHPKW(yield);
+/* PHP 8.1 made `readonly` a keyword, but (unlike any other keyword it seems)
+ * it may still be used as a function name.
+ */
+PHPKW_ok_as_function(readonly);
+
// Compile-time "magic" constants
// From: http://php.net/manual/en/reserved.keywords.php
// also at: http://php.net/manual/en/language.constants.predefined.php
@@ -869,6 +877,7 @@ PHPFN(unset); // "Language construct"
PHPFN(usort);
#undef PHPKW
+#undef PHPKW_ok_as_function
#undef PHPBN1a
#undef PHPBN1b
#undef PHPBN1
diff --git a/Lib/php/phppointers.i b/Lib/php/phppointers.i
index 8b4e75e60..a4ff3c0bd 100644
--- a/Lib/php/phppointers.i
+++ b/Lib/php/phppointers.i
@@ -1,5 +1,5 @@
-%define %pass_by_ref( TYPE, CONVERT_IN, CONVERT_OUT )
-%typemap(in, byref=1) TYPE *REF ($*1_ltype tmp),
+%define %pass_by_ref( TYPE, PHP_TYPE, CONVERT_IN, CONVERT_OUT )
+%typemap(in,byref=1,phptype=PHP_TYPE) TYPE *REF ($*1_ltype tmp),
TYPE &REF ($*1_ltype tmp)
%{
if (Z_ISREF($input)) {
@@ -18,25 +18,25 @@
%}
%enddef
-%pass_by_ref( size_t, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( size_t, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( signed int, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( int, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( unsigned int, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed int, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( int, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( unsigned int, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( signed short, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( short, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( unsigned short, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed short, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( short, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( unsigned short, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( signed long, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( long, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( unsigned long, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed long, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( long, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( unsigned long, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( signed char, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( char, CONVERT_CHAR_IN, ZVAL_STRING );
-%pass_by_ref( unsigned char, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed char, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( char, "string", CONVERT_CHAR_IN, ZVAL_STRING );
+%pass_by_ref( unsigned char, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( float, CONVERT_FLOAT_IN, ZVAL_DOUBLE );
-%pass_by_ref( double, CONVERT_FLOAT_IN, ZVAL_DOUBLE );
+%pass_by_ref( float, "float", CONVERT_FLOAT_IN, ZVAL_DOUBLE );
+%pass_by_ref( double, "float", CONVERT_FLOAT_IN, ZVAL_DOUBLE );
-%pass_by_ref( char *, CONVERT_CHAR_IN, ZVAL_STRING );
+%pass_by_ref( char *, "string", CONVERT_CHAR_IN, ZVAL_STRING );
diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg
index a3569a783..538b7e165 100644
--- a/Lib/php/phprun.swg
+++ b/Lib/php/phprun.swg
@@ -10,8 +10,6 @@
extern "C" {
#endif
-#include "php.h"
-
#if PHP_MAJOR_VERSION < 7
# error These bindings need PHP 7 or later - to generate PHP5 bindings use: SWIG < 4.0.0 and swig -php5
#endif
@@ -20,6 +18,27 @@ extern "C" {
#include "zend_exceptions.h"
#include "zend_inheritance.h"
+#if PHP_MAJOR_VERSION == 7
+/* These macros were new in PHP 8.0. For PHP 7.x we define them to give the
+ * same result except without any type declarations. PHP 7.x supports type
+ * declarations, but not for the return type, and alternate types aren't
+ * supported, so we don't try to support these.
+ */
+# define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(name, byref, num_req, classes, types) \
+ ZEND_BEGIN_ARG_INFO_EX(name, 0, byref, num_req)
+# define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(name, byref, num_req, types) \
+ ZEND_BEGIN_ARG_INFO_EX(name, 0, byref, num_req)
+
+/* NB We can just ignore `default` here we currently always pass NULL for it
+ * (this mechanism for specifying default parameter values was new in PHP 8.0
+ * so it's not useful while we still want to support PHP7 too).
+ */
+# define ZEND_ARG_OBJ_TYPE_MASK(byref, name, classes, types, default) \
+ ZEND_ARG_INFO(byref, name)
+# define ZEND_ARG_TYPE_MASK(byref, name, types, default) \
+ ZEND_ARG_INFO(byref, name)
+#endif
+
#include <stdlib.h> /* for abort(), used in generated code. */
#define SWIG_BOOL_CONSTANT(N, V) REGISTER_BOOL_CONSTANT(#N, V, CONST_CS | CONST_PERSISTENT)
@@ -72,6 +91,29 @@ static int default_error_code = E_ERROR;
#define SWIG_GetModule(clientdata) SWIG_Php_GetModule()
#define SWIG_SetModule(clientdata, pointer) SWIG_Php_SetModule(pointer, *(int*)clientdata)
+static zend_class_entry SWIG_Php_swig_wrapped_interface_ce;
+
+#if PHP_MAJOR_VERSION == 7
+/* zend_class_implements_interface() was new in PHP 8.0.
+ *
+ * We could use instanceof_function_ex(C, I, 1) here for 7.4, but for 7.3
+ * and earlier that doesn't work, so instead we just provide a compatibility
+ * implementation which does what zend_class_implements_interface() does in 8.x
+ * and use that for all 7.x so there are fewer variants to worry about testing.
+ */
+static int zend_class_implements_interface(const zend_class_entry *class_ce, const zend_class_entry *interface_ce) {
+ uint32_t i;
+ if (class_ce->num_interfaces) {
+ for (i = 0; i < class_ce->num_interfaces; i++) {
+ if (class_ce->interfaces[i] == interface_ce) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+#endif
+
/* used to wrap returned objects in so we know whether they are newobject
and need freeing, or not */
typedef struct {
@@ -81,10 +123,10 @@ typedef struct {
zend_object std;
} swig_object_wrapper;
-#define SWIG_Z_FETCH_OBJ_P(zv) php_fetch_object(Z_OBJ_P(zv))
+#define SWIG_Z_FETCH_OBJ_P(zv) swig_php_fetch_object(Z_OBJ_P(zv))
static inline
-swig_object_wrapper * php_fetch_object(zend_object *obj) {
+swig_object_wrapper * swig_php_fetch_object(zend_object *obj) {
return (swig_object_wrapper *)((char *)obj - XtOffsetOf(swig_object_wrapper, std));
}
@@ -115,49 +157,13 @@ SWIG_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject) {
obj = ce->create_object(ce);
ZVAL_OBJ(z, obj);
}
- value = php_fetch_object(obj);
+ value = swig_php_fetch_object(obj);
value->ptr = ptr;
value->newobject = (newobject & 1);
value->type = type;
}
}
-/* This pointer conversion routine takes the native pointer p (along with
- its type name) and converts it by calling appropriate casting functions
- according to ty. The resultant pointer is returned, or NULL is returned
- if the pointer can't be cast.
-
- This is called by SWIG_ConvertPtr which gets the type name from the
- swig_object_wrapper. */
-static void *
-SWIG_ConvertPtrData(void * p, const char *type_name, swig_type_info *ty, int *own) {
- swig_cast_info *tc;
- void *result = 0;
-
- if (!ty) {
- /* They don't care about the target type, so just pass on the pointer! */
- return p;
- }
-
- if (! type_name) {
- /* can't convert p to ptr type ty if we don't know what type p is */
- return NULL;
- }
-
- /* convert and cast p from type_name to ptr as ty. */
- tc = SWIG_TypeCheck(type_name, ty);
- if (tc) {
- int newmemory = 0;
- result = SWIG_TypeCast(tc, p, &newmemory);
- if (newmemory == SWIG_CAST_NEW_MEMORY) {
- assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
- if (own)
- *own |= SWIG_CAST_NEW_MEMORY;
- }
- }
- return result;
-}
-
/* We wrap C/C++ pointers as PHP objects. */
static int
SWIG_ConvertPtrAndOwn(zval *z, void **ptr, swig_type_info *ty, int flags, swig_owntype *own) {
@@ -171,12 +177,49 @@ SWIG_ConvertPtrAndOwn(zval *z, void **ptr, swig_type_info *ty, int flags, swig_o
switch (Z_TYPE_P(z)) {
case IS_OBJECT: {
- swig_object_wrapper *value = SWIG_Z_FETCH_OBJ_P(z);
- *ptr = SWIG_ConvertPtrData(value->ptr, value->type->name, ty, own);
- if (*ptr == NULL) return SWIG_ERROR;
- if (flags & SWIG_POINTER_DISOWN) {
- value->newobject = 0;
+ zend_object *obj = Z_OBJ_P(z);
+ swig_object_wrapper *value;
+ if (ty && ty->clientdata == (void*)obj->ce) {
+ // Object is exactly the class asked for - this handles common cases cheaply,
+ // and in particular the PHP classes we use to wrap a pointer to a non-class.
+ } else if (!zend_class_implements_interface(obj->ce, &SWIG_Php_swig_wrapped_interface_ce)) {
+ // Not an object we've wrapped.
+ return -1;
+ }
+
+ /* convert and cast value->ptr from value->type to ptr as ty. */
+ value = swig_php_fetch_object(obj);
+ if (!ty) {
+ /* They don't care about the target type, so just pass on the pointer! */
+ *ptr = value->ptr;
+ } else {
+ swig_cast_info *tc = SWIG_TypeCheckStruct(value->type, ty);
+ if (tc) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc, value->ptr, &newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
+ if (own)
+ *own |= SWIG_CAST_NEW_MEMORY;
+ }
+ } else {
+ *ptr = NULL;
+ }
+ }
+
+ if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !value->newobject) {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ } else {
+ if (*ptr == NULL)
+ return SWIG_ERROR; /* should be SWIG_NullReferenceError?? */
+ if (flags & SWIG_POINTER_DISOWN) {
+ value->newobject = 0;
+ }
+ if (flags & SWIG_POINTER_CLEAR) {
+ value->ptr = 0;
+ }
}
+
return SWIG_OK;
}
case IS_NULL:
@@ -193,7 +236,7 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) {
}
static const char const_name[] = "swig_runtime_data_type_pointer";
-static swig_module_info *SWIG_Php_GetModule() {
+static swig_module_info *SWIG_Php_GetModule(void) {
zval *pointer = zend_get_constant_str(const_name, sizeof(const_name) - 1);
if (pointer) {
if (Z_TYPE_P(pointer) == IS_LONG) {
@@ -206,3 +249,24 @@ static swig_module_info *SWIG_Php_GetModule() {
static void SWIG_Php_SetModule(swig_module_info *pointer, int module_number) {
REGISTER_LONG_CONSTANT(const_name, (long) pointer, CONST_CS | CONST_PERSISTENT);
}
+
+/* Common parts of the "create_object" object handler. */
+static zend_object *SWIG_Php_do_create_object(zend_class_entry *ce, zend_object_handlers *handlers) {
+ swig_object_wrapper *obj = (swig_object_wrapper*)zend_object_alloc(sizeof(swig_object_wrapper), ce);
+ zend_object_std_init(&obj->std, ce);
+ object_properties_init(&obj->std, ce);
+ obj->std.handlers = handlers;
+ obj->newobject = 1;
+ return &obj->std;
+}
+
+/* Common parts of the "free_obj" object handler.
+ Returns void* pointer if the C/C++ object should be destroyed. */
+static void* SWIG_Php_free_obj(zend_object *object) {
+ if (object) {
+ swig_object_wrapper *obj = swig_php_fetch_object(object);
+ zend_object_std_dtor(&obj->std);
+ if (obj->newobject) return obj->ptr;
+ }
+ return NULL;
+}
diff --git a/Lib/php/std_auto_ptr.i b/Lib/php/std_auto_ptr.i
new file mode 100644
index 000000000..284091657
--- /dev/null
+++ b/Lib/php/std_auto_ptr.i
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr(&$input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $descriptor(TYPE *) of $symname");
+ return;
+ } else {
+ zend_type_error("Expected $descriptor(TYPE *) for argument $argnum of $symname");
+ return;
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ SWIG_SetPointerZval($result, (void *)$1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN);
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(&$input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/php/std_string.i b/Lib/php/std_string.i
index 082a32ce1..b2039786c 100644
--- a/Lib/php/std_string.i
+++ b/Lib/php/std_string.i
@@ -27,7 +27,7 @@ namespace std {
$1 = (Z_TYPE($input) == IS_STRING) ? 1 : 0;
%}
- %typemap(in) string %{
+ %typemap(in, phptype="string") string %{
convert_to_string(&$input);
$1.assign(Z_STRVAL($input), Z_STRLEN($input));
%}
@@ -37,7 +37,7 @@ namespace std {
$result.assign(Z_STRVAL_P($input), Z_STRLEN_P($input));
%}
- %typemap(out) string %{
+ %typemap(out, phptype="string") string %{
ZVAL_STRINGL($result, $1.data(), $1.size());
%}
@@ -45,16 +45,16 @@ namespace std {
ZVAL_STRINGL($input, $1.data(), $1.size());
%}
- %typemap(out) const string & %{
+ %typemap(out, phptype="string") const string & %{
ZVAL_STRINGL($result, $1->data(), $1->size());
%}
%typemap(throws) string, const string& %{
zend_throw_exception(NULL, $1.c_str(), 0);
- return;
+ goto fail;
%}
- %typemap(in) const string & ($*1_ltype temp) %{
+ %typemap(in, phptype="string") const string & ($*1_ltype temp) %{
convert_to_string(&$input);
temp.assign(Z_STRVAL($input), Z_STRLEN($input));
$1 = &temp;
@@ -62,7 +62,7 @@ namespace std {
/* These next two handle a function which takes a non-const reference to
* a std::string and modifies the string. */
- %typemap(in,byref=1) string & ($*1_ltype temp) %{
+ %typemap(in,byref=1, phptype="string") string & ($*1_ltype temp) %{
{
zval * p = Z_ISREF($input) ? Z_REFVAL($input) : &$input;
convert_to_string(p);
@@ -86,5 +86,5 @@ namespace std {
/* SWIG will apply the non-const typemap above to const string& without
* this more specific typemap. */
- %typemap(argout) const string & "";
+ %typemap(argout) const string & ""
}
diff --git a/Lib/php/std_unique_ptr.i b/Lib/php/std_unique_ptr.i
new file mode 100644
index 000000000..1bf31595e
--- /dev/null
+++ b/Lib/php/std_unique_ptr.i
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr(&$input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $descriptor(TYPE *) of $symname");
+ return;
+ } else {
+ zend_type_error("Expected $descriptor(TYPE *) for argument $argnum of $symname");
+ return;
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ SWIG_SetPointerZval($result, (void *)$1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN);
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(&$input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/php/swigmove.i b/Lib/php/swigmove.i
new file mode 100644
index 000000000..b16a3c544
--- /dev/null
+++ b/Lib/php/swigmove.i
@@ -0,0 +1,24 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr(&$input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $&1_descriptor of $symname");
+ return;
+ } else {
+ zend_type_error("Expected $&1_descriptor for argument $argnum of $symname");
+ return;
+ }
+ }
+ if (!argp) {
+ zend_type_error("Invalid null reference for argument $argnum of $&1_descriptor of $symname");
+ return;
+ }
+ SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/php/typemaps.i b/Lib/php/typemaps.i
index 94b351113..718469edc 100644
--- a/Lib/php/typemaps.i
+++ b/Lib/php/typemaps.i
@@ -25,21 +25,21 @@
* ----------------------------------------------------------------------------- */
%define BOOL_TYPEMAP(TYPE)
-%typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
+%typemap(in, phptype="bool") TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
%{
convert_to_boolean(&$input);
temp = (Z_TYPE($input) == IS_TRUE);
$1 = &temp;
%}
-%typemap(argout) TYPE *INPUT, TYPE &INPUT "";
-%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
+%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
+%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;"
%typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
{
zval o;
ZVAL_BOOL(&o, temp$argnum);
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
+%typemap(in, phptype="float") TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
%{
convert_to_boolean($input);
lvalue = (Z_TYPE_P($input) == IS_TRUE);
@@ -52,20 +52,20 @@
%enddef
%define DOUBLE_TYPEMAP(TYPE)
-%typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
+%typemap(in, phptype="float") TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
%{
temp = (TYPE) zval_get_double(&$input);
$1 = &temp;
%}
-%typemap(argout) TYPE *INPUT, TYPE &INPUT "";
-%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
+%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
+%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;"
%typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
{
zval o;
ZVAL_DOUBLE(&o, temp$argnum);
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (TYPE dvalue), TYPE &REFERENCE (TYPE dvalue)
+%typemap(in, phptype="float") TYPE *REFERENCE (TYPE dvalue), TYPE &REFERENCE (TYPE dvalue)
%{
dvalue = (TYPE) zval_get_double(&$input);
$1 = &dvalue;
@@ -77,20 +77,20 @@
%enddef
%define INT_TYPEMAP(TYPE)
-%typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
+%typemap(in, phptype="int") TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
%{
temp = (TYPE) zval_get_long(&$input);
$1 = &temp;
%}
-%typemap(argout) TYPE *INPUT, TYPE &INPUT "";
-%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
+%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
+%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;"
%typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
{
zval o;
ZVAL_LONG(&o, temp$argnum);
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
+%typemap(in, phptype="int") TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
%{
lvalue = (TYPE) zval_get_long(&$input);
$1 = &lvalue;
@@ -122,13 +122,11 @@ INT_TYPEMAP(long long);
if ((long long)LONG_MIN <= temp$argnum && temp$argnum <= (long long)LONG_MAX) {
ZVAL_LONG(&o, (long)temp$argnum);
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)temp$argnum);
- ZVAL_STRING(&o, temp);
+ ZVAL_NEW_STR(&o, zend_strpprintf(0, "%lld", (long long)temp$argnum));
}
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (long long lvalue)
+%typemap(in, phptype="int|string") TYPE *REFERENCE (long long lvalue)
%{
CONVERT_LONG_LONG_IN(lvalue, long long, $input)
$1 = &lvalue;
@@ -138,9 +136,7 @@ INT_TYPEMAP(long long);
if ((long long)LONG_MIN <= lvalue$argnum && lvalue$argnum <= (long long)LONG_MAX) {
ZVAL_LONG(&$arg, (long)temp$argnum);
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)lvalue$argnum);
- ZVAL_STRING(&$arg, temp);
+ ZVAL_NEW_STR(&$arg, zend_strpprintf(0, "%lld", (long long)lvalue$argnum));
}
%}
%typemap(argout) long long &OUTPUT
@@ -148,11 +144,10 @@ INT_TYPEMAP(long long);
if ((long long)LONG_MIN <= *arg$argnum && *arg$argnum <= (long long)LONG_MAX) {
ZVAL_LONG($result, (long)(*arg$argnum));
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)(*arg$argnum));
- ZVAL_STRING($result, temp);
+ ZVAL_NEW_STR($result, zend_strpprintf(0, "%lld", (long long)(*arg$argnum)));
}
%}
+
INT_TYPEMAP(unsigned long long);
%typemap(argout,fragment="t_output_helper") unsigned long long *OUTPUT
{
@@ -160,13 +155,11 @@ INT_TYPEMAP(unsigned long long);
if (temp$argnum <= (unsigned long long)LONG_MAX) {
ZVAL_LONG(&o, temp$argnum);
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)temp$argnum);
- ZVAL_STRING(&o, temp);
+ ZVAL_NEW_STR(&o, zend_strpprintf(0, "%llu", (unsigned long long)temp$argnum));
}
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (unsigned long long lvalue)
+%typemap(in, phptype="int|string") TYPE *REFERENCE (unsigned long long lvalue)
%{
CONVERT_UNSIGNED_LONG_LONG_IN(lvalue, unsigned long long, $input)
$1 = &lvalue;
@@ -176,9 +169,7 @@ INT_TYPEMAP(unsigned long long);
if (lvalue$argnum <= (unsigned long long)LONG_MAX) {
ZVAL_LONG($arg, (long)(lvalue$argnum));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)lvalue$argnum);
- ZVAL_STRING((*$arg), temp);
+ ZVAL_NEW_STR((*$arg), zend_strpprintf(0, "%llu", (unsigned long long)lvalue$argnum));
}
%}
%typemap(argout) unsigned long long &OUTPUT
@@ -186,9 +177,7 @@ INT_TYPEMAP(unsigned long long);
if (*arg$argnum <= (unsigned long long)LONG_MAX) {
ZVAL_LONG($result, (long)(*arg$argnum));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)(*arg$argnum));
- ZVAL_STRING($result, temp);
+ ZVAL_NEW_STR($result, zend_strpprintf(0, "%llu", (unsigned long long)(*arg$argnum)));
}
%}
@@ -252,7 +241,7 @@ INT_TYPEMAP(unsigned long long);
%typemap(argout) unsigned long long &INOUT = unsigned long long *OUTPUT;
%typemap(argout) signed char &INOUT = signed char *OUTPUT;
-%typemap(in) char INPUT[ANY] ( char temp[$1_dim0] )
+%typemap(in, phptype="string") char INPUT[ANY] ( char temp[$1_dim0] )
%{
convert_to_string(&$input);
strncpy(temp, Z_STRVAL($input), $1_dim0);
@@ -267,7 +256,7 @@ INT_TYPEMAP(unsigned long long);
t_output_helper($result, &o);
}
-%typemap(in,numinputs=0) void **OUTPUT (int force),
+%typemap(in,numinputs=0,phptype="?SWIGTYPE") void **OUTPUT (int force),
void *&OUTPUT (int force)
%{
/* If they pass NULL by reference, make it into a void*
diff --git a/Lib/php/utils.i b/Lib/php/utils.i
index b8fd9091d..33db942a9 100644
--- a/Lib/php/utils.i
+++ b/Lib/php/utils.i
@@ -16,7 +16,7 @@
char * endptr;
errno = 0;
lvar = (t) strtoll(Z_STRVAL(invar), &endptr, 10);
- if (*endptr && !errno) break;
+ if (*endptr == '\0' && !errno) break;
}
/* FALL THRU */
default:
@@ -33,7 +33,7 @@
char * endptr;
errno = 0;
lvar = (t) strtoull(Z_STRVAL(invar), &endptr, 10);
- if (*endptr && !errno) break;
+ if (*endptr == '\0' && !errno) break;
}
/* FALL THRU */
default:
@@ -63,12 +63,12 @@
}
%enddef
-%define %pass_by_val( TYPE, CONVERT_IN )
-%typemap(in) TYPE
+%define %pass_by_val( TYPE, PHP_TYPE, CONVERT_IN )
+%typemap(in, phptype=PHP_TYPE) TYPE
%{
CONVERT_IN($1,$1_ltype,$input);
%}
-%typemap(in) const TYPE & ($*1_ltype temp)
+%typemap(in, phptype=PHP_TYPE) const TYPE & ($*1_ltype temp)
%{
CONVERT_IN(temp,$*1_ltype,$input);
$1 = &temp;
@@ -81,7 +81,7 @@
%{
$*1_ltype swig_val;
CONVERT_IN(swig_val, $*1_ltype, *$input);
- $1_ltype temp = new $*1_ltype(($*1_ltype)swig_val);
+ $1_ltype temp = new $*1_ltype(swig_val);
swig_acquire_ownership(temp);
$result = temp;
%}
diff --git a/Lib/pointer.i b/Lib/pointer.i
index ea8e535ab..9ac04ebfc 100644
--- a/Lib/pointer.i
+++ b/Lib/pointer.i
@@ -4,7 +4,7 @@
%echo "pointer.i is deprecated. Use cpointer.i instead."
-%echo "See http://www.swig.org/Doc3.0/Library.html"
+%echo "See https://www.swig.org/Doc3.0/Library.html"
diff --git a/Lib/python/README b/Lib/python/README
index fa8ef61e7..70968e7dd 100644
--- a/Lib/python/README
+++ b/Lib/python/README
@@ -101,4 +101,3 @@ std_container.i general common code for the STD/STL containers
std_vectora.i vector + allocator (allocators are now supported in STD/STL)
typemaps.i old in/out typemaps (doesn't need to be included)
-defarg.swg for processing default arguments with shadow classes
diff --git a/Lib/python/argcargv.i b/Lib/python/argcargv.i
index 717fe7334..419803a81 100644
--- a/Lib/python/argcargv.i
+++ b/Lib/python/argcargv.i
@@ -1,13 +1,10 @@
/* ------------------------------------------------------------
- * --- Argc & Argv ---
+ * SWIG library containing argc and argv multi-argument typemaps
* ------------------------------------------------------------ */
%fragment("SWIG_AsArgcArgv","header",fragment="SWIG_AsCharPtrAndSize") {
SWIGINTERN int
-SWIG_AsArgcArgv(PyObject *input,
- swig_type_info *ppchar_info,
- size_t *argc, char ***argv, int *owner)
-{
+SWIG_AsArgcArgv(PyObject *input, swig_type_info *ppchar_info, size_t *argc, char ***argv, int *owner) {
void *vptr;
int res = SWIG_ConvertPtr(input, &vptr, ppchar_info, 0);
if (!SWIG_IsOK(res)) {
@@ -51,7 +48,7 @@ SWIG_AsArgcArgv(PyObject *input,
} else {
/* seems dangerous, but the user asked for it... */
size_t i = 0;
- if (argv) { while (*argv[i] != 0) ++i;}
+ if (argv) { while (*argv[i] != 0) ++i;}
if (argc) *argc = i;
if (owner) *owner = 0;
return SWIG_OK;
@@ -66,10 +63,10 @@ SWIG_AsArgcArgv(PyObject *input,
%typemap(in,noblock=0,fragment="SWIG_AsArgcArgv") (int ARGC, char **ARGV) (int res,char **argv = 0, size_t argc = 0, int owner= 0) {
res = SWIG_AsArgcArgv($input, $descriptor(char**), &argc, &argv, &owner);
- if (!SWIG_IsOK(res)) {
+ if (!SWIG_IsOK(res)) {
$1 = 0; $2 = 0;
%argument_fail(SWIG_TypeError, "int ARGC, char **ARGV", $symname, $argnum);
- } else {
+ } else {
$1 = %static_cast(argc,$1_ltype);
$2 = %static_cast(argv, $2_ltype);
}
diff --git a/Lib/python/boost_shared_ptr.i b/Lib/python/boost_shared_ptr.i
index 709e7811d..bfd8787c0 100644
--- a/Lib/python/boost_shared_ptr.i
+++ b/Lib/python/boost_shared_ptr.i
@@ -39,7 +39,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -58,12 +58,12 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg
index 4f31a8d54..5cff6835f 100644
--- a/Lib/python/builtin.swg
+++ b/Lib/python/builtin.swg
@@ -6,7 +6,11 @@ SWIGINTERN Py_hash_t
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 @@ SwigPyStaticVar_Type(void) {
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 @@ SwigPyObjectType(void) {
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 */
@@ -414,7 +426,11 @@ SwigPyBuiltin_ThisClosure (PyObject *self, void *SWIGUNUSEDPARM(closure)) {
SWIGINTERN void
SwigPyBuiltin_SetMetaType (PyTypeObject *type, PyTypeObject *metatype)
{
+#if PY_VERSION_HEX >= 0x030900a4
+ Py_SET_TYPE(type, metatype);
+#else
Py_TYPE(type) = metatype;
+#endif
}
diff --git a/Lib/python/defarg.swg b/Lib/python/defarg.swg
deleted file mode 100644
index ba5ff43d4..000000000
--- a/Lib/python/defarg.swg
+++ /dev/null
@@ -1,37 +0,0 @@
-/* This file defines an internal function for processing default arguments
- with proxy classes.
-
- There seems to be no straightforward way to write proxy functions
- involving default arguments. For example :
-
- def foo(arg1,arg2,*args):
- proxyc.foo(arg1,arg2,args)
-
- This fails because args is now a tuple and SWIG doesn't know what to
- do with it.
-
- This file allows a different approach :
-
- def foo(arg1,arg2,*args):
- proxyc.__call_defarg(proxyc.foo,(arg1,arg2,)+args)
-
- Basically, we form a new tuple from the object, call this special
- __call_defarg method and it passes control to the real wrapper function.
- An ugly hack, but it works.
-*/
-
-SWIGINTERN PyObject *swig_call_defargs(PyObject *self, PyObject *args) {
- PyObject *func;
- PyObject *parms;
-
- if (!PyArg_ParseTuple(args, "OO", &func, &parms))
- return NULL;
-
- if (!PyCallable_Check(func)) {
- SWIG_PYTHON_THREAD_BEGIN_BLOCK;
- PyErr_SetString(PyExc_TypeError, "__call_defarg : Need a callable object!");
- SWIG_PYTHON_THREAD_END_BLOCK;
- return NULL;
- }
- return PyObject_Call(func, parms, NULL);
-}
diff --git a/Lib/python/embed.i b/Lib/python/embed.i
index efd048789..3fc2d14e5 100644
--- a/Lib/python/embed.i
+++ b/Lib/python/embed.i
@@ -29,9 +29,23 @@ As far as I know, this module is C++ safe.
#endif
%wrapper %{
+#if !defined(PY_SSIZE_T_CLEAN) && !defined(SWIG_NO_PY_SSIZE_T_CLEAN)
+#define PY_SSIZE_T_CLEAN
+#endif
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic push
+#if defined(__cplusplus) && __cplusplus >=201703L
+#pragma GCC diagnostic ignored "-Wregister" /* For python-2.7 headers that use register */
+#endif
+#endif
#include <Python.h>
+#if __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
+
#ifdef __cplusplus
extern "C"
#endif
diff --git a/Lib/python/pyabc.i b/Lib/python/pyabc.i
index fbd91dce4..cae1e7032 100644
--- a/Lib/python/pyabc.i
+++ b/Lib/python/pyabc.i
@@ -1,10 +1,14 @@
%define %pythonabc(Type, Abc)
- %feature("python:abc", #Abc) Type;
+ %feature("python:abc", Abc) Type;
%enddef
-%pythoncode %{import collections.abc%}
-%pythonabc(std::vector, collections.abc.MutableSequence);
-%pythonabc(std::list, collections.abc.MutableSequence);
-%pythonabc(std::map, collections.abc.MutableMapping);
-%pythonabc(std::multimap, collections.abc.MutableMapping);
-%pythonabc(std::set, collections.abc.MutableSet);
-%pythonabc(std::multiset, collections.abc.MutableSet);
+%pythoncode %{if _swig_python_version_info[0:2] >= (3, 3):
+ import collections.abc
+else:
+ import collections
+%}
+%pythonabc(std::vector, "collections.abc.MutableSequence if _swig_python_version_info >= (3, 3) else collections.MutableSequence");
+%pythonabc(std::list, "collections.abc.MutableSequence if _swig_python_version_info >= (3, 3) else collections.MutableSequence");
+%pythonabc(std::map, "collections.abc.MutableMapping if _swig_python_version_info >= (3, 3) else collections.MutableMapping");
+%pythonabc(std::multimap, "collections.abc.MutableMapping if _swig_python_version_info >= (3, 3) else collections.MutableMapping");
+%pythonabc(std::set, "collections.abc.MutableSet if _swig_python_version_info >= (3, 3) else collections.MutableSet");
+%pythonabc(std::multiset, "collections.abc.MutableSet if _swig_python_version_info >= (3, 3) else collections.MutableSet");
diff --git a/Lib/python/pyclasses.swg b/Lib/python/pyclasses.swg
index 9d6299ff1..31ebdd2a1 100644
--- a/Lib/python/pyclasses.swg
+++ b/Lib/python/pyclasses.swg
@@ -43,7 +43,7 @@ namespace swig {
%apply PyObject * {SwigPtr_PyObject};
%apply PyObject * const& {SwigPtr_PyObject const&};
- %typemap(typecheck,precedence=SWIG_TYPECHECK_SWIGOBJECT,noblock=1) SwigPtr_PyObject const& "$1 = ($input != 0);";
+ %typemap(typecheck,precedence=SWIG_TYPECHECK_SWIGOBJECT,noblock=1) SwigPtr_PyObject const& "$1 = ($input != 0);"
/* For output */
diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg
index 2ddf4c375..d6fdff087 100644
--- a/Lib/python/pycontainer.swg
+++ b/Lib/python/pycontainer.swg
@@ -15,9 +15,9 @@
#include <iostream>
#if PY_VERSION_HEX >= 0x03020000
-# define SWIGPY_SLICE_ARG(obj) ((PyObject*) (obj))
+# define SWIGPY_SLICEOBJECT PyObject
#else
-# define SWIGPY_SLICE_ARG(obj) ((PySliceObject*) (obj))
+# define SWIGPY_SLICEOBJECT PySliceObject
#endif
%}
@@ -781,7 +781,7 @@ namespace swig
#if 1
%newobject __getslice__;
#endif
- %newobject __getitem__(PySliceObject *slice);
+ %newobject __getitem__(SWIGPY_SLICEOBJECT *slice);
#if defined(SWIGPYTHON_BUILTIN)
%feature("python:slot", "nb_nonzero", functype="inquiry") __nonzero__;
@@ -829,13 +829,13 @@ namespace swig
%extend {
/* typemap for slice object support */
- %typemap(in) PySliceObject* {
+ %typemap(in) SWIGPY_SLICEOBJECT* {
if (!PySlice_Check($input)) {
%argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
}
- $1 = (PySliceObject *) $input;
+ $1 = (SWIGPY_SLICEOBJECT *) $input;
}
- %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) PySliceObject* {
+ %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) SWIGPY_SLICEOBJECT* {
$1 = PySlice_Check($input);
}
@@ -865,49 +865,49 @@ namespace swig
/* Overloaded methods for Python 3 compatibility
* (Also useful in Python 2.x)
*/
- Sequence* __getitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) {
+ Sequence* __getitem__(SWIGPY_SLICEOBJECT *slice) throw (std::out_of_range, std::invalid_argument) {
Py_ssize_t i, j, step;
if( !PySlice_Check(slice) ) {
SWIG_Error(SWIG_TypeError, "Slice object expected.");
return NULL;
}
- PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+ PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step);
Sequence::difference_type id = i;
Sequence::difference_type jd = j;
return swig::getslice(self, id, jd, step);
}
- void __setitem__(PySliceObject *slice, const Sequence& v) throw (std::out_of_range, std::invalid_argument) {
+ void __setitem__(SWIGPY_SLICEOBJECT *slice, const Sequence& v) throw (std::out_of_range, std::invalid_argument) {
Py_ssize_t i, j, step;
if( !PySlice_Check(slice) ) {
SWIG_Error(SWIG_TypeError, "Slice object expected.");
return;
}
- PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+ PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step);
Sequence::difference_type id = i;
Sequence::difference_type jd = j;
swig::setslice(self, id, jd, step, v);
}
- void __setitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) {
+ void __setitem__(SWIGPY_SLICEOBJECT *slice) throw (std::out_of_range, std::invalid_argument) {
Py_ssize_t i, j, step;
if( !PySlice_Check(slice) ) {
SWIG_Error(SWIG_TypeError, "Slice object expected.");
return;
}
- PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+ PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step);
Sequence::difference_type id = i;
Sequence::difference_type jd = j;
swig::delslice(self, id, jd, step);
}
- void __delitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) {
+ void __delitem__(SWIGPY_SLICEOBJECT *slice) throw (std::out_of_range, std::invalid_argument) {
Py_ssize_t i, j, step;
if( !PySlice_Check(slice) ) {
SWIG_Error(SWIG_TypeError, "Slice object expected.");
return;
}
- PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+ PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step);
Sequence::difference_type id = i;
Sequence::difference_type jd = j;
swig::delslice(self, id, jd, step);
diff --git a/Lib/python/pydocs.swg b/Lib/python/pydocs.swg
index 1eea41b8d..5a25423d4 100644
--- a/Lib/python/pydocs.swg
+++ b/Lib/python/pydocs.swg
@@ -2,43 +2,43 @@
// Documentation for use with the autodoc feature.
#ifdef SWIG_DOC_DOXYGEN_STYLE
-%typemap(doc) SWIGTYPE "@param $1_name $1_type";
-%typemap(doc) SWIGTYPE * "@param $1_name $1_type";
-%typemap(doc) const SWIGTYPE & "@param $1_name $1_type";
-%typemap(doc) const SWIGTYPE && "@param $1_name $1_type";
-%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type";
-
-%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "@param $1_name $1_type (input/output)";
-%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "@param $1_name $1_type (input)";
-%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "@param $1_name $1_type (output)";
+%typemap(doc) SWIGTYPE "@param $1_name $1_type"
+%typemap(doc) SWIGTYPE * "@param $1_name $1_type"
+%typemap(doc) const SWIGTYPE & "@param $1_name $1_type"
+%typemap(doc) const SWIGTYPE && "@param $1_name $1_type"
+%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type"
+
+%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "@param $1_name $1_type (input/output)"
+%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "@param $1_name $1_type (input)"
+%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "@param $1_name $1_type (output)"
#else
-%typemap(doc) SWIGTYPE "$1_name: $1_type";
-%typemap(doc) SWIGTYPE * "$1_name: $1_type";
-%typemap(doc) const SWIGTYPE & "$1_name: $1_type";
-%typemap(doc) const SWIGTYPE && "$1_name: $1_type";
-%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type";
-
-%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "$1_name: $1_type (input/output)";
-%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "$1_name: $1_type (input)";
-%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "$1_name: $1_type (output)";
+%typemap(doc) SWIGTYPE "$1_name: $1_type"
+%typemap(doc) SWIGTYPE * "$1_name: $1_type"
+%typemap(doc) const SWIGTYPE & "$1_name: $1_type"
+%typemap(doc) const SWIGTYPE && "$1_name: $1_type"
+%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type"
+
+%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "$1_name: $1_type (input/output)"
+%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "$1_name: $1_type (input)"
+%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "$1_name: $1_type (output)"
#endif
// Types to use in Python documentation for the parameters of the given C++ type.
-%typemap(doctype) bool "boolean";
+%typemap(doctype) bool "boolean"
%define int_doctype_for_cppint_type(cppint_type)
- %typemap(doctype) cppint_type, unsigned cppint_type "int";
+ %typemap(doctype) cppint_type, unsigned cppint_type "int"
%enddef
%formacro(int_doctype_for_cppint_type, short, int, long, long long)
-%typemap(doctype) size_t "int";
+%typemap(doctype) size_t "int"
-%typemap(doctype) enum SWIGTYPE "int";
+%typemap(doctype) enum SWIGTYPE "int"
-%typemap(doctype) float, double, long double "float";
+%typemap(doctype) float, double, long double "float"
-%typemap(doctype) char*, std::string "string";
+%typemap(doctype) char*, std::string "string"
%typemap(doctype) SWIGTYPE "$1_basetype"
%typemap(doctype) SWIGTYPE * "$typemap(doctype, $*1_ltype)"
diff --git a/Lib/python/pyerrors.swg b/Lib/python/pyerrors.swg
index 2628de8e6..10b694cde 100644
--- a/Lib/python/pyerrors.swg
+++ b/Lib/python/pyerrors.swg
@@ -64,7 +64,6 @@ SWIG_Python_AddErrorMsg(const char* mesg)
PyErr_Format(type, "%s %s", tmp, mesg);
else
PyErr_Format(type, "%s", mesg);
- SWIG_Python_str_DelForPy3(tmp);
Py_DECREF(old_str);
Py_DECREF(value);
} else {
diff --git a/Lib/python/pyhead.swg b/Lib/python/pyhead.swg
index 4ae8bbe2e..6f37160bb 100644
--- a/Lib/python/pyhead.swg
+++ b/Lib/python/pyhead.swg
@@ -13,7 +13,6 @@
#define PyString_Size(str) PyBytes_Size(str)
#define PyString_InternFromString(key) PyUnicode_InternFromString(key)
#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
-#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x)
#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
#endif
@@ -31,38 +30,19 @@
#endif
-/* Warning: This function will allocate a new string in Python 3,
- * so please call SWIG_Python_str_DelForPy3(x) to free the space.
- */
SWIGINTERN char*
SWIG_Python_str_AsChar(PyObject *str)
{
#if PY_VERSION_HEX >= 0x03030000
return (char *)PyUnicode_AsUTF8(str);
-#elif PY_VERSION_HEX >= 0x03000000
- char *newstr = 0;
- str = PyUnicode_AsUTF8String(str);
- if (str) {
- char *cstr;
- Py_ssize_t len;
- if (PyBytes_AsStringAndSize(str, &cstr, &len) != -1) {
- newstr = (char *) malloc(len+1);
- if (newstr)
- memcpy(newstr, cstr, len+1);
- }
- Py_XDECREF(str);
- }
- return newstr;
#else
return PyString_AsString(str);
#endif
}
-#if PY_VERSION_HEX >= 0x03030000 || PY_VERSION_HEX < 0x03000000
-# define SWIG_Python_str_DelForPy3(x)
-#else
-# define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
-#endif
+/* Was useful for Python 3.0.x-3.2.x - now provided only for compatibility
+ * with any uses in user interface files. */
+#define SWIG_Python_str_DelForPy3(x)
SWIGINTERN PyObject*
@@ -81,7 +61,12 @@ SWIG_Python_str_FromChar(const char *c)
/* SWIGPY_USE_CAPSULE is no longer used within SWIG itself, but some user interface files check for it. */
# define SWIGPY_USE_CAPSULE
-# define SWIGPY_CAPSULE_NAME ("swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
+#ifdef SWIGPYTHON_BUILTIN
+# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule_builtin" SWIG_TYPE_TABLE_NAME
+#else
+# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule" SWIG_TYPE_TABLE_NAME
+#endif
+# define SWIGPY_CAPSULE_NAME ("swig_runtime_data" SWIG_RUNTIME_VERSION "." SWIGPY_CAPSULE_ATTR_NAME)
#if PY_VERSION_HEX < 0x03020000
#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
diff --git a/Lib/python/pyinit.swg b/Lib/python/pyinit.swg
index a6d609d56..6833b455a 100644
--- a/Lib/python/pyinit.swg
+++ b/Lib/python/pyinit.swg
@@ -8,6 +8,8 @@
%fragment("<stddef.h>"); // For offsetof
#endif
+#if defined SWIGPYTHON_FASTPROXY && !defined SWIGPYTHON_BUILTIN
+
%insert(runtime) %{
#ifdef __cplusplus
extern "C" {
@@ -24,226 +26,14 @@ SWIGINTERN PyObject *SWIG_PyStaticMethod_New(PyObject *SWIGUNUSEDPARM(self), PyO
#endif
%}
+#endif
+
%init %{
#ifdef __cplusplus
extern "C" {
#endif
-/* Python-specific SWIG API */
-#define SWIG_newvarlink() SWIG_Python_newvarlink()
-#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr)
-#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants)
-
-/* -----------------------------------------------------------------------------
- * global variable support code.
- * ----------------------------------------------------------------------------- */
-
-typedef struct swig_globalvar {
- char *name; /* Name of global variable */
- PyObject *(*get_attr)(void); /* Return the current value */
- int (*set_attr)(PyObject *); /* Set the value */
- struct swig_globalvar *next;
-} swig_globalvar;
-
-typedef struct swig_varlinkobject {
- PyObject_HEAD
- swig_globalvar *vars;
-} swig_varlinkobject;
-
-SWIGINTERN PyObject *
-swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
-#if PY_VERSION_HEX >= 0x03000000
- return PyUnicode_InternFromString("<Swig global variables>");
-#else
- return PyString_FromString("<Swig global variables>");
-#endif
-}
-
-SWIGINTERN PyObject *
-swig_varlink_str(swig_varlinkobject *v) {
-#if PY_VERSION_HEX >= 0x03000000
- PyObject *str = PyUnicode_InternFromString("(");
- PyObject *tail;
- PyObject *joined;
- swig_globalvar *var;
- for (var = v->vars; var; var=var->next) {
- tail = PyUnicode_FromString(var->name);
- joined = PyUnicode_Concat(str, tail);
- Py_DecRef(str);
- Py_DecRef(tail);
- str = joined;
- if (var->next) {
- tail = PyUnicode_InternFromString(", ");
- joined = PyUnicode_Concat(str, tail);
- Py_DecRef(str);
- Py_DecRef(tail);
- str = joined;
- }
- }
- tail = PyUnicode_InternFromString(")");
- joined = PyUnicode_Concat(str, tail);
- Py_DecRef(str);
- Py_DecRef(tail);
- str = joined;
-#else
- PyObject *str = PyString_FromString("(");
- swig_globalvar *var;
- for (var = v->vars; var; var=var->next) {
- PyString_ConcatAndDel(&str,PyString_FromString(var->name));
- if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
- }
- PyString_ConcatAndDel(&str,PyString_FromString(")"));
-#endif
- return str;
-}
-
-SWIGINTERN void
-swig_varlink_dealloc(swig_varlinkobject *v) {
- swig_globalvar *var = v->vars;
- while (var) {
- swig_globalvar *n = var->next;
- free(var->name);
- free(var);
- var = n;
- }
-}
-
-SWIGINTERN PyObject *
-swig_varlink_getattr(swig_varlinkobject *v, char *n) {
- PyObject *res = NULL;
- swig_globalvar *var = v->vars;
- while (var) {
- if (strcmp(var->name,n) == 0) {
- res = (*var->get_attr)();
- break;
- }
- var = var->next;
- }
- if (res == NULL && !PyErr_Occurred()) {
- PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
- }
- return res;
-}
-
-SWIGINTERN int
-swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
- int res = 1;
- swig_globalvar *var = v->vars;
- while (var) {
- if (strcmp(var->name,n) == 0) {
- res = (*var->set_attr)(p);
- break;
- }
- var = var->next;
- }
- if (res == 1 && !PyErr_Occurred()) {
- PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
- }
- return res;
-}
-
-SWIGINTERN PyTypeObject*
-swig_varlink_type(void) {
- static char varlink__doc__[] = "Swig var link object";
- static PyTypeObject varlink_type;
- static int type_init = 0;
- if (!type_init) {
- const PyTypeObject tmp = {
-#if PY_VERSION_HEX >= 0x03000000
- PyVarObject_HEAD_INIT(NULL, 0)
-#else
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
-#endif
- "swigvarlink", /* tp_name */
- sizeof(swig_varlinkobject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) swig_varlink_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- (getattrfunc) swig_varlink_getattr, /* tp_getattr */
- (setattrfunc) swig_varlink_setattr, /* tp_setattr */
- 0, /* tp_compare */
- (reprfunc) swig_varlink_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- (reprfunc) swig_varlink_str, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- 0, /* tp_flags */
- varlink__doc__, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
-#if PY_VERSION_HEX >= 0x03040000
- 0, /* tp_finalize */
-#endif
-#if PY_VERSION_HEX >= 0x03080000
- 0, /* tp_vectorcall */
-#endif
-#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
- 0, /* tp_print */
-#endif
-#ifdef COUNT_ALLOCS
- 0, /* tp_allocs */
- 0, /* tp_frees */
- 0, /* tp_maxalloc */
- 0, /* tp_prev */
- 0 /* tp_next */
-#endif
- };
- varlink_type = tmp;
- type_init = 1;
- if (PyType_Ready(&varlink_type) < 0)
- return NULL;
- }
- return &varlink_type;
-}
-
-/* Create a variable linking object for use later */
-SWIGINTERN PyObject *
-SWIG_Python_newvarlink(void) {
- swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
- if (result) {
- result->vars = 0;
- }
- return ((PyObject*) result);
-}
-
-SWIGINTERN void
-SWIG_Python_addvarlink(PyObject *p, const char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
- swig_varlinkobject *v = (swig_varlinkobject *) p;
- swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
- if (gv) {
- size_t size = strlen(name)+1;
- gv->name = (char *)malloc(size);
- if (gv->name) {
- memcpy(gv->name, name, size);
- gv->get_attr = get_attr;
- gv->set_attr = set_attr;
- gv->next = v->vars;
- }
- }
- v->vars = gv;
-}
-
-SWIGINTERN PyObject *
-SWIG_globals(void) {
- static PyObject *globals = 0;
- if (!globals) {
- globals = SWIG_newvarlink();
- }
- return globals;
-}
-
/* -----------------------------------------------------------------------------
* constants/methods manipulation
* ----------------------------------------------------------------------------- */
@@ -272,15 +62,12 @@ SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
}
}
-/* -----------------------------------------------------------------------------*/
-/* Fix SwigMethods to carry the callback ptrs when needed */
-/* -----------------------------------------------------------------------------*/
+/* -----------------------------------------------------------------------------
+ * Patch %callback methods' docstrings to hold the callback ptrs
+ * -----------------------------------------------------------------------------*/
SWIGINTERN void
-SWIG_Python_FixMethods(PyMethodDef *methods,
- swig_const_info *const_table,
- swig_type_info **types,
- swig_type_info **types_initial) {
+SWIG_Python_FixMethods(PyMethodDef *methods, const swig_const_info *const_table, swig_type_info **types, swig_type_info **types_initial) {
size_t i;
for (i = 0; methods[i].ml_name; ++i) {
const char *c = methods[i].ml_doc;
@@ -288,7 +75,7 @@ SWIG_Python_FixMethods(PyMethodDef *methods,
c = strstr(c, "swig_ptr: ");
if (c) {
int j;
- swig_const_info *ci = 0;
+ const swig_const_info *ci = 0;
const char *name = c + 10;
for (j = 0; const_table[j].type; ++j) {
if (strncmp(const_table[j].name, name,
@@ -320,6 +107,20 @@ SWIG_Python_FixMethods(PyMethodDef *methods,
}
}
+#ifdef __cplusplus
+}
+#endif
+
+%}
+
+#if defined SWIGPYTHON_FASTPROXY && !defined SWIGPYTHON_BUILTIN
+
+%init %{
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* -----------------------------------------------------------------------------
* Method creation and docstring support functions
* ----------------------------------------------------------------------------- */
@@ -382,6 +183,12 @@ SWIGINTERN PyObject *SWIG_PyStaticMethod_New(PyObject *SWIGUNUSEDPARM(self), PyO
}
#endif
+%}
+
+#endif
+
+%init %{
+
/* -----------------------------------------------------------------------------*
* Partial Init method
* -----------------------------------------------------------------------------*/
diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg
index 0025184d1..9b6dd28ee 100644
--- a/Lib/python/pyrun.swg
+++ b/Lib/python/pyrun.swg
@@ -11,8 +11,8 @@
# error "This version of SWIG only supports Python >= 2.7"
#endif
-#if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03020000
-# error "This version of SWIG only supports Python 3 >= 3.2"
+#if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03030000
+# error "This version of SWIG only supports Python 3 >= 3.3"
#endif
/* Common SWIG API */
@@ -214,6 +214,234 @@ SWIG_Python_CheckNoKeywords(PyObject *kwargs, const char *name) {
#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Python-specific SWIG API */
+#define SWIG_newvarlink() SWIG_Python_newvarlink()
+#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr)
+#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants)
+
+/* -----------------------------------------------------------------------------
+ * global variable support code.
+ * ----------------------------------------------------------------------------- */
+
+typedef struct swig_globalvar {
+ char *name; /* Name of global variable */
+ PyObject *(*get_attr)(void); /* Return the current value */
+ int (*set_attr)(PyObject *); /* Set the value */
+ struct swig_globalvar *next;
+} swig_globalvar;
+
+typedef struct swig_varlinkobject {
+ PyObject_HEAD
+ swig_globalvar *vars;
+} swig_varlinkobject;
+
+SWIGINTERN PyObject *
+swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_InternFromString("<Swig global variables>");
+#else
+ return PyString_FromString("<Swig global variables>");
+#endif
+}
+
+SWIGINTERN PyObject *
+swig_varlink_str(swig_varlinkobject *v) {
+#if PY_VERSION_HEX >= 0x03000000
+ PyObject *str = PyUnicode_InternFromString("(");
+ PyObject *tail;
+ PyObject *joined;
+ swig_globalvar *var;
+ for (var = v->vars; var; var=var->next) {
+ tail = PyUnicode_FromString(var->name);
+ joined = PyUnicode_Concat(str, tail);
+ Py_DecRef(str);
+ Py_DecRef(tail);
+ str = joined;
+ if (var->next) {
+ tail = PyUnicode_InternFromString(", ");
+ joined = PyUnicode_Concat(str, tail);
+ Py_DecRef(str);
+ Py_DecRef(tail);
+ str = joined;
+ }
+ }
+ tail = PyUnicode_InternFromString(")");
+ joined = PyUnicode_Concat(str, tail);
+ Py_DecRef(str);
+ Py_DecRef(tail);
+ str = joined;
+#else
+ PyObject *str = PyString_FromString("(");
+ swig_globalvar *var;
+ for (var = v->vars; var; var=var->next) {
+ PyString_ConcatAndDel(&str,PyString_FromString(var->name));
+ if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
+ }
+ PyString_ConcatAndDel(&str,PyString_FromString(")"));
+#endif
+ return str;
+}
+
+SWIGINTERN void
+swig_varlink_dealloc(swig_varlinkobject *v) {
+ swig_globalvar *var = v->vars;
+ while (var) {
+ swig_globalvar *n = var->next;
+ free(var->name);
+ free(var);
+ var = n;
+ }
+}
+
+SWIGINTERN PyObject *
+swig_varlink_getattr(swig_varlinkobject *v, char *n) {
+ PyObject *res = NULL;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->get_attr)();
+ break;
+ }
+ var = var->next;
+ }
+ if (res == NULL && !PyErr_Occurred()) {
+ PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
+ }
+ return res;
+}
+
+SWIGINTERN int
+swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
+ int res = 1;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->set_attr)(p);
+ break;
+ }
+ var = var->next;
+ }
+ if (res == 1 && !PyErr_Occurred()) {
+ PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
+ }
+ return res;
+}
+
+SWIGINTERN PyTypeObject*
+swig_varlink_type(void) {
+ static char varlink__doc__[] = "Swig var link object";
+ static PyTypeObject varlink_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp = {
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ "swigvarlink", /* tp_name */
+ sizeof(swig_varlinkobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor) swig_varlink_dealloc, /* tp_dealloc */
+#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 */
+ (reprfunc) swig_varlink_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc) swig_varlink_str, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ varlink__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
+ 0, /* tp_del */
+ 0, /* tp_version_tag */
+#if PY_VERSION_HEX >= 0x03040000
+ 0, /* tp_finalize */
+#endif
+#if PY_VERSION_HEX >= 0x03080000
+ 0, /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+ 0, /* tp_print */
+#endif
+#ifdef COUNT_ALLOCS
+ 0, /* tp_allocs */
+ 0, /* tp_frees */
+ 0, /* tp_maxalloc */
+ 0, /* tp_prev */
+ 0 /* tp_next */
+#endif
+ };
+ varlink_type = tmp;
+ type_init = 1;
+ if (PyType_Ready(&varlink_type) < 0)
+ return NULL;
+ }
+ return &varlink_type;
+}
+
+/* Create a variable linking object for use later */
+SWIGINTERN PyObject *
+SWIG_Python_newvarlink(void) {
+ swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
+ if (result) {
+ result->vars = 0;
+ }
+ return ((PyObject*) result);
+}
+
+SWIGINTERN void
+SWIG_Python_addvarlink(PyObject *p, const char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
+ swig_varlinkobject *v = (swig_varlinkobject *) p;
+ swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
+ if (gv) {
+ size_t size = strlen(name)+1;
+ gv->name = (char *)malloc(size);
+ if (gv->name) {
+ memcpy(gv->name, name, size);
+ gv->get_attr = get_attr;
+ gv->set_attr = set_attr;
+ gv->next = v->vars;
+ }
+ }
+ v->vars = gv;
+}
+
+
+static PyObject *Swig_Globals_global = NULL;
+
+SWIGINTERN PyObject *
+SWIG_globals(void) {
+ if (Swig_Globals_global == NULL) {
+ Swig_Globals_global = SWIG_newvarlink();
+ }
+ return Swig_Globals_global;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
/* -----------------------------------------------------------------------------
* Pointer declarations
* ----------------------------------------------------------------------------- */
@@ -495,6 +723,8 @@ SwigPyObject_Check(PyObject *op) {
SWIGRUNTIME PyObject *
SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
+static PyObject* Swig_Capsule_global = NULL;
+
SWIGRUNTIME void
SwigPyObject_dealloc(PyObject *v)
{
@@ -545,7 +775,8 @@ SwigPyObject_dealloc(PyObject *v)
printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
}
#endif
- }
+ Py_XDECREF(Swig_Capsule_global);
+ }
Py_XDECREF(next);
#ifdef SWIGPYTHON_BUILTIN
Py_XDECREF(sobj->dict);
@@ -561,6 +792,7 @@ SwigPyObject_append(PyObject* v, PyObject* next)
PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject");
return NULL;
}
+ ((SwigPyObject *)next)->next = sobj->next;
sobj->next = next;
Py_INCREF(next);
return SWIG_Py_Void();
@@ -687,7 +919,11 @@ SwigPyObject_TypeOnce(void) {
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
@@ -770,6 +1006,12 @@ SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
#ifdef SWIGPYTHON_BUILTIN
sobj->dict = 0;
#endif
+ if (own == SWIG_POINTER_OWN) {
+ /* Obtain a reference to the Python capsule wrapping the module information, so that the
+ * module information is correctly destroyed after all SWIG python objects have been freed
+ * by the GC (and corresponding destructors invoked) */
+ Py_XINCREF(Swig_Capsule_global);
+ }
}
return (PyObject *)sobj;
}
@@ -857,7 +1099,11 @@ SwigPyPacked_TypeOnce(void) {
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
@@ -1112,12 +1358,19 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
}
}
if (sobj) {
- if (own)
- *own = *own | sobj->own;
- if (flags & SWIG_POINTER_DISOWN) {
- sobj->own = 0;
+ if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !sobj->own) {
+ res = SWIG_ERROR_RELEASE_NOT_OWNED;
+ } else {
+ if (own)
+ *own = *own | sobj->own;
+ if (flags & SWIG_POINTER_DISOWN) {
+ sobj->own = 0;
+ }
+ if (flags & SWIG_POINTER_CLEAR) {
+ sobj->ptr = 0;
+ }
+ res = SWIG_OK;
}
- res = SWIG_OK;
} else {
if (implicit_conv) {
SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
@@ -1262,7 +1515,7 @@ SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
Py_DECREF(inst);
inst = 0;
} else {
- Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+ PyType_Modified(Py_TYPE(inst));
}
}
}
@@ -1390,37 +1643,46 @@ SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
void *SWIG_ReturnGlobalTypeList(void *);
#endif
+static PyObject *Swig_TypeCache_global = NULL;
+
/* The python cached type query */
SWIGRUNTIME PyObject *
SWIG_Python_TypeCache(void) {
- static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
- return cache;
+ if (Swig_TypeCache_global == NULL) {
+ Swig_TypeCache_global = PyDict_New();
+ }
+ return Swig_TypeCache_global;
}
SWIGRUNTIME swig_module_info *
SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
+#ifdef SWIG_LINK_RUNTIME
static void *type_pointer = (void *)0;
/* first check if module already created */
if (!type_pointer) {
-#ifdef SWIG_LINK_RUNTIME
type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
+ }
#else
- type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
- if (PyErr_Occurred()) {
- PyErr_Clear();
- type_pointer = (void *)0;
- }
-#endif
+ void *type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ type_pointer = (void *)0;
}
+#endif
return (swig_module_info *) type_pointer;
}
+
+static int interpreter_counter = 0; // how many (sub-)interpreters are using swig_module's types
+
SWIGRUNTIME void
SWIG_Python_DestroyModule(PyObject *obj)
{
swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
swig_type_info **types = swig_module->types;
size_t i;
+ if (--interpreter_counter != 0) // another sub-interpreter may still be using the swig_module's types
+ return;
for (i =0; i < swig_module->size; ++i) {
swig_type_info *ty = types[i];
if (ty->owndata) {
@@ -1431,7 +1693,11 @@ SWIG_Python_DestroyModule(PyObject *obj)
}
Py_DECREF(SWIG_This());
Swig_This_global = NULL;
+ Py_DECREF(SWIG_globals());
+ Swig_Globals_global = NULL;
Py_DECREF(SWIG_Python_TypeCache());
+ Swig_TypeCache_global = NULL;
+ Swig_Capsule_global = NULL;
}
SWIGRUNTIME void
@@ -1445,7 +1711,10 @@ SWIG_Python_SetModule(swig_module_info *swig_module) {
#endif
PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
if (pointer && module) {
- if (PyModule_AddObject(module, "type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer) != 0) {
+ if (PyModule_AddObject(module, SWIGPY_CAPSULE_ATTR_NAME, pointer) == 0) {
+ ++interpreter_counter;
+ Swig_Capsule_global = pointer;
+ } else {
Py_DECREF(pointer);
}
} else {
@@ -1503,7 +1772,6 @@ SWIG_Python_AddErrMesg(const char* mesg, int infront)
} else {
PyErr_Format(type, "%s %s", errmesg, mesg);
}
- SWIG_Python_str_DelForPy3(tmp);
Py_DECREF(old_str);
}
return 1;
@@ -1555,7 +1823,6 @@ SWIG_Python_TypeError(const char *type, PyObject *obj)
if (cstr) {
PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
type, otype, cstr);
- SWIG_Python_str_DelForPy3(cstr);
} else {
PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
type, otype);
@@ -1577,12 +1844,6 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(arg
void *result;
if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
PyErr_Clear();
-#if SWIG_POINTER_EXCEPTION
- if (flags) {
- SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
- SWIG_Python_ArgFail(argnum);
- }
-#endif
}
return result;
}
diff --git a/Lib/python/pyruntime.swg b/Lib/python/pyruntime.swg
index 751bc8d5f..1d028adaf 100644
--- a/Lib/python/pyruntime.swg
+++ b/Lib/python/pyruntime.swg
@@ -4,14 +4,36 @@
# include <math.h>
#endif
+#if !defined(PY_SSIZE_T_CLEAN) && !defined(SWIG_NO_PY_SSIZE_T_CLEAN)
+#define PY_SSIZE_T_CLEAN
+#endif
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic push
+#if defined(__cplusplus) && __cplusplus >=201703L
+#pragma GCC diagnostic ignored "-Wregister" /* For python-2.7 headers that use register */
+#endif
+#endif
+
#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
/* Use debug wrappers with the Python release dll */
+
+#if defined(_MSC_VER) && _MSC_VER >= 1929
+/* Workaround compilation errors when redefining _DEBUG in MSVC 2019 version 16.10 and later
+ * See https://github.com/swig/swig/issues/2090 */
+# include <corecrt.h>
+#endif
+
# undef _DEBUG
# include <Python.h>
# define _DEBUG 1
#else
# include <Python.h>
#endif
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
%}
%insert(runtime) "swigrun.swg"; /* SWIG API */
diff --git a/Lib/python/pythonkw.swg b/Lib/python/pythonkw.swg
index 0138e40e4..a21034524 100644
--- a/Lib/python/pythonkw.swg
+++ b/Lib/python/pythonkw.swg
@@ -2,7 +2,7 @@
Warnings for Python keywords, built-in names and bad names.
*/
-#define PYTHONKW(x) %keywordwarn("'" `x` "' is a python keyword, renaming to '_" `x` "'", rename="_%s") `x`
+#define PYTHONKW(x) %keywordwarn("'" `x` "' is a python keyword", rename="_%s") `x`
#define PYTHONBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in python") `x`
diff --git a/Lib/python/pytypemaps.swg b/Lib/python/pytypemaps.swg
index 0eda17cda..0ae25a686 100644
--- a/Lib/python/pytypemaps.swg
+++ b/Lib/python/pytypemaps.swg
@@ -83,7 +83,7 @@
{ SWIG_PY_POINTER, "$symname", 0, 0, (void *)($value), &$descriptor }
%typemap(consttab) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY));
-%typemap(constcode) SWIGTYPE ((*)(ANY)) "";
+%typemap(constcode) SWIGTYPE ((*)(ANY)) ""
%typemap(constcode) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY));
diff --git a/Lib/python/std_auto_ptr.i b/Lib/python/std_auto_ptr.i
index c94006a68..3d7ae8ba1 100644
--- a/Lib/python/std_auto_ptr.i
+++ b/Lib/python/std_auto_ptr.i
@@ -1,17 +1,39 @@
-/*
- The typemaps here allow handling functions returning std::auto_ptr<>,
- which is the most common use of this type. If you have functions taking it
- as parameter, these typemaps can't be used for them and you need to do
- something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
%define %auto_ptr(TYPE)
-%typemap (out) std::auto_ptr<TYPE > %{
- %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
%}
-%template() std::auto_ptr<TYPE >;
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
%enddef
namespace std {
- template <class T> class auto_ptr {};
-}
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/python/std_unique_ptr.i b/Lib/python/std_unique_ptr.i
new file mode 100644
index 000000000..f988714df
--- /dev/null
+++ b/Lib/python/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/python/swigmove.i b/Lib/python/swigmove.i
new file mode 100644
index 000000000..62ecca768
--- /dev/null
+++ b/Lib/python/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/python/typemaps.i b/Lib/python/typemaps.i
index 5d438ecab..dba63dd59 100644
--- a/Lib/python/typemaps.i
+++ b/Lib/python/typemaps.i
@@ -72,7 +72,7 @@ multiple output values, they are returned in the form of a Python tuple.
For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
+returns the integer part in one of its parameters) :
double modf(double x, double *ip);
diff --git a/Lib/r/boost_shared_ptr.i b/Lib/r/boost_shared_ptr.i
index 668bf4354..87c89b5f9 100644
--- a/Lib/r/boost_shared_ptr.i
+++ b/Lib/r/boost_shared_ptr.i
@@ -35,7 +35,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -54,12 +54,12 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/r/r.swg b/Lib/r/r.swg
index 8cf8cdf53..eeabcf4ba 100644
--- a/Lib/r/r.swg
+++ b/Lib/r/r.swg
@@ -26,9 +26,13 @@ SWIGEXPORT void SWIG_init(void) {
assign(name, _obj);
%end_block %enddef
-%define %raise(obj,type,desc)
-return R_NilValue;
-%enddef
+%runtime %{
+void SWIG_R_Raise(SEXP obj, const char *msg) {
+ Rf_error(Rf_isString(obj) ? STRING_VALUE(obj) : msg);
+}
+%}
+
+#define %raise(OBJ, TYPE, DESC) SWIG_R_Raise(OBJ, "C/C++ exception of type " TYPE); return R_NilValue
%insert("sinit") "srun.swg"
@@ -53,7 +57,7 @@ SWIG_InitializeModule(0);
assert(all(sapply($input, class) == "$R_class"));
%}
-%typemap(out) void "";
+%typemap(out) void ""
%typemap(in) int *, int[ANY],
signed int *, signed int[ANY],
diff --git a/Lib/r/rkw.swg b/Lib/r/rkw.swg
index 074d7dfd9..c4af7084f 100644
--- a/Lib/r/rkw.swg
+++ b/Lib/r/rkw.swg
@@ -2,8 +2,8 @@
Warnings for R keywords, built-in names and bad names.
*/
-#define RKW(x) %keywordwarn("'" `x` "' is a R keyword, renaming to '_" `x`"'", rename="_%s") `x`
-#define RSWIGKW(x) %keywordwarn("'" `x` "' is a SWIG R reserved parameter name, renaming to '_" `x`"'", rename="_%s") `x`
+#define RKW(x) %keywordwarn("'" `x` "' is a R keyword", rename="_%s") `x`
+#define RSWIGKW(x) %keywordwarn("'" `x` "' is a SWIG R reserved parameter name", rename="_%s") `x`
/*
Warnings for R reserved words taken from
diff --git a/Lib/r/rtype.swg b/Lib/r/rtype.swg
index 8fe12230b..a9c067589 100644
--- a/Lib/r/rtype.swg
+++ b/Lib/r/rtype.swg
@@ -3,26 +3,27 @@
for use in class representations.
*/
-%typemap("rtype") int, int *, int & "integer";
-%typemap("rtype") long, long *, long & "integer";
-%typemap("rtype") float, float*, float & "numeric";
-%typemap("rtype") double, double*, double & "numeric";
-%typemap("rtype") char *, char ** "character";
-%typemap("rtype") char "character";
-%typemap("rtype") string, string *, string & "character";
-%typemap("rtype") std::string, std::string *, std::string & "character";
-%typemap("rtype") bool, bool * "logical";
-%typemap("rtype") enum SWIGTYPE "character";
-%typemap("rtype") enum SWIGTYPE * "character";
-%typemap("rtype") enum SWIGTYPE *const "character";
-%typemap("rtype") enum SWIGTYPE & "character";
-%typemap("rtype") const enum SWIGTYPE & "character";
-%typemap("rtype") enum SWIGTYPE && "character";
-%typemap("rtype") SWIGTYPE * "$R_class";
-%typemap("rtype") SWIGTYPE *const "$R_class";
-%typemap("rtype") SWIGTYPE & "$R_class";
-%typemap("rtype") SWIGTYPE && "$R_class";
-%typemap("rtype") SWIGTYPE "$&R_class";
+%typemap("rtype") int, int *, int & "integer"
+%typemap("rtype") long, long *, long & "integer"
+%typemap("rtype") float, float*, float & "numeric"
+%typemap("rtype") double, double*, double & "numeric"
+%typemap("rtype") char *, char ** "character"
+%typemap("rtype") char "character"
+%typemap("rtype") string, string *, string & "character"
+%typemap("rtype") std::string, std::string *, std::string & "character"
+%typemap("rtype") bool, bool * "logical"
+%typemap("rtype") enum SWIGTYPE "character"
+%typemap("rtype") enum SWIGTYPE * "character"
+%typemap("rtype") enum SWIGTYPE *const& "character"
+%typemap("rtype") enum SWIGTYPE & "character"
+%typemap("rtype") const enum SWIGTYPE & "character"
+%typemap("rtype") enum SWIGTYPE && "character"
+%typemap("rtype") SWIGTYPE * "$R_class"
+%typemap("rtype") SWIGTYPE *const "$R_class"
+%typemap("rtype") SWIGTYPE *const& "$*R_class"
+%typemap("rtype") SWIGTYPE & "$R_class"
+%typemap("rtype") SWIGTYPE && "$R_class"
+%typemap("rtype") SWIGTYPE "$&R_class"
%typemap("rtypecheck") int, int &, long, long &
%{ (is.integer($arg) || is.numeric($arg)) && length($arg) == 1 %}
@@ -93,7 +94,7 @@
%typemap(scoercein) enum SWIGTYPE *const
%{ $input = enumToInteger($input, "$R_class"); %}
-%typemap(scoercein) SWIGTYPE, SWIGTYPE *, SWIGTYPE *const, SWIGTYPE &, SWIGTYPE &&
+%typemap(scoercein) SWIGTYPE, SWIGTYPE *, SWIGTYPE *const, SWIGTYPE *const&, SWIGTYPE &, SWIGTYPE &&
%{ if (inherits($input, "ExternalReference")) $input = slot($input,"ref"); %}
/*
@@ -172,6 +173,10 @@ string &, std::string &
%{ $result <- if (is.null($result)) $result
else new("$R_class", ref=$result); %}
+%typemap(scoerceout) SWIGTYPE *const&
+ %{ $result <- if (is.null($result)) $result
+ else new("$*R_class", ref=$result); %}
+
/* Override the SWIGTYPE * above. */
%typemap(scoerceout) char,
diff --git a/Lib/r/std_vector.i b/Lib/r/std_vector.i
index 4ec51dc91..93d1c6256 100644
--- a/Lib/r/std_vector.i
+++ b/Lib/r/std_vector.i
@@ -841,7 +841,7 @@
%typemap("rtypecheck") std::vector<double>, std::vector<double> *, std::vector<double> &
%{ is.numeric($arg) %}
%typemap("rtype") std::vector<double> "numeric"
-%typemap("scoercein") std::vector<double>, std::vector<double> *, std::vector<double> & "$input = as.numeric($input);";
+%typemap("scoercein") std::vector<double>, std::vector<double> *, std::vector<double> & "$input = as.numeric($input);"
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<float>)
%traits_type_name(std::vector<float>)
@@ -857,7 +857,7 @@
%typemap("rtypecheck") std::vector<bool>, std::vector<bool> *, std::vector<bool> &
%{ is.logical($arg) %}
%typemap("rtype") std::vector<bool> "logical"
-%typemap("scoercein") std::vector<bool> , std::vector<bool> & "$input = as.logical($input);";
+%typemap("scoercein") std::vector<bool> , std::vector<bool> & "$input = as.logical($input);"
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<int>);
@@ -866,7 +866,7 @@
%{ is.integer($arg) || is.numeric($arg) %}
%typemap("rtype") std::vector<int> "integer"
-%typemap("scoercein") std::vector<int> , std::vector<int> *, std::vector<int> & "$input = as.integer($input);";
+%typemap("scoercein") std::vector<int> , std::vector<int> *, std::vector<int> & "$input = as.integer($input);"
// strings
%typemap("rtype") std::vector< std::basic_string<char> >,
@@ -974,21 +974,21 @@ std::vector< std::basic_string<char> > *,
%typemap("rtypecheck") std::vector<std::vector<int> >, std::vector<std::vector<int> > *, std::vector<std::vector<int> > &
%{ is.list($arg) && all(sapply($arg , is.integer) || sapply($arg, is.numeric)) %}
%typemap("rtype") std::vector<std::vector<int> >, std::vector<std::vector<int> > *, std::vector<std::vector<int> > & "list"
-%typemap("scoercein") std::vector< std::vector<int> >, std::vector<std::vector<int> > *, std::vector<std::vector<int> > & "$input = lapply($input, as.integer);";
+%typemap("scoercein") std::vector< std::vector<int> >, std::vector<std::vector<int> > *, std::vector<std::vector<int> > & "$input = lapply($input, as.integer);"
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<std::vector<unsigned int> >);
%traits_type_name(std::vector< std::vector<unsigned int> >);
%typemap("rtypecheck") std::vector<std::vector<unsigned int> >, std::vector<std::vector<unsigned int> > *, std::vector<std::vector<unsigned int> > &
%{ is.list($arg) && all(sapply($arg , is.integer) || sapply($arg, is.numeric)) %}
%typemap("rtype") std::vector<std::vector<unsigned int> >, std::vector<std::vector<unsigned int> > *, std::vector<std::vector<unsigned int> > & "list"
-%typemap("scoercein") std::vector< std::vector<unsigned int> >, std::vector<std::vector<int> > *, std::vector<std::vector<unsigned int> > & "$input = lapply($input, as.integer);";
+%typemap("scoercein") std::vector< std::vector<unsigned int> >, std::vector<std::vector<int> > *, std::vector<std::vector<unsigned int> > & "$input = lapply($input, as.integer);"
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<std::vector<float> >);
%traits_type_name(std::vector< std::vector<float> >);
%typemap("rtypecheck") std::vector<std::vector<float> >, std::vector<std::vector<float> > *, std::vector<std::vector<float> > &
%{ is.list($arg) && all(sapply($arg , is.integer) || sapply($arg, is.numeric)) %}
%typemap("rtype") std::vector<std::vector<float> >, std::vector<std::vector<float> > *, std::vector<std::vector<float> > "list"
-%typemap("scoercein") std::vector< std::vector<float> >, std::vector<std::vector<float> > *, std::vector<std::vector<float> > & "$input = lapply($input, as.numeric);";
+%typemap("scoercein") std::vector< std::vector<float> >, std::vector<std::vector<float> > *, std::vector<std::vector<float> > & "$input = lapply($input, as.numeric);"
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<std::vector<double> >);
%traits_type_name(std::vector< std::vector<double> >);
@@ -1003,7 +1003,7 @@ std::vector< std::basic_string<char> > *,
%typemap("rtypecheck") std::vector<std::vector<bool> >, std::vector<std::vector<bool> > *, std::vector<std::vector<bool> > &
%{ is.list($arg) && all(sapply($arg , is.integer) || sapply($arg, is.numeric)) %}
%typemap("rtype") std::vector<std::vector<bool> >, std::vector<std::vector<bool> > *, std::vector<std::vector<bool> > & "list"
-%typemap("scoercein") std::vector< std::vector<bool> >, std::vector<std::vector<bool> > *, std::vector<std::vector<bool> > & "$input = lapply($input, as.logical);";
+%typemap("scoercein") std::vector< std::vector<bool> >, std::vector<std::vector<bool> > *, std::vector<std::vector<bool> > & "$input = lapply($input, as.logical);"
// we don't want these to be given R classes as they
// have already been turned into R vectors.
diff --git a/Lib/r/swigmove.i b/Lib/r/swigmove.i
new file mode 100644
index 000000000..62ecca768
--- /dev/null
+++ b/Lib/r/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/ruby/argcargv.i b/Lib/ruby/argcargv.i
index fc0bc406a..24df9c94a 100644
--- a/Lib/ruby/argcargv.i
+++ b/Lib/ruby/argcargv.i
@@ -1,24 +1,20 @@
/* ------------------------------------------------------------
- * --- Argc & Argv ---
- * ------------------------------------------------------------ */
-
-/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
- Use it as follow:
+ Use it as follows:
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
%inline %{
- int mainApp(size_t argc, const char **argv)
- {
+ int mainApp(size_t argc, const char **argv) {
return argc;
}
- then in the ruby side:
+ then from ruby:
- args = ["asdf", "asdf2"]
- mainApp(args);
+ $args = ["asdf", "asdf2"]
+ mainApp(args)
* ------------------------------------------------------------ */
@@ -31,7 +27,7 @@
VALUE *ptr = RARRAY_PTR($input);
for (i=0; i < size; i++, ptr++) {
$2[i]= StringValuePtr(*ptr);
- }
+ }
$2[i]=NULL;
} else {
$1 = 0; $2 = 0;
diff --git a/Lib/ruby/boost_shared_ptr.i b/Lib/ruby/boost_shared_ptr.i
index 9676bf9d8..70deae4f2 100644
--- a/Lib/ruby/boost_shared_ptr.i
+++ b/Lib/ruby/boost_shared_ptr.i
@@ -35,7 +35,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -54,12 +54,12 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/ruby/rubyclasses.swg b/Lib/ruby/rubyclasses.swg
index b345fcebe..c43f38fc5 100644
--- a/Lib/ruby/rubyclasses.swg
+++ b/Lib/ruby/rubyclasses.swg
@@ -207,8 +207,8 @@ namespace swig {
(VALUEFUNC(swig_rescue_swallow)), Qnil);
}
if (ret == Qnil) {
- VALUE a = rb_funcall( _obj, hash_id, 0 );
- VALUE b = rb_funcall( VALUE(other), hash_id, 0 );
+ VALUE a = rb_funcall2( _obj, hash_id, 0, 0 );
+ VALUE b = rb_funcall2( VALUE(other), hash_id, 0, 0 );
res = op_func(a, b);
} else {
res = RTEST(ret);
diff --git a/Lib/ruby/rubycomplex.swg b/Lib/ruby/rubycomplex.swg
index a62bfe531..d2aaf6cb1 100644
--- a/Lib/ruby/rubycomplex.swg
+++ b/Lib/ruby/rubycomplex.swg
@@ -36,12 +36,12 @@ SWIGINTERN int SWIG_Is_Complex( VALUE obj ) {
SWIGINTERN VALUE SWIG_Complex_Real(VALUE obj) {
static ID real_id = rb_intern("real");
- return rb_funcall(obj, real_id, 0);
+ return rb_funcall2(obj, real_id, 0, 0);
}
SWIGINTERN VALUE SWIG_Complex_Imaginary(VALUE obj) {
static ID imag_id = rb_intern("imag");
- return rb_funcall(obj, imag_id, 0);
+ return rb_funcall2(obj, imag_id, 0, 0);
}
}
diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg
index e72330853..597ae83d2 100644
--- a/Lib/ruby/rubycontainer.swg
+++ b/Lib/ruby/rubycontainer.swg
@@ -803,9 +803,9 @@ namespace swig
static ID id_start = rb_intern("begin");
static ID id_noend = rb_intern("exclude_end?");
- VALUE start = rb_funcall( i, id_start, 0 );
- VALUE end = rb_funcall( i, id_end, 0 );
- bool noend = ( rb_funcall( i, id_noend, 0 ) == Qtrue );
+ VALUE start = rb_funcall2( i, id_start, 0, 0 );
+ VALUE end = rb_funcall2( i, id_end, 0, 0 );
+ bool noend = ( rb_funcall2( i, id_noend, 0, 0 ) == Qtrue );
int len = $self->size();
diff --git a/Lib/ruby/rubyhead.swg b/Lib/ruby/rubyhead.swg
index bf4e36248..e4d9e2147 100644
--- a/Lib/ruby/rubyhead.swg
+++ b/Lib/ruby/rubyhead.swg
@@ -1,5 +1,22 @@
+#if __GNUC__ >= 7
+#pragma GCC diagnostic push
+#if defined(__cplusplus)
+#pragma GCC diagnostic ignored "-Wregister"
+#if __GNUC__ >= 10
+#pragma GCC diagnostic ignored "-Wvolatile"
+#if __GNUC__ >= 11
+#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion"
+#endif
+#endif
+#endif
+#endif
+
#include <ruby.h>
+#if __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
+
/* Ruby 1.9.1 has a "memoisation optimisation" when compiling with GCC which
* breaks using rb_intern as an lvalue, as SWIG does. We work around this
* issue for now by disabling this.
diff --git a/Lib/ruby/rubykw.swg b/Lib/ruby/rubykw.swg
index 194687b95..6b4685eb8 100644
--- a/Lib/ruby/rubykw.swg
+++ b/Lib/ruby/rubykw.swg
@@ -2,7 +2,7 @@
#define RUBY_RUBYKW_SWG_
/* Warnings for Ruby keywords */
-#define RUBYKW(x) %keywordwarn("'" `x` "' is a ruby keyword, renaming to 'C_" `x` "'",rename="C_%s",fullname=1) `x`
+#define RUBYKW(x) %keywordwarn("'" `x` "' is a ruby keyword",rename="C_%s",fullname=1) `x`
/*
diff --git a/Lib/ruby/rubyrun.swg b/Lib/ruby/rubyrun.swg
index 3b6fd32b0..6cac4626a 100644
--- a/Lib/ruby/rubyrun.swg
+++ b/Lib/ruby/rubyrun.swg
@@ -281,6 +281,11 @@ SWIG_Ruby_ConvertPtrAndOwn(VALUE obj, void **ptr, swig_type_info *ty, int flags,
own->own = 0;
}
+ if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE)) {
+ if (!RDATA(obj)->dfree)
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ }
+
/* Check to see if the input object is giving up ownership
of the underlying C struct or C++ object. If so then we
need to reset the destructor since the Ruby object no
@@ -292,7 +297,7 @@ SWIG_Ruby_ConvertPtrAndOwn(VALUE obj, void **ptr, swig_type_info *ty, int flags,
swig_class *sklass = (swig_class *) ty->clientdata;
track = sklass->trackObjects;
}
-
+
if (track) {
/* We are tracking objects for this class. Thus we change the destructor
* to SWIG_RubyRemoveTracking. This allows us to
@@ -306,6 +311,10 @@ SWIG_Ruby_ConvertPtrAndOwn(VALUE obj, void **ptr, swig_type_info *ty, int flags,
}
}
+ if (flags & SWIG_POINTER_CLEAR) {
+ DATA_PTR(obj) = 0;
+ }
+
/* Do type-checking if type info was provided */
if (ty) {
if (ty->clientdata) {
@@ -413,6 +422,7 @@ SWIG_Ruby_SetModule(swig_module_info *pointer)
{
/* register a new class */
VALUE cl = rb_define_class("swig_runtime_data", rb_cObject);
+ rb_undef_alloc_func(cl);
/* create and store the structure pointer to a global variable */
swig_runtime_data_type_pointer = Data_Wrap_Struct(cl, 0, 0, pointer);
rb_define_readonly_variable("$swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, &swig_runtime_data_type_pointer);
@@ -443,7 +453,7 @@ int SWIG_Ruby_arity( VALUE proc, int minimal )
{
if ( rb_respond_to( proc, swig_arity_id ) )
{
- VALUE num = rb_funcall( proc, swig_arity_id, 0 );
+ VALUE num = rb_funcall2( proc, swig_arity_id, 0, 0 );
int arity = NUM2INT(num);
if ( arity < 0 && (arity+1) < -minimal ) return 1;
if ( arity == minimal ) return 1;
diff --git a/Lib/ruby/std_auto_ptr.i b/Lib/ruby/std_auto_ptr.i
index eab8ec53d..3d7ae8ba1 100644
--- a/Lib/ruby/std_auto_ptr.i
+++ b/Lib/ruby/std_auto_ptr.i
@@ -1,17 +1,39 @@
-/*
- The typemaps here allow handling functions returning std::auto_ptr<>,
- which is the most common use of this type. If you have functions taking it
- as parameter, these typemaps can't be used for them and you need to do
- something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
%define %auto_ptr(TYPE)
-%typemap (out) std::auto_ptr<TYPE > %{
- %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
%}
-%template() std::auto_ptr<TYPE >;
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
%enddef
namespace std {
- template <class T> class auto_ptr {};
+ template <class T> class auto_ptr {};
}
diff --git a/Lib/ruby/std_map.i b/Lib/ruby/std_map.i
index 7077fa104..6dd2ffa72 100644
--- a/Lib/ruby/std_map.i
+++ b/Lib/ruby/std_map.i
@@ -96,7 +96,7 @@
int res = SWIG_ERROR;
if ( TYPE(obj) == T_HASH ) {
static ID id_to_a = rb_intern("to_a");
- VALUE items = rb_funcall(obj, id_to_a, 0);
+ VALUE items = rb_funcall2(obj, id_to_a, 0, 0);
res = traits_asptr_stdseq<std::map<K,T>, std::pair<K, T> >::asptr(items, val);
} else {
map_type *p;
diff --git a/Lib/ruby/std_multimap.i b/Lib/ruby/std_multimap.i
index 762a87653..5d8e33e97 100644
--- a/Lib/ruby/std_multimap.i
+++ b/Lib/ruby/std_multimap.i
@@ -23,7 +23,7 @@
int res = SWIG_ERROR;
if ( TYPE(obj) == T_HASH ) {
static ID id_to_a = rb_intern("to_a");
- VALUE items = rb_funcall(obj, id_to_a, 0);
+ VALUE items = rb_funcall2(obj, id_to_a, 0, 0);
return traits_asptr_stdseq<std::multimap<K,T>, std::pair<K, T> >::asptr(items, val);
} else {
multimap_type *p;
diff --git a/Lib/ruby/std_set.i b/Lib/ruby/std_set.i
index e38702ef5..1b425c6b5 100644
--- a/Lib/ruby/std_set.i
+++ b/Lib/ruby/std_set.i
@@ -180,17 +180,14 @@
// Redefine std::set iterator/reverse_iterator typemap
%typemap(out,noblock=1) iterator, reverse_iterator {
- $result = SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,const $type &),
- self),
- swig::Iterator::descriptor(),SWIG_POINTER_OWN);
+ $result = SWIG_NewPointerObj((swig::make_set_nonconst_iterator<$type>($1, self)), swig::Iterator::descriptor(), SWIG_POINTER_OWN);
}
// Redefine std::set std::pair<iterator, bool> typemap
%typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator")
std::pair<iterator, bool> {
$result = rb_ary_new2(2);
- rb_ary_push($result, SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,$type &).first),
- swig::Iterator::descriptor(),SWIG_POINTER_OWN));
+ rb_ary_push($result, SWIG_NewPointerObj((swig::make_set_nonconst_iterator($1.first)), swig::Iterator::descriptor(), SWIG_POINTER_OWN));
rb_ary_push($result, SWIG_From(bool)(%static_cast($1,const $type &).second));
}
diff --git a/Lib/ruby/std_unique_ptr.i b/Lib/ruby/std_unique_ptr.i
new file mode 100644
index 000000000..f988714df
--- /dev/null
+++ b/Lib/ruby/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/ruby/std_unordered_map.i b/Lib/ruby/std_unordered_map.i
index 48c875214..3c6b65027 100644
--- a/Lib/ruby/std_unordered_map.i
+++ b/Lib/ruby/std_unordered_map.i
@@ -23,7 +23,7 @@
int res = SWIG_ERROR;
if (TYPE(obj) == T_HASH) {
static ID id_to_a = rb_intern("to_a");
- VALUE items = rb_funcall(obj, id_to_a, 0);
+ VALUE items = rb_funcall2(obj, id_to_a, 0, 0);
res = traits_asptr_stdseq<std::unordered_map<K,T,Hash,Compare,Alloc>, std::pair<K, T> >::asptr(items, val);
} else {
map_type *p;
diff --git a/Lib/ruby/std_unordered_multimap.i b/Lib/ruby/std_unordered_multimap.i
index ebc53b597..c3261f9e6 100644
--- a/Lib/ruby/std_unordered_multimap.i
+++ b/Lib/ruby/std_unordered_multimap.i
@@ -23,7 +23,7 @@
int res = SWIG_ERROR;
if ( TYPE(obj) == T_HASH ) {
static ID id_to_a = rb_intern("to_a");
- VALUE items = rb_funcall(obj, id_to_a, 0);
+ VALUE items = rb_funcall2(obj, id_to_a, 0, 0);
return traits_asptr_stdseq<std::unordered_multimap<K,T,Hash,Compare,Alloc>, std::pair<K, T> >::asptr(items, val);
} else {
multimap_type *p;
diff --git a/Lib/ruby/swigmove.i b/Lib/ruby/swigmove.i
new file mode 100644
index 000000000..62ecca768
--- /dev/null
+++ b/Lib/ruby/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/ruby/timeval.i b/Lib/ruby/timeval.i
index e7bc2d322..94a75c802 100644
--- a/Lib/ruby/timeval.i
+++ b/Lib/ruby/timeval.i
@@ -55,7 +55,7 @@ struct timeval rb_time_timeval(VALUE);
if (NIL_P($input))
$1 = (time_t)-1;
else
- $1 = NUM2LONG(rb_funcall($input, rb_intern("tv_sec"), 0));
+ $1 = NUM2LONG(rb_funcall2($input, rb_intern("tv_sec"), 0, 0));
}
%typemap(typecheck) time_t
diff --git a/Lib/ruby/typemaps.i b/Lib/ruby/typemaps.i
index c4db82161..683436469 100644
--- a/Lib/ruby/typemaps.i
+++ b/Lib/ruby/typemaps.i
@@ -119,7 +119,7 @@ multiple output values, they are returned in the form of a Ruby Array.
For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
+returns the integer part in one of its parameters) :
double modf(double x, double *ip);
@@ -139,7 +139,7 @@ output values.
*/
%define OUTPUT_TYPEMAP(type, converter, convtype)
-%typemap(in,numinputs=0) type *OUTPUT($*1_ltype temp), type &OUTPUT($*1_ltype temp) "$1 = &temp;";
+%typemap(in,numinputs=0) type *OUTPUT($*1_ltype temp), type &OUTPUT($*1_ltype temp) "$1 = &temp;"
%typemap(argout, fragment="output_helper") type *OUTPUT, type &OUTPUT {
VALUE o = converter(convtype (*$1));
$result = output_helper($result, o);
@@ -161,7 +161,7 @@ OUTPUT_TYPEMAP(double, rb_float_new, (double));
#undef OUTPUT_TYPEMAP
-%typemap(in,numinputs=0) bool *OUTPUT(bool temp), bool &OUTPUT(bool temp) "$1 = &temp;";
+%typemap(in,numinputs=0) bool *OUTPUT(bool temp), bool &OUTPUT(bool temp) "$1 = &temp;"
%typemap(argout, fragment="output_helper") bool *OUTPUT, bool &OUTPUT {
VALUE o = (*$1) ? Qtrue : Qfalse;
$result = output_helper($result, o);
diff --git a/Lib/scilab/boost_shared_ptr.i b/Lib/scilab/boost_shared_ptr.i
index 668bf4354..87c89b5f9 100644
--- a/Lib/scilab/boost_shared_ptr.i
+++ b/Lib/scilab/boost_shared_ptr.i
@@ -35,7 +35,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -54,12 +54,12 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/scilab/scirun.swg b/Lib/scilab/scirun.swg
index 51df9a59e..586d5f16f 100644
--- a/Lib/scilab/scirun.swg
+++ b/Lib/scilab/scirun.swg
@@ -47,10 +47,8 @@ static char *SWIG_Scilab_GetFuncName(void) {
return SwigFuncName;
}
static void SWIG_Scilab_SetFuncName(char *funcName) {
- if (SwigFuncName != NULL) {
- free(SwigFuncName);
- SwigFuncName = NULL;
- }
+ free(SwigFuncName);
+ SwigFuncName = NULL;
if (funcName) {
SwigFuncName = (char *)malloc(strlen(funcName) + 1);
if (SwigFuncName)
@@ -436,7 +434,7 @@ SWIG_Scilab_NewMemberObj(void *pvApiCtx, int iVarOut, void *ptr, int sz, swig_ty
#ifdef __cplusplus
extern "C"
#endif
-int SWIG_this(SWIG_GatewayParameters) {
+SWIGEXPORT int SWIG_this(SWIG_GatewayParameters) {
void *ptrValue = NULL;
if (SwigScilabPtrToObject(pvApiCtx, 1, &ptrValue, NULL, 0, fname) == SWIG_OK) {
SWIG_Scilab_SetOutputPosition(1);
@@ -453,7 +451,7 @@ int SWIG_this(SWIG_GatewayParameters) {
#ifdef __cplusplus
extern "C"
#endif
-int SWIG_ptr(SWIG_GatewayParameters) {
+SWIGEXPORT int SWIG_ptr(SWIG_GatewayParameters) {
if (SWIG_NbInputArgument(pvApiCtx) > 0) {
SciErr sciErr;
int *piAddrVar1 = NULL;
diff --git a/Lib/scilab/sciruntime.swg b/Lib/scilab/sciruntime.swg
index 3de138e11..e772926f7 100644
--- a/Lib/scilab/sciruntime.swg
+++ b/Lib/scilab/sciruntime.swg
@@ -40,7 +40,7 @@ SWIG_Scilab_TypeQuery(const char *name) {
#ifdef __cplusplus
extern "C"
#endif
-int <module>_Init(SWIG_GatewayParameters) {
+SWIGEXPORT int SWIG_<module>_Init(SWIG_GatewayParameters) {
SWIG_InitializeModule(NULL);
SWIG_CreateScilabVariables(pvApiCtx);
swig_module_initialized = 1;
diff --git a/Lib/scilab/std_string.i b/Lib/scilab/std_string.i
index 71ac6d2f4..8736c2a28 100644
--- a/Lib/scilab/std_string.i
+++ b/Lib/scilab/std_string.i
@@ -37,3 +37,11 @@ SWIG_From_dec(std::string)(std::string pstValue) {
}
%include <typemaps/std_string.swg>
+
+%typemap(throws, noblock=1) std::string {
+ SWIG_Scilab_Raise_Ex($1.c_str(), "$type", $&descriptor);
+}
+
+%typemap(throws, noblock=1) const std::string & {
+ SWIG_Scilab_Raise_Ex($1.c_str(), "$type", $descriptor);
+}
diff --git a/Lib/scilab/swigmove.i b/Lib/scilab/swigmove.i
new file mode 100644
index 000000000..62ecca768
--- /dev/null
+++ b/Lib/scilab/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/std/std_basic_string.i b/Lib/std/std_basic_string.i
index fb7afc1e6..e95cb4765 100644
--- a/Lib/std/std_basic_string.i
+++ b/Lib/std/std_basic_string.i
@@ -55,7 +55,16 @@ namespace std {
size_type capacity() const;
- void reserve(size_type __res_arg = 0);
+ void reserve(size_type __res_arg);
+ %extend {
+ void shrink_to_fit() {
+ %#if __cplusplus >= 202002L
+ self->shrink_to_fit();
+ %#else
+ self->reserve();
+ %#endif
+ }
+ }
// Modifiers:
diff --git a/Lib/swig.swg b/Lib/swig.swg
index 6dc215dcf..9f9d53349 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -172,7 +172,7 @@
#define %novaluewrapper %feature("novaluewrapper")
#define %clearnovaluewrapper %feature("novaluewrapper","")
-/* Contract support - Experimental and undocumented */
+/* Contract support - Experimental */
#define %contract %feature("contract")
#define %nocontract %feature("contract","0")
#define %clearcontract %feature("contract","")
@@ -268,7 +268,9 @@ static int NAME(TYPE x) {
*/
-%define %$not "not" %enddef
+/* Note that when %$not is used with another macro, say %enum as follows: %$not %$enum, the result is "notmatch=enum" */
+%define %$not "not" %enddef
+
%define %$isenum "match"="enum" %enddef
%define %$isenumitem "match"="enumitem" %enddef
%define %$isaccess "match"="access" %enddef
@@ -279,6 +281,7 @@ static int NAME(TYPE x) {
%define %$isnamespace "match"="namespace" %enddef
%define %$istemplate "match"="template" %enddef
%define %$isconstant "match"="constant" %enddef /* %constant definition */
+%define %$isusing "match"="using" %enddef
%define %$isunion "match$kind"="union" %enddef
%define %$isfunction "match$kind"="function" %enddef
@@ -445,15 +448,15 @@ namespace std {
/* Set up the typemap for handling new return strings */
#ifdef __cplusplus
-%typemap(newfree) char * "delete [] $1;";
+%typemap(newfree) char * "delete [] $1;"
#else
-%typemap(newfree) char * "free($1);";
+%typemap(newfree) char * "free($1);"
#endif
/* Default typemap for handling char * members */
#ifdef __cplusplus
-%typemap(memberin) char * {
+%typemap(memberin,fragment="<string.h>") char * {
delete [] $1;
if ($input) {
$1 = ($1_type) (new char[strlen((const char *)$input)+1]);
@@ -462,7 +465,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
if ($input) {
$1 = ($1_type) (new char[strlen((const char *)$input)+1]);
strcpy((char *)$1, (const char *)$input);
@@ -470,7 +473,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(globalin) char * {
+%typemap(globalin,fragment="<string.h>") char * {
delete [] $1;
if ($input) {
$1 = ($1_type) (new char[strlen((const char *)$input)+1]);
@@ -479,7 +482,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
if ($input) {
$1 = ($1_type) (new char[strlen((const char *)$input)+1]);
strcpy((char *)$1, (const char *)$input);
@@ -488,7 +491,7 @@ namespace std {
}
}
#else
-%typemap(memberin) char * {
+%typemap(memberin,fragment="<string.h>") char * {
free($1);
if ($input) {
$1 = ($1_type) malloc(strlen((const char *)$input)+1);
@@ -497,7 +500,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
if ($input) {
$1 = ($1_type) malloc(strlen((const char *)$input)+1);
strcpy((char *)$1, (const char *)$input);
@@ -505,7 +508,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(globalin) char * {
+%typemap(globalin,fragment="<string.h>") char * {
free($1);
if ($input) {
$1 = ($1_type) malloc(strlen((const char *)$input)+1);
@@ -514,7 +517,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
if ($input) {
$1 = ($1_type) malloc(strlen((const char *)$input)+1);
strcpy((char *)$1, (const char *)$input);
@@ -527,7 +530,7 @@ namespace std {
/* Character array handling */
-%typemap(memberin) char [ANY] {
+%typemap(memberin,fragment="<string.h>") char [ANY] {
if($input) {
strncpy((char*)$1, (const char *)$input, $1_dim0-1);
$1[$1_dim0-1] = 0;
@@ -536,7 +539,7 @@ namespace std {
}
}
-%typemap(globalin) char [ANY] {
+%typemap(globalin,fragment="<string.h>") char [ANY] {
if($input) {
strncpy((char*)$1, (const char *)$input, $1_dim0-1);
$1[$1_dim0-1] = 0;
@@ -545,25 +548,25 @@ namespace std {
}
}
-%typemap(memberin) char [] {
+%typemap(memberin,fragment="<string.h>") char [] {
if ($input) strcpy((char *)$1, (const char *)$input);
else $1[0] = 0;
}
-%typemap(globalin) char [] {
+%typemap(globalin,fragment="<string.h>") char [] {
if ($input) strcpy((char *)$1, (const char *)$input);
else $1[0] = 0;
}
/* memberin/globalin typemap for arrays. */
-%typemap(memberin) SWIGTYPE [ANY] {
+%typemap(memberin,fragment="<string.h>") SWIGTYPE [ANY] {
size_t ii;
$1_basetype *b = ($1_basetype *) $1;
for (ii = 0; ii < (size_t)$1_size; ii++) b[ii] = *(($1_basetype *) $input + ii);
}
-%typemap(globalin) SWIGTYPE [ANY] {
+%typemap(globalin,fragment="<string.h>") SWIGTYPE [ANY] {
size_t ii;
$1_basetype *b = ($1_basetype *) $1;
for (ii = 0; ii < (size_t)$1_size; ii++) b[ii] = *(($1_basetype *) $input + ii);
@@ -571,7 +574,7 @@ namespace std {
/* memberin/globalin typemap for double arrays. */
-%typemap(memberin) SWIGTYPE [ANY][ANY] {
+%typemap(memberin,fragment="<string.h>") SWIGTYPE [ANY][ANY] {
$basetype (*inp)[$1_dim1] = ($basetype (*)[$1_dim1])($input);
$basetype (*dest)[$1_dim1] = ($basetype (*)[$1_dim1])($1);
size_t ii = 0;
@@ -583,7 +586,7 @@ namespace std {
}
}
-%typemap(globalin) SWIGTYPE [ANY][ANY] {
+%typemap(globalin,fragment="<string.h>") SWIGTYPE [ANY][ANY] {
$basetype (*inp)[$1_dim1] = ($basetype (*)[$1_dim1])($input);
$basetype (*dest)[$1_dim1] = ($basetype (*)[$1_dim1])($1);
size_t ii = 0;
@@ -599,6 +602,10 @@ namespace std {
* Runtime code
* ----------------------------------------------------------------------------- */
+
+%insert("runtime") "swiglabels.swg"
+
+
/* The SwigValueWrapper class */
/*
@@ -649,33 +656,53 @@ namespace std {
* arg1 = *inarg1; // Assignment from a pointer
* arg1 = Vector(1,2,3); // Assignment from a value
*
+ * SwigValueWrapper is a drop in replacement to modify normal value semantics by
+ * using the heap instead of the stack to copy/move the underlying object it is
+ * managing. Smart pointers also manage an underlying object on the heap, so
+ * SwigValueWrapper has characteristics of a smart pointer. The reset function
+ * is specific smart pointer functionality, but cannot be a non-static member as
+ * when SWIG modifies typemap code it assumes non-static member function calls
+ * are routed to the underlying object, changing for example $1.f() to (&x)->f().
+ * The reset function was added as an optimisation to avoid some copying/moving
+ * and to take ownership of an object already created on the heap.
+ *
* The class offers a strong guarantee of exception safety.
- * With regards to the implementation, the private SwigMovePointer nested class is
- * a simple smart pointer with move semantics, much like std::auto_ptr.
+ * With regards to the implementation, the private SwigSmartPointer nested class is
+ * a simple smart pointer providing exception safety, much like std::auto_ptr.
*
* This wrapping technique was suggested by William Fulton and is henceforth
* known as the "Fulton Transform" :-).
*/
#ifdef __cplusplus
-%insert("runtime") %{
+// Placed in the header section to ensure the language specific header files are
+// the first included headers and not <utility>
+%insert("header") %{
#ifdef __cplusplus
+#include <utility>
/* SwigValueWrapper is described in swig.swg */
template<typename T> class SwigValueWrapper {
- struct SwigMovePointer {
+ struct SwigSmartPointer {
T *ptr;
- SwigMovePointer(T *p) : ptr(p) { }
- ~SwigMovePointer() { delete ptr; }
- SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+ SwigSmartPointer(T *p) : ptr(p) { }
+ ~SwigSmartPointer() { delete ptr; }
+ SwigSmartPointer& operator=(SwigSmartPointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+ void reset(T *p) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = p; }
} pointer;
SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
SwigValueWrapper(const SwigValueWrapper<T>& rhs);
public:
SwigValueWrapper() : pointer(0) { }
- SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
+ SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; }
+#if __cplusplus >=201103L
+ SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; }
+ operator T&&() const { return std::move(*pointer.ptr); }
+#else
operator T&() const { return *pointer.ptr; }
- T *operator&() { return pointer.ptr; }
-};%}
+#endif
+ T *operator&() const { return pointer.ptr; }
+ static void reset(SwigValueWrapper& t, T *p) { t.pointer.reset(p); }
+};
/*
* SwigValueInit() is a generic initialisation solution as the following approach:
@@ -686,16 +713,17 @@ public:
*
* unsigned int c_result = unsigned int();
*/
-%insert("runtime") %{
template <typename T> T SwigValueInit() {
return T();
}
+
+#if __cplusplus >=201103L
+# define SWIG_STD_MOVE(OBJ) std::move(OBJ)
+#else
+# define SWIG_STD_MOVE(OBJ) OBJ
+#endif
+
#endif
%}
#endif
-/* The swiglabels */
-
-%insert("runtime") "swiglabels.swg"
-
-
diff --git a/Lib/swigerrors.swg b/Lib/swigerrors.swg
index 1a6d20366..4d5a8e473 100644
--- a/Lib/swigerrors.swg
+++ b/Lib/swigerrors.swg
@@ -1,4 +1,4 @@
-/* Errors in SWIG */
+/* SWIG Errors applicable to all language modules, values are reserved from -1 to -99 */
#define SWIG_UnknownError -1
#define SWIG_IOError -2
#define SWIG_RuntimeError -3
@@ -13,4 +13,3 @@
#define SWIG_MemoryError -12
#define SWIG_NullReferenceError -13
-
diff --git a/Lib/swigfragments.swg b/Lib/swigfragments.swg
index 2cbef7cce..28aa1180f 100644
--- a/Lib/swigfragments.swg
+++ b/Lib/swigfragments.swg
@@ -29,6 +29,10 @@
#include <math.h>
%}
+%fragment("<string.h>", "header") %{
+#include <string.h>
+%}
+
%fragment("<stddef.h>", "header") %{
#include <stddef.h>
%}
diff --git a/Lib/swigrun.swg b/Lib/swigrun.swg
index 5f3159916..f632c4cb6 100644
--- a/Lib/swigrun.swg
+++ b/Lib/swigrun.swg
@@ -44,6 +44,8 @@
#define SWIG_POINTER_DISOWN 0x1
#define SWIG_CAST_NEW_MEMORY 0x2
#define SWIG_POINTER_NO_NULL 0x4
+#define SWIG_POINTER_CLEAR 0x8
+#define SWIG_POINTER_RELEASE (SWIG_POINTER_CLEAR | SWIG_POINTER_DISOWN)
/* Flags for new pointer objects */
#define SWIG_POINTER_OWN 0x1
@@ -129,7 +131,13 @@
*/
#define SWIG_OK (0)
+/* Runtime errors are < 0 */
#define SWIG_ERROR (-1)
+/* Errors in range -1 to -99 are in swigerrors.swg (errors for all languages including those not using the runtime) */
+/* Errors in range -100 to -199 are language specific errors defined in *errors.swg */
+/* Errors < -200 are generic runtime specific errors */
+#define SWIG_ERROR_RELEASE_NOT_OWNED (-200)
+
#define SWIG_IsOK(r) (r >= 0)
#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError)
@@ -144,7 +152,7 @@
#define SWIG_OLDOBJ (SWIG_OK)
#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK)
#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK)
-/* Check, add and del mask methods */
+/* Check, add and del object mask methods */
#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
@@ -290,7 +298,7 @@ SWIG_TypeCheck(const char *c, swig_type_info *ty) {
Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
*/
SWIGRUNTIME swig_cast_info *
-SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
+SWIG_TypeCheckStruct(const swig_type_info *from, swig_type_info *ty) {
if (ty) {
swig_cast_info *iter = ty->cast;
while (iter) {
@@ -350,9 +358,9 @@ SWIG_TypeName(const swig_type_info *ty) {
SWIGRUNTIME const char *
SWIG_TypePrettyName(const swig_type_info *type) {
/* The "str" field contains the equivalent pretty names of the
- type, separated by vertical-bar characters. We choose
- to print the last name, as it is often (?) the most
- specific. */
+ type, separated by vertical-bar characters. Choose the last
+ name. It should be the most specific; a fully resolved name
+ but not necessarily with default template parameters expanded. */
if (!type) return NULL;
if (type->str != NULL) {
const char *last_name = type->str;
diff --git a/Lib/swigwarnings.swg b/Lib/swigwarnings.swg
index 34c98fbda..63ae4c65a 100644
--- a/Lib/swigwarnings.swg
+++ b/Lib/swigwarnings.swg
@@ -52,6 +52,7 @@
%define SWIGWARN_TYPEMAP_CHARLEAK_MSG "451:Setting a const char * variable may leak memory." %enddef
%define SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG "454:Setting a pointer/reference variable may leak memory." %enddef
+%define SWIGWARN_TYPEMAP_WCHARLEAK_MSG "455:Setting a const wchar_t * variable may leak memory." %enddef
%define SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG "470:Thread/reentrant unsafe wrapping, consider returning by value instead." %enddef
%define SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG "473:Returning a pointer or reference in a director method is not recommended." %enddef
%define SWIGWARN_TYPEMAP_INITIALIZER_LIST_MSG "476:Initialization using std::initializer_list." %enddef
@@ -107,6 +108,7 @@
%define SWIGWARN_IGNORE_OPERATOR_NEWARR_MSG "394:operator new[] ignored" %enddef
%define SWIGWARN_IGNORE_OPERATOR_DELARR_MSG "395:operator delete[] ignored" %enddef
%define SWIGWARN_IGNORE_OPERATOR_REF_MSG "396:operator*() ignored" %enddef
+%define SWIGWARN_IGNORE_OPERATOR_LTEQUALGT_MSG "397:operator<=> ignored" %enddef
#define %ignoreoperator(Oper) %ignorewarn(SWIGWARN_IGNORE_OPERATOR_##Oper##_MSG)
diff --git a/Lib/tcl/Makefile.in b/Lib/tcl/Makefile.in
index 13d7d4653..019091c98 100644
--- a/Lib/tcl/Makefile.in
+++ b/Lib/tcl/Makefile.in
@@ -45,7 +45,7 @@ LIBS =
# SWIGCC = Compiler used to compile the wrapper file
SWIG = $(exec_prefix)/bin/swig
-SWIGOPT = -tcl # use -tcl8 for Tcl 8.0
+SWIGOPT = -tcl
SWIGCC = $(CC)
# SWIG Library files. Uncomment if rebuilding tclsh
diff --git a/Lib/tcl/argcargv.i b/Lib/tcl/argcargv.i
new file mode 100644
index 000000000..bbe149ef0
--- /dev/null
+++ b/Lib/tcl/argcargv.i
@@ -0,0 +1,29 @@
+/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------ */
+
+%typemap(in) (int ARGC, char **ARGV) {
+ int i, nitems;
+ Tcl_Obj **listobjv;
+ if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) {
+ SWIG_exception_fail(SWIG_ValueError, "in method '$symname', Expecting list of argv");
+ goto fail;
+ }
+ $1 = ($1_ltype) nitems;
+ $2 = (char **) malloc((nitems+1)*sizeof(char *));
+ for (i = 0; i < nitems; i++) {
+ $2[i] = Tcl_GetStringFromObj(listobjv[i], NULL);
+ }
+ $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ int len;
+ $1 = Tcl_ListObjLength(interp, $input, &len) == TCL_OK;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ if ($2 != NULL) {
+ free((void *)$2);
+ }
+}
diff --git a/Lib/tcl/mactkinit.c b/Lib/tcl/mactkinit.c
deleted file mode 100644
index 18f1f0203..000000000
--- a/Lib/tcl/mactkinit.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/* -----------------------------------------------------------------------------
- * mactkinit.c
- *
- * This is a support file needed to build a new version of Wish.
- * Normally, this capability is found in TkAppInit.c, but this creates
- * tons of namespace problems for many applications.
- * ----------------------------------------------------------------------------- */
-
-#include <Gestalt.h>
-#include <ToolUtils.h>
-#include <Fonts.h>
-#include <Dialogs.h>
-#include <SegLoad.h>
-#include <Traps.h>
-
-#include "tk.h"
-#include "tkInt.h"
-#include "tkMacInt.h"
-
-typedef int (*TclMacConvertEventPtr) _ANSI_ARGS_((EventRecord *eventPtr));
-Tcl_Interp *gStdoutInterp = NULL;
-
-void TclMacSetEventProc _ANSI_ARGS_((TclMacConvertEventPtr procPtr));
-int TkMacConvertEvent _ANSI_ARGS_((EventRecord *eventPtr));
-
-/*
- * Prototypes for functions the ANSI library needs to link against.
- */
-short InstallConsole _ANSI_ARGS_((short fd));
-void RemoveConsole _ANSI_ARGS_((void));
-long WriteCharsToConsole _ANSI_ARGS_((char *buff, long n));
-long ReadCharsFromConsole _ANSI_ARGS_((char *buff, long n));
-char * __ttyname _ANSI_ARGS_((long fildes));
-short SIOUXHandleOneEvent _ANSI_ARGS_((EventRecord *event));
-
-/*
- * Forward declarations for procedures defined later in this file:
- */
-
-/*
- *----------------------------------------------------------------------
- *
- * MacintoshInit --
- *
- * This procedure calls Mac specific initialization calls. Most of
- * these calls must be made as soon as possible in the startup
- * process.
- *
- * Results:
- * Returns TCL_OK if everything went fine. If it didn't the
- * application should probably fail.
- *
- * Side effects:
- * Inits the application.
- *
- *----------------------------------------------------------------------
- */
-
-int
-MacintoshInit()
-{
- int i;
- long result, mask = 0x0700; /* mask = system 7.x */
-
- /*
- * Tk needs us to set the qd pointer it uses. This is needed
- * so Tk doesn't have to assume the availiblity of the qd global
- * variable. Which in turn allows Tk to be used in code resources.
- */
- tcl_macQdPtr = &qd;
-
- InitGraf(&tcl_macQdPtr->thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- InitDialogs((long) NULL);
- InitCursor();
-
- /*
- * Make sure we are running on system 7 or higher
- */
-
- if ((NGetTrapAddress(_Gestalt, ToolTrap) ==
- NGetTrapAddress(_Unimplemented, ToolTrap))
- || (((Gestalt(gestaltSystemVersion, &result) != noErr)
- || (mask != (result & mask))))) {
- panic("Tcl/Tk requires System 7 or higher.");
- }
-
- /*
- * Make sure we have color quick draw
- * (this means we can't run on 68000 macs)
- */
-
- if (((Gestalt(gestaltQuickdrawVersion, &result) != noErr)
- || (result < gestalt32BitQD13))) {
- panic("Tk requires Color QuickDraw.");
- }
-
-
- FlushEvents(everyEvent, 0);
- SetEventMask(everyEvent);
-
- /*
- * Set up stack & heap sizes
- */
- /* TODO: stack size
- size = StackSpace();
- SetAppLimit(GetAppLimit() - 8192);
- */
- MaxApplZone();
- for (i = 0; i < 4; i++) {
- (void) MoreMasters();
- }
-
- TclMacSetEventProc(TkMacConvertEvent);
- TkConsoleCreate();
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * SetupMainInterp --
- *
- * This procedure calls initialization routines require a Tcl
- * interp as an argument. This call effectively makes the passed
- * interpreter the "main" interpreter for the application.
- *
- * Results:
- * Returns TCL_OK if everything went fine. If it didn't the
- * application should probably fail.
- *
- * Side effects:
- * More initialization.
- *
- *----------------------------------------------------------------------
- */
-
-int
-SetupMainInterp(
- Tcl_Interp *interp)
-{
- /*
- * Initialize the console only if we are running as an interactive
- * application.
- */
-
- TkMacInitAppleEvents(interp);
- TkMacInitMenus(interp);
-
- if (strcmp(Tcl_GetVar(interp, "tcl_interactive", TCL_GLOBAL_ONLY), "1")
- == 0) {
- if (TkConsoleInit(interp) == TCL_ERROR) {
- goto error;
- }
- }
-
- /*
- * Attach the global interpreter to tk's expected global console
- */
-
- gStdoutInterp = interp;
-
- return TCL_OK;
-
-error:
- panic(interp->result);
- return TCL_ERROR;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * InstallConsole, RemoveConsole, etc. --
- *
- * The following functions provide the UI for the console package.
- * Users wishing to replace SIOUX with their own console package
- * need only provide the four functions below in a library.
- *
- * Results:
- * See SIOUX documentation for details.
- *
- * Side effects:
- * See SIOUX documentation for details.
- *
- *----------------------------------------------------------------------
- */
-
-short
-InstallConsole(short fd)
-{
-#pragma unused (fd)
-
- return 0;
-}
-
-void
-RemoveConsole(void)
-{
-}
-
-long
-WriteCharsToConsole(char *buffer, long n)
-{
- TkConsolePrint(gStdoutInterp, TCL_STDOUT, buffer, n);
- return n;
-}
-
-long
-ReadCharsFromConsole(char *buffer, long n)
-{
- return 0;
-}
-
-extern char *
-__ttyname(long fildes)
-{
- static char *devicename = "null device";
-
- if (fildes >= 0 && fildes <= 2) {
- return (devicename);
- }
-
- return (0L);
-}
-
-short
-SIOUXHandleOneEvent(EventRecord *event)
-{
- return 0;
-}
diff --git a/Lib/tcl/std_auto_ptr.i b/Lib/tcl/std_auto_ptr.i
new file mode 100644
index 000000000..b24809af7
--- /dev/null
+++ b/Lib/tcl/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ Tcl_SetObjResult(interp, SWIG_NewInstanceObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/tcl/std_unique_ptr.i b/Lib/tcl/std_unique_ptr.i
new file mode 100644
index 000000000..0ea324cda
--- /dev/null
+++ b/Lib/tcl/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+ } else {
+ %argument_fail(res, "TYPE *", $symname, $argnum);
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ Tcl_SetObjResult(interp, SWIG_NewInstanceObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/tcl/std_vector.i b/Lib/tcl/std_vector.i
index 5fba5379f..a74bf3a1b 100644
--- a/Lib/tcl/std_vector.i
+++ b/Lib/tcl/std_vector.i
@@ -34,11 +34,11 @@
%{
#include <vector>
-Tcl_Obj* SwigString_FromString(const std::string &s) {
+SWIGINTERN Tcl_Obj* SwigString_FromString(const std::string &s) {
return Tcl_NewStringObj(s.data(), (int)s.length());
}
-int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
+SWIGINTERN int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
int v;
int res = Tcl_GetBooleanFromObj(interp, o, &v);
if (res == TCL_OK) {
@@ -47,9 +47,10 @@ int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
return res;
}
-int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) {
+SWIGINTERN int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) {
int len;
const char* temp = Tcl_GetStringFromObj(o, &len);
+ (void)interp;
if (temp == NULL)
return TCL_ERROR;
val->assign(temp, len);
@@ -88,12 +89,12 @@ namespace std {
int i;
T* temp;
- if (SWIG_ConvertPtr($input, (void **) &v, \
+ if (SWIG_ConvertPtr($input, (void **) &v,
$&1_descriptor, 0) == 0){
$1 = *v;
} else {
// It isn't a vector< T > so it should be a list of T's
- if(Tcl_ListObjGetElements(interp, $input, \
+ if(Tcl_ListObjGetElements(interp, $input,
&nitems, &listobjv) == TCL_ERROR)
return TCL_ERROR;
$1 = std::vector< T >();
@@ -117,8 +118,8 @@ namespace std {
int i;
T* temp;
- if(SWIG_ConvertPtr($input, (void **) &v, \
- $&1_descriptor, 0) == 0) {
+ if(SWIG_ConvertPtr($input, (void **) &v,
+ $1_descriptor, 0) == 0) {
$1 = v;
} else {
// It isn't a vector< T > so it should be a list of T's
@@ -143,7 +144,7 @@ namespace std {
%typemap(out) vector< T > {
for (unsigned int i=0; i<$1.size(); i++) {
T* ptr = new T((($1_type &)$1)[i]);
- Tcl_ListObjAppendElement(interp, $result, \
+ Tcl_ListObjAppendElement(interp, $result,
SWIG_NewInstanceObj(ptr,
$descriptor(T *),
0));
@@ -156,7 +157,7 @@ namespace std {
T* temp;
std::vector< T > *v;
- if(SWIG_ConvertPtr($input, (void **) &v, \
+ if(SWIG_ConvertPtr($input, (void **) &v,
$&1_descriptor, 0) == 0) {
/* wrapped vector */
$1 = 1;
@@ -168,7 +169,7 @@ namespace std {
else
if (nitems == 0)
$1 = 1;
- //check the first value to see if it is of correct type
+ //check the first value to see if it is of correct type
else if ((SWIG_ConvertPtr(listobjv[0],
(void **) &temp,
$descriptor(T *),0)) != 0)
@@ -185,7 +186,7 @@ namespace std {
T* temp;
std::vector< T > *v;
- if(SWIG_ConvertPtr($input, (void **) &v, \
+ if(SWIG_ConvertPtr($input, (void **) &v,
$1_descriptor, 0) == 0){
/* wrapped vector */
$1 = 1;
@@ -197,7 +198,7 @@ namespace std {
else
if (nitems == 0)
$1 = 1;
- //check the first value to see if it is of correct type
+ //check the first value to see if it is of correct type
else if ((SWIG_ConvertPtr(listobjv[0],
(void **) &temp,
$descriptor(T *),0)) != 0)
@@ -264,7 +265,7 @@ namespace std {
int i;
T temp;
- if(SWIG_ConvertPtr($input, (void **) &v, \
+ if(SWIG_ConvertPtr($input, (void **) &v,
$&1_descriptor, 0) == 0) {
$1 = *v;
} else {
@@ -288,7 +289,7 @@ namespace std {
int i;
T temp;
- if(SWIG_ConvertPtr($input, (void **) &v, \
+ if(SWIG_ConvertPtr($input, (void **) &v,
$1_descriptor, 0) == 0) {
$1 = v;
} else {
@@ -308,7 +309,7 @@ namespace std {
%typemap(out) vector< T > {
for (unsigned int i=0; i<$1.size(); i++) {
- Tcl_ListObjAppendElement(interp, $result, \
+ Tcl_ListObjAppendElement(interp, $result,
CONVERT_TO((($1_type &)$1)[i]));
}
}
@@ -319,7 +320,7 @@ namespace std {
T temp;
std::vector< T > *v;
- if(SWIG_ConvertPtr($input, (void **) &v, \
+ if(SWIG_ConvertPtr($input, (void **) &v,
$&1_descriptor, 0) == 0){
/* wrapped vector */
$1 = 1;
@@ -331,11 +332,11 @@ namespace std {
else
if (nitems == 0)
$1 = 1;
- //check the first value to see if it is of correct type
- if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
- $1 = 0;
- else
- $1 = 1;
+ //check the first value to see if it is of correct type
+ else if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
+ $1 = 0;
+ else
+ $1 = 1;
}
}
@@ -346,7 +347,7 @@ namespace std {
T temp;
std::vector< T > *v;
- if(SWIG_ConvertPtr($input, (void **) &v, \
+ if(SWIG_ConvertPtr($input, (void **) &v,
$1_descriptor, 0) == 0){
/* wrapped vector */
$1 = 1;
@@ -358,11 +359,11 @@ namespace std {
else
if (nitems == 0)
$1 = 1;
- //check the first value to see if it is of correct type
- if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
- $1 = 0;
- else
- $1 = 1;
+ //check the first value to see if it is of correct type
+ else if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
+ $1 = 0;
+ else
+ $1 = 1;
}
}
diff --git a/Lib/tcl/swigmove.i b/Lib/tcl/swigmove.i
new file mode 100644
index 000000000..62ecca768
--- /dev/null
+++ b/Lib/tcl/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/tcl/tclinit.swg b/Lib/tcl/tclinit.swg
index 3140bdcdb..cf14de881 100644
--- a/Lib/tcl/tclinit.swg
+++ b/Lib/tcl/tclinit.swg
@@ -24,7 +24,7 @@ SWIGEXPORT int SWIG_init(Tcl_Interp *);
/* Compatibility version for TCL stubs */
#ifndef SWIG_TCL_STUBS_VERSION
-#define SWIG_TCL_STUBS_VERSION "8.1"
+#define SWIG_TCL_STUBS_VERSION "8.4"
#endif
%}
@@ -100,8 +100,7 @@ SWIGEXPORT int SWIG_init(Tcl_Interp *interp) {
size_t i;
if (interp == 0) return TCL_ERROR;
#ifdef USE_TCL_STUBS
- /* (char*) cast is required to avoid compiler warning/error for Tcl < 8.4. */
- if (Tcl_InitStubs(interp, (char*)SWIG_TCL_STUBS_VERSION, 0) == NULL) {
+ if (Tcl_InitStubs(interp, SWIG_TCL_STUBS_VERSION, 0) == NULL) {
return TCL_ERROR;
}
#endif
diff --git a/Lib/tcl/tclprimtypes.swg b/Lib/tcl/tclprimtypes.swg
index 3b6d04f59..febbffb73 100644
--- a/Lib/tcl/tclprimtypes.swg
+++ b/Lib/tcl/tclprimtypes.swg
@@ -136,30 +136,13 @@ SWIG_From_dec(long long)(long long value)
SWIGINTERN int
SWIG_AsVal_dec(long long)(Tcl_Obj *obj, long long *val)
{
- long v;
- if (Tcl_GetLongFromObj(0,obj, &v) == TCL_OK) {
+ Tcl_WideInt v;
+ if (Tcl_GetWideIntFromObj(0, obj, &v) == TCL_OK) {
+ if (sizeof(v) > sizeof(*val) && (v < LLONG_MIN || v > LLONG_MAX)) {
+ return SWIG_OverflowError;
+ }
if (val) *val = v;
return SWIG_OK;
- } else {
- int len = 0;
- const char *nptr = Tcl_GetStringFromObj(obj, &len);
- if (nptr && len > 0) {
- char *endptr;
- long long v;
- errno = 0;
- v = strtoll(nptr, &endptr,0);
- if (nptr[0] == '\0' || *endptr != '\0')
- return SWIG_TypeError;
- if ((v == LLONG_MAX || v == LLONG_MIN) && errno == ERANGE) {
- errno = 0;
- return SWIG_OverflowError;
- } else {
- if (*endptr == '\0') {
- if (val) *val = v;
- return SWIG_OK;
- }
- }
- }
}
return SWIG_TypeError;
}
diff --git a/Lib/tcl/tclrun.swg b/Lib/tcl/tclrun.swg
index 9010b9c87..e8136051f 100644
--- a/Lib/tcl/tclrun.swg
+++ b/Lib/tcl/tclrun.swg
@@ -67,7 +67,7 @@
#define SWIG_GetConstant SWIG_GetConstantObj
#define SWIG_Tcl_GetConstant SWIG_Tcl_GetConstantObj
-#if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 5
+#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5)
#define SWIG_TCL_HASHTABLE_INIT {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#else
#define SWIG_TCL_HASHTABLE_INIT {0}
@@ -122,6 +122,7 @@ SWIG_Tcl_Disown(void *ptr) {
SWIGRUNTIME int
SWIG_Tcl_ConvertPtrFromString(Tcl_Interp *interp, const char *c, void **ptr, swig_type_info *ty, int flags) {
swig_cast_info *tc;
+ const char *cmd_name;
/* Pointer values must start with leading underscore */
while (*c != '_') {
*ptr = (void *) 0;
@@ -157,23 +158,42 @@ SWIG_Tcl_ConvertPtrFromString(Tcl_Interp *interp, const char *c, void **ptr, swi
c = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), NULL);
}
+ cmd_name = c;
c++;
c = SWIG_UnpackData(c,ptr,sizeof(void *));
+
if (ty) {
tc = c ? SWIG_TypeCheck(c,ty) : 0;
- if (!tc) {
+ if (tc) {
+ Tcl_CmdInfo info;
+ if (Tcl_GetCommandInfo(interp, cmd_name, &info)) {
+ swig_instance *inst = (swig_instance *)info.objClientData;
+ if (!inst->thisvalue) {
+ *ptr = 0;
+ }
+ assert(inst->thisvalue == *ptr);
+ if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !SWIG_Thisown(inst->thisvalue)) {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ } else {
+ if (flags & SWIG_POINTER_DISOWN) {
+ SWIG_Disown((void *) *ptr);
+ }
+ if (flags & SWIG_POINTER_CLEAR) {
+ inst->thisvalue = 0;
+ }
+ {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,(void *) *ptr,&newmemory);
+ assert(!newmemory); /* newmemory handling not yet implemented */
+ }
+ }
+ }
+ } else {
return SWIG_ERROR;
}
- if (flags & SWIG_POINTER_DISOWN) {
- SWIG_Disown((void *) *ptr);
- }
- {
- int newmemory = 0;
- *ptr = SWIG_TypeCast(tc,(void *) *ptr,&newmemory);
- assert(!newmemory); /* newmemory handling not yet implemented */
- }
}
+
return SWIG_OK;
}
@@ -490,9 +510,11 @@ SWIG_Tcl_NewInstanceObj(Tcl_Interp *interp, void *thisvalue, swig_type_info *typ
/* Check to see if this pointer belongs to a class or not */
if (thisvalue && (type->clientdata) && (interp)) {
Tcl_CmdInfo ci;
+ int has_command;
char *name;
name = Tcl_GetStringFromObj(robj,NULL);
- if (!Tcl_GetCommandInfo(interp,name, &ci) || (flags)) {
+ has_command = Tcl_GetCommandInfo(interp, name, &ci);
+ if (!has_command || flags) {
swig_instance *newinst = (swig_instance *) malloc(sizeof(swig_instance));
newinst->thisptr = Tcl_DuplicateObj(robj);
Tcl_IncrRefCount(newinst->thisptr);
@@ -503,6 +525,15 @@ SWIG_Tcl_NewInstanceObj(Tcl_Interp *interp, void *thisvalue, swig_type_info *typ
if (flags) {
SWIG_Acquire(thisvalue);
}
+ } else {
+ swig_instance *inst = (swig_instance *)ci.objClientData;
+ /* Restore thisvalue as SWIG_POINTER_CLEAR may have been used to set it to zero.
+ Occurs when the C pointer is re-used by the memory allocator and the command has
+ been created and not destroyed - bug?? - see cpp11_std_unique_ptr_runme.tcl test. */
+ if (inst->thisvalue != thisvalue) {
+ assert(inst->thisvalue == 0);
+ inst->thisvalue = thisvalue;
+ }
}
}
return robj;
diff --git a/Lib/tcl/tclsh.i b/Lib/tcl/tclsh.i
index 160ba8d8f..21dc35af3 100644
--- a/Lib/tcl/tclsh.i
+++ b/Lib/tcl/tclsh.i
@@ -33,10 +33,6 @@ char *SWIG_RcFileName = "~/.myapprc";
#endif
-#ifdef MAC_TCL
-extern int MacintoshInit _ANSI_ARGS_((void));
-#endif
-
int Tcl_AppInit(Tcl_Interp *interp){
if (Tcl_Init(interp) == TCL_ERROR)
@@ -46,40 +42,16 @@ int Tcl_AppInit(Tcl_Interp *interp){
if (SWIG_init(interp) == TCL_ERROR)
return TCL_ERROR;
-#if TCL_MAJOR_VERSION > 7 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5
- Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY);
-#else
- tcl_RcFileName = SWIG_RcFileName;
-#endif
-#ifdef SWIG_RcRsrcName
- Tcl_SetVar(interp, (char *) "tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL);
-#endif
-
+ Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY);
+
return TCL_OK;
}
-#if TCL_MAJOR_VERSION > 7 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 4
int main(int argc, char **argv) {
-#ifdef MAC_TCL
- char *newArgv[2];
-
- if (MacintoshInit() != TCL_OK) {
- Tcl_Exit(1);
- }
-
- argc = 1;
- newArgv[0] = "tclsh";
- newArgv[1] = NULL;
- argv = newArgv;
-#endif
-
Tcl_Main(argc, argv, Tcl_AppInit);
return(0);
}
-#else
-extern int main();
-#endif
%}
diff --git a/Lib/tcl/tcltypemaps.swg b/Lib/tcl/tcltypemaps.swg
index ad31bcfc9..66cce47ec 100644
--- a/Lib/tcl/tcltypemaps.swg
+++ b/Lib/tcl/tcltypemaps.swg
@@ -77,11 +77,6 @@
#endif
-%typemap(throws,noblock=1) SWIGTYPE CLASS {
- SWIG_set_result(SWIG_NewInstanceObj(%as_voidptr(SWIG_new_copy($1, $1_ltype)), $&1_descriptor, 1));
- SWIG_fail;
-}
-
%typemap(out) SWIGTYPE = SWIGTYPE INSTANCE;
%typemap(out) SWIGTYPE * = SWIGTYPE *INSTANCE;
%typemap(out) SWIGTYPE *const = SWIGTYPE *;
diff --git a/Lib/tcl/tclwstrings.swg b/Lib/tcl/tclwstrings.swg
index b3b682e30..09374c54f 100644
--- a/Lib/tcl/tclwstrings.swg
+++ b/Lib/tcl/tclwstrings.swg
@@ -29,6 +29,7 @@ SWIG_AsWCharPtrAndSize(Tcl_Obj *obj, wchar_t** cptr, size_t* psize, int *alloc)
Tcl_UtfToExternal(0, encoding, src, srcLen, flags, statePtr, dst,
dstLen, &srcRead, &dstWrote, &dstChars);
+ *cptr = (wchar_t*)dst;
if (alloc) *alloc = SWIG_NEWOBJ;
}
if (psize) *psize = len + 1;
diff --git a/Lib/tcl/wish.i b/Lib/tcl/wish.i
index 260032a81..42902850d 100644
--- a/Lib/tcl/wish.i
+++ b/Lib/tcl/wish.i
@@ -35,11 +35,6 @@ as follows (this should be included in a code-block) :
char *SWIG_RcFileName = "~/.wishrc";
#endif
-#ifdef MAC_TCL
-extern int MacintoshInit _ANSI_ARGS_((void));
-extern int SetupMainInterp _ANSI_ARGS_((Tcl_Interp *interp));
-#endif
-
/*
*----------------------------------------------------------------------
*
@@ -61,10 +56,9 @@ extern int SetupMainInterp _ANSI_ARGS_((Tcl_Interp *interp));
int Tcl_AppInit(Tcl_Interp *interp)
{
-#ifndef MAC_TCL
Tk_Window main;
main = Tk_MainWindow(interp);
-#endif
+
/*
* Call the init procedures for included packages. Each call should
* look like this:
@@ -93,10 +87,6 @@ int Tcl_AppInit(Tcl_Interp *interp)
return TCL_ERROR;
}
-#ifdef MAC_TCL
- SetupMainInterp(interp);
-#endif
-
/*
* Specify a user-specific startup file to invoke if the application
* is run interactively. Typically the startup file is "~/.apprc"
@@ -104,35 +94,12 @@ int Tcl_AppInit(Tcl_Interp *interp)
* then no user-specific startup file will be run under any conditions.
*/
-#if TCL_MAJOR_VERSION >= 8 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5
- Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY);
-#else
- tcl_RcFileName = SWIG_RcFileName;
-#endif
-
-/* For Macintosh might also want this */
-
-#ifdef MAC_TCL
-#ifdef SWIG_RcRsrcName
- Tcl_SetVar(interp, (char *) "tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL_ONLY);
-#endif
-#endif
+ Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY);
return TCL_OK;
}
#if TK_MAJOR_VERSION >= 4
int main(int argc, char **argv) {
-
-#ifdef MAC_TCL
- char *newArgv[2];
- if (MacintoshInit() != TCL_OK) {
- Tcl_Exit(1);
- }
- argc = 1;
- newArgv[0] = "Wish";
- newArgv[1] = NULL;
- argv = newArgv;
-#endif
Tk_Main(argc, argv, Tcl_AppInit);
return(0);
}
diff --git a/Lib/typemaps/attribute.swg b/Lib/typemaps/attribute.swg
index 37c3340cf..7d4767f52 100644
--- a/Lib/typemaps/attribute.swg
+++ b/Lib/typemaps/attribute.swg
@@ -7,132 +7,6 @@
/*
The following macros convert a pair of set/get methods
into a "native" attribute.
-
- Use %attribute when you have a pair of get/set methods to a primitive type
- like in:
-
- %attribute(A, int, a, get_a, set_a);
-
- struct A
- {
- int get_a() const;
- void set_a(int aa);
- };
-
- If you don't provide a 'set' method, a 'read-only' attribute
- is generated, ie, like in:
-
- %attribute(A, int, c, get_c);
-
- Use %attributeref when you have const/non-const reference access methods
- for primitive types or class/structs, like in:
-
- %attributeref(A, int, b);
-
- struct A
- {
- const int& b() const;
- int& b();
- };
-
- %attributeref(B, int, c);
-
- struct B
- {
- int& c();
- };
-
- You can also use
-
- %attributeref(Class, AttributeType, AttributeName, AccessorMethod)
-
- if the internal C++ reference methods have a different name from the
- attribute you want, so
-
- %attributeref(B, int, d, c);
-
- is the same as the last example, but instead of the attribute 'c' being
- called 'c', it is called 'd'.
-
- Now you can use the attributes like so:
-
- x = A()
- x.a = 3 # calls A::set_a
- print x.a # calls A::get_a
-
- x.b = 3 # calls A::b()
- print x.b # calls A::b() const
-
- Use %attribute2 instead of %attribute to indicate that reference-pointer
- translation is required. You use %attribute2 instead of %attribute in
- cases like this:
-
- %attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
- %inline %{
- struct MyFoo {
- int x;
- };
- class MyClass {
- MyFoo foo;
- public:
- MyFoo& GetFoo() { return foo; }
- void SetFoo(const MyFoo& other) { foo = other; }
- };
- %}
-
- Here, the data type of the property is a wrapped type (MyFoo) and on the
- C++ side it is passed by reference. The problem is that the SWIG wrapper will
- pass around a pointer (MyFoo *) which is not compatible with the reference
- type of the accessors (MyFoo &). Therefore, if you use %attribute, you'll get
- an error from your C/C++ compiler. %attribute2 translates between a pointer
- and a reference to eliminate the error. In case you're confused, let's make it
- simple: just use %attribute at first, but if the C/C++ compiler gives an error
- while compiling the wrapper, try %attribute2 instead.
-
- NOTE: remember that if the type contains commas, such as 'std::pair<int,int>',
- you need to use the macro like:
-
- %attributeref(A, %arg(std::pair<int,int>), pval);
-
- where %arg() 'normalizes' the type to be understood as a single
- argument, otherwise the macro will get confused by the comma.
-
- The %attributeval is the same as %attribute, but should be used when the type
- is a class/struct (ie a non-primitive type) and when the get and set methods
- return/pass by value. The following is very similar to the above example, but
- note that the access is by value rather than reference.
-
- %attributeval(MyClassVal, MyFoo, ReadWriteFoo, GetFoo, SetFoo);
- %attributeval(MyClassVal, MyFoo, ReadOnlyFoo, GetFoo);
- %inline %{
- class MyClassVal {
- MyFoo foo;
- public:
- MyFoo GetFoo() { return foo; }
- void SetFoo(MyFoo other) { foo = other; }
- };
- %}
-
- The %attributestring is the same as %attributeval, but should be used for string
- class types, which are unusual as they are a class on the C++ side, but normally an
- immutable/primitive type in the target language. Example usage for std::string:
-
- %include <std_string.i>
- %attributestring(MyStringyClass, std::string, ReadWriteString, GetString, SetString);
- %attributestring(MyStringyClass, std::string, ReadOnlyString, GetString);
- %inline %{
- class MyStringyClass {
- std::string str;
- public:
- MyStringyClass(const std::string &val) : str(val) {}
- std::string GetString() { return str; }
- void SetString(std::string other) { str = other; }
- };
- %}
-
- The %attributestring also works for class types that have %naturalvar turned
- on and so is also useful for shared_ptr which has %naturalvar turned on in %shared_ptr.
-
*/
//
diff --git a/Lib/typemaps/cpointer.swg b/Lib/typemaps/cpointer.swg
index 94bbbd6bc..a5ac07d85 100644
--- a/Lib/typemaps/cpointer.swg
+++ b/Lib/typemaps/cpointer.swg
@@ -55,7 +55,7 @@ typedef struct {
return %new_instance(TYPE);
}
~NAME() {
- if ($self) %delete($self);
+ %delete($self);
}
}
@@ -105,7 +105,7 @@ typedef struct {
%define %pointer_functions(TYPE,NAME)
%{
- static TYPE *new_##NAME() {
+ static TYPE *new_##NAME(void) {
return %new_instance(TYPE);
}
@@ -114,7 +114,7 @@ typedef struct {
}
static void delete_##NAME(TYPE *obj) {
- if (obj) %delete(obj);
+ %delete(obj);
}
static void NAME ##_assign(TYPE *obj, TYPE value) {
@@ -126,7 +126,7 @@ typedef struct {
}
%}
-TYPE *new_##NAME();
+TYPE *new_##NAME(void);
TYPE *copy_##NAME(TYPE value);
void delete_##NAME(TYPE *obj);
void NAME##_assign(TYPE *obj, TYPE value);
diff --git a/Lib/typemaps/cstrings.swg b/Lib/typemaps/cstrings.swg
index 0aca61101..42ce4d9bb 100644
--- a/Lib/typemaps/cstrings.swg
+++ b/Lib/typemaps/cstrings.swg
@@ -59,7 +59,7 @@
%typemap(in,noblock=1,numinputs=0) TYPEMAP (Char temp[MAX+1]) {
$1 = ($1_ltype) temp;
}
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
%typemap(argout,noblock=1,fragment= #SWIG_FromCharPtr ) TYPEMAP {
$1[MAX] = 0;
%append_output(SWIG_FromCharPtr($1));
@@ -85,7 +85,7 @@
%typemap(in,noblock=1,numinputs=0) TYPEMAP(Char temp[SIZE]) {
$1 = ($1_ltype) temp;
}
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
%typemap(argout,noblock=1,fragment= #SWIG_FromCharPtrAndSize) TYPEMAP {
%append_output(SWIG_FromCharPtrAndSize($1,SIZE));
}
@@ -122,7 +122,7 @@
temp[n - 1] = 0;
$1 = ($1_ltype) temp;
}
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
%typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) TYPEMAP {
$1[MAX] = 0;
%append_output(SWIG_FromCharPtr($1));
@@ -160,7 +160,7 @@
if (alloc == SWIG_NEWOBJ) %delete_array(t);
$1[n-1] = 0;
}
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
%typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) TYPEMAP {
%append_output(SWIG_FromCharPtr($1));
%delete_array($1);
@@ -247,7 +247,7 @@
%typemap(in,noblock=1,numinputs=0) TYPEMAP($*1_ltype temp = 0) {
$1 = &temp;
}
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
%typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) TYPEMAP {
if (*$1) {
%append_output(SWIG_FromCharPtr(*$1));
@@ -275,7 +275,7 @@
%typemap(in,noblock=1,numinputs=0) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) {
$1 = &temp; $2 = &tempn;
}
-%typemap(freearg,match="in") (TYPEMAP,SIZE) "";
+%typemap(freearg,match="in") (TYPEMAP,SIZE) ""
%typemap(argout,noblock=1,fragment=#SWIG_FromCharPtrAndSize)(TYPEMAP,SIZE) {
if (*$1) {
%append_output(SWIG_FromCharPtrAndSize(*$1,*$2));
diff --git a/Lib/typemaps/exception.swg b/Lib/typemaps/exception.swg
index b60a32996..aece8326f 100644
--- a/Lib/typemaps/exception.swg
+++ b/Lib/typemaps/exception.swg
@@ -19,6 +19,7 @@
#endif
#define %varnullref_fmt(_type,_name) %nullref_fmt() %varfail_fmt(_type, _name)
#define %outnullref_fmt(_type) %nullref_fmt() %outfail_fmt(_type)
+#define %releasenotownedfail_fmt(_type,_name,_argn) "in method '" `_name` "', cannot release ownership as memory is not owned for argument " `_argn`" of type '" `_type`"'"
/* setting an error */
#define %error(code,msg...) SWIG_Error(code, msg)
@@ -30,7 +31,7 @@
%define_as(SWIG_exception_fail(code, msg), %block(%error(code, msg); SWIG_fail))
-%define_as(SWIG_contract_assert(expr, msg), if (!(expr)) { %error(SWIG_RuntimeError, msg); SWIG_fail; } else)
+%define_as(SWIG_contract_assert(expr, msg), do { if (!(expr)) { %error(SWIG_RuntimeError, msg); SWIG_fail; } } while (0))
}
diff --git a/Lib/typemaps/fragments.swg b/Lib/typemaps/fragments.swg
index e83f415c4..e76a694ee 100644
--- a/Lib/typemaps/fragments.swg
+++ b/Lib/typemaps/fragments.swg
@@ -120,10 +120,6 @@ inline int SWIG_isfinite_func(T x) {
# define SWIG_isfinite(X) (SWIG_isfinite_func(X))
# elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
# define SWIG_isfinite(X) (__builtin_isfinite(X))
-# elif defined(__clang__) && defined(__has_builtin)
-# if __has_builtin(__builtin_isfinite)
-# define SWIG_isfinite(X) (__builtin_isfinite(X))
-# endif
# elif defined(_MSC_VER)
# define SWIG_isfinite(X) (_finite(X))
# elif defined(__sun) && defined(__SVR4)
diff --git a/Lib/typemaps/ptrtypes.swg b/Lib/typemaps/ptrtypes.swg
index e8439e6dc..ca54fcdc2 100644
--- a/Lib/typemaps/ptrtypes.swg
+++ b/Lib/typemaps/ptrtypes.swg
@@ -35,7 +35,7 @@
$1 = *ptr;
if (SWIG_IsNewObj(res)) %delete(ptr);
}
- %typemap(freearg) Type "";
+ %typemap(freearg) Type ""
%typemap(in,fragment=frag) const Type & (int res = SWIG_OLDOBJ) {
Type *ptr = (Type *)0;
res = asptr_meth($input, &ptr);
diff --git a/Lib/typemaps/string.swg b/Lib/typemaps/string.swg
index 4b7072365..72f4aa5b5 100644
--- a/Lib/typemaps/string.swg
+++ b/Lib/typemaps/string.swg
@@ -30,6 +30,7 @@ SWIG_strnlen(const char* s, size_t maxlen)
%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 87e97dd74..1237d98df 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,
@@ -78,7 +79,7 @@
if (!SWIG_IsOK(res)) {
%variable_fail(res,"$type","$name");
}
- if ($1) SWIG_DeleteCharArray($1);
+ SWIG_DeleteCharArray($1);
if (alloc == SWIG_NEWOBJ) {
$1 = cptr;
} else {
@@ -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)) {
@@ -108,7 +109,7 @@
/* memberin */
%typemap(memberin,noblock=1) Char * {
- if ($1) SWIG_DeleteCharArray($1);
+ SWIG_DeleteCharArray($1);
if ($input) {
size_t size = SWIG_CharPtrLen(%reinterpret_cast($input, const Char *)) + 1;
$1 = ($1_type)SWIG_NewCopyCharArray(%reinterpret_cast($input, const Char *), size, Char);
@@ -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);
@@ -129,7 +130,7 @@
/* globalin */
%typemap(globalin,noblock=1) Char * {
- if ($1) SWIG_DeleteCharArray($1);
+ SWIG_DeleteCharArray($1);
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);
@@ -265,7 +266,7 @@
}
$1 = %reinterpret_cast(temp, $1_ltype);
}
-%typemap(freearg) Char [ANY], const Char [ANY] "";
+%typemap(freearg) Char [ANY], const Char [ANY] ""
%typemap(in,noblock=1,fragment=#SWIG_AsCharArray) const Char (&)[ANY] (Char temp[$1_dim0], int res)
{
@@ -275,7 +276,7 @@
}
$1 = &temp;
}
-%typemap(freearg) const Char (&)[ANY] "";
+%typemap(freearg) const Char (&)[ANY] ""
%typemap(out,fragment=#SWIG_FromCharPtrAndSize,fragment=#SWIG_CharBufLen)
Char [ANY], const Char[ANY]
@@ -501,6 +502,7 @@
#ifndef %_typemap2_string
%define %_typemap2_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -591,6 +593,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
%_typemap_string(StringCode,
Char,
+ WarningLeakMsg,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
SWIG_CharPtrLen,
@@ -609,6 +612,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
* ------------------------------------------------------------ */
%define %typemaps_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -616,6 +620,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
SWIG_CharBufLen,
FragLimits, CHAR_MIN, CHAR_MAX)
%_typemap2_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -631,6 +636,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
* ------------------------------------------------------------ */
%define %typemaps_string_alloc(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -640,6 +646,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
SWIG_DeleteCharArray,
FragLimits, CHAR_MIN, CHAR_MAX)
%_typemap2_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
diff --git a/Lib/typemaps/swigmacros.swg b/Lib/typemaps/swigmacros.swg
index 687b0680e..b772eb04b 100644
--- a/Lib/typemaps/swigmacros.swg
+++ b/Lib/typemaps/swigmacros.swg
@@ -109,16 +109,6 @@ nocppval
#endif
%enddef
-/* insert the SWIGVERSION in the interface and the wrapper code */
-#if SWIG_VERSION
-%insert("header") {
-%define_as(SWIGVERSION, SWIG_VERSION)
-%#define SWIG_VERSION SWIGVERSION
-}
-#endif
-
-
-
/* -----------------------------------------------------------------------------
* Casting operators
* ----------------------------------------------------------------------------- */
diff --git a/Lib/typemaps/swigmove.swg b/Lib/typemaps/swigmove.swg
new file mode 100644
index 000000000..b0a296850
--- /dev/null
+++ b/Lib/typemaps/swigmove.swg
@@ -0,0 +1,19 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.swg
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr($input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "$1_type", $symname, $argnum);
+ } else {
+ %argument_fail(res, "$1_type", $symname, $argnum);
+ }
+ }
+ if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
+ SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/typemaps/swigobject.swg b/Lib/typemaps/swigobject.swg
index b1e6dc9d8..26c6ba8ed 100644
--- a/Lib/typemaps/swigobject.swg
+++ b/Lib/typemaps/swigobject.swg
@@ -2,7 +2,7 @@
* Language Object * - Just pass straight through unmodified
* ------------------------------------------------------------ */
-%typemap(in) SWIG_Object "$1 = $input;";
+%typemap(in) SWIG_Object "$1 = $input;"
%typemap(in,noblock=1) SWIG_Object const & ($*ltype temp)
{
@@ -30,8 +30,8 @@
#if defined(SWIG_DIRECTOR_TYPEMAPS)
-%typemap(directorin) SWIG_Object "$input = $1;";
-%typemap(directorout) SWIG_Object "$result = $input;";
+%typemap(directorin) SWIG_Object "$input = $1;"
+%typemap(directorout) SWIG_Object "$result = $input;"
#endif /* SWIG_DIRECTOR_TYPEMAPS */
diff --git a/Lib/typemaps/swigtype.swg b/Lib/typemaps/swigtype.swg
index 402313ebf..69f83794d 100644
--- a/Lib/typemaps/swigtype.swg
+++ b/Lib/typemaps/swigtype.swg
@@ -9,7 +9,7 @@
}
$1 = %reinterpret_cast(argp, $ltype);
}
-%typemap(freearg) SWIGTYPE * "";
+%typemap(freearg) SWIGTYPE * ""
%typemap(in, noblock=1) SWIGTYPE [] (void *argp = 0, int res = 0) {
res = SWIG_ConvertPtr($input, &argp,$descriptor, $disown | %convertptr_flags);
@@ -18,7 +18,7 @@
}
$1 = %reinterpret_cast(argp, $ltype);
}
-%typemap(freearg) SWIGTYPE [] "";
+%typemap(freearg) SWIGTYPE [] ""
%typemap(in, noblock=1) SWIGTYPE *const& (void *argp = 0, int res = 0, $*1_ltype temp) {
@@ -29,7 +29,7 @@
temp = %reinterpret_cast(argp, $*ltype);
$1 = %reinterpret_cast(&temp, $1_ltype);
}
-%typemap(freearg) SWIGTYPE *const& "";
+%typemap(freearg) SWIGTYPE *const& ""
/* Reference */
@@ -41,7 +41,7 @@
if (!argp) { %argument_nullref("$type", $symname, $argnum); }
$1 = %reinterpret_cast(argp, $ltype);
}
-%typemap(freearg) SWIGTYPE & "";
+%typemap(freearg) SWIGTYPE & ""
#if defined(__cplusplus) && defined(%implicitconv_flag)
%typemap(in,noblock=1,implicitconv=1) const SWIGTYPE & (void *argp = 0, int res = 0) {
@@ -56,51 +56,23 @@
{
if (SWIG_IsNewObj(res$argnum)) %delete($1);
}
-#else
-%typemap(in,noblock=1) const SWIGTYPE & (void *argp, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- if (!argp) { %argument_nullref("$type", $symname, $argnum); }
- $1 = %reinterpret_cast(argp, $ltype);
-}
#endif
/* Rvalue reference */
-%typemap(in, noblock=1) SWIGTYPE && (void *argp = 0, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
+%typemap(in, noblock=1, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) {
+ res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE | %convertptr_flags);
if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- if (!argp) { %argument_nullref("$type", $symname, $argnum); }
- $1 = %reinterpret_cast(argp, $ltype);
-}
-%typemap(freearg) SWIGTYPE && "";
-
-#if defined(__cplusplus) && defined(%implicitconv_flag)
-%typemap(in,noblock=1,implicitconv=1) const SWIGTYPE && (void *argp = 0, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags | %implicitconv_flag);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- if (!argp) { %argument_nullref("$type", $symname, $argnum); }
- $1 = %reinterpret_cast(argp, $ltype);
-}
-%typemap(freearg,noblock=1,match="in",implicitconv=1) const SWIGTYPE &&
-{
- if (SWIG_IsNewObj(res$argnum)) %delete($1);
-}
-#else
-%typemap(in,noblock=1) const SWIGTYPE && (void *argp, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ %releasenotowned_fail(res, "$type", $symname, $argnum);
+ } else {
+ %argument_fail(res, "$type", $symname, $argnum);
+ }
}
if (!argp) { %argument_nullref("$type", $symname, $argnum); }
$1 = %reinterpret_cast(argp, $ltype);
+ rvrdeleter.reset($1);
}
-#endif
+%typemap(freearg) SWIGTYPE && ""
/* By value */
#if defined(__cplusplus) && defined(%implicitconv_flag)
@@ -146,9 +118,15 @@
}
/* Return by value */
+#ifdef __cplusplus
%typemap(out, noblock=1) SWIGTYPE {
- %set_output(SWIG_NewPointerObj(%new_copy($1, $ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+ %set_output(SWIG_NewPointerObj((new $1_ltype($1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
}
+#else
+%typemap(out, noblock=1) SWIGTYPE {
+ %set_output(SWIG_NewPointerObj(%new_copy($1, $1_ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+}
+#endif
/* -----------------------------------------------------------------------------
* --- Variable input ---
@@ -389,6 +367,7 @@
int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
$1 = SWIG_CheckState(res);
}
+
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE && {
void *vptr = 0;
int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
@@ -411,7 +390,7 @@
/* directorin */
%typemap(directorin,noblock=1) SWIGTYPE {
- $input = SWIG_NewPointerObj(%as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags);
+ $input = SWIG_NewPointerObj((new $1_ltype(SWIG_STD_MOVE($1))), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags);
}
%typemap(directorin,noblock=1) SWIGTYPE * {
@@ -534,7 +513,7 @@
* ------------------------------------------------------------ */
%typemap(throws,noblock=1) SWIGTYPE {
- %raise(SWIG_NewPointerObj(%new_copy($1, $ltype),$&descriptor,SWIG_POINTER_OWN), "$type", $&descriptor);
+ %raise(SWIG_NewPointerObj(%new_copy($1, $1_ltype),$&descriptor,SWIG_POINTER_OWN), "$type", $&descriptor);
}
%typemap(throws,noblock=1) SWIGTYPE * {
@@ -703,9 +682,15 @@
/* INSTANCE typemap */
+#ifdef __cplusplus
+%typemap(out,noblock=1) SWIGTYPE INSTANCE {
+ %set_output(SWIG_NewInstanceObj((new $1_ltype($1)), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags));
+}
+#else
%typemap(out,noblock=1) SWIGTYPE INSTANCE {
%set_output(SWIG_NewInstanceObj(%new_copy($1, $1_ltype), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags));
}
+#endif
%typemap(out,noblock=1) SWIGTYPE *INSTANCE, SWIGTYPE &INSTANCE, SWIGTYPE INSTANCE[] {
%set_output(SWIG_NewInstanceObj(%as_voidptr($1), $1_descriptor, $owner | %newinstance_flags));
diff --git a/Lib/typemaps/swigtypemaps.swg b/Lib/typemaps/swigtypemaps.swg
index 4e5bb2b04..733e5acd0 100644
--- a/Lib/typemaps/swigtypemaps.swg
+++ b/Lib/typemaps/swigtypemaps.swg
@@ -140,6 +140,7 @@
#define %argument_nullref(type, name, argn) SWIG_exception_fail(SWIG_ValueError, %argnullref_fmt(type, name, argn))
#define %variable_fail(code, type, name) SWIG_exception_fail(%default_code(code), %varfail_fmt(type, name))
#define %variable_nullref(type, name) SWIG_exception_fail(SWIG_ValueError, %varnullref_fmt(type, name))
+#define %releasenotowned_fail(code, type, name, argn) SWIG_exception_fail(%default_code(code), %releasenotownedfail_fmt(type, name, argn))
#if defined(SWIG_DIRECTOR_TYPEMAPS)
#define %dirout_fail(code, type) SWIG_DirOutFail(%default_code(code), %outfail_fmt(type))
diff --git a/Lib/typemaps/valtypes.swg b/Lib/typemaps/valtypes.swg
index 11eac5985..f2f34acfc 100644
--- a/Lib/typemaps/valtypes.swg
+++ b/Lib/typemaps/valtypes.swg
@@ -38,7 +38,7 @@
}
$1 = %static_cast(val,$ltype);
}
- %typemap(freearg) Type "";
+ %typemap(freearg) Type ""
%typemap(in,noblock=1,fragment=frag) const Type & ($*ltype temp, Type val, int ecode = 0) {
ecode = asval_meth($input, &val);
if (!SWIG_IsOK(ecode)) {
@@ -47,7 +47,7 @@
temp = %static_cast(val, $*ltype);
$1 = &temp;
}
- %typemap(freearg) const Type& "";
+ %typemap(freearg) const Type& ""
%enddef
/* out */
diff --git a/Lib/typemaps/void.swg b/Lib/typemaps/void.swg
index bbd68ed87..795992bf4 100644
--- a/Lib/typemaps/void.swg
+++ b/Lib/typemaps/void.swg
@@ -10,7 +10,7 @@
%argument_fail(res, "$type", $symname, $argnum);
}
}
-%typemap(freearg) void * "";
+%typemap(freearg) void * ""
%typemap(in,noblock=1) void * const& ($*ltype temp = 0, int res) {
res = SWIG_ConvertPtr($input, %as_voidptrptr(&temp), 0, $disown);
@@ -19,7 +19,7 @@
}
$1 = &temp;
}
-%typemap(freearg) void * const& "";
+%typemap(freearg) void * const& ""
/* out */
diff --git a/Lib/typemaps/wstring.swg b/Lib/typemaps/wstring.swg
index cd409d1ce..d99c0bb38 100644
--- a/Lib/typemaps/wstring.swg
+++ b/Lib/typemaps/wstring.swg
@@ -31,6 +31,7 @@ SWIG_wcsnlen(const wchar_t* s, size_t maxlen)
%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/Makefile.in b/Makefile.in
index 6edfc240a..3e8f93d19 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -29,7 +29,6 @@ TARGET = $(TARGET_NOEXE)@EXEEXT@
SOURCE = Source
CCACHE = CCache
DOCS = Doc/Manual
-HAVE_CXX11 = @HAVE_CXX11@
swig: libfiles source ccache
@@ -59,23 +58,23 @@ docs-main:
# All the languages SWIG speaks (when it wants to)
#####################################################################
-skip-tcl = test -n "@SKIP_TCL@"
-skip-perl5 = test -n "@SKIP_PERL5@"
-skip-python = test -n "@SKIP_PYTHON@"
-skip-java = test -n "@SKIP_JAVA@"
+skip-csharp = test -n "@SKIP_CSHARP@"
+skip-d = test -n "@SKIP_D@"
+skip-go = test -n "@SKIP_GO@"
skip-guile = test -n "@SKIP_GUILE@"
+skip-java = test -n "@SKIP_JAVA@"
+skip-javascript = test -n "@SKIP_JAVASCRIPT@"
+skip-lua = test -n "@SKIP_LUA@"
skip-mzscheme = test -n "@SKIP_MZSCHEME@"
-skip-ruby = test -n "@SKIP_RUBY@"
-skip-php = test -n "@SKIP_PHP@"
skip-ocaml = test -n "@SKIP_OCAML@"
skip-octave = test -n "@SKIP_OCTAVE@"
-skip-csharp = test -n "@SKIP_CSHARP@"
-skip-lua = test -n "@SKIP_LUA@"
+skip-perl5 = test -n "@SKIP_PERL5@"
+skip-php = test -n "@SKIP_PHP@"
+skip-python = test -n "@SKIP_PYTHON@"
skip-r = test -n "@SKIP_R@"
+skip-ruby = test -n "@SKIP_RUBY@"
skip-scilab = test -n "@SKIP_SCILAB@"
-skip-go = test -n "@SKIP_GO@"
-skip-d = test -n "@SKIP_D@"
-skip-javascript = test -n "@SKIP_JAVASCRIPT@"
+skip-tcl = test -n "@SKIP_TCL@"
# Additional dependencies for some tests
skip-android = test -n "@SKIP_ANDROID@"
@@ -100,47 +99,47 @@ check-aliveness:
test -x ./$(TARGET)
./$(TARGET) -version
./$(TARGET) -help
- @$(skip-tcl) || ./$(TARGET) -tcl -help
- @$(skip-perl5) || ./$(TARGET) -perl -help
- @$(skip-python) || ./$(TARGET) -python -help
- @$(skip-java) || ./$(TARGET) -java -help
+ @$(skip-csharp) || ./$(TARGET) -csharp -help
+ @$(skip-d) || ./$(TARGET) -d -help
+ @$(skip-go) || ./$(TARGET) -go -help
@$(skip-guile) || ./$(TARGET) -guile -help
+ @$(skip-java) || ./$(TARGET) -java -help
+ @$(skip-javascript) || ./$(TARGET) -javascript -help
+ @$(skip-lua) || ./$(TARGET) -lua -help
@$(skip-mzscheme) || ./$(TARGET) -mzscheme -help
- @$(skip-ruby) || ./$(TARGET) -ruby -help
@$(skip-ocaml) || ./$(TARGET) -ocaml -help
@$(skip-octave) || ./$(TARGET) -octave -help
+ @$(skip-perl5) || ./$(TARGET) -perl -help
@$(skip-php) || ./$(TARGET) -php7 -help
- @$(skip-csharp) || ./$(TARGET) -csharp -help
- @$(skip-lua) || ./$(TARGET) -lua -help
+ @$(skip-python) || ./$(TARGET) -python -help
@$(skip-r) || ./$(TARGET) -r -help
+ @$(skip-ruby) || ./$(TARGET) -ruby -help
@$(skip-scilab) || ./$(TARGET) -scilab -help
- @$(skip-go) || ./$(TARGET) -go -help
- @$(skip-d) || ./$(TARGET) -d -help
- @$(skip-javascript) || ./$(TARGET) -javascript -help
+ @$(skip-tcl) || ./$(TARGET) -tcl -help
check-ccache:
test -z "$(ENABLE_CCACHE)" || (cd $(CCACHE) && $(MAKE) check)
# Checks / displays versions of each target language
check-versions: \
- check-tcl-version \
- check-perl5-version \
- check-python-version \
- check-java-version \
- check-javascript-version \
check-android-version \
+ check-csharp-version \
+ check-d-version \
+ check-go-version \
check-guile-version \
+ check-java-version \
+ check-javascript-version \
+ check-lua-version \
check-mzscheme-version \
- check-ruby-version \
check-ocaml-version \
check-octave-version \
+ check-perl5-version \
check-php-version \
- check-csharp-version \
- check-lua-version \
+ check-python-version \
check-r-version \
+ check-ruby-version \
check-scilab-version \
- check-go-version \
- check-d-version
+ check-tcl-version \
# all examples
check-%-version :
@@ -157,43 +156,43 @@ check-%-version :
# Checks examples for compilation (does not run them)
check-examples: \
- check-tcl-examples \
- check-perl5-examples \
- check-python-examples \
- check-java-examples \
check-android-examples \
+ check-csharp-examples \
+ check-d-examples \
+ check-go-examples \
check-guile-examples \
+ check-java-examples \
+ check-javascript-examples \
+ check-lua-examples \
check-mzscheme-examples \
- check-ruby-examples \
check-ocaml-examples \
check-octave-examples \
+ check-perl5-examples \
check-php-examples \
- check-csharp-examples \
- check-lua-examples \
+ check-python-examples \
check-r-examples \
+ check-ruby-examples \
check-scilab-examples \
- check-go-examples \
- check-d-examples \
- check-javascript-examples
+ check-tcl-examples \
-tcl_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/tcl/check.list)
-perl5_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/perl5/check.list)
-python_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/python/check.list)
-java_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/java/check.list)
android_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/android/check.list)
+csharp_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/csharp/check.list)
+d_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/d/check.list)
+go_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list)
guile_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/guile/check.list)
+java_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/java/check.list)
+javascript_examples:=$(shell sed '/^\#/d' $(srcdir)/Examples/javascript/check.list)
+lua_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/lua/check.list)
mzscheme_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/mzscheme/check.list)
-ruby_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/ruby/check.list)
ocaml_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/ocaml/check.list)
octave_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/octave/check.list)
+perl5_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/perl5/check.list)
php_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/php/check.list)
-csharp_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/csharp/check.list)
-lua_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/lua/check.list)
+python_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/python/check.list)
r_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/r/check.list)
+ruby_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/ruby/check.list)
scilab_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/scilab/check.list)
-go_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list)
-d_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/d/check.list)
-javascript_examples:=$(shell sed '/^\#/d' $(srcdir)/Examples/javascript/check.list)
+tcl_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/tcl/check.list)
# all examples
check-%-examples :
@@ -218,23 +217,23 @@ check-%-examples :
# Checks testcases in the test-suite excluding those which are known to be broken
check-test-suite: \
check-errors-test-suite \
- check-tcl-test-suite \
- check-perl5-test-suite \
- check-python-test-suite \
- check-java-test-suite \
+ check-csharp-test-suite \
+ check-d-test-suite \
+ check-go-test-suite \
check-guile-test-suite \
+ check-java-test-suite \
+ check-javascript-test-suite \
+ check-lua-test-suite \
check-mzscheme-test-suite \
- check-ruby-test-suite \
check-ocaml-test-suite \
check-octave-test-suite \
+ check-perl5-test-suite \
check-php-test-suite \
- check-csharp-test-suite \
- check-lua-test-suite \
+ check-python-test-suite \
check-r-test-suite \
+ check-ruby-test-suite \
check-scilab-test-suite \
- check-go-test-suite \
- check-d-test-suite \
- check-javascript-test-suite
+ check-tcl-test-suite \
check-%-test-suite:
@if test -z "$(skip-$*)"; then \
@@ -249,7 +248,7 @@ check-%-test-suite:
echo warning: cannot $(ACTION) $* test-suite "(no dir $$dir)";\
else \
echo $(ACTION)ing $* test-suite; \
- (cd $$dir && $(MAKE) $(FLAGS) $(ACTION) HAVE_CXX11=$(HAVE_CXX11)) \
+ (cd $$dir && $(MAKE) $(FLAGS) $(ACTION)) \
|| passed=false; \
fi; \
test $$passed = true
@@ -265,46 +264,46 @@ check: check-aliveness check-ccache check-versions check-examples check-test-sui
# Run known-to-be-broken as well as not broken testcases in the test-suite
all-test-suite: \
- all-tcl-test-suite \
- all-perl5-test-suite \
- all-python-test-suite \
- all-java-test-suite \
+ all-csharp-test-suite \
+ all-d-test-suite \
+ all-go-test-suite \
all-guile-test-suite \
+ all-java-test-suite \
+ all-javascript-test-suite \
+ all-lua-test-suite \
all-mzscheme-test-suite \
- all-ruby-test-suite \
all-ocaml-test-suite \
all-octave-test-suite \
+ all-perl5-test-suite \
all-php-test-suite \
- all-csharp-test-suite \
- all-lua-test-suite \
+ all-python-test-suite \
all-r-test-suite \
+ all-ruby-test-suite \
all-scilab-test-suite \
- all-go-test-suite \
- all-d-test-suite \
- all-javascript-test-suite
+ all-tcl-test-suite \
all-%-test-suite:
@$(MAKE) $(FLAGS) check-$*-test-suite ACTION=all
# Run known-to-be-broken testcases in the test-suite
broken-test-suite: \
- broken-tcl-test-suite \
- broken-perl5-test-suite \
- broken-python-test-suite \
- broken-java-test-suite \
+ broken-csharp-test-suite \
+ broken-d-test-suite \
+ broken-go-test-suite \
broken-guile-test-suite \
+ broken-java-test-suite \
+ broken-javascript-test-suite \
+ broken-lua-test-suite \
broken-mzscheme-test-suite \
- broken-ruby-test-suite \
broken-ocaml-test-suite \
broken-octave-test-suite \
+ broken-perl5-test-suite \
broken-php-test-suite \
- broken-csharp-test-suite \
- broken-lua-test-suite \
+ broken-python-test-suite \
broken-r-test-suite \
- broken-scilab-test-suite \
- broken-go-test-suite \
- broken-d-test-suite \
- broken-javascript-test-suite
+ broken-ruby-test-suite \
+ broken-scilab-test-suite \
+ broken-tcl-test-suite \
broken-%-test-suite:
@$(MAKE) $(FLAGS) check-$*-test-suite ACTION=broken
@@ -341,7 +340,7 @@ clean-ccache:
# DISTCLEAN - clean what configure built
#####################################################################
-DISTCLEAN-DEAD = config.status config.log config.cache swig.spec Makefile mkmf.log preinst-swig
+DISTCLEAN-DEAD = config.status config.log config.cache Makefile mkmf.log preinst-swig
distclean-helper: distclean-test-suite distclean-examples distclean-tools distclean-dead
@@ -497,24 +496,11 @@ uninstall-ccache:
# DIST and other maintenance
############################################################################
-# distribution directory
-dd = @PACKAGE_NAME@-@PACKAGE_VERSION@
-srpm = @PACKAGE_NAME@-@PACKAGE_VERSION@
-
dist:
@echo "'make dist' not implemented - use Tools/mkdist.py instead - e.g.:"
@echo "Tools/mkdist.py @VERSION@ master"
@false
-srcrpm:
- rm -fr $(srpm) $(srpm).src.rpm
- echo "TODO: update to use git instead of cvs"
- cvs export -d $(srpm) -r HEAD SWIG
- cp swig.spec $(srpm)
- tar -cf - $(srpm) | gzip --best > $(srpm).tar.gz
- rm -fr $(srpm)
- rpmbuild -ts $(srpm).tar.gz
-
# Update the autoconf files for detecting host/targets. Automake will do this in
# version 1.10 for our case of not having a top level Makefile.am. Until then we
# can fetch them manually and will have to commit them to Git.
diff --git a/README b/README
index ba8ded0d5..ff28090fb 100644
--- a/README
+++ b/README
@@ -14,7 +14,7 @@ language.
Up-to-date SWIG related information can be found at
- http://www.swig.org
+ https://www.swig.org
A SWIG FAQ and other hints can be found on the SWIG Wiki:
@@ -26,7 +26,7 @@ Please see the LICENSE file for details of the SWIG license. For
further insight into the license including the license of SWIG's
output code, please visit
- http://www.swig.org/legal.html
+ https://www.swig.org/legal.html
Release Notes
=============
@@ -49,7 +49,7 @@ There is some technical developer documentation available in the
Doc/Devel subdirectory. This is not necessarily up-to-date, but it
has some information on SWIG internals.
-Documentation is also online at http://www.swig.org/doc.html.
+Documentation is also online at https://www.swig.org/doc.html.
Backwards Compatibility
=======================
@@ -70,7 +70,7 @@ full installation instructions for Windows, Unix and Mac OS X
using the release tarball/zip file. The INSTALL file has generic
build and installation instructions for Unix users.
Users wishing to build and install code from Github should
-visit http://swig.org/svn.html to obtain the more detailed
+visit https://swig.org/svn.html to obtain the more detailed
instructions required for building code obtained from Github - extra
steps are required compared to building from the release tarball.
@@ -92,7 +92,7 @@ will convert these old style project files into a current solution file.
Known Issues
============
There are minor known bugs, details of which are in the bug tracker, see
-http://www.swig.org/bugs.html.
+https://www.swig.org/bugs.html.
Troubleshooting
===============
@@ -134,7 +134,7 @@ and Windows). All contributions help.
If you would like to join the SWIG development team or contribute a
language module to the distribution, please contact the swig-devel
-mailing list, details at http://www.swig.org/mail.html.
+mailing list, details at https://www.swig.org/mail.html.
-- The SWIG Maintainers
diff --git a/RELEASENOTES b/RELEASENOTES
index da60d543f..39bc80cc4 100644
--- a/RELEASENOTES
+++ b/RELEASENOTES
@@ -5,11 +5,29 @@ and CHANGES files.
Release Notes
=============
Detailed release notes are available with the release and are also
-published on the SWIG web site at http://swig.org/release.html.
+published on the SWIG web site at https://swig.org/release.html.
SWIG-4.1.0 summary:
+- Add Javascript Node v12-v18 support, remove support prior to v6.
+- Octave 6.0 to 6.4 support added.
- Add PHP 8 support.
- PHP wrapping is now done entirely via PHP's C API - no more .php wrapper.
+- Perl 5.8.0 is now the oldest version SWIG supports.
+- Python 3.3 is now the oldest Python 3 version SWIG supports.
+- Python 3.9-3.11 support added.
+- Various memory leak fixes in Python generated code.
+- Scilab 5.5-6.1 support improved.
+- Many improvements for each and every target language.
+- Various preprocessor expression handling improvements.
+- Improved C99, C++11, C++14, C++17 support. Start adding C++20 standard.
+- Make SWIG much more move semantics friendly.
+- Add C++ std::unique_ptr support.
+- Few minor C++ template handling improvements.
+- Various C++ using declaration fixes.
+- Few fixes for handling Doxygen comments.
+- GitHub Actions is now used instead of Travis CI for continuous integration.
+- Add building SWIG using CMake as a secondary build system.
+- Update optional SWIG build dependency for regex support from PCRE to PCRE2.
SWIG-4.0.2 summary:
- A few fixes around doxygen comment handling.
@@ -125,7 +143,7 @@ SWIG-3.0.1 summary:
SWIG-3.0.0 summary:
- This is a major new release focusing primarily on C++ improvements.
- C++11 support added. Please see documentation for details of supported
- features: http://www.swig.org/Doc3.0/CPlusPlus11.html
+ features: https://www.swig.org/Doc3.0/CPlusPlus11.html
- Nested class support added. This has been taken full advantage of in
Java and C#. Other languages can use the nested classes, but require
further work for a more natural integration into the target language.
@@ -232,7 +250,7 @@ SWIG-2.0.1 summary:
and Python language modules.
SWIG-2.0.0 summary:
-- License changes, see LICENSE file and http://www.swig.org/legal.html.
+- License changes, see LICENSE file and https://www.swig.org/legal.html.
- Much better nested class/struct support.
- Much improved template partial specialization and explicit
specialization handling.
diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h
index c67ffeaba..2b63f034d 100644
--- a/Source/CParse/cparse.h
+++ b/Source/CParse/cparse.h
@@ -4,15 +4,15 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* cparse.h
*
* SWIG parser module.
* ----------------------------------------------------------------------------- */
-#ifndef SWIG_CPARSE_H_
-#define SWIG_CPARSE_H_
+#ifndef SWIG_CPARSE_H
+#define SWIG_CPARSE_H
#include "swig.h"
#include "swigwarn.h"
@@ -43,7 +43,7 @@ extern "C" {
extern void scanner_clear_rename(void);
extern void scanner_set_location(String *file, int line);
extern void scanner_set_main_input_file(String *file);
- extern String *scanner_get_main_input_file();
+ extern String *scanner_get_main_input_file(void);
extern void Swig_cparse_follow_locators(int);
extern void start_inline(char *, int);
extern String *scanner_ccode;
diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c
index 2113b9cc6..2eb3f9774 100644
--- a/Source/CParse/cscanner.c
+++ b/Source/CParse/cscanner.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* scanner.c
*
@@ -123,7 +123,7 @@ void Swig_cparse_cplusplusout(int v) {
* Initialize buffers
* ------------------------------------------------------------------------- */
-void scanner_init() {
+void scanner_init(void) {
scan = NewScanner();
Scanner_idstart(scan,"%");
scan_init = 1;
@@ -214,13 +214,13 @@ void skip_decl(void) {
tok = Scanner_token(scan);
if (tok == 0) {
if (!Swig_error_count()) {
- Swig_error(cparse_file, start_line, "Missing semicolon. Reached end of input.\n");
+ Swig_error(cparse_file, start_line, "Missing semicolon (';'). Reached end of input.\n");
}
return;
}
if (tok == SWIG_TOKEN_LBRACE) {
if (Scanner_skip_balanced(scan,'{','}') < 0) {
- Swig_error(cparse_file, start_line, "Missing '}'. Reached end of input.\n");
+ Swig_error(cparse_file, start_line, "Missing closing brace ('}'). Reached end of input.\n");
}
break;
}
@@ -267,7 +267,7 @@ static int yylook(void) {
case SWIG_TOKEN_RBRACE:
num_brace--;
if (num_brace < 0) {
- Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '}'\n");
+ Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous closing brace ('}')\n");
num_brace = 0;
} else {
return RBRACE;
@@ -331,6 +331,8 @@ static int yylook(void) {
return COLON;
case SWIG_TOKEN_DCOLONSTAR:
return DSTAR;
+ case SWIG_TOKEN_LTEQUALGT:
+ return LESSEQUALGREATER;
case SWIG_TOKEN_DCOLON:
{
@@ -351,6 +353,23 @@ static int yylook(void) {
}
break;
+ case SWIG_TOKEN_ELLIPSIS:
+ return ELLIPSIS;
+
+ case SWIG_TOKEN_LLBRACKET:
+ do {
+ tok = Scanner_token(scan);
+ } while ((tok != SWIG_TOKEN_RRBRACKET) && (tok > 0));
+ if (tok <= 0) {
+ Swig_error(cparse_file, cparse_line, "Unbalanced double brackets, missing closing (']]'). Reached end of input.\n");
+ }
+ break;
+
+ case SWIG_TOKEN_RRBRACKET:
+ /* Turn an unmatched ]] back into two ] - e.g. `a[a[0]]` */
+ scanner_next_token(RBRACKET);
+ return RBRACKET;
+
/* Look for multi-character sequences */
case SWIG_TOKEN_RSTRING:
@@ -525,11 +544,11 @@ void scanner_set_location(String *file, int line) {
Scanner_set_location(scan,file,line-1);
}
-void scanner_check_typedef() {
+void scanner_check_typedef(void) {
check_typedef = 1;
}
-void scanner_ignore_typedef() {
+void scanner_ignore_typedef(void) {
check_typedef = 0;
}
@@ -537,7 +556,7 @@ void scanner_last_id(int x) {
last_id = x;
}
-void scanner_clear_rename() {
+void scanner_clear_rename(void) {
rename_active = 0;
}
@@ -551,7 +570,7 @@ void scanner_set_main_input_file(String *file) {
main_input_file = file;
}
-String *scanner_get_main_input_file() {
+String *scanner_get_main_input_file(void) {
return main_input_file;
}
@@ -570,6 +589,9 @@ int yylex(void) {
scanner_init();
}
+ Delete(cparse_unknown_directive);
+ cparse_unknown_directive = NULL;
+
if (next_token) {
l = next_token;
next_token = 0;
@@ -948,10 +970,8 @@ int yylex(void) {
return (yylex());
} else {
- Delete(cparse_unknown_directive);
- cparse_unknown_directive = NULL;
-
/* SWIG directives */
+ String *stext = 0;
if (strcmp(yytext, "%module") == 0)
return (MODULE);
if (strcmp(yytext, "%insert") == 0)
@@ -1028,8 +1048,23 @@ int yylex(void) {
if (strcmp(yytext, "%warn") == 0)
return (WARN);
- /* Note down the apparently unknown directive for error reporting. */
+ /* Note down the apparently unknown directive for error reporting - if
+ * we end up reporting a generic syntax error we'll instead report an
+ * error for his as an unknown directive. Then we treat it as MODULO
+ * (`%`) followed by an identifier and if that parses OK then
+ * `cparse_unknown_directive` doesn't get used.
+ *
+ * This allows `a%b` to be handled in expressions without a space after
+ * the operator.
+ */
cparse_unknown_directive = NewString(yytext);
+ stext = NewString(yytext + 1);
+ Seek(stext,0,SEEK_SET);
+ Setfile(stext,cparse_file);
+ Setline(stext,cparse_line);
+ Scanner_push(scan,stext);
+ Delete(stext);
+ return (MODULO);
}
/* Have an unknown identifier, as a last step, we'll do a typedef lookup on it. */
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index c48d3a6f2..7f685e84e 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* parser.y
*
@@ -13,18 +13,27 @@
* some point. Beware.
* ----------------------------------------------------------------------------- */
-/* There are 6 known shift-reduce conflicts in this file, fail compilation if any
- more are introduced.
+/* There are a small number of known shift-reduce conflicts in this file, fail
+ compilation if any more are introduced.
Please don't increase the number of the conflicts if at all possible. And if
you really have no choice but to do it, make sure you clearly document each
new conflict in this file.
*/
-%expect 6
+%expect 7
%{
#define yylex yylex
+/* doh.h uses #pragma GCC poison with GCC to prevent direct calls to certain
+ * standard C library functions being introduced, but those cause errors due
+ * to checks like `#if defined YYMALLOC || defined malloc` in the bison
+ * template code. We can't easily arrange to include headers after that
+ * template code, so instead we disable the problematic poisoning for this
+ * file.
+ */
+#define DOH_NO_POISON_MALLOC_FREE
+
#include "swig.h"
#include "cparse.h"
#include "preprocessor.h"
@@ -32,13 +41,16 @@
/* We do this for portability */
#undef alloca
-#define alloca malloc
+#define alloca Malloc
+
+#define YYMALLOC Malloc
+#define YYFREE Free
/* -----------------------------------------------------------------------------
* Externals
* ----------------------------------------------------------------------------- */
-int yyparse();
+int yyparse(void);
/* NEW Variables */
@@ -337,7 +349,7 @@ static String *make_name(Node *n, String *name,SwigType *decl) {
}
/* Generate an unnamed identifier */
-static String *make_unnamed() {
+static String *make_unnamed(void) {
unnamed++;
return NewStringf("$unnamed%d$",unnamed);
}
@@ -862,7 +874,7 @@ static void add_typedef_name(Node *n, Node *declnode, String *oldName, Symtab *c
/* If the class name is qualified. We need to create or lookup namespace entries */
-static Symtab *set_scope_to_global() {
+static Symtab *set_scope_to_global(void) {
Symtab *symtab = Swig_symbol_global_scope();
Swig_symbol_setscope(symtab);
return symtab;
@@ -1587,6 +1599,9 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
Node *node;
};
+// Define special token END for end of input.
+%token END 0
+
%token <id> ID
%token <str> HBLOCK
%token <id> POUND
@@ -1596,7 +1611,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL
%token <intvalue> TYPEDEF
%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
-%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD
+%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD ELLIPSIS
%token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
%token BEGINFILE ENDOFFILE
%token ILLEGAL CONSTANT
@@ -1611,7 +1626,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
%token WARN
%token LESSTHAN GREATERTHAN DELETE_KW DEFAULT
-%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO
+%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO LESSEQUALGREATER
%token ARROW
%token QUESTIONMARK
%token TYPES PARMS
@@ -1633,6 +1648,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%left AND
%left EQUALTO NOTEQUALTO
%left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO
+%left LESSEQUALGREATER
%left LSHIFT RSHIFT
%left PLUS MINUS
%left STAR SLASH MODULO
@@ -1671,11 +1687,11 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%type <p> templateparameter ;
%type <id> templcpptype cpptype classkey classkeyopt access_specifier;
%type <node> base_specifier;
-%type <str> ellipsis variadic;
+%type <str> variadic;
%type <type> type rawtype type_right anon_bitfield_type decltype ;
%type <bases> base_list inherit raw_inherit;
%type <dtype> definetype def_args etype default_delete deleted_definition explicit_default;
-%type <dtype> expr exprnum exprcompound valexpr exprmem;
+%type <dtype> expr exprnum exprsimple exprcompound valexpr exprmem callparms callptail;
%type <id> ename ;
%type <id> less_valparms_greater;
%type <str> type_qualifier;
@@ -1697,9 +1713,10 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%type <ptype> type_specifier primitive_type_list ;
%type <node> fname stringtype;
%type <node> featattr;
-%type <node> lambda_introducer lambda_body;
+%type <node> lambda_introducer lambda_body lambda_template;
%type <pl> lambda_tail;
%type <str> virt_specifier_seq virt_specifier_seq_opt;
+%type <str> class_virt_specifier_opt;
%%
@@ -1779,7 +1796,7 @@ declaration : swig_directive { $$ = $1; }
} else {
Swig_error(cparse_file, cparse_line, "Syntax error in input(1).\n");
}
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
/* Out of class constructor/destructor declarations */
| c_constructor_decl {
@@ -1860,7 +1877,7 @@ extend_directive : EXTEND options classkeyopt idcolon LBRACE {
} else {
/* Previous typedef class definition. Use its symbol table.
Deprecated, just the real name should be used.
- Note that %extend before the class typedef never worked, only %extend after the class typdef. */
+ Note that %extend before the class typedef never worked, only %extend after the class typedef. */
prev_symtab = Swig_symbol_setscope(Getattr(cls, "symtab"));
current_class = cls;
SWIG_WARN_NODE_BEGIN(cls);
@@ -1936,6 +1953,9 @@ clear_directive : CLEAR tm_list SEMI {
/* ------------------------------------------------------------
%constant name = value;
%constant type name = value;
+
+ Note: Source/Preprocessor/cpp.c injects `%constant X = Y;` for
+ each `#define X Y` so that's handled here too.
------------------------------------------------------------ */
constant_directive : CONSTANT identifier EQUAL definetype SEMI {
@@ -2010,6 +2030,10 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI {
Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n");
$$ = 0;
}
+ | CONSTANT error END {
+ Swig_error(cparse_file,cparse_line,"Missing semicolon (';') after %%constant.\n");
+ Exit(EXIT_FAILURE);
+ }
;
/* ------------------------------------------------------------
@@ -2716,26 +2740,23 @@ typemap_directive : TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace {
/* typemap method type (lang,method) or (method) */
typemap_type : kwargs {
- Hash *p;
- String *name;
- p = nextSibling($1);
- if (p && (!Getattr(p,"value"))) {
- /* this is the deprecated two argument typemap form */
- Swig_warning(WARN_DEPRECATED_TYPEMAP_LANG,cparse_file, cparse_line,
- "Specifying the language name in %%typemap is deprecated - use #ifdef SWIG<LANG> instead.\n");
- /* two argument typemap form */
- name = Getattr($1,"name");
- if (!name || (Strcmp(name,typemap_lang))) {
- $$.method = 0;
- $$.kwargs = 0;
- } else {
- $$.method = Getattr(p,"name");
- $$.kwargs = nextSibling(p);
+ String *name = Getattr($1, "name");
+ Hash *p = nextSibling($1);
+ $$.method = name;
+ $$.kwargs = p;
+ if (Getattr($1, "value")) {
+ Swig_error(cparse_file, cparse_line,
+ "%%typemap method shouldn't have a value specified.\n");
+ }
+ while (p) {
+ if (!Getattr(p, "value")) {
+ Swig_error(cparse_file, cparse_line,
+ "%%typemap attribute '%s' is missing its value. If this is specifying the target language, that's no longer supported: use #ifdef SWIG<LANG> instead.\n",
+ Getattr(p, "name"));
+ /* Set to empty value to avoid segfaults later. */
+ Setattr(p, "value", NewStringEmpty());
}
- } else {
- /* one-argument typemap-form */
- $$.method = Getattr($1,"name");
- $$.kwargs = p;
+ p = nextSibling(p);
}
}
;
@@ -2963,6 +2984,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
String *nname = NewStringf("__dummy_%d__", cnt++);
Swig_cparse_template_expand(templnode,nname,temparms,tscope);
Setattr(templnode,"sym:name",nname);
+ SetFlag(templnode,"hidden");
Delete(nname);
Setattr(templnode,"feature:onlychildren", "typemap,typemapitem,typemapcopy,typedef,types,fragment,apply");
if ($3) {
@@ -3126,14 +3148,22 @@ c_declaration : c_decl {
Setattr($$,"name",$2);
appendChild($$,n);
while (n) {
- SwigType *decl = Getattr(n,"decl");
- if (SwigType_isfunction(decl) && !Equal(Getattr(n, "storage"), "typedef")) {
+ String *s = Getattr(n, "storage");
+ if (s) {
+ if (Strstr(s, "thread_local")) {
+ Insert(s,0,"externc ");
+ } else if (!Equal(s, "typedef")) {
+ Setattr(n,"storage","externc");
+ }
+ } else {
Setattr(n,"storage","externc");
}
n = nextSibling(n);
}
} else {
- Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
+ if (!Equal($2,"C++")) {
+ Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
+ }
$$ = new_node("extern");
Setattr($$,"name",$2);
appendChild($$,firstChild($5));
@@ -3355,11 +3385,11 @@ c_decl_tail : SEMI {
| error {
$$ = 0;
if (yychar == RPAREN) {
- Swig_error(cparse_file, cparse_line, "Unexpected ')'.\n");
+ Swig_error(cparse_file, cparse_line, "Unexpected closing parenthesis (')').\n");
} else {
- Swig_error(cparse_file, cparse_line, "Syntax error - possibly a missing semicolon.\n");
+ Swig_error(cparse_file, cparse_line, "Syntax error - possibly a missing semicolon (';').\n");
}
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
;
@@ -3376,6 +3406,10 @@ cpp_alternate_rettype : primitive_type { $$ = $1; }
*/
| TYPE_RAW { $$ = $1; }
| idcolon { $$ = $1; }
+ | idcolon AND {
+ $$ = $1;
+ SwigType_add_reference($$);
+ }
| decltype { $$ = $1; }
;
@@ -3387,17 +3421,17 @@ cpp_alternate_rettype : primitive_type { $$ = $1; }
auto myFunc = [](int x, int y) throw() -> int { return x+y; };
auto six = [](int x, int y) { return x+y; }(4, 2);
------------------------------------------------------------ */
-cpp_lambda_decl : storage_class AUTO idcolon EQUAL lambda_introducer LPAREN parms RPAREN cpp_const lambda_body lambda_tail {
+cpp_lambda_decl : storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const lambda_body lambda_tail {
$$ = new_node("lambda");
Setattr($$,"name",$3);
add_symbols($$);
}
- | storage_class AUTO idcolon EQUAL lambda_introducer LPAREN parms RPAREN cpp_const ARROW type lambda_body lambda_tail {
+ | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const ARROW type lambda_body lambda_tail {
$$ = new_node("lambda");
Setattr($$,"name",$3);
add_symbols($$);
}
- | storage_class AUTO idcolon EQUAL lambda_introducer lambda_body lambda_tail {
+ | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template lambda_body lambda_tail {
$$ = new_node("lambda");
Setattr($$,"name",$3);
add_symbols($$);
@@ -3410,6 +3444,13 @@ lambda_introducer : LBRACKET {
}
;
+lambda_template : LESSTHAN {
+ skip_balanced('<','>');
+ $$ = 0;
+ }
+ | empty { $$ = 0; }
+ ;
+
lambda_body : LBRACE {
skip_balanced('{','}');
$$ = 0;
@@ -3649,7 +3690,7 @@ c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
}
if (err) {
Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
;
@@ -3668,7 +3709,11 @@ cpp_declaration : cpp_class_decl { $$ = $1; }
/* A simple class/struct/union definition */
-cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
+
+/* Note that class_virt_specifier_opt for supporting final classes introduces one shift-reduce conflict
+ with C style variable declarations, such as: struct X final; */
+
+cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit LBRACE {
String *prefix;
List *bases = 0;
Node *scope = 0;
@@ -3676,10 +3721,10 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
$<node>$ = new_node("class");
Setline($<node>$,cparse_start_line);
Setattr($<node>$,"kind",$2);
- if ($4) {
- Setattr($<node>$,"baselist", Getattr($4,"public"));
- Setattr($<node>$,"protectedbaselist", Getattr($4,"protected"));
- Setattr($<node>$,"privatebaselist", Getattr($4,"private"));
+ if ($5) {
+ Setattr($<node>$,"baselist", Getattr($5,"public"));
+ Setattr($<node>$,"protectedbaselist", Getattr($5,"protected"));
+ Setattr($<node>$,"privatebaselist", Getattr($5,"private"));
}
Setattr($<node>$,"allows_typedef","1");
@@ -3707,8 +3752,8 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
Setattr($<node>$, "Classprefix", $3);
Classprefix = NewString($3);
/* Deal with inheritance */
- if ($4)
- bases = Swig_make_inherit_list($3,Getattr($4,"public"),Namespaceprefix);
+ if ($5)
+ bases = Swig_make_inherit_list($3,Getattr($5,"public"),Namespaceprefix);
prefix = SwigType_istemplate_templateprefix($3);
if (prefix) {
String *fbase, *tbase;
@@ -3788,7 +3833,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
Delattr($$, "prev_symtab");
/* Check for pure-abstract class */
- Setattr($$,"abstracts", pure_abstracts($7));
+ Setattr($$,"abstracts", pure_abstracts($8));
/* This bit of code merges in a previously defined %extend directive (if any) */
{
@@ -3804,12 +3849,12 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
scpname = Swig_symbol_qualifiedscopename(0);
Setattr(classes, scpname, $$);
- appendChild($$, $7);
+ appendChild($$, $8);
if (am)
Swig_extend_append_previous($$, am);
- p = $9;
+ p = $10;
if (p && !nscope_inner) {
if (!cparse_cplusplus && currentOuterClass)
appendChild(currentOuterClass, p);
@@ -3833,8 +3878,8 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
}
p = nextSibling(p);
}
- if ($9 && Cmp($1,"typedef") == 0)
- add_typedef_name($$, $9, $3, cscope, scpname);
+ if ($10 && Cmp($1,"typedef") == 0)
+ add_typedef_name($$, $10, $3, cscope, scpname);
Delete(scpname);
if (cplus_mode != CPLUS_PUBLIC) {
@@ -3856,12 +3901,12 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
if (cplus_mode == CPLUS_PRIVATE) {
$$ = 0; /* skip private nested classes */
} else if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) {
- $$ = nested_forward_declaration($1, $2, $3, Copy($3), $9);
+ $$ = nested_forward_declaration($1, $2, $3, Copy($3), $10);
} else if (nscope_inner) {
/* this is tricky */
/* we add the declaration in the original namespace */
if (Strcmp(nodeType(nscope_inner), "class") == 0 && cparse_cplusplus && ignore_nested_classes && !GetFlag($$, "feature:flatnested"))
- $$ = nested_forward_declaration($1, $2, $3, Copy($3), $9);
+ $$ = nested_forward_declaration($1, $2, $3, Copy($3), $10);
appendChild(nscope_inner, $$);
Swig_symbol_setscope(Getattr(nscope_inner, "symtab"));
Delete(Namespaceprefix);
@@ -3873,14 +3918,14 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
Swig_symbol_setscope(cscope);
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- add_symbols($9);
+ add_symbols($10);
if (nscope) {
$$ = nscope; /* here we return recreated namespace tower instead of the class itself */
- if ($9) {
- appendSibling($$, $9);
+ if ($10) {
+ appendSibling($$, $10);
}
} else if (!SwigType_istemplate(ty) && template_parameters == 0) { /* for template we need the class itself */
- $$ = $9;
+ $$ = $10;
}
} else {
Delete(yyrename);
@@ -3891,7 +3936,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
outer = Getattr(outer, "nested:outer");
appendSibling(outer, $$);
Swig_symbol_setscope(cscope); /* declaration goes in the parent scope */
- add_symbols($9);
+ add_symbols($10);
set_scope_to_global();
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
@@ -3904,7 +3949,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
} else {
yyrename = Copy(Getattr($<node>$, "class_rename"));
add_symbols($$);
- add_symbols($9);
+ add_symbols($10);
Delattr($$, "class_rename");
}
}
@@ -4355,18 +4400,30 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN {
parsing_template_declaration = 0;
}
- /* Explicit template instantiation */
+ /* Class template explicit instantiation definition */
| TEMPLATE cpptype idcolon {
Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
$$ = 0;
}
- /* Explicit template instantiation without the translation unit */
+ /* Function template explicit instantiation definition */
+ | TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN {
+ Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
+ $$ = 0;
+ }
+
+ /* Class template explicit instantiation declaration (extern template) */
| EXTERN TEMPLATE cpptype idcolon {
- Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
+ Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n");
$$ = 0;
}
- ;
+
+ /* Function template explicit instantiation declaration (extern template) */
+ | EXTERN TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN {
+ Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n");
+ $$ = 0;
+ }
+ ;
cpp_template_possible: c_decl {
$$ = $1;
@@ -4629,10 +4686,8 @@ cpp_members : cpp_member cpp_members {
| include_directive { $$ = $1; }
| empty { $$ = 0;}
| error {
- int start_line = cparse_line;
- skip_decl();
- Swig_error(cparse_file,start_line,"Syntax error in input(3).\n");
- SWIG_exit(EXIT_FAILURE);
+ Swig_error(cparse_file,cparse_line,"Syntax error in input(3).\n");
+ Exit(EXIT_FAILURE);
} cpp_members {
$$ = $3;
}
@@ -5062,7 +5117,13 @@ extern_string : EXTERN string {
storage_class : EXTERN { $$ = "extern"; }
| extern_string { $$ = $1; }
- | extern_string THREAD_LOCAL { $$ = "thread_local"; }
+ | extern_string THREAD_LOCAL {
+ if (Equal($1, "extern")) {
+ $$ = "extern thread_local";
+ } else {
+ $$ = "externc thread_local";
+ }
+ }
| extern_string TYPEDEF { $$ = "typedef"; }
| STATIC { $$ = "static"; }
| TYPEDEF { $$ = "typedef"; }
@@ -5143,7 +5204,7 @@ parm_no_dox : rawtype parameter_declarator {
Setattr($$,"value",$7.val);
}
}
- | PERIOD PERIOD PERIOD {
+ | ELLIPSIS {
SwigType *t = NewString("v(...)");
$$ = NewParmWithoutFileLineInfo(t, 0);
previousNode = currentNode;
@@ -5230,6 +5291,20 @@ valparm : parm {
}
;
+callparms : valexpr callptail {
+ $$ = $1;
+ Printf($$.val, "%s", $2);
+ }
+ | empty { $$.val = NewStringEmpty(); }
+ ;
+
+callptail : COMMA valexpr callptail {
+ $$.val = NewStringf(",%s%s", $2, $3);
+ $$.type = 0;
+ }
+ | empty { $$.val = NewStringEmpty(); }
+ ;
+
def_args : EQUAL definetype {
$$ = $2;
if ($2.type == T_ERROR) {
@@ -5488,16 +5563,16 @@ declarator : pointer notso_direct_declarator {
/* Variadic versions eg. MyClasses&... myIds */
- | pointer PERIOD PERIOD PERIOD notso_direct_declarator {
- $$ = $5;
+ | pointer ELLIPSIS notso_direct_declarator {
+ $$ = $3;
if ($$.type) {
SwigType_push($1,$$.type);
Delete($$.type);
}
$$.type = $1;
}
- | pointer AND PERIOD PERIOD PERIOD notso_direct_declarator {
- $$ = $6;
+ | pointer AND ELLIPSIS notso_direct_declarator {
+ $$ = $4;
SwigType_add_reference($1);
if ($$.type) {
SwigType_push($1,$$.type);
@@ -5505,8 +5580,8 @@ declarator : pointer notso_direct_declarator {
}
$$.type = $1;
}
- | pointer LAND PERIOD PERIOD PERIOD notso_direct_declarator {
- $$ = $6;
+ | pointer LAND ELLIPSIS notso_direct_declarator {
+ $$ = $4;
SwigType_add_rvalue_reference($1);
if ($$.type) {
SwigType_push($1,$$.type);
@@ -5514,34 +5589,34 @@ declarator : pointer notso_direct_declarator {
}
$$.type = $1;
}
- | PERIOD PERIOD PERIOD direct_declarator {
- $$ = $4;
+ | ELLIPSIS direct_declarator {
+ $$ = $2;
if (!$$.type) $$.type = NewStringEmpty();
}
- | AND PERIOD PERIOD PERIOD notso_direct_declarator {
- $$ = $5;
+ | AND ELLIPSIS notso_direct_declarator {
+ $$ = $3;
$$.type = NewStringEmpty();
SwigType_add_reference($$.type);
- if ($5.type) {
- SwigType_push($$.type,$5.type);
- Delete($5.type);
+ if ($3.type) {
+ SwigType_push($$.type,$3.type);
+ Delete($3.type);
}
}
- | LAND PERIOD PERIOD PERIOD notso_direct_declarator {
+ | LAND ELLIPSIS notso_direct_declarator {
/* Introduced in C++11, move operator && */
/* Adds one S/R conflict */
- $$ = $5;
+ $$ = $3;
$$.type = NewStringEmpty();
SwigType_add_rvalue_reference($$.type);
- if ($5.type) {
- SwigType_push($$.type,$5.type);
- Delete($5.type);
+ if ($3.type) {
+ SwigType_push($$.type,$3.type);
+ Delete($3.type);
}
}
- | idcolon DSTAR PERIOD PERIOD PERIOD notso_direct_declarator {
+ | idcolon DSTAR ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty();
- $$ = $6;
+ $$ = $4;
SwigType_add_memberpointer(t,$1);
if ($$.type) {
SwigType_push(t,$$.type);
@@ -5549,9 +5624,9 @@ declarator : pointer notso_direct_declarator {
}
$$.type = t;
}
- | pointer idcolon DSTAR PERIOD PERIOD PERIOD notso_direct_declarator {
+ | pointer idcolon DSTAR ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty();
- $$ = $7;
+ $$ = $5;
SwigType_add_memberpointer(t,$2);
SwigType_push($1,t);
if ($$.type) {
@@ -5561,8 +5636,8 @@ declarator : pointer notso_direct_declarator {
$$.type = $1;
Delete(t);
}
- | pointer idcolon DSTAR AND PERIOD PERIOD PERIOD notso_direct_declarator {
- $$ = $8;
+ | pointer idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
+ $$ = $6;
SwigType_add_memberpointer($1,$2);
SwigType_add_reference($1);
if ($$.type) {
@@ -5571,8 +5646,8 @@ declarator : pointer notso_direct_declarator {
}
$$.type = $1;
}
- | pointer idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator {
- $$ = $8;
+ | pointer idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
+ $$ = $6;
SwigType_add_memberpointer($1,$2);
SwigType_add_rvalue_reference($1);
if ($$.type) {
@@ -5581,9 +5656,9 @@ declarator : pointer notso_direct_declarator {
}
$$.type = $1;
}
- | idcolon DSTAR AND PERIOD PERIOD PERIOD notso_direct_declarator {
+ | idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty();
- $$ = $7;
+ $$ = $5;
SwigType_add_memberpointer(t,$1);
SwigType_add_reference(t);
if ($$.type) {
@@ -5592,9 +5667,9 @@ declarator : pointer notso_direct_declarator {
}
$$.type = t;
}
- | idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator {
+ | idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty();
- $$ = $7;
+ $$ = $5;
SwigType_add_memberpointer(t,$1);
SwigType_add_rvalue_reference(t);
if ($$.type) {
@@ -6505,23 +6580,38 @@ exprmem : ID ARROW ID {
$$.val = NewStringf("%s->%s", $1, $3);
$$.type = 0;
}
+ | ID ARROW ID LPAREN callparms RPAREN {
+ $$.val = NewStringf("%s->%s(%s)", $1, $3, $5);
+ $$.type = 0;
+ }
| exprmem ARROW ID {
$$ = $1;
Printf($$.val, "->%s", $3);
}
-/* This generates a shift-reduce
+ | exprmem ARROW ID LPAREN callparms RPAREN {
+ $$ = $1;
+ Printf($$.val, "->%s(%s)", $3, $5);
+ }
| ID PERIOD ID {
$$.val = NewStringf("%s.%s", $1, $3);
$$.type = 0;
}
-*/
+ | ID PERIOD ID LPAREN callparms RPAREN {
+ $$.val = NewStringf("%s.%s(%s)", $1, $3, $5);
+ $$.type = 0;
+ }
| exprmem PERIOD ID {
$$ = $1;
Printf($$.val, ".%s", $3);
}
+ | exprmem PERIOD ID LPAREN callparms RPAREN {
+ $$ = $1;
+ Printf($$.val, ".%s(%s)", $3, $5);
+ }
;
-valexpr : exprnum {
+/* Non-compound expression */
+exprsimple : exprnum {
$$ = $1;
}
| exprmem {
@@ -6536,12 +6626,30 @@ valexpr : exprnum {
$$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
$$.type = T_ULONG;
}
- | SIZEOF PERIOD PERIOD PERIOD LPAREN type parameter_declarator RPAREN {
- SwigType_push($6,$7.type);
- $$.val = NewStringf("sizeof...(%s)",SwigType_str($6,0));
+ | SIZEOF ELLIPSIS LPAREN type parameter_declarator RPAREN {
+ SwigType_push($4,$5.type);
+ $$.val = NewStringf("sizeof...(%s)",SwigType_str($4,0));
$$.type = T_ULONG;
}
- | exprcompound { $$ = $1; }
+ /* We don't support all valid expressions here currently - e.g.
+ * sizeof(<unaryop> x) doesn't work - but those are unlikely to
+ * be seen in real code.
+ *
+ * Note: sizeof(x) is not handled here, but instead by the rule
+ * for sizeof(<type>) because it matches that syntactically.
+ */
+ | SIZEOF LPAREN exprsimple RPAREN {
+ $$.val = NewStringf("sizeof(%s)", $3.val);
+ $$.type = T_ULONG;
+ }
+ /* `sizeof expr` without parentheses is valid for an expression,
+ * but not for a type. This doesn't support `sizeof x` in
+ * addition to the case not supported above.
+ */
+ | SIZEOF exprsimple {
+ $$.val = NewStringf("sizeof(%s)", $2.val);
+ $$.type = T_ULONG;
+ }
| wstring {
$$.val = $1;
$$.rawval = NewStringf("L\"%s\"", $$.val);
@@ -6576,6 +6684,11 @@ valexpr : exprnum {
$$.final = 0;
}
+ ;
+
+valexpr : exprsimple { $$ = $1; }
+ | exprcompound { $$ = $1; }
+
/* grouping */
| LPAREN expr RPAREN %prec CAST {
$$.val = NewStringf("(%s)",$2.val);
@@ -6646,15 +6759,11 @@ valexpr : exprnum {
$$ = $2;
$$.val = NewStringf("&%s",$2.val);
}
- | LAND expr {
- $$ = $2;
- $$.val = NewStringf("&&%s",$2.val);
- }
| STAR expr {
$$ = $2;
$$.val = NewStringf("*%s",$2.val);
}
- ;
+ ;
exprnum : NUM_INT { $$ = $1; }
| NUM_FLOAT { $$ = $1; }
@@ -6722,16 +6831,24 @@ exprcompound : expr PLUS expr {
$$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
-/* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these.
- | expr GREATERTHAN expr {
- $$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
+ /* Trying to parse `>` in the general case results in conflicts
+ * in the parser, but all user-reported cases are actually inside
+ * parentheses and we can handle that case.
+ */
+ | LPAREN expr GREATERTHAN expr RPAREN {
+ $$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
- | expr LESSTHAN expr {
- $$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
+
+ /* Similarly for `<` except trying to handle exprcompound on the
+ * left side gives a shift/reduce conflict, so also restrict
+ * handling to non-compound subexpressions there. Again this
+ * covers all user-reported cases.
+ */
+ | LPAREN exprsimple LESSTHAN expr RPAREN {
+ $$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
-*/
| expr GREATERTHANOREQUALTO expr {
$$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
@@ -6740,6 +6857,15 @@ exprcompound : expr PLUS expr {
$$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
+ | expr LESSEQUALGREATER expr {
+ $$.val = NewStringf("%s <=> %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
+ /* Really `<=>` returns one of `std::strong_ordering`,
+ * `std::partial_ordering` or `std::weak_ordering`, but we
+ * fake it by treating the return value as `int`. The main
+ * thing to do with the return value in this context is to
+ * compare it with 0, for which `int` does the job. */
+ $$.type = T_INT;
+ }
| expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
$$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5));
/* This may not be exactly right, but is probably good enough
@@ -6778,14 +6904,9 @@ exprcompound : expr PLUS expr {
}
;
-ellipsis : PERIOD PERIOD PERIOD {
+variadic : ELLIPSIS {
$$ = NewString("...");
}
- ;
-
-variadic : ellipsis {
- $$ = $1;
- }
| empty {
$$ = 0;
}
@@ -6875,11 +6996,11 @@ templcpptype : CLASS {
$$ = (char *)"typename";
if (!inherit_list) last_cpptype = $$;
}
- | CLASS PERIOD PERIOD PERIOD {
+ | CLASS ELLIPSIS {
$$ = (char *)"class...";
if (!inherit_list) last_cpptype = $$;
}
- | TYPENAME PERIOD PERIOD PERIOD {
+ | TYPENAME ELLIPSIS {
$$ = (char *)"typename...";
if (!inherit_list) last_cpptype = $$;
}
@@ -6946,6 +7067,14 @@ virt_specifier_seq_opt : virt_specifier_seq {
}
;
+class_virt_specifier_opt : FINAL {
+ $$ = NewString("1");
+ }
+ | empty {
+ $$ = 0;
+ }
+ ;
+
exception_specification : THROW LPAREN parms RPAREN {
$$.throws = $3;
$$.throwf = NewString("1");
@@ -7085,8 +7214,8 @@ ctor_initializer : COLON mem_initializer_list
mem_initializer_list : mem_initializer
| mem_initializer_list COMMA mem_initializer
- | mem_initializer PERIOD PERIOD PERIOD
- | mem_initializer_list COMMA mem_initializer PERIOD PERIOD PERIOD
+ | mem_initializer ELLIPSIS
+ | mem_initializer_list COMMA mem_initializer ELLIPSIS
;
mem_initializer : idcolon LPAREN {
diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c
index 2f38cc2c2..0dec21586 100644
--- a/Source/CParse/templ.c
+++ b/Source/CParse/templ.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* templ.c
*
@@ -19,7 +19,7 @@ static int template_debug = 0;
const char *baselists[3];
-void SwigType_template_init() {
+void SwigType_template_init(void) {
baselists[0] = "baselist";
baselists[1] = "protectedbaselist";
baselists[2] = "privatebaselist";
@@ -234,6 +234,94 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri
}
}
+/* -----------------------------------------------------------------------------
+ * cparse_fix_function_decl()
+ *
+ * Move the prefix of the "type" attribute (excluding any trailing qualifier)
+ * to the end of the "decl" attribute.
+ * Examples:
+ * decl="f().", type="p.q(const).char" => decl="f().p.", type="q(const).char"
+ * decl="f().p.", type="p.SomeClass" => decl="f().p.p.", type="SomeClass"
+ * decl="f().", type="r.q(const).p.int" => decl="f().r.q(const).p.", type="int"
+ * ----------------------------------------------------------------------------- */
+
+static void cparse_fix_function_decl(String *name, SwigType *decl, SwigType *type) {
+ String *prefix;
+ int prefixLen;
+ SwigType *last;
+
+ /* The type's prefix is what potentially has to be moved to the end of 'decl' */
+ prefix = SwigType_prefix(type);
+
+ /* First some parts (qualifier and array) have to be removed from prefix
+ in order to remain in the 'type' attribute. */
+ last = SwigType_last(prefix);
+ while (last) {
+ if (SwigType_isqualifier(last) || SwigType_isarray(last)) {
+ /* Keep this part in the 'type' */
+ Delslice(prefix, Len(prefix) - Len(last), DOH_END);
+ Delete(last);
+ last = SwigType_last(prefix);
+ } else {
+ /* Done with processing prefix */
+ Delete(last);
+ last = 0;
+ }
+ }
+
+ /* Transfer prefix from the 'type' to the 'decl' attribute */
+ prefixLen = Len(prefix);
+ if (prefixLen > 0) {
+ Append(decl, prefix);
+ Delslice(type, 0, prefixLen);
+ if (template_debug) {
+ Printf(stdout, " change function '%s' to type='%s', decl='%s'\n", name, type, decl);
+ }
+ }
+
+ Delete(prefix);
+}
+
+/* -----------------------------------------------------------------------------
+ * cparse_postprocess_expanded_template()
+ *
+ * This function postprocesses the given node after template expansion.
+ * Currently the only task to perform is fixing function decl and type attributes.
+ * ----------------------------------------------------------------------------- */
+
+static void cparse_postprocess_expanded_template(Node *n) {
+ String *nodeType;
+ if (!n)
+ return;
+ nodeType = nodeType(n);
+ if (Getattr(n, "error"))
+ return;
+
+ if (Equal(nodeType, "cdecl")) {
+ /* A simple C declaration */
+ SwigType *d = Getattr(n, "decl");
+ if (d && SwigType_isfunction(d)) {
+ /* A function node */
+ SwigType *t = Getattr(n, "type");
+ if (t) {
+ String *name = Getattr(n, "name");
+ cparse_fix_function_decl(name, d, t);
+ }
+ }
+ } else {
+ /* Look for any children */
+ Node *cn = firstChild(n);
+ while (cn) {
+ cparse_postprocess_expanded_template(cn);
+ cn = nextSibling(cn);
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * partial_arg()
+ * ----------------------------------------------------------------------------- */
+
static
String *partial_arg(String *s, String *p) {
char *c;
@@ -249,7 +337,7 @@ String *partial_arg(String *s, String *p) {
}
prefix = NewStringWithSize(cp, (int)(c - cp));
newarg = Copy(s);
- Replace(newarg, prefix, "", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
+ Replace(newarg, prefix, "", DOH_REPLACE_FIRST);
Delete(prefix);
return newarg;
}
@@ -335,6 +423,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
if (tp) {
Symtab *tsdecl = Getattr(n, "sym:symtab");
+ String *tsname = Getattr(n, "sym:name");
while (p && tp) {
String *name, *value, *valuestr, *tmp, *tmpr;
int sz, i;
@@ -376,11 +465,18 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
sz = Len(typelist);
for (i = 0; i < sz; i++) {
String *s = Getitem(typelist, i);
- /* Replace(s,name,value, DOH_REPLACE_ID); */
- /* Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, dvalue, tbase, iname, s); */
- SwigType_typename_replace(s, name, dvalue);
- SwigType_typename_replace(s, tbase, iname);
- /* Printf(stdout,"'%s'\n", s); */
+ /*
+ The approach of 'trivially' replacing template arguments is kind of fragile.
+ In particular if types with similar name in different namespaces appear.
+ We will not replace template args if a type/class exists with the same
+ name which is not a template.
+ */
+ Node * tynode = Swig_symbol_clookup(s, 0);
+ String *tyname = tynode ? Getattr(tynode, "sym:name") : 0;
+ if (!tyname || !tsname || !Equal(tyname, tsname) || Getattr(tynode, "templatetype")) {
+ SwigType_typename_replace(s, name, dvalue);
+ SwigType_typename_replace(s, tbase, iname);
+ }
}
tmp = NewStringf("#%s", name);
@@ -413,6 +509,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
}
}
}
+ cparse_postprocess_expanded_template(n);
/* Patch bases */
{
@@ -620,7 +717,7 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
int parms_len = ParmList_len(parms);
int *priorities_row;
max_possible_partials = Len(partials);
- priorities_matrix = (int *)malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */
+ priorities_matrix = (int *)Malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */
priorities_row = priorities_matrix;
for (pi = First(partials); pi.item; pi = Next(pi)) {
Parm *p = parms;
@@ -818,7 +915,7 @@ success:
Printf(stdout, " chosen template:'%s'\n", Getattr(n, "name"));
}
Delete(parms);
- free(priorities_matrix);
+ Free(priorities_matrix);
return n;
}
diff --git a/Source/CParse/util.c b/Source/CParse/util.c
index 714bb2972..00863c035 100644
--- a/Source/CParse/util.c
+++ b/Source/CParse/util.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* util.c
*
diff --git a/Source/DOH/base.c b/Source/DOH/base.c
index f5e418893..8731a5f11 100644
--- a/Source/DOH/base.c
+++ b/Source/DOH/base.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* base.c
*
@@ -18,10 +18,6 @@
* DohDelete()
* ----------------------------------------------------------------------------- */
-#ifndef SWIG_DEBUG_DELETE
-#define SWIG_DEBUG_DELETE 0
-#endif
-
void DohDelete(DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
@@ -29,13 +25,8 @@ void DohDelete(DOH *obj) {
if (!obj)
return;
if (!DohCheck(b)) {
-#if SWIG_DEBUG_DELETE
- fputs("DOH: Fatal error. Attempt to delete a non-doh object.\n", stderr);
- abort();
-#else
- assert(0);
-#endif
- return;
+ fputs("Fatal internal error: Attempt to delete a non-DOH object.\n", stderr);
+ Exit(EXIT_FAILURE);
}
if (b->flag_intern)
return;
@@ -64,13 +55,8 @@ DOH *DohCopy(const DOH *obj) {
if (!obj)
return 0;
if (!DohCheck(b)) {
-#if SWIG_DEBUG_DELETE
- fputs("DOH: Fatal error. Attempt to copy a non-doh object.\n", stderr);
- abort();
-#else
- assert(0);
-#endif
- return 0;
+ fputs("Fatal internal error: Attempt to copy a non-DOH object.\n", stderr);
+ Exit(EXIT_FAILURE);
}
objinfo = b->type;
if (objinfo->doh_copy) {
@@ -389,6 +375,18 @@ DOH *DohKeys(DOH *obj) {
}
/* -----------------------------------------------------------------------------
+ * DohSortedKeys()
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *)) {
+ DOHList *keys = DohKeys(obj);
+ if (keys) {
+ DohSortList(keys, cmp);
+ }
+ return keys;
+}
+
+/* -----------------------------------------------------------------------------
* DohGetInt()
* ----------------------------------------------------------------------------- */
diff --git a/Source/DOH/doh.h b/Source/DOH/doh.h
index fd0530e9c..45a1f7fc8 100644
--- a/Source/DOH/doh.h
+++ b/Source/DOH/doh.h
@@ -4,22 +4,21 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* doh.h
*
* This file describes of the externally visible functions in DOH.
* ----------------------------------------------------------------------------- */
-#ifndef _DOH_H
-#define _DOH_H
+#ifndef SWIG_DOH_H
+#define SWIG_DOH_H
-#ifndef MACSWIG
#include "swigconfig.h"
-#endif
-#include <stdio.h>
#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
/* Set the namespace prefix for DOH API functions. This can be used to control
visibility of the functions in libraries */
@@ -53,6 +52,7 @@
#define DohSetattr DOH_NAMESPACE(Setattr)
#define DohDelattr DOH_NAMESPACE(Delattr)
#define DohKeys DOH_NAMESPACE(Keys)
+#define DohSortedKeys DOH_NAMESPACE(SortedKeys)
#define DohGetInt DOH_NAMESPACE(GetInt)
#define DohGetDouble DOH_NAMESPACE(GetDouble)
#define DohGetChar DOH_NAMESPACE(GetChar)
@@ -122,6 +122,12 @@
#define DohIterator DOH_NAMESPACE(Iterator)
#define DohFirst DOH_NAMESPACE(First)
#define DohNext DOH_NAMESPACE(Next)
+#define DohMalloc DOH_NAMESPACE(Malloc)
+#define DohRealloc DOH_NAMESPACE(Realloc)
+#define DohCalloc DOH_NAMESPACE(Calloc)
+#define DohFree DOH_NAMESPACE(Free)
+#define DohSetExitHandler DOH_NAMESPACE(SetExitHandler)
+#define DohExit DOH_NAMESPACE(Exit)
#endif
#define DOH_MAJOR_VERSION 0
@@ -163,12 +169,11 @@ typedef struct {
/* Memory management */
-#ifndef DohMalloc
-#define DohMalloc malloc
-#endif
-#ifndef DohRealloc
-#define DohRealloc realloc
-#endif
+/* Wrappers around malloc(), realloc() and calloc() which never return NULL. */
+extern void *DohMalloc(size_t size);
+extern void *DohRealloc(void *ptr, size_t size);
+extern void *DohCalloc(size_t n, size_t size);
+
#ifndef DohFree
#define DohFree free
#endif
@@ -197,6 +202,7 @@ extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_c
extern int DohDelattr(DOH *obj, const DOHString_or_char *name);
extern int DohCheckattr(DOH *obj, const DOHString_or_char *name, const DOHString_or_char *value);
extern DOH *DohKeys(DOH *obj);
+extern DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *));
extern int DohGetInt(DOH *obj, const DOHString_or_char *name);
extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int);
extern double DohGetDouble(DOH *obj, const DOHString_or_char *name);
@@ -271,6 +277,24 @@ extern int DohGetMaxHashExpand(void);
extern void DohSetmark(DOH *obj, int x);
extern int DohGetmark(DOH *obj);
+/* Set the function for DohExit() to call instead of exit().
+ *
+ * The registered function can perform clean up, etc. It should simply
+ * return when done and then exit() will get called. Bear in mind that
+ * the handler function can be called after malloc() has failed, so it's
+ * a good idea for it to avoid allocating additional memory.
+ *
+ * The registered handler function is unregistered by DohExit() before calling
+ * it to avoid the potential for infinite loops.
+ *
+ * Note: This is sort of like C's atexit(), only for DohExit(). However
+ * only one function can be registered (setting a new function overrides the
+ * previous one) and the registered function is passed the exit status so can
+ * vary its actions based on that.
+ */
+extern void DohSetExitHandler(void (*new_handler)(int));
+extern void DohExit(int status);
+
/* -----------------------------------------------------------------------------
* Strings.
* ----------------------------------------------------------------------------- */
@@ -364,7 +388,7 @@ extern void DohMemoryDebug(void);
#define Push(s,x) DohInsertitem(s,DOH_BEGIN,x)
#define Len DohLen
#define Data DohData
-#define Char (char *) Data
+#define Char(X) ((char *) Data(X))
#define Cmp DohCmp
#define Equal DohEqual
#define Setline DohSetline
@@ -422,6 +446,7 @@ extern void DohMemoryDebug(void);
#define FileErrorDisplay DohFileErrorDisplay
#define NewVoid DohNewVoid
#define Keys DohKeys
+#define SortedKeys DohSortedKeys
#define Strcmp DohStrcmp
#define Strncmp DohStrncmp
#define Strstr DohStrstr
@@ -440,6 +465,12 @@ extern void DohMemoryDebug(void);
#define Next DohNext
#define Iterator DohIterator
#define SortList DohSortList
+#define Malloc DohMalloc
+#define Realloc DohRealloc
+#define Calloc DohCalloc
+#define Free DohFree
+#define SetExitHandler DohSetExitHandler
+#define Exit DohExit
#endif
#ifdef NIL
@@ -448,5 +479,29 @@ extern void DohMemoryDebug(void);
#define NIL (char *) NULL
+/* Defines to allow use of poisoned identifiers.
+ *
+ * For DOH-internal use only!
+ */
+#define doh_internal_calloc calloc
+#define doh_internal_exit exit
+/* doh_internal_free not needed as Free() is a macro defined above. */
+#define doh_internal_malloc malloc
+#define doh_internal_realloc realloc
+
+#if defined __GNUC__ && defined DOH_POISON
+/* Use Malloc(), Realloc(), Calloc(), and Free() instead (which will exit with
+ * an error rather than return NULL).
+ */
+# ifndef DOH_NO_POISON_MALLOC_FREE
+/* This works around bison's template checking if malloc and free are defined,
+ * which triggers GCC's poison checks.
+ */
+# pragma GCC poison malloc free
+# endif
+# pragma GCC poison realloc calloc
+/* Use Exit() instead (which will remove output files on error). */
+# pragma GCC poison abort exit
+#endif
-#endif /* DOH_H */
+#endif /* SWIG_DOH_H */
diff --git a/Source/DOH/dohint.h b/Source/DOH/dohint.h
index 87def9d3d..b637debd2 100644
--- a/Source/DOH/dohint.h
+++ b/Source/DOH/dohint.h
@@ -4,15 +4,15 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* dohint.h
*
* This file describes internally managed objects.
* ----------------------------------------------------------------------------- */
-#ifndef _DOHINT_H
-#define _DOHINT_H
+#ifndef SWIG_DOHINT_H
+#define SWIG_DOHINT_H
#include "doh.h"
@@ -128,4 +128,4 @@ typedef struct {
extern DOH *DohObjMalloc(DohObjInfo *type, void *data); /* Allocate a DOH object */
extern void DohObjFree(DOH *ptr); /* Free a DOH object */
-#endif /* DOHINT_H */
+#endif /* SWIG_DOHINT_H */
diff --git a/Source/DOH/file.c b/Source/DOH/file.c
index 96f700223..4bcf5d5e1 100644
--- a/Source/DOH/file.c
+++ b/Source/DOH/file.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* file.c
*
@@ -35,7 +35,7 @@ typedef struct {
* reference count of the underlying DOH objects.
* ----------------------------------------------------------------------------- */
-static DOHList *open_files_list_instance() {
+static DOHList *open_files_list_instance(void) {
static DOHList *all_open_files = 0;
if (!all_open_files)
all_open_files = DohNewList();
@@ -73,7 +73,7 @@ static void open_files_list_remove(DohFile *f) {
* Close all opened files, to be called on program termination
* ----------------------------------------------------------------------------- */
-void DohCloseAllOpenFiles() {
+void DohCloseAllOpenFiles(void) {
int i;
DOHList *all_open_files = open_files_list_instance();
for (i = 0; i < DohLen(all_open_files); i++) {
@@ -291,10 +291,6 @@ DOH *DohNewFile(DOHString *filename, const char *mode, DOHList *newfiles) {
return 0;
f = (DohFile *) DohMalloc(sizeof(DohFile));
- if (!f) {
- fclose(file);
- return 0;
- }
if (newfiles)
Append(newfiles, filename);
f->filep = file;
@@ -314,8 +310,6 @@ DOH *DohNewFile(DOHString *filename, const char *mode, DOHList *newfiles) {
DOH *DohNewFileFromFile(FILE *file) {
DohFile *f;
f = (DohFile *) DohMalloc(sizeof(DohFile));
- if (!f)
- return 0;
f->filep = file;
f->fd = 0;
f->closeondel = 0;
@@ -331,8 +325,6 @@ DOH *DohNewFileFromFile(FILE *file) {
DOH *DohNewFileFromFd(int fd) {
DohFile *f;
f = (DohFile *) DohMalloc(sizeof(DohFile));
- if (!f)
- return 0;
f->filep = 0;
f->fd = fd;
f->closeondel = 0;
diff --git a/Source/DOH/fio.c b/Source/DOH/fio.c
index 77419008c..972fb23df 100644
--- a/Source/DOH/fio.c
+++ b/Source/DOH/fio.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* fio.c
*
diff --git a/Source/DOH/hash.c b/Source/DOH/hash.c
index c2bc3dd95..b9d501e3c 100644
--- a/Source/DOH/hash.c
+++ b/Source/DOH/hash.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* hash.c
*
@@ -173,10 +173,7 @@ static void resize(Hash *h) {
p = p + 2;
}
- table = (HashNode **) DohMalloc(newsize * sizeof(HashNode *));
- for (i = 0; i < newsize; i++) {
- table[i] = 0;
- }
+ table = (HashNode **) DohCalloc(newsize, sizeof(HashNode *));
/* Walk down the old set of nodes and re-place */
h->hashsize = newsize;
diff --git a/Source/DOH/list.c b/Source/DOH/list.c
index 8a96a9a60..cc619022d 100644
--- a/Source/DOH/list.c
+++ b/Source/DOH/list.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* list.c
*
@@ -27,7 +27,6 @@ extern DohObjInfo DohListType;
static
void more(List *l) {
l->items = (void **) DohRealloc(l->items, l->maxitems * 2 * sizeof(void *));
- assert(l->items);
l->maxitems *= 2;
}
@@ -346,15 +345,10 @@ DohObjInfo DohListType = {
#define MAXLISTITEMS 8
DOH *DohNewList(void) {
- List *l;
- int i;
- l = (List *) DohMalloc(sizeof(List));
+ List *l = (List *) DohMalloc(sizeof(List));
l->nitems = 0;
l->maxitems = MAXLISTITEMS;
- l->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
- for (i = 0; i < MAXLISTITEMS; i++) {
- l->items[i] = 0;
- }
+ l->items = (void **) DohCalloc(l->maxitems, sizeof(void *));
l->file = 0;
l->line = 0;
return DohObjMalloc(&DohListType, l);
diff --git a/Source/DOH/memory.c b/Source/DOH/memory.c
index 4a9494e85..f8081d3ae 100644
--- a/Source/DOH/memory.c
+++ b/Source/DOH/memory.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* memory.c
*
@@ -14,6 +14,9 @@
#include "dohint.h"
+#include <stdio.h>
+#include <stdlib.h>
+
#ifndef DOH_POOL_SIZE
#define DOH_POOL_SIZE 4194304
#endif
@@ -45,13 +48,10 @@ static int pools_initialized = 0;
* CreatePool() - Create a new memory pool
* ---------------------------------------------------------------------- */
-static void CreatePool() {
+static void CreatePool(void) {
Pool *p = 0;
p = (Pool *) DohMalloc(sizeof(Pool));
- assert(p);
- p->ptr = (DohBase *) DohMalloc(sizeof(DohBase) * PoolSize);
- assert(p->ptr);
- memset(p->ptr, 0, sizeof(DohBase) * PoolSize);
+ p->ptr = (DohBase *) DohCalloc(PoolSize, sizeof(DohBase));
p->len = PoolSize;
p->blen = PoolSize * sizeof(DohBase);
p->current = 0;
@@ -65,7 +65,7 @@ static void CreatePool() {
* InitPools() - Initialize the memory allocator
* ---------------------------------------------------------------------- */
-static void InitPools() {
+static void InitPools(void) {
if (pools_initialized)
return;
CreatePool(); /* Create initial pool */
@@ -234,3 +234,59 @@ void DohMemoryDebug(void) {
#endif
}
+
+/* Function to call instead of exit(). */
+static void (*doh_exit_handler)(int) = NULL;
+
+void DohSetExitHandler(void (*new_handler)(int)) {
+ doh_exit_handler = new_handler;
+}
+
+void DohExit(int status) {
+ if (doh_exit_handler) {
+ void (*handler)(int) = doh_exit_handler;
+ /* Unset the handler to avoid infinite loops if it tries to do something
+ * which calls DohExit() (e.g. calling Malloc() and that failing).
+ */
+ doh_exit_handler = NULL;
+ handler(status);
+ }
+ doh_internal_exit(status);
+}
+
+static void allocation_failed(size_t n, size_t size) {
+ /* Report and exit as directly as possible to try to avoid further issues due
+ * to lack of memory. */
+ if (n == 1) {
+#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L
+ fprintf(stderr, "Failed to allocate %zu bytes\n", size);
+#else
+ fprintf(stderr, "Failed to allocate %lu bytes\n", (unsigned long)size);
+#endif
+ } else {
+#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L
+ fprintf(stderr, "Failed to allocate %zu*%zu bytes\n", n, size);
+#else
+ fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size);
+#endif
+ }
+ DohExit(EXIT_FAILURE);
+}
+
+void *DohMalloc(size_t size) {
+ void *p = doh_internal_malloc(size);
+ if (!p) allocation_failed(1, size);
+ return p;
+}
+
+void *DohRealloc(void *ptr, size_t size) {
+ void *p = doh_internal_realloc(ptr, size);
+ if (!p) allocation_failed(1, size);
+ return p;
+}
+
+void *DohCalloc(size_t n, size_t size) {
+ void *p = doh_internal_calloc(n, size);
+ if (!p) allocation_failed(n, size);
+ return p;
+}
diff --git a/Source/DOH/string.c b/Source/DOH/string.c
index 093330b89..c86cab0be 100644
--- a/Source/DOH/string.c
+++ b/Source/DOH/string.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* string.c
*
@@ -180,19 +180,27 @@ static int String_hash(DOH *so) {
if (s->hashkey >= 0) {
return s->hashkey;
} else {
- char *c = s->str;
+ /* We use the djb2 hash function: https://theartincode.stanis.me/008-djb2/
+ *
+ * One difference is we use initial seed 0. It seems the usual seed value
+ * is intended to help spread out hash values, which is beneficial if
+ * linear probing is used but DOH Hash uses a chain of buckets instead, and
+ * grouped hash values are probably more cache friendly. In tests using
+ * 0 seems slightly faster anyway.
+ */
+ const char *c = s->str;
unsigned int len = s->len > 50 ? 50 : s->len;
unsigned int h = 0;
unsigned int mlen = len >> 2;
unsigned int i = mlen;
for (; i; --i) {
- h = (h << 5) + *(c++);
- h = (h << 5) + *(c++);
- h = (h << 5) + *(c++);
- h = (h << 5) + *(c++);
+ h = h + (h << 5) + *(c++);
+ h = h + (h << 5) + *(c++);
+ h = h + (h << 5) + *(c++);
+ h = h + (h << 5) + *(c++);
}
for (i = len - (mlen << 2); i; --i) {
- h = (h << 5) + *(c++);
+ h = h + (h << 5) + *(c++);
}
h &= 0x7fffffff;
s->hashkey = (int)h;
@@ -229,7 +237,6 @@ static void DohString_append(DOH *so, const DOHString_or_char *str) {
if (newlen >= newmaxsize - 1)
newmaxsize = newlen + 1;
s->str = (char *) DohRealloc(s->str, newmaxsize);
- assert(s->str);
s->maxsize = newmaxsize;
}
tc = s->str;
@@ -296,7 +303,6 @@ static int String_insert(DOH *so, int pos, DOH *str) {
while (s->maxsize <= s->len + len) {
int newsize = 2 * s->maxsize;
s->str = (char *) DohRealloc(s->str, newsize);
- assert(s->str);
s->maxsize = newsize;
}
memmove(s->str + pos + len, s->str + pos, (s->len - pos));
@@ -424,7 +430,6 @@ static int String_write(DOH *so, const void *buffer, int len) {
newlen = s->sp + len + 1;
if (newlen > s->maxsize) {
s->str = (char *) DohRealloc(s->str, newlen);
- assert(s->str);
s->maxsize = newlen;
s->len = s->sp + len;
}
@@ -517,7 +522,6 @@ static int String_putc(DOH *so, int ch) {
if (len > (maxsize - 2)) {
maxsize *= 2;
tc = (char *) DohRealloc(tc, maxsize);
- assert(tc);
s->maxsize = (int) maxsize;
s->str = tc;
}
@@ -614,11 +618,13 @@ static char *match_identifier(char *base, char *s, char *token, int tokenlen) {
if (!s)
return 0;
if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
- s += tokenlen;
+ /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+ ++s;
continue;
}
if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
- s += tokenlen;
+ /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+ ++s;
continue;
}
return s;
@@ -628,12 +634,14 @@ static char *match_identifier(char *base, char *s, char *token, int tokenlen) {
static char *match_identifier_begin(char *base, char *s, char *token, int tokenlen) {
+ (void)tokenlen;
while (s) {
s = strstr(s, token);
if (!s)
return 0;
if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
- s += tokenlen;
+ /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+ ++s;
continue;
}
return s;
@@ -648,7 +656,8 @@ static char *match_identifier_end(char *base, char *s, char *token, int tokenlen
if (!s)
return 0;
if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
- s += tokenlen;
+ /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+ ++s;
continue;
}
return s;
@@ -663,7 +672,8 @@ static char *match_number_end(char *base, char *s, char *token, int tokenlen) {
if (!s)
return 0;
if (isdigit((int) *(s + tokenlen))) {
- s += tokenlen;
+ /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+ ++s;
continue;
}
return s;
@@ -923,7 +933,6 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
newsize *= 2;
ns = (char *) DohMalloc(newsize);
- assert(ns);
t = ns;
s = first;
diff --git a/Source/DOH/void.c b/Source/DOH/void.c
index 6111a8c49..bbecca21b 100644
--- a/Source/DOH/void.c
+++ b/Source/DOH/void.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* void.c
*
diff --git a/Source/Doxygen/doxycommands.h b/Source/Doxygen/doxycommands.h
index b5d65af65..782b6ab94 100644
--- a/Source/Doxygen/doxycommands.h
+++ b/Source/Doxygen/doxycommands.h
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* doxycommands.h
*
@@ -44,6 +44,8 @@ const int sectionIndicatorsSize = sizeof(sectionIndicators) / sizeof(*sectionInd
const char *simpleCommands[] = {
// the first line are escaped chars, except \~, which is a language ID command.
"n", "$", "@", "\\", "&", "~", "<", ">", "#", "%", "\"", ".", "::",
+ // Member groups, which we currently ignore.
+ "{", "}",
"endcond",
"callgraph", "callergraph", "showinitializer", "hideinitializer", "internal",
"nosubgrouping", "public", "publicsection", "private", "privatesection",
diff --git a/Source/Doxygen/doxyentity.cxx b/Source/Doxygen/doxyentity.cxx
index 8b9f65736..6fe97dd36 100644
--- a/Source/Doxygen/doxyentity.cxx
+++ b/Source/Doxygen/doxyentity.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* doxyentity.cxx
*
diff --git a/Source/Doxygen/doxyentity.h b/Source/Doxygen/doxyentity.h
index 93737e604..e475141a3 100644
--- a/Source/Doxygen/doxyentity.h
+++ b/Source/Doxygen/doxyentity.h
@@ -4,15 +4,15 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* doxyentity.h
*
* Part of the Doxygen comment translation module of SWIG.
* ----------------------------------------------------------------------------- */
-#ifndef DOXYGENENTITY_H_
-#define DOXYGENENTITY_H_
+#ifndef SWIG_DOXYENTITY_H
+#define SWIG_DOXYENTITY_H
#include <string>
#include <list>
diff --git a/Source/Doxygen/doxyparser.cxx b/Source/Doxygen/doxyparser.cxx
index d5a0a15eb..0c445f1a0 100644
--- a/Source/Doxygen/doxyparser.cxx
+++ b/Source/Doxygen/doxyparser.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* doxyparser.cxx
* ----------------------------------------------------------------------------- */
@@ -1241,18 +1241,21 @@ void DoxygenParser::processHtmlTags(size_t &pos, const std::string &line) {
// prepend '<' to distinguish HTML tags from doxygen commands
if (!cmd.empty() && addDoxyCommand(m_tokenList, '<' + cmd)) {
// it is a valid HTML command
+ if (pos == string::npos) {
+ pos = line.size();
+ }
if (line[pos] != '>') {
// it should be HTML tag with args,
// for example <A ...>, <IMG ...>, ...
if (isEndHtmlTag) {
m_tokenListIt = m_tokenList.end();
- printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": Illegal end HTML tag without '>' found.");
+ printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": Illegal end HTML tag without greater-than ('>') found.");
}
endHtmlPos = line.find(">", pos);
if (endHtmlPos == string::npos) {
m_tokenListIt = m_tokenList.end();
- printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": HTML tag without '>' found.");
+ printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": HTML tag without greater-than ('>') found.");
}
// add args of HTML command, like link URL, image URL, ...
m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, endHtmlPos - pos)));
@@ -1266,7 +1269,7 @@ void DoxygenParser::processHtmlTags(size_t &pos, const std::string &line) {
}
}
- if (pos != string::npos) {
+ if (pos < line.size()) {
pos++; // skip '>'
}
} else {
diff --git a/Source/Doxygen/doxyparser.h b/Source/Doxygen/doxyparser.h
index e692729ce..a60446517 100644
--- a/Source/Doxygen/doxyparser.h
+++ b/Source/Doxygen/doxyparser.h
@@ -4,13 +4,13 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* doxyparser.h
* ----------------------------------------------------------------------------- */
-#ifndef DOXYGENPARSER_H_
-#define DOXYGENPARSER_H_
+#ifndef SWIG_DOXYPARSER_H
+#define SWIG_DOXYPARSER_H
#include <string>
#include <list>
#include <map>
@@ -238,7 +238,7 @@ private:
* Method for Adding a Simple Command
* Format: @command
* Plain commands, such as newline etc, they contain no other data
- * \n \\ \@ \& \$ \# \< \> \%
+ * \n \\ \@ \& \$ \# \< \> \% \{ \}
*/
void addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList);
/*
diff --git a/Source/Doxygen/doxytranslator.cxx b/Source/Doxygen/doxytranslator.cxx
index fb21de75c..a638717ec 100644
--- a/Source/Doxygen/doxytranslator.cxx
+++ b/Source/Doxygen/doxytranslator.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* doxytranslator.cxx
*
diff --git a/Source/Doxygen/doxytranslator.h b/Source/Doxygen/doxytranslator.h
index a72a31df6..f0d3b1b06 100644
--- a/Source/Doxygen/doxytranslator.h
+++ b/Source/Doxygen/doxytranslator.h
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* doxytranslator.h
*
@@ -12,8 +12,8 @@
* systems.
* ----------------------------------------------------------------------------- */
-#ifndef DOXYGENTRANSLATOR_H_
-#define DOXYGENTRANSLATOR_H_
+#ifndef SWIG_DOXYTRANSLATOR_H
+#define SWIG_DOXYTRANSLATOR_H
#include "swig.h"
#include "doxyentity.h"
diff --git a/Source/Doxygen/javadoc.cxx b/Source/Doxygen/javadoc.cxx
index d9313f981..a1406b230 100644
--- a/Source/Doxygen/javadoc.cxx
+++ b/Source/Doxygen/javadoc.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* javadoc.cxx
* ----------------------------------------------------------------------------- */
@@ -152,7 +152,7 @@ void JavaDocConverter::fillStaticTables() {
tagHandlers["f{"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
tagHandlers["warning"] = make_pair(&JavaDocConverter::handleTagMessage, "Warning: ");
- // this command just prints it's contents
+ // this command just prints its contents
// (it is internal command of swig's parser, contains plain text)
tagHandlers["plainstd::string"] = make_pair(&JavaDocConverter::handlePlainString, "");
tagHandlers["plainstd::endl"] = make_pair(&JavaDocConverter::handleNewLine, "");
@@ -463,7 +463,11 @@ void JavaDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translate
if (it != tag.entityList.end())
title = it->data;
- translatedComment += "<img src=" + file;
+ translatedComment += "<img src=";
+ if (file.size() >= 2 && file[0] == '"' && file[file.size() - 1] == '"')
+ translatedComment += file;
+ else
+ translatedComment += "\"" + file + "\"";
if (title.size())
translatedComment += " alt=" + title;
diff --git a/Source/Doxygen/javadoc.h b/Source/Doxygen/javadoc.h
index 6feff5295..d2c956c9d 100644
--- a/Source/Doxygen/javadoc.h
+++ b/Source/Doxygen/javadoc.h
@@ -4,15 +4,15 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* javadoc.h
*
* Module to return documentation for nodes formatted for JavaDoc
* ----------------------------------------------------------------------------- */
-#ifndef JAVADOCCONVERTER_H_
-#define JAVADOCCONVERTER_H_
+#ifndef SWIG_JAVADOC_H
+#define SWIG_JAVADOC_H
#include "doxytranslator.h"
#include <map>
diff --git a/Source/Doxygen/pydoc.cxx b/Source/Doxygen/pydoc.cxx
index c84095b8f..28f6051a7 100644
--- a/Source/Doxygen/pydoc.cxx
+++ b/Source/Doxygen/pydoc.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* pydoc.cxx
*
@@ -302,7 +302,7 @@ void PyDocConverter::fillStaticTables() {
tagHandlers["ref"] = make_handler(&PyDocConverter::handleTagRef);
tagHandlers["result"] = tagHandlers["return"] = tagHandlers["returns"] = make_handler(&PyDocConverter::handleTagReturn);
- // this command just prints it's contents
+ // this command just prints its contents
// (it is internal command of swig's parser, contains plain text)
tagHandlers["plainstd::string"] = make_handler(&PyDocConverter::handlePlainString);
tagHandlers["plainstd::endl"] = make_handler(&PyDocConverter::handleNewLine);
diff --git a/Source/Doxygen/pydoc.h b/Source/Doxygen/pydoc.h
index 19885276f..880ee3069 100644
--- a/Source/Doxygen/pydoc.h
+++ b/Source/Doxygen/pydoc.h
@@ -4,15 +4,15 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* pydoc.h
*
* Module to return documentation for nodes formatted for PyDoc
* ----------------------------------------------------------------------------- */
-#ifndef PYDOCCONVERTER_H_
-#define PYDOCCONVERTER_H_
+#ifndef SWIG_PYDOC_H
+#define SWIG_PYDOC_H
#include <list>
#include <string>
diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h
index 955a8773a..fc379c014 100644
--- a/Source/Include/swigwarn.h
+++ b/Source/Include/swigwarn.h
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swigwarn.h
*
@@ -22,8 +22,8 @@
* This file is used as the input for generating Lib/swigwarn.swg.
* ----------------------------------------------------------------------------- */
-#ifndef SWIGWARN_H_
-#define SWIGWARN_H_
+#ifndef SWIG_SWIGWARN_H
+#define SWIG_SWIGWARN_H
#define WARN_NONE 0
@@ -52,7 +52,7 @@
#define WARN_DEPRECATED_NAME 121
#define WARN_DEPRECATED_NOEXTERN 122
#define WARN_DEPRECATED_NODEFAULT 123
-#define WARN_DEPRECATED_TYPEMAP_LANG 124
+/* Unused since 4.1.0: #define WARN_DEPRECATED_TYPEMAP_LANG 124 */
#define WARN_DEPRECATED_INPUT_FILE 125
#define WARN_DEPRECATED_NESTED_WORKAROUND 126
@@ -93,6 +93,7 @@
#define WARN_PARSE_NESTED_TEMPLATE 324
#define WARN_PARSE_NAMED_NESTED_CLASS 325
#define WARN_PARSE_EXTEND_NAME 326
+#define WARN_PARSE_EXTERN_TEMPLATE 327
#define WARN_CPP11_LAMBDA 340
#define WARN_CPP11_ALIAS_DECLARATION 341 /* redundant now */
@@ -146,8 +147,9 @@
#define WARN_IGNORE_OPERATOR_NEWARR 394 /* new [] */
#define WARN_IGNORE_OPERATOR_DELARR 395 /* delete [] */
#define WARN_IGNORE_OPERATOR_REF 396 /* operator *() */
+#define WARN_IGNORE_OPERATOR_LTEQUALGT 397 /* <=> */
-/* 394-399 are reserved */
+/* please leave 350-399 free for WARN_IGNORE_OPERATOR_* */
/* -- Type system and typemaps -- */
@@ -162,6 +164,7 @@
#define WARN_TYPEMAP_SWIGTYPE 452 /* No longer issued */
#define WARN_TYPEMAP_APPLY_UNDEF 453
#define WARN_TYPEMAP_SWIGTYPELEAK 454
+#define WARN_TYPEMAP_WCHARLEAK 455
#define WARN_TYPEMAP_IN_UNDEF 460
#define WARN_TYPEMAP_OUT_UNDEF 461
@@ -212,6 +215,7 @@
#define WARN_LANG_EXTEND_DESTRUCTOR 523
#define WARN_LANG_EXPERIMENTAL 524
#define WARN_LANG_DIRECTOR_FINAL 525
+#define WARN_LANG_USING_NAME_DIFFERENT 526
/* -- Doxygen comments -- */
@@ -223,7 +227,7 @@
#define WARN_DOXYGEN_UNKNOWN_CHARACTER 565
#define WARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE 566
-/* -- Reserved (600-799) -- */
+/* -- Reserved (600-699) -- */
/* -- Language module specific warnings (700 - 899) -- */
@@ -277,7 +281,7 @@
#define WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC 824
#define WARN_JAVA_NO_DIRECTORCONNECT_ATTR 825
#define WARN_JAVA_NSPACE_WITHOUT_PACKAGE 826
-#define WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847
+#define WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 827
/* please leave 810-829 free for Java */
diff --git a/Source/Makefile.am b/Source/Makefile.am
index 5cfb88839..095c5d4ea 100644
--- a/Source/Makefile.am
+++ b/Source/Makefile.am
@@ -6,8 +6,6 @@ AUTOMAKE_OPTIONS = foreign nostdinc subdir-objects 1.7.2
SOURCE_DIR=$(top_srcdir)/Source
BUILD_SOURCE_DIR=$(top_builddir)/Source
-SWIG_CXX_DEFS = @SWILL@
-
AM_CPPFLAGS = -I$(BUILD_SOURCE_DIR)/Include \
-I$(BUILD_SOURCE_DIR)/CParse \
-I$(SOURCE_DIR)/Include \
@@ -18,7 +16,7 @@ AM_CPPFLAGS = -I$(BUILD_SOURCE_DIR)/Include \
-I$(SOURCE_DIR)/Swig \
-I$(SOURCE_DIR)/Modules
-AM_CXXFLAGS = $(SWIG_CXX_DEFS)
+AM_CXXFLAGS =
AM_YFLAGS = -d
@@ -46,7 +44,6 @@ eswig_SOURCES = CParse/cscanner.c \
Doxygen/pydoc.cxx \
Doxygen/pydoc.h \
Modules/allocate.cxx \
- Modules/browser.cxx \
Modules/contract.cxx \
Modules/csharp.cxx \
Modules/d.cxx \
@@ -98,7 +95,6 @@ eswig_SOURCES = CParse/cscanner.c \
Swig/wrapfunc.c
bin_PROGRAMS = eswig
-eswig_LDADD = @SWIGLIBS@
# Override the link stage to avoid using Libtool
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx
index 23683c385..0e1262f83 100644
--- a/Source/Modules/allocate.cxx
+++ b/Source/Modules/allocate.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* allocate.cxx
*
@@ -197,7 +197,7 @@ class Allocate:public Dispatcher {
// Found a polymorphic method.
// Mark the polymorphic method, in case the virtual keyword was not used.
Setattr(n, "storage", "virtual");
- if (!Getattr(b, "feature:interface")) { // interface implementation neither hides nor overrides
+ if (!GetFlag(b, "feature:interface")) { // interface implementation neither hides nor overrides
if (both_have_public_access || both_have_protected_access) {
if (!is_non_public_base(inclass, b))
Setattr(n, "override", base); // Note C# definition of override, ie access must be the same
@@ -779,6 +779,12 @@ Allocate():
if (Swig_storage_isstatic(n)) {
Setattr(n, "cplus:staticbase", inclass);
+ } else if (Cmp(Getattr(n, "kind"), "variable") == 0) {
+ /* Check member variable to determine whether assignment is valid */
+ if (SwigType_isreference(Getattr(n, "type"))) {
+ /* Can't assign a class with reference member data */
+ Setattr(inclass, "allocate:noassign", "1");
+ }
}
String *name = Getattr(n, "name");
diff --git a/Source/Modules/browser.cxx b/Source/Modules/browser.cxx
deleted file mode 100644
index 217b40a7e..000000000
--- a/Source/Modules/browser.cxx
+++ /dev/null
@@ -1,421 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * browser.cxx
- *
- * A web-base parse tree browser using SWILL. This is an optional
- * feature that's normally disabled.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-#ifdef SWIG_SWILL
-extern "C" {
-#include "swill.h"
-} static FILE *out = 0;
-static Node *view_top = 0;
-
-class Browser:public Dispatcher {
- void show_checkbox(Node *t, Node *n) {
- int v = 0;
- if (Getmeta(n, "visible")) {
- v = 1;
- }
- if (v) {
- Printf(out, "<a name=\"n%p\"></a>[<a href=\"hide.html?node=%p&hn=%p#n%p\">-</a>] ", n, t, n, n);
- } else {
- Printf(out, "<a name=\"n%p\"></a>[<a href=\"show.html?node=%p&hn=%p#n%p\">+</a>] ", n, t, n, n);
- }
- }
- void show_attributes(Node *obj) {
- if (!Getmeta(obj, "visible"))
- return;
- String *os = NewString("");
- String *k;
- Iterator ki;
- ki = First(obj);
- while (ki.key) {
- k = ki.key;
- if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) ||
- (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) {
- /* Do nothing */
- } else if (Cmp(k, "parms") == 0) {
- String *o = NewString("");
- Printf(o, "%s", ParmList_protostr(Getattr(obj, k)));
- Replaceall(o, "&", "&amp;");
- Replaceall(o, "<", "&lt;");
- Replaceall(o, ">", "&gt;");
- Printf(os, "<a href=\"data.html?n=%p\">?</a> %-12s - %s\n", Getattr(obj, k), k, o);
- Delete(o);
- } else {
- DOH *o;
- char *trunc = "";
- if (DohIsString(Getattr(obj, k))) {
- o = Str(Getattr(obj, k));
- if (Len(o) > 70) {
- trunc = "...";
- }
- Replaceall(o, "&", "&amp;");
- Replaceall(o, "<", "&lt;");
- Printf(os, "<a href=\"data.html?n=%p\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc);
- Delete(o);
- } else {
- Printf(os, "<a href=\"data.html?n=%p\">?</a> %-12s - %p\n", Getattr(obj, k), k, Getattr(obj, k));
- }
- }
- ki = Next(ki);
- }
- Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
- Delete(os);
- }
-
-public:
- virtual int emit_one(Node *n) {
- char *tag = Char(nodeType(n));
- char *file = Char(Getfile(n));
- int line = Getline(n);
- char *name = GetChar(n, "name");
-
- show_checkbox(view_top, n);
- Printf(out, "<b><a href=\"index.html?node=%p\">%s</a></b>", n, tag);
- if (name) {
- Printf(out, " (%s)", name);
- }
- Printf(out, ". %s:%d\n", file, line);
- Printf(out, "<br>");
- Dispatcher::emit_one(n);
- return SWIG_OK;
- }
- virtual int emit_children(Node *n) {
- if (Getmeta(n, "visible")) {
- Printf(out, "<blockquote>\n");
- Dispatcher::emit_children(n);
- Printf(out, "</blockquote>\n");
- }
- return SWIG_OK;
- }
- virtual int defaultHandler(Node *n) {
- show_attributes(n);
- return SWIG_OK;
- }
- virtual int top(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int includeDirective(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int importDirective(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
- virtual int extendDirective(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int classDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
- virtual int templateDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
- virtual int lambdaDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
- virtual int enumDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int typemapDirective(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int namespaceDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int usingDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
-};
-
-static int browser_exit = 0;
-static Node *tree_top = 0;
-static Browser *browse = 0;
-
-/* ----------------------------------------------------------------------
- * exit_handler() - Force the browser to exit
- * ---------------------------------------------------------------------- */
-
-void exit_handler(FILE *f) {
- browser_exit = 1;
- Printf(f, "Terminated.\n");
-}
-
-/* ----------------------------------------------------------------------
- * node_handler() - Generate information about a specific node
- * ---------------------------------------------------------------------- */
-
-static void display(FILE *f, Node *n) {
- /* Print standard HTML header */
-
- Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version());
- Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version());
- Printf(f, "[ <a href=\"exit.html\">Exit</a> ]");
- Printf(f, " [ <a href=\"index.html?node=%p\">Top</a> ]", tree_top);
- if (n != tree_top) {
- Printf(f, " [ <a href=\"index.html?node=%p\">Up</a> ]", parentNode(n));
- }
- Printf(f, " [ <a href=\"symbol.html\">Symbols</a> ]");
- Printf(f, "<br><hr><p>\n");
-
- out = f;
-
- browse->emit_one(n);
-
- /* Print standard footer */
- Printf(f, "<br><hr></BODY></HTML>\n");
-
-}
-
-void node_handler(FILE *f) {
- Node *n = 0;
- if (!swill_getargs("p(node)", &n)) {
- n = tree_top;
- }
- view_top = n;
- display(f, n);
-}
-
-
-/* ----------------------------------------------------------------------
- * hide_handler() - Hide a node
- * ---------------------------------------------------------------------- */
-
-void hide_handler(FILE *f) {
- Node *n = 0;
- if (!swill_getargs("p(hn)", &n)) {
- n = 0;
- }
- if (n) {
- Delmeta(n, "visible");
- }
- node_handler(f);
-}
-
-void show_handler(FILE *f) {
- Node *n = 0;
- if (!swill_getargs("p(hn)", &n)) {
- n = 0;
- }
- if (n) {
- Setmeta(n, "visible", "1");
- }
- node_handler(f);
-}
-
-void raw_data(FILE *out, Node *obj) {
- if (!obj)
- return;
- if (DohIsMapping(obj)) {
- String *k;
- Iterator ki;
- String *os = NewString("");
- Printf(os, "Hash {\n");
- ki = First(obj);
- while (ki.key) {
- k = ki.key;
- DOH *o;
- const char *trunc = "";
- if (DohIsString(Getattr(obj, k))) {
- o = Str(Getattr(obj, k));
- if (Len(o) > 70) {
- trunc = "...";
- }
- Replaceall(o, "<", "&lt;");
- Printf(os, " <a href=\"data.html?n=%p\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc);
- Delete(o);
- } else {
- Printf(os, " <a href=\"data.html?n=%p\">?</a> %-12s - %p\n", Getattr(obj, k), k, Getattr(obj, k));
- }
- ki = Next(ki);
- }
- Printf(os, "}\n");
- Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
- Delete(os);
- } else if (DohIsString(obj)) {
- String *o = Str(obj);
- Replaceall(o, "<", "&lt;");
- Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(o));
- Delete(o);
- } else if (DohIsSequence(obj)) {
- int i;
- String *os = NewString("");
- Printf(os, "List [\n");
- for (i = 0; i < Len(obj); i++) {
- DOH *o = Getitem(obj, i);
- const char *trunc = "";
- if (DohIsString(o)) {
- String *s = Str(o);
- if (Len(s) > 70) {
- trunc = "...";
- }
- Replaceall(o, "<", "&lt;");
- Printf(os, " <a href=\"data.html?n=%p\">?</a> [%d] - \"%(escape)-0.70s%s\"\n", o, i, s, trunc);
- Delete(s);
- } else {
- Printf(os, " <a href=\"data.html?n=%p\">?</a> [%d] - %p\n", o, i, o);
- }
- }
- Printf(os, "\n]\n");
- Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
- Delete(os);
- }
-}
-
-void data_handler(FILE *f) {
- DOH *n = 0;
- if (!swill_getargs("p(n)", &n)) {
- n = 0;
- }
- Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version());
- Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version());
- Printf(f, "[ <a href=\"exit.html\">Exit</a> ]");
- Printf(f, " [ <a href=\"index.html?node=%p\">Top</a> ]", tree_top);
- Printf(f, "<br><hr><p>\n");
- if (n) {
- raw_data(f, n);
- }
- /* Print standard footer */
- Printf(f, "<br><hr></BODY></HTML>\n");
-}
-
-void symbol_handler(FILE *f) {
- Symtab *sym;
- char *name = 0;
-
- Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version());
- Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version());
- Printf(f, "[ <a href=\"exit.html\">Exit</a> ]");
- Printf(f, " [ <a href=\"index.html?node=%p\">Top</a> ]", tree_top);
- Printf(f, " [ <a href=\"symbol.html\">Symbols</a> ]");
- Printf(f, "<br><hr><p>\n");
-
- if (!swill_getargs("p(sym)|s(name)", &sym, &name)) {
- sym = Swig_symbol_getscope("");
- name = 0;
- }
- if (!sym) {
- Printf(f, "No symbol table specified!\n");
- return;
- }
- {
- String *q = Swig_symbol_qualifiedscopename(sym);
- if (!Len(q)) {
- Printf(f, "<b>Symbol table: :: (global)</b><br>\n");
- } else {
- Printf(f, "<b>Symbol table: %s</b><br>\n", q);
- }
- Delete(q);
- }
-
- fprintf(f, "<p><form action=\"symbol.html\" method=GET>\n");
- fprintf(f, "Symbol lookup: <input type=text name=name size=40></input><br>\n");
- fprintf(f, "<input type=hidden name=sym value=\"%p\">\n", sym);
- fprintf(f, "Submit : <input type=submit></input>\n");
- fprintf(f, "</form>");
-
- if (name) {
- Node *n = Swig_symbol_clookup(name, sym);
- Printf(f, "Symbol '%s':\n", name);
- Printf(f, "<blockquote>\n");
- if (!n) {
- Printf(f, "Not defined!\n");
- } else {
- raw_data(f, n);
- }
- Printf(f, "</blockquote>\n");
- }
-
- Printf(f, "<p><b>Nested scopes</b><br>\n");
- Printf(f, "<blockquote><pre>\n");
- {
- Hash *h;
- h = firstChild(sym);
- while (h) {
- Printf(f, "<a href=\"symbol.html?sym=%p\">%s</a>\n", h, Getattr(h, "name"));
- h = nextSibling(h);
- }
- }
- Printf(f, "</pre></blockquote>\n");
-
- Printf(f, "<p><b>Symbol table contents</b></br>\n");
- raw_data(f, Getattr(sym, "symtab"));
- Printf(f, "<br><hr></BODY></HTML>\n");
-
-}
-#endif
-
-void Swig_browser(Node *top, int port) {
-#ifdef SWIG_SWILL
- int sport;
- browser_exit = 0;
-
- /* Initialize the server */
- sport = swill_init(port);
- if (sport < 0) {
- Printf(stderr, "Couldn't open socket on port %d. Sorry.\n", port);
- return;
- }
- browse = new Browser();
- Setmeta(top, "visible", "1");
- tree_top = top;
-
- Printf(stderr, "SWIG: Tree browser listening on port %d\n", sport);
-
- swill_handle("exit.html", exit_handler, 0);
- swill_handle("index.html", node_handler, 0);
- swill_handle("hide.html", hide_handler, 0);
- swill_handle("show.html", show_handler, 0);
- swill_handle("data.html", data_handler, 0);
- swill_handle("symbol.html", symbol_handler, 0);
- swill_netscape("index.html");
-
- while (!browser_exit) {
- swill_serve();
- }
- Printf(stderr, "Browser terminated.\n");
- swill_close();
- delete browse;
- return;
-#else
- (void) top;
- (void) port;
-#endif
-}
diff --git a/Source/Modules/cffi.cxx b/Source/Modules/cffi.cxx
deleted file mode 100644
index 6333fa153..000000000
--- a/Source/Modules/cffi.cxx
+++ /dev/null
@@ -1,1184 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * cffi.cxx
- *
- * cffi language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <ctype.h>
-
-//#define CFFI_DEBUG
-//#define CFFI_WRAP_DEBUG
-
-static const char *usage = "\
-CFFI Options (available with -cffi)\n\
- -generate-typedef - Use defctype to generate shortcuts according to the\n\
- typedefs in the input.\n\
- -[no]cwrap - Turn on or turn off generation of an intermediate C\n\
- file when creating a C interface. By default this is\n\
- only done for C++ code.\n\
- -[no]swig-lisp - Turn on or off generation of code for helper lisp\n\
- macro, functions, etc. which SWIG uses while\n\
- generating wrappers. These macros, functions may still\n\
- be used by generated wrapper code.\n\
-";
-
-class CFFI:public Language {
-public:
- String *f_cl;
- String *f_clhead;
- String *f_clwrap;
- bool CWrap; // generate wrapper file for C code?
- File *f_begin;
- File *f_runtime;
- File *f_cxx_header;
- File *f_cxx_wrapper;
- File *f_clos;
-
- String *module;
- virtual void main(int argc, char *argv[]);
- virtual int top(Node *n);
- virtual int functionWrapper(Node *n);
- virtual int variableWrapper(Node *n);
- virtual int constantWrapper(Node *n);
- // virtual int classDeclaration(Node *n);
- virtual int enumDeclaration(Node *n);
- virtual int typedefHandler(Node *n);
-
- //c++ specific code
- virtual int constructorHandler(Node *n);
- virtual int destructorHandler(Node *n);
- virtual int memberfunctionHandler(Node *n);
- virtual int membervariableHandler(Node *n);
- virtual int classHandler(Node *n);
-
-private:
- static void checkConstraints(ParmList *parms, Wrapper *f);
- static void argout(ParmList *parms, Wrapper *f);
- static String *freearg(ParmList *parms);
- static void cleanupFunction(Node *n, Wrapper *f, ParmList *parms);
-
- void emit_defun(Node *n, String *name);
- void emit_defmethod(Node *n);
- void emit_initialize_instance(Node *n);
- void emit_getter(Node *n);
- void emit_setter(Node *n);
- void emit_class(Node *n);
- void emit_struct_union(Node *n, bool un);
- void emit_export(Node *n, String *name);
- void emit_inline(Node *n, String *name);
- String *lispy_name(char *name);
- String *lispify_name(Node *n, String *ty, const char *flag, bool kw = false);
- String *convert_literal(String *num_param, String *type, bool try_to_split = true);
- String *infix_to_prefix(String *val, char split_op, const String *op, String *type);
- String *strip_parens(String *string);
- String *trim(String *string);
- int generate_typedef_flag;
- bool no_swig_lisp;
-};
-
-void CFFI::main(int argc, char *argv[]) {
- int i;
-
- Preprocessor_define("SWIGCFFI 1", 0);
- SWIG_library_directory("cffi");
- SWIG_config_file("cffi.swg");
- generate_typedef_flag = 0;
- no_swig_lisp = false;
- CWrap = false;
- for (i = 1; i < argc; i++) {
- if (!Strcmp(argv[i], "-help")) {
- Printf(stdout, "%s\n", usage);
- } else if (!strcmp(argv[i], "-cwrap")) {
- CWrap = true;
- Swig_mark_arg(i);
- } else if ((Strcmp(argv[i], "-generate-typedef") == 0)) {
- generate_typedef_flag = 1;
- Swig_mark_arg(i);
- } else if (!strcmp(argv[i], "-nocwrap")) {
- CWrap = false;
- Swig_mark_arg(i);
- } else if (!strcmp(argv[i], "-swig-lisp")) {
- no_swig_lisp = false;
- Swig_mark_arg(i);
- } else if (!strcmp(argv[i], "-noswig-lisp")) {
- no_swig_lisp = true;
- Swig_mark_arg(i);
- }
-
- }
- f_clhead = NewString("");
- f_clwrap = NewString("");
- f_cl = NewString("");
-
- allow_overloading();
-}
-
-int CFFI::top(Node *n) {
- File *f_null = NewString("");
- module = Getattr(n, "name");
-
- String *cxx_filename = Getattr(n, "outfile");
- String *lisp_filename = NewString("");
-
- Printf(lisp_filename, "%s%s.lisp", SWIG_output_directory(), module);
-
- File *f_lisp = NewFile(lisp_filename, "w", SWIG_output_files());
- if (!f_lisp) {
- FileErrorDisplay(lisp_filename);
- SWIG_exit(EXIT_FAILURE);
- }
-
- if (CPlusPlus || CWrap) {
- f_begin = NewFile(cxx_filename, "w", SWIG_output_files());
- if (!f_begin) {
- Delete(f_lisp);
- Printf(stderr, "Unable to open %s for writing\n", cxx_filename);
- SWIG_exit(EXIT_FAILURE);
- }
-
- String *clos_filename = NewString("");
- Printf(clos_filename, "%s%s-clos.lisp", SWIG_output_directory(), module);
- f_clos = NewFile(clos_filename, "w", SWIG_output_files());
- if (!f_clos) {
- Delete(f_lisp);
- Printf(stderr, "Unable to open %s for writing\n", cxx_filename);
- SWIG_exit(EXIT_FAILURE);
- }
- } else {
- f_begin = NewString("");
- f_clos = NewString("");
- }
-
- f_runtime = NewString("");
- f_cxx_header = f_runtime;
- f_cxx_wrapper = NewString("");
-
- Swig_register_filebyname("header", f_cxx_header);
- Swig_register_filebyname("wrapper", f_cxx_wrapper);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("lisphead", f_clhead);
- if (!no_swig_lisp)
- Swig_register_filebyname("swiglisp", f_cl);
- else
- Swig_register_filebyname("swiglisp", f_null);
-
- Swig_banner(f_begin);
-
- Printf(f_runtime, "\n\n#ifndef SWIGCFFI\n#define SWIGCFFI\n#endif\n\n");
-
- Swig_banner_target_lang(f_lisp, ";;;");
-
- Language::top(n);
- Printf(f_lisp, "%s\n", f_clhead);
- Printf(f_lisp, "%s\n", f_cl);
- Printf(f_lisp, "%s\n", f_clwrap);
-
- Delete(f_lisp);
- Delete(f_cl);
- Delete(f_clhead);
- Delete(f_clwrap);
- Dump(f_runtime, f_begin);
- Delete(f_runtime);
- Delete(f_begin);
- Delete(f_cxx_wrapper);
- Delete(f_null);
-
- return SWIG_OK;
-}
-
-int CFFI::classHandler(Node *n) {
-#ifdef CFFI_DEBUG
- Printf(stderr, "class %s::%s\n", "some namespace", //current_namespace,
- Getattr(n, "sym:name"));
-#endif
- String *name = Getattr(n, "sym:name");
- String *kind = Getattr(n, "kind");
-
- // maybe just remove this check and get rid of the else clause below.
- if (Strcmp(kind, "struct") == 0) {
- emit_struct_union(n, false);
- return SWIG_OK;
- } else if (Strcmp(kind, "union") == 0) {
- emit_struct_union(n, true);
- return SWIG_OK;
- } else if (Strcmp(kind, "class") == 0) {
- emit_class(n);
- Language::classHandler(n);
- } else {
- Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
- Printf(stderr, " (name: %s)\n", name);
- SWIG_exit(EXIT_FAILURE);
- return SWIG_OK;
- }
-
- return SWIG_OK;
-}
-
-int CFFI::constructorHandler(Node *n) {
-#ifdef CFFI_DEBUG
- Printf(stderr, "constructor %s\n", Getattr(n, "name"));
- Printf(stderr, "constructor %s\n and %s", Getattr(n, "kind"), Getattr(n, "sym:name"));
-#endif
- Setattr(n, "cffi:constructorfunction", "1");
- // Let SWIG generate a global forwarding function.
- return Language::constructorHandler(n);
-}
-
-int CFFI::destructorHandler(Node *n) {
-#ifdef CFFI_DEBUG
- Printf(stderr, "destructor %s\n", Getattr(n, "name"));
-#endif
-
- // Let SWIG generate a global forwarding function.
- return Language::destructorHandler(n);
-}
-
-void CFFI::emit_defmethod(Node *n) {
- String *args_placeholder = NewStringf("");
- String *args_call = NewStringf("");
-
- ParmList *pl = Getattr(n, "parms");
- int argnum = 0;
- Node *parent = getCurrentClass();
- bool first = 0;
-
- for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
- String *argname = Getattr(p, "name");
- String *ffitype = Swig_typemap_lookup("lispclass", p, "", 0);
-
- int tempargname = 0;
-
- if(!first)
- first = true;
- else
- Printf(args_placeholder, " ");
-
- if (!argname) {
- argname = NewStringf("arg%d", argnum);
- tempargname = 1;
- } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) {
- argname = NewStringf("t-arg%d", argnum);
- tempargname = 1;
- }
- if (Len(ffitype) > 0)
- Printf(args_placeholder, "(%s %s)", argname, ffitype);
- else
- Printf(args_placeholder, "%s", argname);
-
- if (ffitype && Strcmp(ffitype, lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'classname")) == 0)
- Printf(args_call, " (ff-pointer %s)", argname);
- else
- Printf(args_call, " %s", argname);
-
- Delete(ffitype);
-
- if (tempargname)
- Delete(argname);
- }
-
- String *method_name = Getattr(n, "name");
- int x = Replace(method_name, "operator ", "", DOH_REPLACE_FIRST); //
-
- if (x == 1)
- Printf(f_clos, "(cl:shadow \"%s\")\n", method_name);
-
- Printf(f_clos, "(cl:defmethod %s (%s)\n (%s%s))\n\n",
- lispify_name(n, lispy_name(Char(method_name)), "'method"), args_placeholder,
- lispify_name(n, Getattr(n, "sym:name"), "'function"), args_call);
-
-}
-
-void CFFI::emit_initialize_instance(Node *n) {
- String *args_placeholder = NewStringf("");
- String *args_call = NewStringf("");
-
- ParmList *pl = Getattr(n, "parms");
- int argnum = 0;
- Node *parent = getCurrentClass();
-
- for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
- String *argname = Getattr(p, "name");
- String *ffitype = Swig_typemap_lookup("lispclass", p, "", 0);
-
- int tempargname = 0;
- if (!argname) {
- argname = NewStringf("arg%d", argnum);
- tempargname = 1;
- } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) {
- argname = NewStringf("t-arg%d", argnum);
- tempargname = 1;
- }
- if (Len(ffitype) > 0)
- Printf(args_placeholder, " (%s %s)", argname, ffitype);
- else
- Printf(args_placeholder, " %s", argname);
-
- if (ffitype && Strcmp(ffitype, lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'classname")) == 0)
- Printf(args_call, " (ff-pointer %s)", argname);
- else
- Printf(args_call, " %s", argname);
-
- Delete(ffitype);
-
- if (tempargname)
- Delete(argname);
- }
-
- Printf(f_clos, "(cl:defmethod initialize-instance :after ((obj %s) &key%s)\n (setf (slot-value obj 'ff-pointer) (%s%s)))\n\n",
- lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), args_placeholder,
- lispify_name(n, Getattr(n, "sym:name"), "'function"), args_call);
-
-}
-
-void CFFI::emit_setter(Node *n) {
- Node *parent = getCurrentClass();
- Printf(f_clos, "(cl:defmethod (cl:setf %s) (arg0 (obj %s))\n (%s (ff-pointer obj) arg0))\n\n",
- lispify_name(n, Getattr(n, "name"), "'method"),
- lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), lispify_name(n, Getattr(n, "sym:name"), "'function"));
-}
-
-
-void CFFI::emit_getter(Node *n) {
- Node *parent = getCurrentClass();
- Printf(f_clos, "(cl:defmethod %s ((obj %s))\n (%s (ff-pointer obj)))\n\n",
- lispify_name(n, Getattr(n, "name"), "'method"),
- lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), lispify_name(n, Getattr(n, "sym:name"), "'function"));
-}
-
-int CFFI::memberfunctionHandler(Node *n) {
- // Let SWIG generate a global forwarding function.
- Setattr(n, "cffi:memberfunction", "1");
- return Language::memberfunctionHandler(n);
-}
-
-int CFFI::membervariableHandler(Node *n) {
- // Let SWIG generate a get/set function pair.
- Setattr(n, "cffi:membervariable", "1");
- return Language::membervariableHandler(n);
-}
-
-
-void CFFI::checkConstraints(ParmList *parms, Wrapper *f) {
- Parm *p = parms;
- while (p) {
- String *tm = Getattr(p, "tmap:check");
- if (!tm) {
- p = nextSibling(p);
- } else {
- tm = Copy(tm);
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(f->code, tm, "\n\n", NULL);
- Delete(tm);
- p = Getattr(p, "tmap:check:next");
- }
- }
-}
-
-void CFFI::argout(ParmList *parms, Wrapper *f) {
- Parm *p = parms;
- while (p) {
- String *tm = Getattr(p, "tmap:argout");
- if (!tm) {
- p = nextSibling(p);
- } else {
- tm = Copy(tm);
- Replaceall(tm, "$result", Swig_cresult_name());
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(f->code, tm, "\n", NULL);
- Delete(tm);
- p = Getattr(p, "tmap:argout:next");
- }
- }
-}
-
-String *CFFI::freearg(ParmList *parms) {
- String *ret = NewString("");
- Parm *p = parms;
- while (p) {
- String *tm = Getattr(p, "tmap:freearg");
- if (!tm) {
- p = nextSibling(p);
- } else {
- tm = Copy(tm);
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(ret, tm, "\n", NULL);
- Delete(tm);
- p = Getattr(p, "tmap:freearg:next");
- }
- }
- return ret;
-}
-
-void CFFI::cleanupFunction(Node *n, Wrapper *f, ParmList *parms) {
- String *cleanup = freearg(parms);
- Printv(f->code, cleanup, NULL);
-
- if (GetFlag(n, "feature:new")) {
- String *tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
- if (tm) {
- Printv(f->code, tm, "\n", NULL);
- Delete(tm);
- }
- }
-
- Replaceall(f->code, "$cleanup", cleanup);
- Delete(cleanup);
-
- Replaceall(f->code, "$symname", Getattr(n, "sym:name"));
-}
-
-int CFFI::functionWrapper(Node *n) {
-
- ParmList *parms = Getattr(n, "parms");
- String *iname = Getattr(n, "sym:name");
- Wrapper *f = NewWrapper();
-
- String *raw_return_type = Swig_typemap_lookup("ctype", n, "", 0);
- SwigType *return_type = Swig_cparse_type(raw_return_type);
- SwigType *resolved = SwigType_typedef_resolve_all(return_type);
- int is_void_return = (Cmp(resolved, "void") == 0);
- Delete(resolved);
-
- if (!is_void_return) {
- String *lresult_init = NewStringf("lresult = (%s)0", raw_return_type);
- Wrapper_add_localv(f, "lresult", raw_return_type, lresult_init, NIL);
- Delete(lresult_init);
- }
-
- String *overname = 0;
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- } else {
- if (!addSymbol(iname, n)) {
- DelWrapper(f);
- return SWIG_ERROR;
- }
- }
-
- String *wname = Swig_name_wrapper(iname);
- if (overname) {
- Append(wname, overname);
- }
- Setattr(n, "wrap:name", wname);
-
- // Emit all of the local variables for holding arguments.
- emit_parameter_variables(parms, f);
-
- // Attach the standard typemaps
- Swig_typemap_attach_parms("ctype", parms, f);
- emit_attach_parmmaps(parms, f);
-
- int num_arguments = emit_num_arguments(parms);
- String *name_and_parms = NewStringf("%s (", wname);
- int i;
- Parm *p;
- int gencomma = 0;
-
-#ifdef CFFI_DEBUG
- Printf(stderr, "function - %s - %d\n", Getattr(n, "name"), num_arguments);
-#endif
-
- for (i = 0, p = parms; i < num_arguments; i++) {
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *c_parm_type = Swig_cparse_type(Getattr(p, "tmap:ctype"));
- String *arg = NewStringf("l%s", Getattr(p, "lname"));
-
- // Emit parameter declaration
- if (gencomma)
- Printf(name_and_parms, ", ");
- String *parm_decl = SwigType_str(c_parm_type, arg);
- Printf(name_and_parms, "%s", parm_decl);
-#ifdef CFFI_DEBUG
- Printf(stderr, " param: %s\n", parm_decl);
-#endif
- Delete(parm_decl);
- gencomma = 1;
-
- // Emit parameter conversion code
- String *parm_code = Getattr(p, "tmap:in");
- {
- Replaceall(parm_code, "$input", arg);
- Setattr(p, "emit:input", arg);
- Printf(f->code, "%s\n", parm_code);
- p = Getattr(p, "tmap:in:next");
- }
-
- Delete(arg);
- }
- Printf(name_and_parms, ")");
-
- // Emit the function definition
- String *signature = SwigType_str(return_type, name_and_parms);
- Printf(f->def, "EXPORT %s {", signature);
-
- checkConstraints(parms, f);
-
- Printf(f->code, " try {\n");
-
- String *actioncode = emit_action(n);
-
- String *result_convert = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode);
- if (result_convert) {
- Replaceall(result_convert, "$result", "lresult");
- Printf(f->code, "%s\n", result_convert);
- }
- Delete(result_convert);
-
- argout(parms, f);
-
- cleanupFunction(n, f, parms);
-
- /* See if there is any return cleanup code */
- String *tm = 0;
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
-
- if (!is_void_return) {
- Printf(f->code, " return lresult;\n");
- }
-
- emit_return_variable(n, Getattr(n, "type"), f);
-
- Printf(f->code, " } catch (...) {\n");
- if (!is_void_return)
- Printf(f->code, " return (%s)0;\n", raw_return_type);
- Printf(f->code, " }\n");
- Printf(f->code, "}\n");
-
- if (CPlusPlus)
- Wrapper_print(f, f_runtime);
-
- if (CPlusPlus) {
- emit_defun(n, wname);
- if (Getattr(n, "cffi:memberfunction"))
- emit_defmethod(n);
- else if (Getattr(n, "cffi:membervariable")) {
- if (Getattr(n, "memberget"))
- emit_getter(n);
- else if (Getattr(n, "memberset"))
- emit_setter(n);
- }
- else if (Getattr(n, "cffi:constructorfunction")) {
- emit_initialize_instance(n);
- }
- } else
- emit_defun(n, iname);
-
- // if (!overloaded || !Getattr(n, "sym:nextSibling")) {
- // update_package_if_needed(n);
- // emit_buffered_defuns(n);
- // // this is the last overload.
- // if (overloaded) {
- // emit_dispatch_defun(n);
- // }
- // }
-
- Delete(wname);
- DelWrapper(f);
-
- return SWIG_OK;
-}
-
-
-void CFFI::emit_defun(Node *n, String *name) {
- String *func_name = Getattr(n, "sym:name");
-
- ParmList *pl = Getattr(n, "parms");
-
- int argnum = 0;
-
- func_name = lispify_name(n, func_name, "'function");
-
- emit_inline(n, func_name);
-
- Printf(f_cl, "\n(cffi:defcfun (\"%s\" %s)", name, func_name);
- String *ffitype = Swig_typemap_lookup("cout", n, ":pointer", 0);
-
- Printf(f_cl, " %s", ffitype);
- Delete(ffitype);
-
- for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
-
- if (SwigType_isvarargs(Getattr(p, "type"))) {
- Printf(f_cl, "\n %s", NewString("&rest"));
- continue;
- }
-
- String *argname = Getattr(p, "name");
-
- ffitype = Swig_typemap_lookup("cin", p, "", 0);
-
- int tempargname = 0;
- if (!argname) {
-
- argname = NewStringf("arg%d", argnum);
- tempargname = 1;
- } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) {
- argname = NewStringf("t_arg%d", argnum);
- tempargname = 1;
- }
-
- Printf(f_cl, "\n (%s %s)", argname, ffitype);
-
- Delete(ffitype);
-
- if (tempargname)
- Delete(argname);
- }
- Printf(f_cl, ")\n"); /* finish arg list */
-
- emit_export(n, func_name);
-}
-
-
-int CFFI::constantWrapper(Node *n) {
- String *type = Getattr(n, "type");
- String *converted_value;
- if (SwigType_type(type) == T_STRING) {
- converted_value = NewString(Getattr(n, "rawval"));
- } else {
- converted_value = convert_literal(Getattr(n, "value"), type);
- }
-
- String *name = lispify_name(n, Getattr(n, "sym:name"), "'constant");
-
- if (Strcmp(name, "t") == 0 || Strcmp(name, "T") == 0)
- name = NewStringf("t_var");
-
- Printf(f_cl, "\n(cl:defconstant %s %s)\n", name, converted_value);
- Delete(converted_value);
-
- emit_export(n, name);
- return SWIG_OK;
-}
-
-int CFFI::variableWrapper(Node *n) {
- String *var_name = Getattr(n, "sym:name");
- String *lisp_type = Swig_typemap_lookup("cin", n, "", 0);
- String *lisp_name = lispify_name(n, var_name, "'variable");
-
- if (Strcmp(lisp_name, "t") == 0 || Strcmp(lisp_name, "T") == 0)
- lisp_name = NewStringf("t_var");
-
- Printf(f_cl, "\n(cffi:defcvar (\"%s\" %s)\n %s)\n", var_name, lisp_name, lisp_type);
-
- Delete(lisp_type);
-
- emit_export(n, lisp_name);
- return SWIG_OK;
-}
-
-int CFFI::typedefHandler(Node *n) {
- if (generate_typedef_flag && strncmp(Char(Getattr(n, "type")), "enum", 4)) {
- String *lisp_name = lispify_name(n, Getattr(n, "name"), "'typename");
- Printf(f_cl, "\n(cffi:defctype %s %s)\n", lisp_name, Swig_typemap_lookup("cin", n, "", 0));
- emit_export(n, lisp_name);
- }
- return Language::typedefHandler(n);
-}
-
-int CFFI::enumDeclaration(Node *n) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- String *name = Getattr(n, "sym:name");
- bool slot_name_keywords;
- String *lisp_name = 0;
- if (name && Len(name) != 0) {
- lisp_name = lispify_name(n, name, "'enumname");
- if (GetFlag(n, "feature:bitfield")) {
- Printf(f_cl, "\n(cffi:defbitfield %s", lisp_name);
- } else {
- Printf(f_cl, "\n(cffi:defcenum %s", lisp_name);
- }
- slot_name_keywords = true;
-
- //Registering the enum name to the cin and cout typemaps
- Parm *pattern = NewParm(name, NULL, n);
- Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
- Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
- Delete(pattern);
- //Registering with the kind, i.e., enum
- pattern = NewParm(NewStringf("enum %s", name), NULL, n);
- Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
- Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
- Delete(pattern);
-
- } else {
- Printf(f_cl, "\n(defanonenum %s", name);
- slot_name_keywords = false;
- }
-
- for (Node *c = firstChild(n); c; c = nextSibling(c)) {
-
- String *slot_name = lispify_name(c, Getattr(c, "name"), "'enumvalue", slot_name_keywords);
- String *value = Getattr(c, "enumvalue");
-
- if (!value || GetFlag(n, "feature:bitfield:ignore_values"))
- Printf(f_cl, "\n\t%s", slot_name);
- else {
- String *type = Getattr(c, "type");
- String *converted_value = convert_literal(value, type);
- Printf(f_cl, "\n\t(%s #.%s)", slot_name, converted_value);
- Delete(converted_value);
- }
- Delete(value);
- }
-
- Printf(f_cl, ")\n");
-
- // No need to export keywords
- if (lisp_name && Len(lisp_name) != 0) {
- emit_export(n, lisp_name);
- } else {
- for (Node *c = firstChild(n); c; c = nextSibling(c))
- emit_export(c, lispify_name(c, Getattr(c, "name"), "'enumvalue"));
- }
-
- return SWIG_OK;
-}
-void CFFI::emit_class(Node *n) {
-
-#ifdef CFFI_WRAP_DEBUG
- Printf(stderr, "emit_class: ENTER... '%s'(%p)\n", Getattr(n, "sym:name"), n);
-#endif
-
- String *name = Getattr(n, "sym:name");
- String *lisp_name = lispify_name(n, lispy_name(Char(name)), "'classname");
-
- String *bases = Getattr(n, "bases");
- String *supers = NewString("(");
- if (bases) {
- int first = 1;
- for (Iterator i = First(bases); i.item; i = Next(i)) {
- if (!first)
- Printf(supers, " ");
- String *s = Getattr(i.item, "name");
- Printf(supers, "%s", lispify_name(i.item, lispy_name(Char(s)), "'classname"));
- }
- } else {
- // Printf(supers,"ff:foreign-pointer");
- }
-
- Printf(supers, ")");
- Printf(f_clos, "\n(cl:defclass %s%s", lisp_name, supers);
- Printf(f_clos, "\n ((ff-pointer :reader ff-pointer)))\n\n");
-
- Parm *pattern = NewParm(Getattr(n, "name"), NULL, n);
-
- Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
- SwigType_add_pointer(Getattr(pattern, "type"));
- Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
- SwigType_add_qualifier(Getattr(pattern, "type"), "const");
- Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
- SwigType_del_pointer(Getattr(pattern, "type"));
- SwigType_add_reference(Getattr(pattern, "type"));
- Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
-
-#ifdef CFFI_WRAP_DEBUG
- Printf(stderr, " pattern %s name %s .. ... %s .\n", pattern, lisp_name);
-#endif
-
- Delete(pattern);
-
- // Walk children to generate type definition.
- String *slotdefs = NewString(" ");
-
-#ifdef CFFI_WRAP_DEBUG
- Printf(stderr, " walking children...\n");
-#endif
-
- Node *c;
- for (c = firstChild(n); c; c = nextSibling(c)) {
- String *storage_type = Getattr(c, "storage");
- if ((!Strcmp(nodeType(c), "cdecl") && (!storage_type || Strcmp(storage_type, "typedef")))) {
- String *access = Getattr(c, "access");
-
- // hack. why would decl have a value of "variableHandler" and now "0"?
- String *childDecl = Getattr(c, "decl");
- // Printf(stderr,"childDecl = '%s' (%s)\n", childDecl, Getattr(c,"view"));
- if (!Strcmp(childDecl, "0"))
- childDecl = NewString("");
-
- SwigType *childType = NewStringf("%s%s", childDecl,
- Getattr(c, "type"));
- String *cname = (access && Strcmp(access, "public")) ? NewString("nil") : Copy(Getattr(c, "name"));
-
- if (!SwigType_isfunction(childType)) {
- // Printf(slotdefs, ";;; member functions don't appear as slots.\n ");
- // Printf(slotdefs, ";; ");
- // String *ns = listify_namespace(Getattr(n, "cffi:package"));
- String *ns = NewString("");
-#ifdef CFFI_WRAP_DEBUG
- Printf(stderr, "slot name = '%s' ns = '%s' class-of '%s' and type = '%s'\n", cname, ns, name, childType);
-#endif
- Printf(slotdefs, "(#.(swig-insert-id \"%s\" %s :type :slot :class \"%s\") %s)", cname, ns, name, childType); //compose_foreign_type(childType)
- Delete(ns);
- if (access && Strcmp(access, "public"))
- Printf(slotdefs, " ;; %s member", access);
-
- Printf(slotdefs, "\n ");
- }
- Delete(childType);
- Delete(cname);
- }
- }
-
-
- // String *ns_list = listify_namespace(Getattr(n,"cffi:namespace"));
- // update_package_if_needed(n,f_clhead);
- // Printf(f_clos,
- // "(swig-def-foreign-class \"%s\"\n %s\n (:%s\n%s))\n\n",
- // name, supers, kind, slotdefs);
-
- Delete(supers);
- // Delete(ns_list);
-
- // Parm *pattern = NewParm(name, NULL, n);
- // Swig_typemap_register("cin",pattern,lisp_name,NULL,NULL);
- //Swig_typemap_register("cout",pattern,lisp_name,NULL,NULL);
- //Delete(pattern);
-
-#ifdef CFFI_WRAP_DEBUG
- Printf(stderr, "emit_class: EXIT\n");
-#endif
-}
-
-// Includes structs
-void CFFI::emit_struct_union(Node *n, bool un = false) {
-#ifdef CFFI_DEBUG
- Printf(stderr, "struct/union %s\n", Getattr(n, "name"));
- Printf(stderr, "struct/union %s\n and %s", Getattr(n, "kind"), Getattr(n, "sym:name"));
-#endif
-
- String *name = Getattr(n, "sym:name");
- String *kind = Getattr(n, "kind");
-
- if (Strcmp(kind, "struct") != 0 && Strcmp(kind, "union") != 0) {
- Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
- Printf(stderr, " (name: %s)\n", name);
- SWIG_exit(EXIT_FAILURE);
- }
- String *lisp_name = lispify_name(n, name, "'classname");
-
- //Register the struct/union name to the cin and cout typemaps
-
- Parm *pattern = NewParm(name, NULL, n);
- Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
- Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
- Delete(pattern);
- //Registering with the kind, i.e., struct or union
- pattern = NewParm(NewStringf("%s %s", kind, name), NULL, n);
- Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
- Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
- Delete(pattern);
-
- if (un) {
- Printf(f_cl, "\n(cffi:defcunion %s", lisp_name);
- } else
- Printf(f_cl, "\n(cffi:defcstruct %s", lisp_name);
-
-
- for (Node *c = firstChild(n); c; c = nextSibling(c)) {
-#ifdef CFFI_DEBUG
- Printf(stderr, "struct/union %s\n", Getattr(c, "name"));
- Printf(stderr, "struct/union %s and %s \n", Getattr(c, "kind"), Getattr(c, "sym:name"));
-#endif
-
- if (Strcmp(nodeType(c), "cdecl")) {
- //C declaration ignore
- // Printf(stderr, "Structure %s has a slot that we can't deal with.\n",
- // name);
- // Printf(stderr, "nodeType: %s, name: %s, type: %s\n",
- // nodeType(c),
- // Getattr(c, "name"),
- // Getattr(c, "type"));
- // SWIG_exit(EXIT_FAILURE);
- } else {
- SwigType *childType = NewStringf("%s%s", Getattr(c, "decl"), Getattr(c, "type"));
-
- Node *node = NewHash();
- Setattr(node, "type", childType);
- Setfile(node, Getfile(n));
- Setline(node, Getline(n));
- const String *tm = Swig_typemap_lookup("cin", node, "", 0);
-
- String *typespec = tm ? NewString(tm) : NewString("");
-
- String *slot_name = lispify_name(c, Getattr(c, "sym:name"), "'slotname");
- if (slot_name && (Strcmp(slot_name, "t") == 0 || Strcmp(slot_name, "T") == 0))
- slot_name = NewStringf("t_var");
-
- if (SwigType_isarray(childType) && SwigType_array_ndim(childType) == 1) {
- String *dim = SwigType_array_getdim(childType, 0);
- Printf(f_cl, "\n\t(%s %s :count %s)", slot_name, typespec, dim);
- Delete(dim);
- } else
- Printf(f_cl, "\n\t(%s %s)", slot_name, typespec);
-
- Delete(node);
- Delete(childType);
- Delete(typespec);
- }
- }
-
- Printf(f_cl, ")\n");
-
- emit_export(n, lisp_name);
- for (Node *child = firstChild(n); child; child = nextSibling(child)) {
- if (!Strcmp(nodeType(child), "cdecl")) {
- emit_export(child, lispify_name(child, Getattr(child, "sym:name"), "'slotname"));
- }
- }
-
- /* Add this structure to the known lisp types */
- //Printf(stdout, "Adding %s foreign type\n", name);
- // add_defined_foreign_type(name);
-
-}
-
-void CFFI::emit_export(Node *n, String *name) {
- if (GetInt(n, "feature:export")) {
- String* package = Getattr(n, "feature:export:package");
- Printf(f_cl, "\n(cl:export '%s%s%s)\n", name, package ? " " : "",
- package ? package : "");
- }
-}
-
-void CFFI::emit_inline(Node *n, String *name) {
- if (GetInt(n, "feature:inline"))
- Printf(f_cl, "\n(cl:declaim (cl:inline %s))\n", name);
-}
-
-String *CFFI::lispify_name(Node *n, String *ty, const char *flag, bool kw) {
- String *intern_func = Getattr(n, "feature:intern_function");
- if (intern_func) {
- if (Strcmp(intern_func, "1") == 0)
- intern_func = NewStringf("swig-lispify");
- return NewStringf("#.(%s \"%s\" %s%s)", intern_func, ty, flag, kw ? " :keyword" : "");
- } else if (kw)
- return NewStringf(":%s", ty);
- else
- return ty;
-}
-
-/* utilities */
-/* returns new string w/ parens stripped */
-String *CFFI::strip_parens(String *string) {
- char *s = Char(string), *p;
- int len = Len(string);
- String *res;
-
- if (len == 0 || s[0] != '(' || s[len - 1] != ')') {
- return NewString(string);
- }
-
- p = (char *) malloc(len - 2 + 1);
- if (!p) {
- Printf(stderr, "Malloc failed\n");
- SWIG_exit(EXIT_FAILURE);
- }
-
- strncpy(p, s + 1, len - 1);
- p[len - 2] = 0; /* null terminate */
-
- res = NewString(p);
- free(p);
-
- return res;
-}
-
-String *CFFI::trim(String *str) {
- char *c = Char(str);
- while (*c != '\0' && isspace((int) *c))
- ++c;
- String *result = NewString(c);
- Chop(result);
- return result;
-}
-
-String *CFFI::infix_to_prefix(String *val, char split_op, const String *op, String *type) {
- List *ored = Split(val, split_op, -1);
-
- // some float hackery
- //i don't understand it, if you do then please explain
- // if ( ((split_op == '+') || (split_op == '-')) && Len(ored) == 2 &&
- // (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE ||
- // SwigType_type(type) == T_LONGDOUBLE) ) {
- // // check that we're not splitting a float
- // String *possible_result = convert_literal(val, type, false);
- // if (possible_result) return possible_result;
-
- // }
-
- // try parsing the split results. if any part fails, kick out.
- bool part_failed = false;
- if (Len(ored) > 1) {
- String *result = NewStringf("(%s", op);
- for (Iterator i = First(ored); i.item; i = Next(i)) {
- String *converted = convert_literal(i.item, type);
- if (converted) {
- Printf(result, " %s", converted);
- Delete(converted);
- } else {
- part_failed = true;
- break;
- }
- }
- Printf(result, ")");
- Delete(ored);
- return part_failed ? 0 : result;
- } else {
- Delete(ored);
- }
- return 0;
-}
-
-/* To be called by code generating the lisp interface
- Will return a String containing the literal based on type.
- Will return null if there are problems.
-
- try_to_split defaults to true (see stub above).
-*/
-String *CFFI::convert_literal(String *literal, String *type, bool try_to_split) {
- String *num_param = Copy(literal);
- String *trimmed = trim(num_param);
- String *num = strip_parens(trimmed), *res = 0;
- Delete(trimmed);
- char *s = Char(num);
-
- // very basic parsing of infix expressions.
- if (try_to_split) {
- if ((res = infix_to_prefix(num, '|', "cl:logior", type)))
- return res;
- if ((res = infix_to_prefix(num, '&', "cl:logand", type)))
- return res;
- if ((res = infix_to_prefix(num, '^', "cl:logxor", type)))
- return res;
- if ((res = infix_to_prefix(num, '*', "cl:*", type)))
- return res;
- if ((res = infix_to_prefix(num, '/', "cl:/", type)))
- return res;
- if ((res = infix_to_prefix(num, '+', "cl:+", type)))
- return res;
- if ((res = infix_to_prefix(num, '-', "cl:-", type)))
- return res;
- }
-
- if (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE) {
- // Use CL syntax for float literals
-
- // careful. may be a float identifier or float constant.
- char *num_start = Char(num);
- char *num_end = num_start + strlen(num_start) - 1;
-
- bool is_literal = isdigit(*num_start) || (*num_start == '.') || (*num_start == '+') || (*num_start == '-');
-
- String *lisp_exp = 0;
- if (is_literal) {
- if (*num_end == 'f' || *num_end == 'F') {
- lisp_exp = NewString("f");
- } else {
- lisp_exp = NewString("d");
- }
-
- if (*num_end == 'l' || *num_end == 'L' || *num_end == 'f' || *num_end == 'F') {
- *num_end = '\0';
- num_end--;
- }
-
- int exponents = Replaceall(num, "e", lisp_exp) + Replaceall(num, "E", lisp_exp);
-
- if (!exponents)
- Printf(num, "%s0", lisp_exp);
-
- if (exponents > 1 || (exponents + Replaceall(num, ".", ".") == 0)) {
- Delete(num);
- num = 0;
- }
- }
- return num;
- } else if (SwigType_type(type) == T_CHAR) {
- /* Use CL syntax for character literals */
- String* result = NewStringf("#\\%s", s);
- Delete(num);
- return result;
- } else if (SwigType_type(type) == T_STRING) {
- /* Use CL syntax for string literals */
- String* result = NewStringf("\"%s\"", num_param);
- Delete(num);
- return result;
- } else if (SwigType_type(type) == T_INT || SwigType_type(type) == T_UINT) {
- // Printf(stderr, "Is a T_INT or T_UINT %s, before replaceall\n", s);
- const char *num_start = Char(num);
- bool is_literal = isdigit(*num_start) || (*num_start == '.') || (*num_start == '+') || (*num_start == '-');
- if (is_literal) {
- Replaceall(num, "u", "");
- Replaceall(num, "U", "");
- Replaceall(num, "l", "");
- Replaceall(num, "L", "");
- }
-
- int i, j;
- if (sscanf(s, "%d >> %d", &i, &j) == 2) {
- String* result = NewStringf("(cl:ash %d -%d)", i, j);
- Delete(num);
- return result;
- } else if (sscanf(s, "%d << %d", &i, &j) == 2) {
- String* result = NewStringf("(cl:ash %d %d)", i, j);
- Delete(num);
- return result;
- }
- }
-
- if (Len(num) >= 2 && s[0] == '0') { /* octal or hex */
- if (s[1] == 'x'){
- Replace(num,"0","#",DOH_REPLACE_FIRST);
- }
- else{
- Replace(num,"0","#o",DOH_REPLACE_FIRST);
- }
- }
- return num;
-}
-
-//less flexible as it does the conversion in C, the lispify name does the conversion in lisp
-String *CFFI::lispy_name(char *name) {
- bool helper = false;
- String *new_name = NewString("");
- for (unsigned int i = 0; i < strlen(name); i++) {
- if (name[i] == '_' || name[i] == '-') {
- Printf(new_name, "%c", '-');
- helper = false;
- } else if (name[i] >= 'A' && name[i] <= 'Z') {
- if (helper)
- Printf(new_name, "%c", '-');
- Printf(new_name, "%c", ('a' + (name[i] - 'A')));
- helper = false;
- } else {
- helper = true;
- Printf(new_name, "%c", name[i]);
- }
- }
- return new_name;
-}
-
-extern "C" Language *swig_cffi(void) {
- return new CFFI();
-}
diff --git a/Source/Modules/contract.cxx b/Source/Modules/contract.cxx
index 7e0eaf9e0..dfc85ebe7 100644
--- a/Source/Modules/contract.cxx
+++ b/Source/Modules/contract.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* contract.cxx
*
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index edb79e13e..240a002b4 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* 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++ */
@@ -316,24 +316,24 @@ public:
if (!outfile) {
Printf(stderr, "Unable to determine outfile\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (directorsEnabled()) {
if (!outfile_h) {
Printf(stderr, "Unable to determine outfile_h\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
@@ -399,7 +399,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGCSHARP\n#define SWIGCSHARP\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "CSHARP");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@@ -670,7 +670,7 @@ public:
f_single_out = NewFile(filen, "w", SWIG_output_files());
if (!f_single_out) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -684,7 +684,7 @@ public:
File *f = NewFile(filen, "w", SWIG_output_files());
if (!f) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -1699,10 +1699,9 @@ public:
* addInterfaceNameAndUpcasts()
* ----------------------------------------------------------------------------- */
- void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *c_classname) {
- List *keys = Keys(base_list);
- for (Iterator it = First(keys); it.item; it = Next(it)) {
- Node *base = Getattr(base_list, it.item);
+ void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) {
+ for (Iterator it = First(base_list); it.item; it = Next(it)) {
+ Node *base = it.item;
SwigType *c_baseclassname = Getattr(base, "name");
String *interface_name = Getattr(base, "interface:name");
if (Len(interface_list))
@@ -1729,7 +1728,6 @@ public:
Delete(cptr_method_name);
Delete(interface_code);
}
- Delete(keys);
}
/* -----------------------------------------------------------------------------
@@ -1806,7 +1804,7 @@ public:
if (baselist) {
Iterator base = First(baselist);
while (base.item) {
- if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
+ if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) {
SwigType *baseclassname = Getattr(base.item, "name");
if (!c_baseclassname) {
String *name = getProxyName(baseclassname);
@@ -1825,7 +1823,7 @@ public:
}
}
}
- Hash *interface_bases = Getattr(n, "interface:bases");
+ List *interface_bases = Getattr(n, "interface:bases");
if (interface_bases)
addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
@@ -1964,9 +1962,32 @@ public:
// Only emit if there is at least one director method
Printf(proxy_class_code, "\n");
Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes) {\n");
- Printf(proxy_class_code,
- " global::System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance, null, methodTypes, null);\n");
- Printf(proxy_class_code, " bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(%s));\n", proxy_class_name);
+ Printf(proxy_class_code, " global::System.Reflection.MethodInfo[] methodInfos = this.GetType().GetMethods(\n");
+ Printf(proxy_class_code, " global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance);\n");
+ Printf(proxy_class_code, " foreach (global::System.Reflection.MethodInfo methodInfo in methodInfos) {\n");
+ Printf(proxy_class_code, " if (methodInfo.DeclaringType == null)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " if (methodInfo.Name != methodName)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " var parameters = methodInfo.GetParameters();\n");
+ Printf(proxy_class_code, " if (parameters.Length != methodTypes.Length)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " bool parametersMatch = true;\n");
+ Printf(proxy_class_code, " for (var i = 0; i < parameters.Length; i++) {\n");
+ Printf(proxy_class_code, " if (parameters[i].ParameterType != methodTypes[i]) {\n");
+ Printf(proxy_class_code, " parametersMatch = false;\n");
+ Printf(proxy_class_code, " break;\n");
+ Printf(proxy_class_code, " }\n");
+ Printf(proxy_class_code, " }\n\n");
+ Printf(proxy_class_code, " if (!parametersMatch)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " if (methodInfo.IsVirtual && (methodInfo.DeclaringType.IsSubclassOf(typeof(%s))) &&\n", proxy_class_name);
+ Printf(proxy_class_code, " methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType) {\n");
+ Printf(proxy_class_code, " return true;\n");
+ Printf(proxy_class_code, " }\n");
+ Printf(proxy_class_code, " }\n\n");
+ Printf(proxy_class_code, " return false;\n");
+
/* Could add this code to cover corner case where the GetMethod() returns a method which allows type
* promotion, eg it will return foo(double), if looking for foo(int).
if (hasDerivedMethod) {
@@ -1986,7 +2007,7 @@ public:
}
}
*/
- Printf(proxy_class_code, " return hasDerivedMethod;\n");
+ //Printf(proxy_class_code, " return hasDerivedMethod;\n");
Printf(proxy_class_code, " }\n");
}
@@ -2045,7 +2066,7 @@ public:
if (List *baselist = Getattr(n, "bases")) {
String *bases = 0;
for (Iterator base = First(baselist); base.item; base = Next(base)) {
- if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
+ if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface"))
continue; // TODO: warn about skipped non-interface bases
String *base_iname = Getattr(base.item, "interface:name");
if (!bases)
@@ -2096,7 +2117,7 @@ public:
if (proxy_flag) {
proxy_class_name = NewString(Getattr(n, "sym:name"));
- String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
+ String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
if (Node *outer = Getattr(n, "nested:outer")) {
String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
@@ -2122,12 +2143,12 @@ public:
full_imclass_name = NewStringf("%s", imclass_name);
if (Cmp(proxy_class_name, imclass_name) == 0) {
Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (Cmp(proxy_class_name, module_class_name) == 0) {
Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
} else {
if (namespce) {
@@ -2152,7 +2173,7 @@ public:
destructor_call = NewString("");
proxy_class_constants_code = NewString("");
- if (Getattr(n, "feature:interface")) {
+ if (GetFlag(n, "feature:interface")) {
interface_class_code = NewString("");
String *output_directory = outputDirectory(nspace);
f_interface = getOutputFile(output_directory, interface_name);
@@ -2323,7 +2344,7 @@ public:
String *pre_code = NewString("");
String *post_code = NewString("");
String *terminator_code = NewString("");
- bool is_interface = Getattr(parentNode(n), "feature:interface") != 0
+ bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable")
&& !static_flag && Getattr(n, "interface:owner") == 0;
if (!proxy_flag)
@@ -2553,8 +2574,8 @@ public:
Replaceall(imcall, "$imfuncname", intermediary_function_name);
String *excode = NewString("");
Node *directorNode = Getattr(n, "directorNode");
- if (directorNode) {
- UpcallData *udata = Getattr(directorNode, "upcalldata");
+ UpcallData *udata = directorNode ? Getattr(directorNode, "upcalldata") : 0;
+ if (udata) {
String *methid = Getattr(udata, "class_methodidx");
if (!Cmp(return_type, "void"))
@@ -2572,6 +2593,7 @@ public:
} else {
Replaceall(imcall, "$imfuncname", intermediary_function_name);
}
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
@@ -2615,6 +2637,7 @@ public:
if ((tm = Swig_typemap_lookup("csvarin", variable_parm, "", 0))) {
substituteClassname(cvariable_type, tm);
Replaceall(tm, "$csinput", "value");
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarin", variable_parm);
Printf(proxy_class_code, "%s", tm);
@@ -2629,6 +2652,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarout", n);
Printf(proxy_class_code, "%s", tm);
@@ -3141,6 +3165,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
@@ -3179,6 +3204,7 @@ public:
if ((tm = Getattr(p, "tmap:csvarin"))) {
substituteClassname(pt, tm);
Replaceall(tm, "$csinput", "value");
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarin", p);
Printf(module_class_code, "%s", tm);
@@ -3193,6 +3219,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarout", n);
Printf(module_class_code, "%s", tm);
@@ -3660,7 +3687,7 @@ public:
if (newdir_error) {
Printf(stderr, "%s\n", newdir_error);
Delete(newdir_error);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
Delete(nspace_subdirectory);
diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx
index b7283eac2..31f300f2e 100644
--- a/Source/Modules/d.cxx
+++ b/Source/Modules/d.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* d.cxx
*
@@ -378,24 +378,24 @@ public:
if (!outfile) {
Printf(stderr, "Unable to determine outfile\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (directorsEnabled()) {
if (!outfile_h) {
Printf(stderr, "Unable to determine outfile_h\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
@@ -472,7 +472,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGD\n#define SWIGD\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "D");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@@ -518,7 +518,7 @@ public:
File *im_d_file = NewFile(filen, "w", SWIG_output_files());
if (!im_d_file) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -549,7 +549,7 @@ public:
File *proxy_d_file = NewFile(filen, "w", SWIG_output_files());
if (!proxy_d_file) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -583,7 +583,7 @@ public:
File *file = NewFile(filename, "w", SWIG_output_files());
if (!file) {
FileErrorDisplay(filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(filename);
@@ -863,7 +863,7 @@ public:
File *class_file = NewFile(filename, "w", SWIG_output_files());
if (!class_file) {
FileErrorDisplay(filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filename));
Delete(filename);
@@ -1335,7 +1335,7 @@ public:
Delete(output_directory);
if (!class_file) {
FileErrorDisplay(filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filename));
Delete(filename);
@@ -2898,6 +2898,7 @@ private:
} else {
Replaceall(imcall, "$imfuncname", intermediary_function_name);
}
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
@@ -3100,6 +3101,7 @@ private:
else
Replaceall(tm, "$owner", "false");
replaceClassname(tm, t);
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
@@ -3400,7 +3402,7 @@ private:
} else {
Printv(upcasts_code,
"SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
- "(", baseclassname, " *objectRef) {\n",
+ "(", classname, " *objectRef) {\n",
" return (", baseclassname, " *)objectRef;\n"
"}\n",
"\n", NIL);
@@ -3434,7 +3436,7 @@ private:
class_file = NewFile(filename, "w", SWIG_output_files());
if (!class_file) {
FileErrorDisplay(filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filename));
Delete(filename);
@@ -3756,7 +3758,7 @@ private:
Swig_error(input_file, line_number,
"Class name cannot be equal to intermediary D module name: %s\n",
class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
String *nspace = getNSpace();
@@ -3769,7 +3771,7 @@ private:
Swig_error(input_file, line_number,
"Class name cannot be the same as the root package it is in: %s\n",
class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(dotless_package);
} else {
@@ -3778,7 +3780,7 @@ private:
Swig_error(input_file, line_number,
"Class name cannot be the same as the outermost namespace it is in: %s\n",
class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(outer);
}
@@ -3790,7 +3792,7 @@ private:
Swig_error(input_file, line_number,
"Class name cannot be the same as the innermost namespace it is in: %s\n",
class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(inner);
} else {
@@ -3798,7 +3800,7 @@ private:
Swig_error(input_file, line_number,
"Class name cannot be equal to proxy D module name: %s\n",
class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
}
@@ -4498,7 +4500,7 @@ private:
if (newdir_error) {
Printf(stderr, "%s\n", newdir_error);
Delete(newdir_error);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
Delete(nspace_subdirectory);
diff --git a/Source/Modules/directors.cxx b/Source/Modules/directors.cxx
index 196974792..14e2e8466 100644
--- a/Source/Modules/directors.cxx
+++ b/Source/Modules/directors.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* directors.cxx
*
@@ -97,7 +97,6 @@ String *Swig_director_declaration(Node *n) {
String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
String *func;
- int i = 0;
int comma = 0;
Parm *p = parms;
SwigType *pt;
@@ -115,7 +114,6 @@ String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
pname = Getattr(p, "name");
Printf(func, "%s", pname);
comma = 1;
- i++;
}
p = nextSibling(p);
}
@@ -235,3 +233,38 @@ void Swig_director_parms_fixup(ParmList *parms) {
}
}
+/* -----------------------------------------------------------------------------
+ * Swig_director_can_unwrap()
+ *
+ * Determine whether a function's return type can be returned as an existing
+ * target language object instead of creating a new target language object.
+ * Must be a director class and only for return by pointer or reference only
+ * (not by value or by pointer to pointer etc).
+ * ----------------------------------------------------------------------------- */
+
+bool Swig_director_can_unwrap(Node *n) {
+
+ // FIXME: this will not try to unwrap directors returned as non-director
+ // base class pointers!
+
+ bool unwrap = false;
+
+ String *type = Getattr(n, "type");
+ SwigType *t = SwigType_typedef_resolve_all(type);
+ SwigType *t1 = SwigType_strip_qualifiers(t);
+ SwigType *prefix = SwigType_prefix(t1);
+
+ if (Strcmp(prefix, "p.") == 0 || Strcmp(prefix, "r.") == 0) {
+ Node *parent = Swig_methodclass(n);
+ Node *module = Getattr(parent, "module");
+ Node *target = Swig_directormap(module, t1);
+ if (target)
+ unwrap = true;
+ }
+
+ Delete(prefix);
+ Delete(t1);
+ Delete(t);
+
+ return unwrap;
+}
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx
index edfa57ccd..74adc5400 100644
--- a/Source/Modules/emit.cxx
+++ b/Source/Modules/emit.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* emit.cxx
*
diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx
index c4d61e583..bf63bec63 100644
--- a/Source/Modules/go.cxx
+++ b/Source/Modules/go.cxx
@@ -1,6 +1,10 @@
/* -----------------------------------------------------------------------------
- * See the LICENSE file for information on copyright, usage and redistribution
- * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ * This file is part of SWIG, which is licensed as a whole under version 3
+ * (or any later version) of the GNU General Public License. Some additional
+ * terms also apply to certain portions of SWIG. The full details of the SWIG
+ * license and copyrights can be found in the LICENSE and COPYRIGHT files
+ * included with the SWIG source code as distributed by the SWIG developers
+ * and at https://www.swig.org/legal.html.
*
* go.cxx
*
@@ -244,7 +248,6 @@ private:
virtual void main(int argc, char *argv[]) {
SWIG_library_directory("go");
- bool display_help = false;
bool saw_nocgo_flag = false;
// Process command line options.
@@ -329,7 +332,6 @@ private:
Swig_arg_error();
}
} else if (strcmp(argv[i], "-help") == 0) {
- display_help = true;
Printf(stdout, "%s\n", usage);
}
}
@@ -337,7 +339,7 @@ private:
if (saw_nocgo_flag) {
Printf(stderr, "SWIG -go: -no-cgo option is no longer supported\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (gccgo_flag && !pkgpath_option && !prefix_option) {
@@ -351,14 +353,6 @@ private:
Preprocessor_define("SWIGGO_GCCGO 1", 0);
}
- // This test may be removed in the future, when we can assume that
- // everybody has upgraded to Go 1.1. The code below is prepared
- // for this test to simply be taken out.
- if (intgo_type_size == 0 && !display_help) {
- Printf(stderr, "SWIG -go: -intgosize option required but not specified\n");
- SWIG_exit(EXIT_FAILURE);
- }
-
if (intgo_type_size == 32) {
Preprocessor_define("SWIGGO_INTGO_SIZE 32", 0);
} else if (intgo_type_size == 64) {
@@ -377,7 +371,7 @@ private:
/* ---------------------------------------------------------------------
* top()
*
- * For 6g/8g, we are going to create the following files:
+ * For gc, we are going to create the following files:
*
* 1) A .c or .cxx file compiled with gcc. This file will contain
* function wrappers. Each wrapper will take a pointer to a
@@ -453,7 +447,7 @@ private:
FILE *swig_input = Swig_open(swig_filename);
if (swig_input == NULL) {
FileErrorDisplay(swig_filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
String *swig_input_content = Swig_read_file(swig_input);
siphash(&hash, Char(swig_input_content), Len(swig_input_content));
@@ -467,25 +461,25 @@ private:
f_c_begin = NewFile(c_filename, "w", SWIG_output_files());
if (!f_c_begin) {
FileErrorDisplay(c_filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (directorsEnabled()) {
if (!c_filename_h) {
Printf(stderr, "Unable to determine outfile_h\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_c_directors_h = NewFile(c_filename_h, "w", SWIG_output_files());
if (!f_c_directors_h) {
FileErrorDisplay(c_filename_h);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
f_go_begin = NewFile(go_filename, "w", SWIG_output_files());
if (!f_go_begin) {
FileErrorDisplay(go_filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_c_runtime = NewString("");
@@ -518,6 +512,9 @@ private:
Swig_register_filebyname("cgo_comment_typedefs", f_cgo_comment_typedefs);
Swig_banner(f_c_begin);
+
+ Swig_obligatory_macros(f_c_runtime, "GO");
+
if (CPlusPlus) {
Printf(f_c_begin, "\n// source: %s\n\n", swig_filename);
} else {
@@ -525,6 +522,7 @@ private:
}
Printf(f_c_runtime, "#define SWIGMODULE %s\n", module);
+
if (gccgo_flag) {
Printf(f_c_runtime, "#define SWIGGO_PREFIX %s\n", go_prefix);
}
@@ -1262,9 +1260,15 @@ private:
String *goin = goGetattr(p, "tmap:goin");
if (goin == NULL) {
- Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL);
+ Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
+ bool need_close = false;
if ((i == 0 && info->is_destructor) || ((i > 0 || !info->receiver || info->base || info->is_constructor) && goTypeIsInterface(p, pt))) {
- Printv(f_go_wrappers, ".Swigcptr()", NULL);
+ Printv(f_go_wrappers, "getSwigcptr(", NULL);
+ need_close = true;
+ }
+ Printv(f_go_wrappers, ln, NULL);
+ if (need_close) {
+ Printv(f_go_wrappers, ")", NULL);
}
Printv(f_go_wrappers, "\n", NULL);
Setattr(p, "emit:goinput", ln);
@@ -1457,7 +1461,7 @@ private:
p = getParm(p);
SwigType *pt = Copy(Getattr(p, "type"));
- if (SwigType_isarray(pt)) {
+ if (SwigType_isarray(pt) && Getattr(p, "tmap:gotype") == NULL) {
SwigType_del_array(pt);
SwigType_add_pointer(pt);
}
@@ -2208,95 +2212,127 @@ private:
}
for (Node *ni = Getattr(base, "firstChild"); ni; ni = nextSibling(ni)) {
-
- if (GetFlag(ni, "feature:ignore")) {
- continue;
+ int r = goBaseEntry(n, bases, local, ni);
+ if (r != SWIG_OK) {
+ return r;
}
+ }
- if (!is_public(ni)) {
- continue;
+ List *baselist = Getattr(base, "bases");
+ if (baselist && Len(baselist) > 0) {
+ for (Iterator b = First(baselist); b.item; b = Next(b)) {
+ List *nb = Copy(bases);
+ Append(nb, Getattr(b.item, "classtype"));
+ int r = addBase(n, b.item, nb, local);
+ Delete(nb);
+ if (r != SWIG_OK) {
+ return r;
+ }
}
+ }
- String *type = Getattr(ni, "nodeType");
- if (Strcmp(type, "constructor") == 0 || Strcmp(type, "destructor") == 0 || Strcmp(type, "enum") == 0 || Strcmp(type, "using") == 0 || Strcmp(type, "classforward") == 0 || Strcmp(type, "template") == 0) {
- continue;
- }
- String *storage = Getattr(ni, "storage");
- if (storage && (Strcmp(storage, "typedef") == 0 || Strcmp(storage, "friend") == 0)) {
- continue;
- }
+ return SWIG_OK;
+ }
- String *mname = Getattr(ni, "sym:name");
- if (!mname) {
- continue;
- }
+ /* ------------------------------------------------------------
+ * goBaseEntry()
+ *
+ * Implement one entry defined in a parent class for a child class.
+ * n is the child class.
+ * ------------------------------------------------------------ */
- String *lname = Getattr(ni, "name");
- if (Getattr(class_methods, lname)) {
- continue;
- }
- if (Getattr(local, lname)) {
- continue;
- }
- Setattr(local, lname, NewString(""));
+ int goBaseEntry(Node* n, List* bases, Hash *local, Node* entry) {
+ if (GetFlag(entry, "feature:ignore")) {
+ return SWIG_OK;
+ }
- String *ty = NewString(Getattr(ni, "type"));
- SwigType_push(ty, Getattr(ni, "decl"));
- String *fullty = SwigType_typedef_resolve_all(ty);
- bool is_function = SwigType_isfunction(fullty) ? true : false;
- Delete(ty);
- Delete(fullty);
+ if (!is_public(entry)) {
+ return SWIG_OK;
+ }
+
+ String *type = Getattr(entry, "nodeType");
+ if (Strcmp(type, "constructor") == 0 || Strcmp(type, "destructor") == 0 || Strcmp(type, "enum") == 0 || Strcmp(type, "using") == 0 || Strcmp(type, "classforward") == 0 || Strcmp(type, "template") == 0) {
+ return SWIG_OK;
+ }
+
+ if (Strcmp(type, "extend") == 0) {
+ for (Node* extend = firstChild(entry); extend; extend = nextSibling(extend)) {
+ if (isStatic(extend)) {
+ // If we don't do this, the extend_default test case fails.
+ continue;
+ }
- if (is_function) {
- int r = goBaseMethod(n, bases, ni);
+ int r = goBaseEntry(n, bases, local, extend);
if (r != SWIG_OK) {
return r;
}
+ }
+ return SWIG_OK;
+ }
- if (Getattr(ni, "sym:overloaded")) {
- for (Node *on = Getattr(ni, "sym:nextSibling"); on; on = Getattr(on, "sym:nextSibling")) {
- r = goBaseMethod(n, bases, on);
- if (r != SWIG_OK) {
- return r;
- }
- }
+ String *storage = Getattr(entry, "storage");
+ if (storage && (Strcmp(storage, "typedef") == 0 || Strcmp(storage, "friend") == 0)) {
+ return SWIG_OK;
+ }
- String *receiver = class_receiver;
- bool is_static = isStatic(ni);
- if (is_static) {
- receiver = NULL;
- }
- String *go_name = buildGoName(Getattr(ni, "sym:name"), is_static, false);
- r = makeDispatchFunction(ni, go_name, receiver, is_static, NULL, false);
- Delete(go_name);
+ String *mname = Getattr(entry, "sym:name");
+ if (!mname) {
+ return SWIG_OK;
+ }
+
+ String *lname = Getattr(entry, "name");
+ if (Getattr(class_methods, lname)) {
+ return SWIG_OK;
+ }
+ if (Getattr(local, lname)) {
+ return SWIG_OK;
+ }
+ Setattr(local, lname, NewString(""));
+
+ String *ty = NewString(Getattr(entry, "type"));
+ SwigType_push(ty, Getattr(entry, "decl"));
+ String *fullty = SwigType_typedef_resolve_all(ty);
+ bool is_function = SwigType_isfunction(fullty) ? true : false;
+ Delete(ty);
+ Delete(fullty);
+
+ if (is_function) {
+ int r = goBaseMethod(n, bases, entry);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ if (Getattr(entry, "sym:overloaded")) {
+ for (Node *on = Getattr(entry, "sym:nextSibling"); on; on = Getattr(on, "sym:nextSibling")) {
+ r = goBaseMethod(n, bases, on);
if (r != SWIG_OK) {
return r;
}
}
- } else {
- int r = goBaseVariable(n, bases, ni);
- if (r != SWIG_OK) {
- return r;
- }
- }
- }
- List *baselist = Getattr(base, "bases");
- if (baselist && Len(baselist) > 0) {
- for (Iterator b = First(baselist); b.item; b = Next(b)) {
- List *nb = Copy(bases);
- Append(nb, Getattr(b.item, "classtype"));
- int r = addBase(n, b.item, nb, local);
- Delete(nb);
+ String *receiver = class_receiver;
+ bool is_static = isStatic(entry);
+ if (is_static) {
+ receiver = NULL;
+ }
+ String *go_name = buildGoName(Getattr(entry, "sym:name"), is_static, false);
+ r = makeDispatchFunction(entry, go_name, receiver, is_static, NULL, false);
+ Delete(go_name);
if (r != SWIG_OK) {
- return r;
+ return r;
}
}
+ } else {
+ int r = goBaseVariable(n, bases, entry);
+ if (r != SWIG_OK) {
+ return r;
+ }
}
return SWIG_OK;
}
+
/* ------------------------------------------------------------
* goBaseMethod()
*
@@ -2351,7 +2387,13 @@ private:
}
}
- int r = makeWrappers(method, go_name, overname, wname, bases, Getattr(method, "parms"), result, is_static);
+ // A method added by %extend in a base class may have void parms.
+ ParmList* parms = Getattr(method, "parms");
+ if (parms != NULL && SwigType_type(Getattr(parms, "type")) == T_VOID) {
+ parms = NULL;
+ }
+
+ int r = makeWrappers(method, go_name, overname, wname, bases, parms, result, is_static);
Swig_restore(method);
@@ -2506,7 +2548,7 @@ private:
Printv(interfaces, "\tSwigIs", go_base_name, "()\n", NULL);
Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet", go_base_name, "() ", go_base_type, " {\n", NULL);
- Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(p.Swigcptr())\n", NULL);
+ Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(getSwigcptr(p))\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_type, "\n", NULL);
@@ -2708,7 +2750,7 @@ private:
Printv(f_go_wrappers, "}\n\n", NULL);
Printv(f_go_wrappers, "func (p *", director_struct_name, ") Swigcptr() uintptr {\n", NULL);
- Printv(f_go_wrappers, "\treturn p.", go_type_name, ".Swigcptr()\n", NULL);
+ Printv(f_go_wrappers, "\treturn getSwigcptr(p.", go_type_name, ")\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
Printv(f_go_wrappers, "func (p *", director_struct_name, ") SwigIs", go_name, "() {\n", NULL);
@@ -2866,9 +2908,15 @@ private:
String *goin = goGetattr(p, "tmap:goin");
if (goin == NULL) {
- Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL);
+ Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
+ bool need_close = false;
if (goTypeIsInterface(p, pt)) {
- Printv(f_go_wrappers, ".Swigcptr()", NULL);
+ Printv(f_go_wrappers, "getSwigcptr(", NULL);
+ need_close = true;
+ }
+ Printv(f_go_wrappers, ln, NULL);
+ if (need_close) {
+ Printv(f_go_wrappers, ")", NULL);
}
Printv(f_go_wrappers, "\n", NULL);
} else {
@@ -3461,9 +3509,15 @@ private:
// the goin typemap.
String *goin = goGetattr(p, "tmap:goin");
if (goin == NULL) {
- Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL);
+ Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
+ bool need_close = false;
if (goTypeIsInterface(p, pt)) {
- Printv(f_go_wrappers, ".Swigcptr()", NULL);
+ Printv(f_go_wrappers, "getSwigcptr(", NULL);
+ need_close = true;
+ }
+ Printv(f_go_wrappers, ln, NULL);
+ if (need_close) {
+ Printv(f_go_wrappers, ")", NULL);
}
Printv(f_go_wrappers, "\n", NULL);
} else {
@@ -3472,7 +3526,7 @@ private:
goin = Copy(goin);
Replaceall(goin, "$input", ln);
Replaceall(goin, "$result", ivar);
- Printv(f_go_wrappers, goin, NULL);
+ Printv(f_go_wrappers, goin, "\n", NULL);
Delete(goin);
}
@@ -3534,114 +3588,11 @@ private:
Printv(f_go_wrappers, "}\n\n", NULL);
- // Define a method in the C++ director class that the C++ upcall
- // function can call. This permits an upcall to a protected
- // method.
-
if (!GetFlag(n, "abstract")) {
- String *upcall_method_name = NewString("_swig_upcall_");
- Append(upcall_method_name, name);
- if (overname) {
- Append(upcall_method_name, overname);
- }
- SwigType *rtype = Getattr(n, "classDirectorMethods:type");
- String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0);
- Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
- Delete(upcall_decl);
-
- Printv(f_c_directors_h, " ", NULL);
- if (SwigType_type(result) != T_VOID) {
- Printv(f_c_directors_h, "return ", NULL);
- }
-
- String *super_call = Swig_method_call(super, parms);
- Printv(f_c_directors_h, super_call, ";\n", NULL);
- Delete(super_call);
-
- Printv(f_c_directors_h, " }\n", NULL);
-
- // Define the C++ function that the Go function calls.
-
- SwigType *first_type = NULL;
- Parm *first_parm = parms;
- if (!is_static) {
- first_type = NewString("SwigDirector_");
- Append(first_type, class_name);
- SwigType_add_pointer(first_type);
- first_parm = NewParm(first_type, "p", n);
- set_nextSibling(first_parm, parms);
- }
-
- Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL);
-
- Setattr(n, "wrap:name", upcall_wname);
-
- String *action = NewString("");
- if (SwigType_type(result) != T_VOID) {
- Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL);
- if (SwigType_isreference(result)) {
- Printv(action, "&", NULL);
- }
- }
- Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL);
-
- p = parms;
- int i = 0;
- while (p != NULL) {
- if (SwigType_type(Getattr(p, "type")) != T_VOID) {
- String *pname = Swig_cparm_name(NULL, i + 1);
- if (i > 0) {
- Printv(action, ", ", NULL);
- }
-
- // A parameter whose type is a reference is converted into a
- // pointer type by gcCTypeForGoValue. We are calling a
- // function which expects a reference so we need to convert
- // back.
- if (SwigType_isreference(Getattr(p, "type"))) {
- Printv(action, "*", NULL);
- }
-
- Printv(action, pname, NULL);
- Delete(pname);
- i++;
- }
- p = nextSibling(p);
- }
- Printv(action, ");", NULL);
- Setattr(n, "wrap:action", action);
-
- cgoWrapperInfo info;
-
- info.n = n;
- info.go_name = go_name;
- info.overname = overname;
- info.wname = upcall_wname;
- info.base = NULL;
- info.parms = first_parm;
- info.result = result;
- info.is_static = is_static;
- info.receiver = NULL;
- info.is_constructor = false;
- info.is_destructor = false;
-
- int r = cgoGccWrapper(&info);
- if (r != SWIG_OK) {
- return r;
- }
-
- Delete(first_type);
- if (first_parm != parms) {
- Delete(first_parm);
- }
-
- Swig_restore(n);
- Delete(upcall_method_name);
-
// Define a function that uses the Go director type that other
// methods in the Go type can call to get parent methods.
- Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(p ", cn, NULL);
+ Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(swig_p ", cn, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
@@ -3694,7 +3645,7 @@ private:
}
}
- Printv(call, "C.", upcall_wname, "(C.uintptr_t(p.(*",
+ Printv(call, "C.", upcall_wname, "(C.uintptr_t(swig_p.(*",
director_struct_name, ").", go_type_name, ")", NULL);
p = parms;
@@ -3709,9 +3660,15 @@ private:
String *goin = goGetattr(p, "tmap:goin");
if (goin == NULL) {
- Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL);
+ Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
+ bool need_close = false;
if (goTypeIsInterface(p, pt)) {
- Printv(f_go_wrappers, ".Swigcptr()", NULL);
+ Printv(f_go_wrappers, "getSwigcptr(", NULL);
+ need_close = true;
+ }
+ Printv(f_go_wrappers, ln, NULL);
+ if (need_close) {
+ Printv(f_go_wrappers, ")", NULL);
}
Printv(f_go_wrappers, "\n", NULL);
} else {
@@ -3720,7 +3677,7 @@ private:
goin = Copy(goin);
Replaceall(goin, "$input", ln);
Replaceall(goin, "$result", ivar);
- Printv(f_go_wrappers, goin, NULL);
+ Printv(f_go_wrappers, goin, "\n", NULL);
Delete(goin);
}
@@ -3782,6 +3739,109 @@ private:
if (wt) {
Delete(wt);
}
+
+ // Define a method in the C++ director class that the C++
+ // upcall function can call. This permits an upcall to a
+ // protected method.
+
+ String *upcall_method_name = NewString("_swig_upcall_");
+ Append(upcall_method_name, name);
+ if (overname) {
+ Append(upcall_method_name, overname);
+ }
+ SwigType *rtype = Getattr(n, "classDirectorMethods:type");
+ String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0);
+ Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
+ Delete(upcall_decl);
+
+ Printv(f_c_directors_h, " ", NULL);
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f_c_directors_h, "return ", NULL);
+ }
+
+ String *super_call = Swig_method_call(super, parms);
+ Printv(f_c_directors_h, super_call, ";\n", NULL);
+ Delete(super_call);
+
+ Printv(f_c_directors_h, " }\n", NULL);
+
+ // Define the C++ function that the Go function calls.
+
+ SwigType *first_type = NULL;
+ Parm *first_parm = parms;
+ if (!is_static) {
+ first_type = NewString("SwigDirector_");
+ Append(first_type, class_name);
+ SwigType_add_pointer(first_type);
+ first_parm = NewParm(first_type, "p", n);
+ set_nextSibling(first_parm, parms);
+ }
+
+ Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL);
+
+ Setattr(n, "wrap:name", upcall_wname);
+
+ String *action = NewString("");
+ if (SwigType_type(result) != T_VOID) {
+ Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL);
+ if (SwigType_isreference(result)) {
+ Printv(action, "&", NULL);
+ }
+ }
+ Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL);
+
+ p = parms;
+ int i = 0;
+ while (p != NULL) {
+ if (SwigType_type(Getattr(p, "type")) != T_VOID) {
+ String *pname = Swig_cparm_name(NULL, i + 1);
+ if (i > 0) {
+ Printv(action, ", ", NULL);
+ }
+
+ // A parameter whose type is a reference is converted into a
+ // pointer type by gcCTypeForGoValue. We are calling a
+ // function which expects a reference so we need to convert
+ // back.
+ if (SwigType_isreference(Getattr(p, "type"))) {
+ Printv(action, "*", NULL);
+ }
+
+ Printv(action, pname, NULL);
+ Delete(pname);
+ i++;
+ }
+ p = nextSibling(p);
+ }
+ Printv(action, ");", NULL);
+ Setattr(n, "wrap:action", action);
+
+ cgoWrapperInfo info;
+
+ info.n = n;
+ info.go_name = go_name;
+ info.overname = overname;
+ info.wname = upcall_wname;
+ info.base = NULL;
+ info.parms = first_parm;
+ info.result = result;
+ info.is_static = is_static;
+ info.receiver = NULL;
+ info.is_constructor = false;
+ info.is_destructor = false;
+
+ int r = cgoGccWrapper(&info);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ Delete(first_type);
+ if (first_parm != parms) {
+ Delete(first_parm);
+ }
+
+ Swig_restore(n);
+ Delete(upcall_method_name);
}
// The Go function which invokes the method. This is called by
@@ -3830,7 +3890,7 @@ private:
if (SwigType_type(result) != T_VOID) {
Printv(call, "swig_r = ", NULL);
if (result_is_interface) {
- Printv(call, result_wrapper, "(", NULL);
+ Printv(call, result_wrapper, "(getSwigcptr(", NULL);
}
}
Printv(call, "swig_p.", go_with_over_name, "(", NULL);
@@ -3890,7 +3950,7 @@ private:
Printv(call, ")", NULL);
if (result_is_interface) {
- Printv(call, ".Swigcptr())", NULL);
+ Printv(call, "))", NULL);
}
Printv(call, "\n", NULL);
@@ -5085,7 +5145,7 @@ private:
}
String *t = Copy(type);
- if (SwigType_isarray(t)) {
+ if (SwigType_isarray(t) && Getattr(n, "tmap:gotype") == NULL) {
SwigType_del_array(t);
SwigType_add_pointer(t);
}
@@ -5226,10 +5286,14 @@ private:
}
}
- if (Getattr(undefined_types, ty) && !Getattr(defined_types, ty)) {
+ String* go_type = goType(n, ty);
+
+ if (Getattr(undefined_types, ty) && !Getattr(defined_types, go_type)) {
+ Delete(go_type);
return goWrapperType(n, type, true);
}
+ Delete(go_type);
return goType(n, type);
}
@@ -5280,7 +5344,7 @@ private:
* gcCTypeForGoValue()
*
* Given a type, return the C/C++ type which will be used to catch
- * the value in Go. This is the 6g/8g version.
+ * the value in Go. This is the gc version.
* ---------------------------------------------------------------------- */
String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) {
@@ -5289,7 +5353,19 @@ private:
String *tail = NewString("");
SwigType *t = SwigType_typedef_resolve_all(type);
- if (!SwigType_isreference(t)) {
+ bool is_const_ref = false;
+ if (SwigType_isreference(t)) {
+ SwigType* tt = Copy(t);
+ SwigType_del_reference(tt);
+ if (SwigType_isqualifier(tt)) {
+ String* q = SwigType_parm(tt);
+ if (Strcmp(q, "const") == 0) {
+ is_const_ref = true;
+ }
+ }
+ Delete(tt);
+ }
+ if (!is_const_ref) {
while (Strncmp(gt, "*", 1) == 0) {
Replace(gt, "*", "", DOH_REPLACE_FIRST);
Printv(tail, "*", NULL);
@@ -5433,17 +5509,6 @@ private:
}
/* ----------------------------------------------------------------------
- * gccgoCTypeForGoValue()
- *
- * Given a type, return the C/C++ type which will be used to catch
- * the value in Go. This is the gccgo version.
- * ---------------------------------------------------------------------- */
-
- String *gccgoCTypeForGoValue(Node *n, SwigType *type, String *name) {
- return gcCTypeForGoValue(n, type, name);
- }
-
- /* ----------------------------------------------------------------------
* goTypeIsInterface
*
* Return whether this C++ type is represented as an interface type
diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx
index d7d3da8fc..605e03197 100644
--- a/Source/Modules/guile.cxx
+++ b/Source/Modules/guile.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* 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
@@ -132,7 +131,7 @@ public:
if (argv[i]) {
if (strcmp(argv[i], "-help") == 0) {
fputs(usage, stdout);
- SWIG_exit(EXIT_SUCCESS);
+ Exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "-prefix") == 0) {
if (argv[i + 1]) {
prefix = NewString(argv[i + 1]);
@@ -176,7 +175,7 @@ public:
procdoc = NewFile(argv[i + 1], "w", SWIG_output_files());
if (!procdoc) {
FileErrorDisplay(argv[i + 1]);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
@@ -255,7 +254,7 @@ public:
if (goops) {
if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) {
Printf(stderr, "guile: GOOPS support requires passive or module linkage\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
@@ -298,7 +297,7 @@ public:
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
@@ -322,7 +321,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGGUILE\n#define SWIGGUILE\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "GUILE");
/* Write out directives and declarations */
@@ -476,7 +475,8 @@ public:
Printf(f_init, "}\n");
break;
default:
- abort(); // for now
+ fputs("Fatal internal error: Invalid Guile linkage setting.\n", stderr);
+ Exit(EXIT_FAILURE);
}
if (scmstub) {
@@ -495,7 +495,7 @@ public:
File *scmstubfile = NewFile(fname, "w", SWIG_output_files());
if (!scmstubfile) {
FileErrorDisplay(fname);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(fname);
@@ -526,7 +526,7 @@ public:
File *goopsfile = NewFile(fname, "w", SWIG_output_files());
if (!goopsfile) {
FileErrorDisplay(fname);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(fname);
Swig_banner_target_lang(goopsfile, ";;;");
@@ -947,20 +947,16 @@ public:
if (!is_setter) {
/* Strip off "-get" */
- char *pws_name = (char *) malloc(sizeof(char) * (len - 3));
- strncpy(pws_name, pc, len - 3);
- pws_name[len - 4] = 0;
if (struct_member == 2) {
/* There was a setter, so create a procedure with setter */
Printf(f_init, "scm_c_define");
- Printf(f_init, "(\"%s\", " "scm_make_procedure_with_setter(getter, setter));\n", pws_name);
+ Printf(f_init, "(\"%.*s\", " "scm_make_procedure_with_setter(getter, setter));\n", pc, len - 4);
} else {
/* There was no setter, so make an alias to the getter */
Printf(f_init, "scm_c_define");
- Printf(f_init, "(\"%s\", getter);\n", pws_name);
+ Printf(f_init, "(\"%.*s\", getter);\n", pc, len - 4);
}
- Printf(exported_symbols, "\"%s\", ", pws_name);
- free(pws_name);
+ Printf(exported_symbols, "\"%.*s\", ", pc, len - 4);
}
} else {
/* Register the function */
diff --git a/Source/Modules/interface.cxx b/Source/Modules/interface.cxx
index fee6cd7da..5a9242399 100644
--- a/Source/Modules/interface.cxx
+++ b/Source/Modules/interface.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* interface.cxx
*
@@ -15,6 +15,7 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
+#include "cparse.h"
static bool interface_feature_enabled = false;
@@ -28,25 +29,31 @@ static bool interface_feature_enabled = false;
static List *collect_interface_methods(Node *n) {
List *methods = NewList();
- if (Hash *bases = Getattr(n, "interface:bases")) {
- List *keys = Keys(bases);
- for (Iterator base = First(keys); base.item; base = Next(base)) {
- Node *cls = Getattr(bases, base.item);
+ if (List *bases = Getattr(n, "interface:bases")) {
+ for (Iterator base = First(bases); base.item; base = Next(base)) {
+ Node *cls = base.item;
if (cls == n)
continue;
for (Node *child = firstChild(cls); child; child = nextSibling(child)) {
if (Cmp(nodeType(child), "cdecl") == 0) {
if (GetFlag(child, "feature:ignore") || Getattr(child, "interface:owner"))
continue; // skip methods propagated to bases
- Node *m = Copy(child);
- set_nextSibling(m, NIL);
- set_previousSibling(m, NIL);
- Setattr(m, "interface:owner", cls);
- Append(methods, m);
+ if (!checkAttribute(child, "kind", "function"))
+ continue;
+ if (checkAttribute(child, "storage", "static"))
+ continue; // accept virtual methods, non-virtual methods too... mmm??. Warn that the interface class has something that is not a virtual method?
+ Node *nn = copyNode(child);
+ Setattr(nn, "interface:owner", cls);
+ ParmList *parms = CopyParmList(Getattr(child, "parms"));
+ Setattr(nn, "parms", parms);
+ Delete(parms);
+ ParmList *throw_parm_list = Getattr(child, "throws");
+ if (throw_parm_list)
+ Setattr(nn, "throws", CopyParmList(throw_parm_list));
+ Append(methods, nn);
}
}
}
- Delete(keys);
}
return methods;
}
@@ -55,17 +62,17 @@ static List *collect_interface_methods(Node *n) {
* collect_interface_bases
* ----------------------------------------------------------------------------- */
-static void collect_interface_bases(Hash *bases, Node *n) {
- if (Getattr(n, "feature:interface")) {
+static void collect_interface_bases(List *bases, Node *n) {
+ if (GetFlag(n, "feature:interface")) {
String *name = Getattr(n, "interface:name");
if (!Getattr(bases, name))
- Setattr(bases, name, n);
+ Append(bases, n);
}
if (List *baselist = Getattr(n, "bases")) {
for (Iterator base = First(baselist); base.item; base = Next(base)) {
if (!GetFlag(base.item, "feature:ignore")) {
- if (Getattr(base.item, "feature:interface"))
+ if (GetFlag(base.item, "feature:interface"))
collect_interface_bases(bases, base.item);
}
}
@@ -83,21 +90,21 @@ static void collect_interface_bases(Hash *bases, Node *n) {
* ----------------------------------------------------------------------------- */
static void collect_interface_base_classes(Node *n) {
- if (Getattr(n, "feature:interface")) {
+ if (GetFlag(n, "feature:interface")) {
// check all bases are also interfaces
if (List *baselist = Getattr(n, "bases")) {
for (Iterator base = First(baselist); base.item; base = Next(base)) {
if (!GetFlag(base.item, "feature:ignore")) {
- if (!Getattr(base.item, "feature:interface")) {
+ if (!GetFlag(base.item, "feature:interface")) {
Swig_error(Getfile(n), Getline(n), "Base class '%s' of '%s' is not similarly marked as an interface.\n", SwigType_namestr(Getattr(base.item, "name")), SwigType_namestr(Getattr(n, "name")));
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
}
}
}
- Hash *interface_bases = NewHash();
+ List *interface_bases = NewList();
collect_interface_bases(interface_bases, n);
if (Len(interface_bases) == 0)
Delete(interface_bases);
@@ -110,11 +117,11 @@ static void collect_interface_base_classes(Node *n) {
* ----------------------------------------------------------------------------- */
static void process_interface_name(Node *n) {
- if (Getattr(n, "feature:interface")) {
+ if (GetFlag(n, "feature:interface")) {
String *interface_name = Getattr(n, "feature:interface:name");
if (!Len(interface_name)) {
Swig_error(Getfile(n), Getline(n), "The interface feature for '%s' is missing the name attribute.\n", SwigType_namestr(Getattr(n, "name")));
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (Strchr(interface_name, '%')) {
String *name = NewStringf(interface_name, Getattr(n, "sym:name"));
@@ -139,7 +146,7 @@ void Swig_interface_propagate_methods(Node *n) {
process_interface_name(n);
collect_interface_base_classes(n);
List *methods = collect_interface_methods(n);
- bool is_interface = Getattr(n, "feature:interface") != 0;
+ 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;
@@ -164,8 +171,25 @@ void Swig_interface_propagate_methods(Node *n) {
}
Delete(this_decl_resolved);
if (!identically_overloaded_method) {
- // TODO: Fix if the method is overloaded with different arguments / has default args
- appendChild(n, mi.item);
+ // Add method copied from base class to this derived class
+ Node *cn = mi.item;
+ Delattr(cn, "sym:overname");
+ String *prefix = Getattr(n, "name");
+ String *name = Getattr(cn, "name");
+ String *decl = Getattr(cn, "decl");
+ String *oldname = Getattr(cn, "sym:name");
+
+ String *symname = Swig_name_make(cn, prefix, name, decl, oldname);
+ if (Strcmp(symname, "$ignore") != 0) {
+ Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
+ Node *on = Swig_symbol_add(symname, cn);
+ assert(on == cn);
+
+ // Features from the copied base class method are already present, now add in features specific to the added method in the derived class
+ Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
+ Swig_symbol_setscope(oldscope);
+ appendChild(n, cn);
+ }
} else {
Delete(mi.item);
}
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
index 444fe02d1..773945af2 100644
--- a/Source/Modules/java.cxx
+++ b/Source/Modules/java.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* 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"
@@ -371,24 +371,24 @@ public:
if (!outfile) {
Printf(stderr, "Unable to determine outfile\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (directorsEnabled()) {
if (!outfile_h) {
Printf(stderr, "Unable to determine outfile_h\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
@@ -456,7 +456,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGJAVA\n#define SWIGJAVA\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "JAVA");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@@ -521,7 +521,7 @@ public:
File *f_im = NewFile(filen, "w", SWIG_output_files());
if (!f_im) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -576,7 +576,7 @@ public:
File *f_module = NewFile(filen, "w", SWIG_output_files());
if (!f_module) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -635,7 +635,7 @@ public:
File *f_module = NewFile(filen, "w", SWIG_output_files());
if (!f_module) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -1332,10 +1332,7 @@ public:
// Add extra indentation
Replaceall(enum_code, "\n", "\n ");
Replaceall(enum_code, " \n", "\n");
- if (GetFlag(getCurrentClass(), "feature:interface"))
- Printv(interface_class_code, " ", enum_code, "\n\n", NIL);
- else
- Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
+ Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
} else {
// Global enums are defined in their own file
String *output_directory = outputDirectory(nspace);
@@ -1343,7 +1340,7 @@ public:
File *f_enum = NewFile(filen, "w", SWIG_output_files());
if (!f_enum) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -1843,10 +1840,9 @@ public:
* addInterfaceNameAndUpcasts()
* ----------------------------------------------------------------------------- */
- void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *c_classname) {
- List *keys = Keys(base_list);
- for (Iterator it = First(keys); it.item; it = Next(it)) {
- Node *base = Getattr(base_list, it.item);
+ void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) {
+ for (Iterator it = First(base_list); it.item; it = Next(it)) {
+ Node *base = it.item;
SwigType *c_baseclassname = Getattr(base, "name");
String *interface_name = Getattr(base, "interface:name");
if (Len(interface_list))
@@ -1873,7 +1869,6 @@ public:
Delete(cptr_method_name);
Delete(interface_code);
}
- Delete(keys);
}
/* -----------------------------------------------------------------------------
@@ -1959,7 +1954,7 @@ public:
if (baselist) {
Iterator base = First(baselist);
while (base.item) {
- if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
+ if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) {
SwigType *baseclassname = Getattr(base.item, "name");
if (!c_baseclassname) {
String *name = getProxyName(baseclassname);
@@ -1979,7 +1974,7 @@ public:
}
}
- Hash *interface_bases = Getattr(n, "interface:bases");
+ List *interface_bases = Getattr(n, "interface:bases");
if (interface_bases)
addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
@@ -2140,7 +2135,7 @@ public:
if (List *baselist = Getattr(n, "bases")) {
String *bases = 0;
for (Iterator base = First(baselist); base.item; base = Next(base)) {
- if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
+ if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface"))
continue; // TODO: warn about skipped non-interface bases
String *base_iname = Getattr(base.item, "interface:name");
if (!bases)
@@ -2215,12 +2210,12 @@ public:
if (Cmp(proxy_class_name, imclass_name) == 0) {
Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (Cmp(proxy_class_name, module_class_name) == 0) {
Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
} else {
if (outerClassesPrefix) {
@@ -2236,7 +2231,7 @@ public:
}
}
- String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
+ String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
if (outerClassesPrefix) {
String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix;
if (!addSymbol(proxy_class_name, n, fnspace))
@@ -2260,7 +2255,7 @@ public:
f_proxy = NewFile(filen, "w", SWIG_output_files());
if (!f_proxy) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -2287,14 +2282,14 @@ public:
destructor_throws_clause = NewString("");
proxy_class_constants_code = NewString("");
- if (Getattr(n, "feature:interface")) {
+ if (GetFlag(n, "feature:interface")) {
interface_class_code = NewString("");
String *output_directory = outputDirectory(nspace);
String *filen = NewStringf("%s%s.java", output_directory, interface_name);
f_interface = NewFile(filen, "w", SWIG_output_files());
if (!f_interface) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, filen); // file name ownership goes to the list
emitBanner(f_interface);
@@ -2462,7 +2457,7 @@ public:
bool setter_flag = false;
String *pre_code = NewString("");
String *post_code = NewString("");
- bool is_interface = Getattr(parentNode(n), "feature:interface") != 0
+ bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable")
&& !static_flag && Getattr(n, "interface:owner") == 0;
if (!proxy_flag)
@@ -2694,6 +2689,7 @@ public:
Replaceall(imcall, "$imfuncname", intermediary_function_name);
}
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$jnicall", imcall);
} else {
Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
@@ -3179,6 +3175,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$jnicall", imcall);
} else {
Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
@@ -3497,7 +3494,7 @@ public:
File *f_swigtype = NewFile(filen, "w", SWIG_output_files());
if (!f_swigtype) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -3712,7 +3709,7 @@ public:
if (newdir_error) {
Printf(stderr, "%s\n", newdir_error);
Delete(newdir_error);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
Delete(nspace_subdirectory);
diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
index 431dd4744..17effc220 100644
--- a/Source/Modules/javascript.cxx
+++ b/Source/Modules/javascript.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* javascript.cxx
*
@@ -166,7 +166,7 @@ public:
*/
virtual int exitClass(Node *) {
return SWIG_OK;
- };
+ }
/**
* Invoked at the beginning of the variableHandler.
@@ -178,7 +178,7 @@ public:
*/
virtual int exitVariable(Node *) {
return SWIG_OK;
- };
+ }
/**
* Invoked at the beginning of the functionHandler.
@@ -190,7 +190,7 @@ public:
*/
virtual int exitFunction(Node *) {
return SWIG_OK;
- };
+ }
/**
* Invoked by functionWrapper callback after call to Language::functionWrapper.
@@ -537,21 +537,21 @@ void JAVASCRIPT::main(int argc, char *argv[]) {
if (strcmp(argv[i], "-v8") == 0) {
if (engine != -1) {
Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
- SWIG_exit(-1);
+ Exit(EXIT_FAILURE);
}
Swig_mark_arg(i);
engine = JSEmitter::V8;
} else if (strcmp(argv[i], "-jsc") == 0) {
if (engine != -1) {
Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
- SWIG_exit(-1);
+ Exit(EXIT_FAILURE);
}
Swig_mark_arg(i);
engine = JSEmitter::JavascriptCore;
} else if (strcmp(argv[i], "-node") == 0) {
if (engine != -1) {
Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
- SWIG_exit(-1);
+ Exit(EXIT_FAILURE);
}
Swig_mark_arg(i);
engine = JSEmitter::NodeJS;
@@ -595,7 +595,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) {
default:
{
Printf(stderr, "SWIG Javascript: Unknown engine. Please specify one of '-jsc', '-v8' or '-node'.\n");
- SWIG_exit(-1);
+ Exit(EXIT_FAILURE);
break;
}
}
@@ -666,7 +666,7 @@ Template JSEmitter::getTemplate(const String *name) {
if (!templ) {
Printf(stderr, "Could not find template %s\n.", name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Template t(templ, name);
@@ -760,13 +760,10 @@ int JSEmitter::emitWrapperFunction(Node *n) {
ret = emitSetter(n, is_member, is_static);
} else if (is_getter) {
ret = emitGetter(n, is_member, is_static);
- } else {
- Swig_print_node(n);
}
} else {
Printf(stderr, "Warning: unsupported wrapper function type\n");
- Swig_print_node(n);
ret = SWIG_ERROR;
}
} else {
@@ -778,7 +775,6 @@ int JSEmitter::emitWrapperFunction(Node *n) {
ret = emitDtor(n);
} else {
Printf(stderr, "Warning: unsupported wrapper function type");
- Swig_print_node(n);
ret = SWIG_ERROR;
}
}
@@ -936,7 +932,7 @@ int JSEmitter::emitDtor(Node *n) {
SwigType *type = state.clazz(TYPE);
String *p_classtype = SwigType_add_pointer(state.clazz(TYPE));
String *ctype = SwigType_lstr(p_classtype, "");
- String *free = NewString("");
+ String *jsfree = NewString("");
// (Taken from JSCore implementation.)
/* The if (Extend) block was taken from the Ruby implementation.
@@ -979,9 +975,9 @@ int JSEmitter::emitDtor(Node *n) {
// TODO: generate dtors more similar to other wrappers
// EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used.
if (SwigType_isarray(type)) {
- Printf(free, "delete [] (%s)", ctype);
+ Printf(jsfree, "delete [] (%s)", ctype);
} else {
- Printf(free, "delete (%s)", ctype);
+ Printf(jsfree, "delete (%s)", ctype);
}
String *destructor_action = Getattr(n, "wrap:action");
@@ -994,7 +990,7 @@ int JSEmitter::emitDtor(Node *n) {
{
SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject);
if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject);
- if(t) free(t);
+ free(t);
}
%}
@@ -1007,7 +1003,7 @@ int JSEmitter::emitDtor(Node *n) {
${type}* arg1 = (${type}*)t->swigCObject;
${destructor_action}
}
- if(t) free(t);
+ free(t);
Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action")
to decide if the user has a preferred destructor action.
@@ -1031,7 +1027,7 @@ int JSEmitter::emitDtor(Node *n) {
state.clazz(DTOR, wrap_name);
t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED))
.replace("$jswrapper", wrap_name)
- .replace("$jsfree", free)
+ .replace("$jsfree", jsfree)
.replace("$jstype", ctype);
t_dtor.replace("${destructor_action}", destructor_action);
@@ -1041,14 +1037,14 @@ int JSEmitter::emitDtor(Node *n) {
state.clazz(DTOR, wrap_name);
t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED))
.replace("$jswrapper", wrap_name)
- .replace("$jsfree", free)
+ .replace("$jsfree", jsfree)
.replace("$jstype", ctype)
.pretty_print(f_wrappers);
}
Delete(p_classtype);
Delete(ctype);
- Delete(free);
+ Delete(jsfree);
return SWIG_OK;
}
@@ -1143,7 +1139,7 @@ int JSEmitter::emitConstant(Node *n) {
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
- // HACK: forcing usage of cppvalue for v8 (which turned out to fix typdef_struct.i, et. al)
+ // HACK: forcing usage of cppvalue for v8 (which turned out to fix typedef_struct.i, et. al)
if (State::IsSet(state.globals(FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) {
value = Getattr(n, "cppvalue");
}
@@ -1409,7 +1405,6 @@ int JSEmitter::switchNamespace(Node *n) {
String *_nspace = lang->getNSpace();
if (!Equal(nspace, _nspace)) {
Printf(stdout, "##### Custom vs Language::getNSpace(): %s | %s\n", nspace, _nspace);
- Swig_print_node(n);
}
#endif
@@ -1576,7 +1571,7 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma
break;
default:
Printf(stderr, "Illegal MarshallingMode.");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
tm = emitInputTypemap(n, p, wrapper, arg);
Delete(arg);
@@ -1599,7 +1594,7 @@ int JSCEmitter::initialize(Node *n) {
f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files());
if (!f_wrap_cpp) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
/* Initialization of members */
@@ -1620,6 +1615,8 @@ int JSCEmitter::initialize(Node *n) {
Swig_banner(f_wrap_cpp);
+ Swig_obligatory_macros(f_runtime, "JAVASCRIPT");
+
return SWIG_OK;
}
@@ -1920,7 +1917,7 @@ int V8Emitter::initialize(Node *n) {
f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files());
if (!f_wrap_cpp) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
@@ -1950,6 +1947,8 @@ int V8Emitter::initialize(Node *n) {
Swig_banner(f_wrap_cpp);
+ Swig_obligatory_macros(f_runtime, "JAVASCRIPT");
+
return SWIG_OK;
}
@@ -2214,7 +2213,7 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar
break;
default:
Printf(stderr, "Illegal MarshallingMode.");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
tm = emitInputTypemap(n, p, wrapper, arg);
@@ -2370,7 +2369,7 @@ Template::Template(const String *code_) {
if (!code_) {
Printf(stdout, "Template code was null. Illegal input for template.");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
code = NewString(code_);
templateName = NewString("");
@@ -2380,7 +2379,7 @@ Template::Template(const String *code_, const String *templateName_) {
if (!code_) {
Printf(stdout, "Template code was null. Illegal input for template.");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
code = NewString(code_);
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
index 66aebdea1..1e10e51d6 100644
--- a/Source/Modules/lang.cxx
+++ b/Source/Modules/lang.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* lang.cxx
*
@@ -77,6 +77,9 @@ static Hash *classhash;
extern int GenerateDefault;
extern int ForceExtern;
extern int AddExtern;
+extern "C" {
+ extern int UseWrapperSuffix;
+}
/* import modes */
@@ -1320,16 +1323,21 @@ int Language::staticmemberfunctionHandler(Node *n) {
Delete(mrename);
mrename = mangled;
- if (Getattr(n, "sym:overloaded") && code) {
- Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
- }
+ if (code) {
+ // See Swig_MethodToFunction() for the explanation of this code.
+ if (Getattr(n, "sym:overloaded")) {
+ Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
+ } else if (UseWrapperSuffix) {
+ Append(cname, "__SWIG");
+ }
- if (!defaultargs && code) {
- /* Hmmm. An added static member. We have to create a little wrapper for this */
- String *mangled_cname = Swig_name_mangle(cname);
- Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0);
- Setattr(n, "extendname", mangled_cname);
- Delete(mangled_cname);
+ if (!defaultargs) {
+ /* Hmmm. An added static member. We have to create a little wrapper for this */
+ String *mangled_cname = Swig_name_mangle(cname);
+ Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0);
+ Setattr(n, "extendname", mangled_cname);
+ Delete(mangled_cname);
+ }
}
}
@@ -1840,20 +1848,82 @@ static String *vtable_method_id(Node *n) {
String *tmp = SwigType_pop_function(local_decl);
Delete(local_decl);
local_decl = tmp;
- Node *method_id = NewStringf("%s|%s", name, local_decl);
+ String *method_id = NewStringf("%s|%s", name, local_decl);
Delete(local_decl);
return method_id;
}
+/* ----------------------------------------------------------------------
+ * Language::unrollOneVirtualMethod()
+ * ---------------------------------------------------------------------- */
+
+void Language::unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) {
+ if (!checkAttribute(n, "storage", "virtual"))
+ return;
+ if (GetFlag(n, "final"))
+ return;
+
+ String *nodeType = Getattr(n, "nodeType");
+
+ /* we need to add methods(cdecl) and destructor (to check for throw decl) */
+ int is_destructor = (Cmp(nodeType, "destructor") == 0);
+ if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
+ String *decl = Getattr(n, "decl");
+ /* extra check for function type and proper access */
+ if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(n)) || need_nonpublic_member(n))) {
+ String *name = Getattr(n, "name");
+ String *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(n);
+ /* Make sure that the new method overwrites the existing: */
+ int len = Len(vm);
+ const int DO_NOT_REPLACE = -1;
+ int replace = DO_NOT_REPLACE;
+ for (int i = 0; i < len; i++) {
+ Node *item = Getitem(vm, i);
+ String *check_vmid = Getattr(item, "vmid");
+
+ if (Strcmp(method_id, check_vmid) == 0) {
+ replace = i;
+ break;
+ }
+ }
+ /* filling a new method item */
+ String *fqdname = NewStringf("%s::%s", classname, name);
+ Hash *item = NewHash();
+ Setattr(item, "fqdname", fqdname);
+ Node *m = Copy(n);
+
+ /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
+ SwigType *ty = NewString(Getattr(m, "type"));
+ SwigType_push(ty, decl);
+ if (SwigType_isqualifier(ty)) {
+ Delete(SwigType_pop(ty));
+ }
+ Delete(SwigType_pop_function(ty));
+ Setattr(m, "returntype", ty);
+
+ String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
+ /* apply the features of the original method found in the base class */
+ Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
+ Setattr(item, "methodNode", m);
+ Setattr(item, "vmid", method_id);
+ if (replace == DO_NOT_REPLACE)
+ Append(vm, item);
+ else
+ Setitem(vm, replace, item);
+ Setattr(n, "directorNode", m);
+
+ Delete(mname);
+ }
+ if (is_destructor) {
+ virtual_destructor = 1;
+ }
+ }
+}
/* ----------------------------------------------------------------------
* Language::unrollVirtualMethods()
* ---------------------------------------------------------------------- */
-int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase) {
- Node *ni;
- String *nodeType;
- String *classname;
- String *decl;
+int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) {
bool first_base = false;
// recurse through all base classes to build the vtable
List *bl = Getattr(n, "bases");
@@ -1862,10 +1932,11 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_
for (bi = First(bl); bi.item; bi = Next(bi)) {
if (first_base && !director_multiple_inheritance)
break;
- unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor);
+ unrollVirtualMethods(bi.item, parent, vm, virtual_destructor);
first_base = true;
}
}
+
// recurse through all protected base classes to build the vtable, as needed
bl = Getattr(n, "protectedbases");
if (bl) {
@@ -1873,88 +1944,28 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_
for (bi = First(bl); bi.item; bi = Next(bi)) {
if (first_base && !director_multiple_inheritance)
break;
- unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor, 1);
+ unrollVirtualMethods(bi.item, parent, vm, virtual_destructor, 1);
first_base = true;
}
}
+
// find the methods that need directors
- classname = Getattr(n, "name");
- for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
+ String *classname = Getattr(n, "name");
+ for (Node *ni = firstChild(n); ni; ni = nextSibling(ni)) {
/* we only need to check the virtual members */
- nodeType = Getattr(ni, "nodeType");
- int is_using = (Cmp(nodeType, "using") == 0);
- Node *nn = is_using ? firstChild(ni) : ni; /* assume there is only one child node for "using" nodes */
- if (is_using) {
- if (nn)
- nodeType = Getattr(nn, "nodeType");
- else
- continue; // A private "using" node
- }
- if (!checkAttribute(nn, "storage", "virtual"))
- continue;
- if (GetFlag(nn, "final"))
- continue;
- /* we need to add methods(cdecl) and destructor (to check for throw decl) */
- int is_destructor = (Cmp(nodeType, "destructor") == 0);
- if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
- decl = Getattr(nn, "decl");
- /* extra check for function type and proper access */
- if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(nn)) || need_nonpublic_member(nn))) {
- String *name = Getattr(nn, "name");
- Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(nn);
- /* Make sure that the new method overwrites the existing: */
- int len = Len(vm);
- const int DO_NOT_REPLACE = -1;
- int replace = DO_NOT_REPLACE;
- for (int i = 0; i < len; i++) {
- Node *item = Getitem(vm, i);
- String *check_vmid = Getattr(item, "vmid");
-
- if (Strcmp(method_id, check_vmid) == 0) {
- replace = i;
- break;
- }
- }
- /* filling a new method item */
- String *fqdname = NewStringf("%s::%s", classname, name);
- Hash *item = NewHash();
- Setattr(item, "fqdname", fqdname);
- Node *m = Copy(nn);
-
- /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
- SwigType *ty = NewString(Getattr(m, "type"));
- SwigType_push(ty, decl);
- if (SwigType_isqualifier(ty)) {
- Delete(SwigType_pop(ty));
- }
- Delete(SwigType_pop_function(ty));
- Setattr(m, "returntype", ty);
-
- String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
- /* apply the features of the original method found in the base class */
- Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
- Setattr(item, "methodNode", m);
- Setattr(item, "vmid", method_id);
- if (replace == DO_NOT_REPLACE)
- Append(vm, item);
- else
- Setitem(vm, replace, item);
- Setattr(nn, "directorNode", m);
-
- Delete(mname);
- }
- if (is_destructor) {
- virtual_destructor = 1;
+ if (Equal(nodeType(ni), "using")) {
+ for (Node *nn = firstChild(ni); nn; nn = Getattr(nn, "sym:nextSibling")) {
+ unrollOneVirtualMethod(classname, nn, parent, vm, virtual_destructor, protectedbase);
}
}
+ unrollOneVirtualMethod(classname, ni, parent, vm, virtual_destructor, protectedbase);
}
/*
We delete all the nodirector methods. This prevents the
generation of 'empty' director classes.
- But this has to be done outside the previous 'for'
- and the recursive loop!.
+ Done once we've collated all the virtual methods into vm.
*/
if (n == parent) {
int len = Len(vm);
@@ -2191,7 +2202,7 @@ int Language::classDirector(Node *n) {
}
List *vtable = NewList();
int virtual_destructor = 0;
- unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
+ unrollVirtualMethods(n, n, vtable, virtual_destructor);
// Emit all the using base::member statements for non virtual members (allprotected mode)
Node *ni;
@@ -3783,7 +3794,7 @@ int Language::abstractClassTest(Node *n) {
#endif
for (int i = 0; i < labs; i++) {
Node *ni = Getitem(abstracts, i);
- Node *method_id = vtable_method_id(ni);
+ String *method_id = vtable_method_id(ni);
if (!method_id)
continue;
bool exists_item = false;
diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx
index 4ba9cb8c3..d3cf96b52 100644
--- a/Source/Modules/lua.cxx
+++ b/Source/Modules/lua.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* lua.cxx
*
@@ -50,7 +50,7 @@
/**** Diagnostics:
With the #define REPORT(), you can change the amount of diagnostics given
This helps me search the parse tree & figure out what is going on inside SWIG
- (because its not clear or documented)
+ (because it's not clear or documented)
*/
#define REPORT(T,D) // no info:
//#define REPORT(T,D) {Printf(stdout,T"\n");} // only title
@@ -304,7 +304,7 @@ public:
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
@@ -329,7 +329,7 @@ public:
/* Standard stuff for the SWIG runtime section */
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGLUA\n#define SWIGLUA\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "LUA");
emitLuaFlavor(f_runtime);
@@ -435,7 +435,7 @@ public:
/* NEW LANGUAGE NOTE:***********************************************
This is it!
you get this one right, and most of your work is done
- but its going to take some file to get it working right
+ but it's going to take some file to get it working right
quite a bit of this is generally boilerplate code
(or stuff I don't understand)
that which matters will have extra added comments
@@ -556,6 +556,12 @@ public:
this line adds this into the wrapper code
NEW LANGUAGE NOTE:END *********************************************** */
Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL);
+ // SWIG_fail in lua leads to a call to lua_error() which calls longjmp()
+ // which means the destructors of any live function-local C++ objects won't
+ // get run. To avoid this happening, we wrap almost everything in the
+ // function in a block, and end that right before lua_error() at which
+ // point those destructors will get called.
+ if (CPlusPlus) Append(f->def, "\n{");
/* NEW LANGUAGE NOTE:***********************************************
this prints the list of args, eg for a C fn
@@ -766,10 +772,12 @@ public:
/* Close the function */
Printv(f->code, "return SWIG_arg;\n", NIL);
// add the failure cleanup code:
- Printv(f->code, "\nif(0) SWIG_fail;\n", NIL);
- Printv(f->code, "\nfail:\n", NIL);
- Printv(f->code, "$cleanup", "lua_error(L);\n", NIL);
- Printv(f->code, "return SWIG_arg;\n", NIL);
+ Printv(f->code, "\nfail: SWIGUNUSED;\n", "$cleanup", NIL);
+ if (CPlusPlus) Append(f->code, "}\n");
+ Printv(f->code, "lua_error(L);\n", NIL);
+ // lua_error() calls longjmp() but we need a dummy return to avoid compiler
+ // warnings.
+ Printv(f->code, "return 0;\n", NIL);
Printf(f->code, "}\n");
/* Substitute the cleanup code */
@@ -1418,7 +1426,6 @@ public:
List *baselist = Getattr(n, "bases");
if (baselist && Len(baselist)) {
Iterator b;
- int index = 0;
b = First(baselist);
while (b.item) {
String *bname = Getattr(b.item, "name");
@@ -1431,7 +1438,6 @@ public:
Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
b = Next(b);
- index++;
}
}
// First, print class static part
@@ -2053,8 +2059,8 @@ public:
if (GetFlag(carrays_hash, "lua:class_instance")) {
String *static_cls = Getattr(carrays_hash, "lua:class_instance:static_hash");
assert(static_cls);
- // static_cls is swig_lua_namespace. This structure can't be use with eLua(LTR)
- // Instead structure describing its methods isused
+ // static_cls is swig_lua_namespace. This structure can't be used with eLua(LTR)
+ // Instead a structure describing its methods is used
String *static_cls_cname = Getattr(static_cls, "methods:name");
assert(static_cls_cname);
Printv(metatable_tab, tab4, "{LSTRKEY(\".static\"), LROVAL(", static_cls_cname, ")},\n", NIL);
@@ -2225,36 +2231,6 @@ public:
};
-/* NEW LANGUAGE NOTE:***********************************************
- in order to add you language into swig, you need to make the following changes:
- - write this file (obviously)
- - add into the makefile (not 100% clear on how to do this)
- - edit swigmain.cxx to add your module
-
-near the top of swigmain.cxx, look for this code & add you own codes
-======= begin change ==========
-extern "C" {
- Language *swig_tcl(void);
- Language *swig_python(void);
- //etc,etc,etc...
- Language *swig_lua(void); // this is my code
-}
-
- //etc,etc,etc...
-
-swig_module modules[] = {
- {"-guile", swig_guile, "Guile"},
- {"-java", swig_java, "Java"},
- //etc,etc,etc...
- {"-lua", swig_lua, "Lua"}, // this is my code
- {NULL, NULL, NULL} // this must come at the end of the list
-};
-======= end change ==========
-
-This is all that is needed
-
-NEW LANGUAGE NOTE:END ************************************************/
-
/* -----------------------------------------------------------------------------
* swig_lua() - Instantiate module
* ----------------------------------------------------------------------------- */
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index d8f2ab6b4..f5bdec644 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* main.cxx
*
@@ -37,9 +37,13 @@ int Verbose = 0;
int AddExtern = 0;
int NoExcept = 0;
int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
+extern "C" {
+ int UseWrapperSuffix = 0; // If 1, append suffix to non-overloaded functions too.
+}
+
+/* Suppress warning messages for private inheritance, etc by default.
+ These are enabled by command line option -Wextra.
-/* Suppress warning messages for private inheritance, preprocessor evaluation etc...
- WARN_PP_EVALUATION 202
WARN_PARSE_PRIVATE_INHERIT 309
WARN_PARSE_BUILTIN_NAME 321
WARN_PARSE_REDUNDANT 322
@@ -47,7 +51,7 @@ int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
WARN_LANG_OVERLOAD_CONST 512
*/
-#define EXTRA_WARNINGS "202,309,403,405,512,321,322"
+#define EXTRA_WARNINGS "309,403,405,512,321,322"
extern "C" {
extern String *ModuleName;
@@ -74,6 +78,7 @@ static const char *usage1 = (const char *) "\
-debug-symbols - Display target language symbols in the symbol tables\n\
-debug-csymbols - Display C symbols in the symbol tables\n\
-debug-lsymbols - Display target language layer symbols\n\
+ -debug-quiet - Display less parse tree node debug info when using other -debug options\n\
-debug-tags - Display information about the tags found in the interface\n\
-debug-template - Display information for debugging templates\n\
-debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages\n\
@@ -137,7 +142,7 @@ static const char *usage4 = (const char *) "\
-oh <headfile> - Set name of C++ output header file for directors to <headfile>\n\
-outcurrentdir - Set default output dir to current dir instead of input file's path\n\
-outdir <dir> - Set language specific files output directory to <dir>\n\
- -pcreversion - Display PCRE version information\n\
+ -pcreversion - Display PCRE2 version information\n\
-small - Compile in virtual elimination and compact mode\n\
-swiglib - Report location of SWIG library and exit\n\
-templatereduce - Reduce all the typedefs in templates\n\
@@ -193,7 +198,6 @@ static int dump_tags = 0;
static int dump_module = 0;
static int dump_top = 0;
static int dump_xml = 0;
-static int browse = 0;
static int dump_typedef = 0;
static int dump_classes = 0;
static int werror = 0;
@@ -403,14 +407,14 @@ static void SWIG_dump_runtime() {
outfile = lang->defaultExternalRuntimeFilename();
if (!outfile) {
Printf(stderr, "*** Please provide a filename for the external runtime\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
runtime = NewFile(outfile, "w", SWIG_output_files());
if (!runtime) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Swig_banner(runtime);
@@ -420,7 +424,7 @@ static void SWIG_dump_runtime() {
if (!s) {
Printf(stderr, "*** Unable to open 'swiglabels.swg'\n");
Delete(runtime);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printf(runtime, "%s", s);
Delete(s);
@@ -429,7 +433,7 @@ static void SWIG_dump_runtime() {
if (!s) {
Printf(stderr, "*** Unable to open 'swigerrors.swg'\n");
Delete(runtime);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printf(runtime, "%s", s);
Delete(s);
@@ -438,7 +442,7 @@ static void SWIG_dump_runtime() {
if (!s) {
Printf(stderr, "*** Unable to open 'swigrun.swg'\n");
Delete(runtime);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printf(runtime, "%s", s);
Delete(s);
@@ -451,13 +455,13 @@ static void SWIG_dump_runtime() {
if (!s) {
Printf(stderr, "*** Unable to open 'runtime.swg'\n");
Delete(runtime);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printf(runtime, "%s", s);
Delete(s);
Delete(runtime);
- SWIG_exit(EXIT_SUCCESS);
+ Exit(EXIT_SUCCESS);
}
static void getoptions(int argc, char *argv[]) {
@@ -471,13 +475,14 @@ static void getoptions(int argc, char *argv[]) {
Swig_mark_arg(i);
} else if (strncmp(argv[i], "-I", 2) == 0) {
// Add a new directory search path
- char *a = Swig_copy_string(argv[i] + 2);
- Swig_add_directory((DOH *) a);
- free(a);
+ Swig_add_directory((String_or_char*)(argv[i] + 2));
Swig_mark_arg(i);
} else if (strncmp(argv[i], "-D", 2) == 0) {
String *d = NewString(argv[i] + 2);
- Replace(d, "=", " ", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
+ if (Replace(d, "=", " ", DOH_REPLACE_FIRST) == 0) {
+ // Match C preprocessor behaviour whereby -DFOO sets FOO=1.
+ Append(d, " 1");
+ }
Preprocessor_define((DOH *) d, 0);
Delete(d);
// Create a symbol
@@ -530,7 +535,7 @@ static void getoptions(int argc, char *argv[]) {
Printf(stdout, "%s\n", version);
Delete(version);
Swig_mark_arg(i);
- SWIG_exit(EXIT_SUCCESS);
+ Exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "-small") == 0) {
Wrapper_compact_print_mode_set(1);
Wrapper_virtual_elimination_mode_set(1);
@@ -593,7 +598,7 @@ static void getoptions(int argc, char *argv[]) {
Printf(stdout, "%s\n", SwigLib);
if (SwigLibWinUnix)
Printf(stdout, "%s\n", SwigLibWinUnix);
- SWIG_exit(EXIT_SUCCESS);
+ Exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "-o") == 0) {
Swig_mark_arg(i);
if (argv[i + 1]) {
@@ -646,7 +651,7 @@ static void getoptions(int argc, char *argv[]) {
#endif
);
fprintf(stdout, "\nPlease see %s for reporting bugs and further information\n", PACKAGE_BUGREPORT);
- SWIG_exit(EXIT_SUCCESS);
+ Exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "-copyright") == 0) {
fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version());
fprintf(stdout, "Copyright (c) 1995-1998\n");
@@ -655,7 +660,7 @@ static void getoptions(int argc, char *argv[]) {
fprintf(stdout, "University of Chicago\n");
fprintf(stdout, "Copyright (c) 2005-2006\n");
fprintf(stdout, "Arizona Board of Regents (University of Arizona)\n");
- SWIG_exit(EXIT_SUCCESS);
+ Exit(EXIT_SUCCESS);
} else if (strncmp(argv[i], "-l", 2) == 0) {
// Add a new directory search path
Append(libfiles, argv[i] + 2);
@@ -777,6 +782,9 @@ static void getoptions(int argc, char *argv[]) {
} else if (strncmp(argv[i], "-w", 2) == 0) {
Swig_mark_arg(i);
Swig_warnfilter(argv[i] + 2, 1);
+ } else if (strcmp(argv[i], "-debug-quiet") == 0) {
+ Swig_print_quiet(1);
+ Swig_mark_arg(i);
} else if (strcmp(argv[i], "-debug-symtabs") == 0) {
dump_symtabs = 1;
Swig_mark_arg(i);
@@ -845,9 +853,6 @@ static void getoptions(int argc, char *argv[]) {
} else if (strcmp(argv[i], "-nocontract") == 0) {
Swig_mark_arg(i);
Swig_contract_mode_set(0);
- } else if (strcmp(argv[i], "-browse") == 0) {
- browse = 1;
- Swig_mark_arg(i);
} else if ((strcmp(argv[i], "-debug-typedef") == 0) || (strcmp(argv[i], "-dump_typedef") == 0)) {
dump_typedef = 1;
Swig_mark_arg(i);
@@ -879,9 +884,14 @@ static void getoptions(int argc, char *argv[]) {
}
}
+static void SWIG_exit_handler(int status);
+
int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
char *c;
+ /* Set function for Exit() to call. */
+ SetExitHandler(SWIG_exit_handler);
+
/* Initialize the SWIG core */
Swig_init();
@@ -901,25 +911,11 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
Preprocessor_define((DOH *) "SWIG 1", 0);
Preprocessor_define((DOH *) "__STDC__", 0);
- // Set the SWIG version value in format 0xAABBCC from package version expected to be in format A.B.C
- String *package_version = NewString(PACKAGE_VERSION); /* Note that the fakeversion has not been set at this point */
- char *token = strtok(Char(package_version), ".");
- String *vers = NewString("SWIG_VERSION 0x");
- int count = 0;
- while (token) {
- int len = (int)strlen(token);
- assert(len == 1 || len == 2);
- Printf(vers, "%s%s", (len == 1) ? "0" : "", token);
- token = strtok(NULL, ".");
- count++;
- }
- Delete(package_version);
- assert(count == 3); // Check version format is correct
-
- /* Turn on contracts */
+ String *vers = Swig_package_version_hex();
+ Preprocessor_define(vers, 0);
+ Delete(vers);
Swig_contract_mode_set(1);
- Preprocessor_define(vers, 0);
/* Turn off directors mode */
Wrapper_director_mode_set(0);
@@ -968,7 +964,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
if (help) {
Printf(stdout, "\nNote: 'swig -<lang> -help' displays options for a specific target language.\n\n");
- SWIG_exit(EXIT_SUCCESS); // Exit if we're in help mode
+ Exit(EXIT_SUCCESS); // Exit if we're in help mode
}
// Check all of the options to make sure we're cool.
@@ -977,7 +973,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
if (CPlusPlus && cparse_cplusplusout) {
Printf(stderr, "The -c++out option is for C input but C++ input has been requested via -c++\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
install_opts(argc, argv);
@@ -1042,7 +1038,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
File *f_outfile = NewFile(outfile, "w", SWIG_output_files());
if (!f_outfile) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
} else {
if (Verbose)
Printf(stdout, "'%s' checked out from the SWIG library.\n", outfile);
@@ -1070,7 +1066,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
} else {
Printf(stderr, "Unable to find file '%s'.\n", input_file);
}
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
} else {
Swig_warning(WARN_DEPRECATED_INPUT_FILE, "SWIG", 1, "Use of the include path to find the input file is deprecated and will not work with ccache. Please include the path when specifying the input file.\n"); // so that behaviour is like c/c++ compilers
}
@@ -1079,7 +1075,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
if (!tlm) {
Printf(stderr, "No target language specified.\n");
Printf(stderr, "Use 'swig -help' for more information.\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (!no_cpp) {
@@ -1103,11 +1099,11 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
fclose(df);
}
if (Swig_error_count()) {
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (cpp_only) {
Printf(stdout, "%s", cpps);
- SWIG_exit(EXIT_SUCCESS);
+ Exit(EXIT_SUCCESS);
}
if (depend) {
if (!no_cpp) {
@@ -1129,14 +1125,14 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
f_dependencies_file = NewFile(dependencies_file, "w", SWIG_output_files());
if (!f_dependencies_file) {
FileErrorDisplay(dependencies_file);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
} else if (!depend_only) {
String *filename = NewStringf("%s_wrap.%s", basename, depends_extension);
f_dependencies_file = NewFile(filename, "w", SWIG_output_files());
if (!f_dependencies_file) {
FileErrorDisplay(filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
} else
f_dependencies_file = stdout;
@@ -1169,14 +1165,14 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
if (f_dependencies_file != stdout)
Delete(f_dependencies_file);
if (depend_only)
- SWIG_exit(EXIT_SUCCESS);
+ Exit(EXIT_SUCCESS);
Delete(inputfile_filename);
Delete(basename);
Delete(phony_targets);
} else {
Printf(stderr, "Cannot generate dependencies with -nopreprocess\n");
// Actually we could but it would be inefficient when just generating dependencies, as it would be done after Swig_cparse
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
Seek(cpps, 0, SEEK_SET);
@@ -1281,13 +1277,13 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
if (top) {
if (!Getattr(top, "name")) {
Printf(stderr, "No module name specified using %%module or -module.\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
} else {
/* Set some filename information on the object */
String *infile = scanner_get_main_input_file();
if (!infile) {
Printf(stderr, "Missing input file in preprocessed output.\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Setattr(top, "infile", infile); // Note: if nopreprocess then infile is the original input file, otherwise input_file
Setattr(top, "inputfile", input_file);
@@ -1319,15 +1315,12 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
if (tlm->status == Experimental) {
Swig_warning(WARN_LANG_EXPERIMENTAL, "SWIG", 1, "Experimental target language. "
"Target language %s specified by %s is an experimental language. "
- "Please read about SWIG experimental languages, http://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n",
+ "Please read about SWIG experimental languages, https://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n",
tlm->help ? tlm->help : "", tlm->name);
}
lang->top(top);
- if (browse) {
- Swig_browser(top, 0);
- }
Delete(infile_filename);
Delete(basename);
}
@@ -1361,7 +1354,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
if (!f_outfiles) {
Printf(stderr, "Failed to write list of output files to the filename '%s' specified in CCACHE_OUTFILES environment variable - ", outfiles);
FileErrorDisplay(outfiles);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
} else {
int i;
for (i = 0; i < Len(all_output_files); i++)
@@ -1383,22 +1376,22 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
error_count += Swig_error_count();
if (error_count != 0)
- SWIG_exit(error_count);
+ Exit(EXIT_FAILURE);
return 0;
}
/* -----------------------------------------------------------------------------
- * SWIG_exit()
+ * SWIG_exit_handler()
*
* Cleanup and either freeze or exit
* ----------------------------------------------------------------------------- */
-void SWIG_exit(int exit_code) {
+static void SWIG_exit_handler(int status) {
while (freeze) {
}
- if (exit_code > 0) {
+ if (status > 0) {
CloseAllOpenFiles();
/* Remove all generated files */
@@ -1411,6 +1404,4 @@ void SWIG_exit(int exit_code) {
}
}
}
-
- exit(exit_code);
}
diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx
index 3ff691662..e22f8bb7a 100644
--- a/Source/Modules/mzscheme.cxx
+++ b/Source/Modules/mzscheme.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* mzscheme.cxx
*
@@ -12,7 +12,6 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
-
#include <ctype.h>
static const char *usage = "\
@@ -66,7 +65,7 @@ public:
if (argv[i]) {
if (strcmp(argv[i], "-help") == 0) {
fputs(usage, stdout);
- SWIG_exit(0);
+ Exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "-prefix") == 0) {
if (argv[i + 1]) {
prefix = NewString(argv[i + 1]);
@@ -130,7 +129,7 @@ public:
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
@@ -148,7 +147,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGMZSCHEME\n#define SWIGMZSCHEME\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "MZSCHEME");
module = Getattr(n, "name");
diff --git a/Source/Modules/nested.cxx b/Source/Modules/nested.cxx
index 0fcd5ad18..d027eebe5 100644
--- a/Source/Modules/nested.cxx
+++ b/Source/Modules/nested.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* nested.cxx
*
@@ -396,7 +396,7 @@ void Swig_nested_name_unnamed_c_structs(Node *n) {
Delete(ins);
Delattr(c, "nested:outer");
} else {
- // global unnamed struct - ignore it and it's instances
+ // global unnamed struct - ignore it and its instances
SetFlag(c, "feature:ignore");
while (next && Getattr(next, "nested:unnamedtype") == c) {
SetFlag(next, "feature:ignore");
diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx
index caa9725c0..963a0c2d1 100644
--- a/Source/Modules/ocaml.cxx
+++ b/Source/Modules/ocaml.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* ocaml.cxx
*
@@ -12,7 +12,6 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
-
#include <ctype.h>
static const char *usage = "\
@@ -99,10 +98,10 @@ public:
if (argv[i]) {
if (strcmp(argv[i], "-help") == 0) {
fputs(usage, stdout);
- SWIG_exit(0);
+ Exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "-where") == 0) {
PrintIncludeArg();
- SWIG_exit(0);
+ Exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "-prefix") == 0) {
if (argv[i + 1]) {
prefix = NewString(argv[i + 1]);
@@ -228,7 +227,7 @@ public:
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
@@ -277,7 +276,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGOCAML\n#define SWIGOCAML\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "OCAML");
Printf(f_runtime, "#define SWIG_MODULE \"%s\"\n", module);
/* Module name */
@@ -311,12 +310,12 @@ public:
String *mlfilen = NewStringf("%s%s", SWIG_output_directory(), mlfile);
if ((f_mlout = NewFile(mlfilen, "w", SWIG_output_files())) == 0) {
FileErrorDisplay(mlfilen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
String *mlifilen = NewStringf("%s%s", SWIG_output_directory(), mlifile);
if ((f_mliout = NewFile(mlifilen, "w", SWIG_output_files())) == 0) {
FileErrorDisplay(mlifilen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
emitBanner(f_mlout);
emitBanner(f_mliout);
@@ -398,26 +397,18 @@ public:
*/
void oc_SwigType_del_reference(SwigType *t) {
- char *c = Char(t);
- if (strncmp(c, "q(", 2) == 0) {
- Delete(SwigType_pop(t));
- c = Char(t);
- }
- if (strncmp(c, "r.", 2)) {
- printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n");
- abort();
+ if (SwigType_isqualifier(t)) {
+ SwigType_del_qualifier(t);
}
- Replace(t, "r.", "", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
+ SwigType_del_reference(t);
}
void oc_SwigType_del_array(SwigType *t) {
- char *c = Char(t);
- if (strncmp(c, "q(", 2) == 0) {
- Delete(SwigType_pop(t));
- c = Char(t);
+ if (SwigType_isqualifier(t)) {
+ SwigType_del_qualifier(t);
}
- if (strncmp(c, "a(", 2) == 0) {
- Delete(SwigType_pop(t));
+ if (SwigType_isarray(t)) {
+ SwigType_del_array(t);
}
}
@@ -1247,6 +1238,7 @@ public:
int enumvalueDeclaration(Node *n) {
String *name = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
SwigType *qtype = 0;
if (name_qualifier_type) {
@@ -1254,8 +1246,8 @@ public:
Printv(qtype, name, NIL);
}
- if (const_enum && qtype && name && !Getattr(seen_enumvalues, name)) {
- Setattr(seen_enumvalues, name, "true");
+ if (const_enum && qtype && symname && !Getattr(seen_enumvalues, symname)) {
+ Setattr(seen_enumvalues, symname, "true");
SetFlag(n, "feature:immutable");
Setattr(n, "feature:enumvalue", "1"); // this does not appear to be used
@@ -1264,10 +1256,10 @@ public:
String *evname = SwigType_manglestr(qtype);
Insert(evname, 0, "SWIG_ENUM_");
- Setattr(n, "feature:enumvname", name);
+ Setattr(n, "feature:enumvname", symname);
Setattr(n, "feature:symname", evname);
Delete(evname);
- Printf(f_enumtypes_value, "| `%s\n", name);
+ Printf(f_enumtypes_value, "| `%s\n", symname);
return Language::enumvalueDeclaration(n);
} else
@@ -1495,10 +1487,6 @@ public:
int i;
char source[256];
- int outputs = 0;
- if (!is_void)
- outputs++;
-
/* build argument list and type conversion string */
for (i = 0, idx = 0, p = l; i < num_arguments; i++) {
@@ -1506,9 +1494,6 @@ public:
p = Getattr(p, "tmap:ignore:next");
}
- if (Getattr(p, "tmap:directorargout") != 0)
- outputs++;
-
String *pname = Getattr(p, "name");
String *ptype = Getattr(p, "type");
@@ -1662,20 +1647,13 @@ public:
/* any existing helper functions to handle this? */
if (!is_void) {
if (!(ignored_method && !pure_virtual)) {
- /* A little explanation:
- * The director_enum test case makes a method whose return type
- * is an enum type. returntype here is "int". gcc complains
- * about an implicit enum conversion, and although i don't strictly
- * agree with it, I'm working on fixing the error:
- *
- * Below is what I came up with. It's not great but it should
- * always essentially work.
- */
+ String *rettype = SwigType_str(returntype, 0);
if (!SwigType_isreference(returntype)) {
- Printf(w->code, "CAMLreturn_type((%s)c_result);\n", SwigType_lstr(returntype, ""));
+ Printf(w->code, "CAMLreturn_type((%s)c_result);\n", rettype);
} else {
- Printf(w->code, "CAMLreturn_type(*c_result);\n");
+ Printf(w->code, "CAMLreturn_type((%s)*c_result);\n", rettype);
}
+ Delete(rettype);
}
} else {
Printf(w->code, "CAMLreturn0;\n");
diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx
index 04b315eaf..352105b9b 100644
--- a/Source/Modules/octave.cxx
+++ b/Source/Modules/octave.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* octave.cxx
*
@@ -119,7 +119,7 @@ public:
} else if (strcmp(argv[i], "-nocppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
}
@@ -167,7 +167,7 @@ public:
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_header = NewString("");
@@ -190,7 +190,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGOCTAVE\n#define SWIGOCTAVE\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "OCTAVE");
Printf(f_runtime, "#define SWIG_name_d \"%s\"\n", module);
Printf(f_runtime, "#define SWIG_name %s\n", module);
@@ -835,7 +835,7 @@ public:
String *setwname = Swig_name_wrapper(setname);
Octave_begin_function(n, setf->def, setname, setwname, true);
- Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
+ Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();\n", iname);
if (is_assignable(n)) {
Setattr(n, "wrap:name", setname);
if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
@@ -1003,7 +1003,6 @@ public:
List *baselist = Getattr(n, "bases");
if (baselist && Len(baselist)) {
Iterator b;
- int index = 0;
b = First(baselist);
while (b.item) {
String *bname = Getattr(b.item, "name");
@@ -1016,7 +1015,6 @@ public:
Printf(base_class_names, "\"%s\",", bname_mangled);
Printf(base_class, "0,");
b = Next(b);
- index++;
Delete(bname_mangled);
}
}
diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx
index 8a4ce48f7..b94e87ebb 100644
--- a/Source/Modules/overload.cxx
+++ b/Source/Modules/overload.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* overload.cxx
*
@@ -339,7 +339,6 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
Setattr(nodes[i].n, "overload:ignore", "1");
Append(result, nodes[i].n);
// Printf(stdout,"[ %d ] %d %s\n", i, nodes[i].implicitconv_function, ParmList_errorstr(nodes[i].parms));
- // Swig_print_node(nodes[i].n);
if (i == nnodes-1 || nodes[i].argc != nodes[i+1].argc) {
if (argc_changed_index+2 < nnodes && (nodes[argc_changed_index+1].argc == nodes[argc_changed_index+2].argc)) {
// Add additional implicitconv functions in same order as already ranked.
@@ -351,7 +350,6 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
SetFlag(nodes[j].n, "implicitconvtypecheckoff");
Append(result, nodes[j].n);
// Printf(stdout,"[ %d ] %d + %s\n", j, nodes[j].implicitconv_function, ParmList_errorstr(nodes[j].parms));
- // Swig_print_node(nodes[j].n);
}
}
}
diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx
index e87f9f310..0cbf6b17a 100644
--- a/Source/Modules/perl5.cxx
+++ b/Source/Modules/perl5.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* perl5.cxx
*
@@ -21,7 +21,7 @@ Perl 5 Options (available with -perl5)\n\
-const - Wrap constants as constants and not variables (implies -proxy)\n\
-nopm - Do not generate the .pm file\n\
-noproxy - Don't create proxy classes\n\
- -proxy - Create proxy classes\n\
+ -proxy - Create proxy classes (enabled by default)\n\
-static - Omit code related to dynamic loading\n\
\n";
@@ -154,11 +154,11 @@ public:
if (strcmp(argv[i], "-package") == 0) {
Printv(stderr,
"*** -package is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
} else if (strcmp(argv[i], "-interface") == 0) {
Printv(stderr,
"*** -interface is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
} else if (strcmp(argv[i], "-exportall") == 0) {
export_all = 1;
Swig_mark_arg(i);
@@ -197,7 +197,7 @@ public:
} else if (strcmp(argv[i], "-nocppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
}
@@ -276,7 +276,7 @@ public:
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
@@ -289,7 +289,7 @@ public:
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
@@ -319,7 +319,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGPERL\n#define SWIGPERL\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "PERL");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@@ -407,7 +407,7 @@ public:
String *filen = NewStringf("%s%s", SWIG_output_directory(), pmfile);
if ((f_pm = NewFile(filen, "w", SWIG_output_files())) == 0) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(filen);
filen = NULL;
@@ -445,13 +445,7 @@ public:
Printv(magic,
"#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n",
- "#ifdef PERL_OBJECT\n",
- "#define MAGIC_CLASS _wrap_", underscore_module, "_var::\n",
- "class _wrap_", underscore_module, "_var : public CPerlObj {\n",
- "public:\n",
- "#else\n",
"#define MAGIC_CLASS\n",
- "#endif\n",
"SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *SWIGUNUSEDPARM(sv), MAGIC *SWIGUNUSEDPARM(mg)) {\n",
tab4, "MAGIC_PPERL\n", tab4, "croak(\"Value is read-only.\");\n", tab4, "return 0;\n", "}\n", NIL);
@@ -470,7 +464,6 @@ public:
/* Dump out variable wrappers */
- Printv(magic, "\n\n#ifdef PERL_OBJECT\n", "};\n", "#endif\n", NIL);
Printv(magic, "\n#ifdef __cplusplus\n}\n#endif\n", NIL);
Printf(f_header, "%s\n", magic);
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index d1ef52b48..a2e741215 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -1,10 +1,10 @@
/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
+ * This file is part of SWIG, which is licensed as a whole under version 3
* (or any later version) of the GNU General Public License. Some additional
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* php.cxx
*
@@ -13,9 +13,10 @@
*/
#include "swigmod.h"
-
+#include <algorithm>
#include <ctype.h>
#include <errno.h>
+#include <limits.h>
static const char *usage = "\
PHP Options (available with -php7)\n\
@@ -64,6 +65,8 @@ static String *pragma_phpinfo;
static String *pragma_version;
static String *class_name = NULL;
+static String *base_class = NULL;
+static String *destructor_action = NULL;
static String *magic_set = NULL;
static String *magic_get = NULL;
static String *magic_isset = NULL;
@@ -73,33 +76,38 @@ static String *fake_class_name() {
static String *result = NULL;
if (!result) {
result = Len(prefix) ? prefix : module;
- if (!s_creation) {
- s_creation = NewStringEmpty();
- }
if (!fake_cs_entry) {
- fake_cs_entry = NewStringf("static zend_function_entry class_%s_functions[] = {\n", result);
+ fake_cs_entry = NewStringf("static const zend_function_entry class_%s_functions[] = {\n", result);
}
- Printf(s_creation, "/* class entry for %s */\n",result);
- Printf(s_creation, "zend_class_entry *SWIGTYPE_%s_ce;\n\n",result);
+
+ Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n",result);
+
Printf(s_oinit, " INIT_CLASS_ENTRY(internal_ce, \"%s\", class_%s_functions);\n", result, result);
- Printf(s_oinit, " SWIGTYPE_%s_ce = zend_register_internal_class(&internal_ce);\n", result);
+ Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", result);
Printf(s_oinit, "\n");
}
return result;
}
+static String *swig_wrapped_interface_ce() {
+ static String *result = NULL;
+ if (!result) {
+ result = NewStringf("SWIG_Php_swig_wrapped_interface_ce");
+ Printf(s_oinit, " INIT_CLASS_ENTRY(%s, \"SWIG\\\\wrapped\", NULL);\n", result);
+ }
+ return result;
+}
+
/* To reduce code size (generated and compiled) we only want to emit each
* different arginfo once, so we need to track which have been used.
*/
static Hash *arginfo_used;
/* Track non-class pointer types we need to to wrap */
-static Hash *zend_types = 0;
+static Hash *raw_pointer_types = 0;
static int shadow = 1;
-static String *wrapping_member_constant = NULL;
-
// These static variables are used to pass some state from Handlers into functionWrapper
static enum {
standard = 0,
@@ -108,6 +116,7 @@ static enum {
membervar,
staticmembervar,
constructor,
+ destructor,
directorconstructor,
directordisown
} wrapperType = standard;
@@ -116,51 +125,11 @@ extern "C" {
static void (*r_prevtracefunc) (const SwigType *t, String *mangled, String *clientdata) = 0;
}
-static void print_creation_free_wrapper(Node *n) {
- if (!s_creation) {
- s_creation = NewStringEmpty();
- }
-
- String *s = s_creation;
-
- Printf(s, "/* class entry for %s */\n",class_name);
- Printf(s, "zend_class_entry *SWIGTYPE_%s_ce;\n\n",class_name);
- Printf(s, "/* class object handlers for %s */\n",class_name);
- Printf(s, "zend_object_handlers %s_object_handlers;\n\n",class_name);
-
- if (Getattr(n, "has_destructor")) {
- Printf(s, "/* Garbage Collection Method for class %s */\n",class_name);
- Printf(s, "void %s_free_storage(zend_object *object) {\n",class_name);
- Printf(s, " swig_object_wrapper *obj = 0;\n");
- Printf(s, " if (!object)\n");
- Printf(s, " return;\n");
- Printf(s, " obj = php_fetch_object(object);\n");
-
- Printf(s, " zend_object_std_dtor(&obj->std);\n");
-
- // expand %delete typemap instead of SWIG_remove?
- Printf(s, " if (obj->newobject)\n");
- Printf(s, " SWIG_remove((%s *)obj->ptr);\n", Getattr(n, "classtype"));
- Printf(s, "}\n\n");
- }
-
- Printf(s, "/* Object Creation Method for class %s */\n",class_name);
- Printf(s, "zend_object * %s_object_new(zend_class_entry *ce) {\n",class_name);
- Printf(s, " swig_object_wrapper *obj = (swig_object_wrapper*)zend_object_alloc(sizeof(swig_object_wrapper), ce);\n");
- Printf(s, " zend_object_std_init(&obj->std, ce);\n");
- Printf(s, " object_properties_init(&obj->std, ce);\n");
- Printf(s, " %s_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n", class_name);
- if (Getattr(n, "has_destructor")) {
- Printf(s, " %s_object_handlers.free_obj = %s_free_storage;\n", class_name, class_name);
- }
- Printf(s, " obj->std.handlers = &%s_object_handlers;\n obj->newobject = 1;\n return &obj->std;\n}\n\n\n",class_name);
-}
-
static void SwigPHP_emit_pointer_type_registrations() {
- if (!zend_types)
+ if (!raw_pointer_types)
return;
- Iterator ki = First(zend_types);
+ Iterator ki = First(raw_pointer_types);
if (!ki.key)
return;
@@ -168,7 +137,7 @@ static void SwigPHP_emit_pointer_type_registrations() {
Printf(s_wrappers, "static zend_object_handlers swig_ptr_object_handlers;\n\n");
Printf(s_wrappers, "/* Object Creation Method for pointer wrapping class */\n");
- Printf(s_wrappers, "static zend_object * swig_ptr_object_new(zend_class_entry *ce) {\n");
+ Printf(s_wrappers, "static zend_object *swig_ptr_object_new(zend_class_entry *ce) {\n");
Printf(s_wrappers, " swig_object_wrapper *obj = (swig_object_wrapper*)zend_object_alloc(sizeof(swig_object_wrapper), ce);\n");
Printf(s_wrappers, " zend_object_std_init(&obj->std, ce);\n");
Printf(s_wrappers, " object_properties_init(&obj->std, ce);\n");
@@ -180,48 +149,358 @@ static void SwigPHP_emit_pointer_type_registrations() {
Printf(s_wrappers, "/* Implement __toString equivalent, since that worked for the old-style resource wrapped pointers. */\n");
Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n");
Printf(s_wrappers, "static int swig_ptr_cast_object(zval *z, zval *retval, int type) {\n");
+ Append(s_wrappers, "#elif PHP_MAJOR_VERSION > 8 || PHP_MINOR_VERSION >= 2\n");
+ Printf(s_wrappers, "static ZEND_RESULT_CODE swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n");
Append(s_wrappers, "#else\n");
Printf(s_wrappers, "static int swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n");
Append(s_wrappers, "#endif\n");
Printf(s_wrappers, " if (type == IS_STRING) {\n");
- Printf(s_wrappers, " char buf[80];\n");
Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n");
Printf(s_wrappers, " swig_object_wrapper *obj = SWIG_Z_FETCH_OBJ_P(z);\n");
Append(s_wrappers, "#else\n");
- Printf(s_wrappers, " swig_object_wrapper *obj = php_fetch_object(zobj);\n");
+ Printf(s_wrappers, " swig_object_wrapper *obj = swig_php_fetch_object(zobj);\n");
Append(s_wrappers, "#endif\n");
- Printv(s_wrappers, " sprintf(buf, \"SWIGPointer(%p,owned=%d)\", obj->ptr, obj->newobject);\n", NIL);
- Printf(s_wrappers, " ZVAL_STRING(retval, buf);\n");
+ Printv(s_wrappers, " ZVAL_NEW_STR(retval, zend_strpprintf(0, \"SWIGPointer(%p,owned=%d)\", obj->ptr, obj->newobject));\n", NIL);
Printf(s_wrappers, " return SUCCESS;\n");
Printf(s_wrappers, " }\n");
Printf(s_wrappers, " return FAILURE;\n");
Printf(s_wrappers, "}\n\n");
Printf(s_oinit, "\n /* Register classes to represent non-class pointer types */\n");
- Printf(s_oinit, " memcpy(&swig_ptr_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));\n");
+ Printf(s_oinit, " swig_ptr_object_handlers = *zend_get_std_object_handlers();\n");
Printf(s_oinit, " swig_ptr_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n");
Printf(s_oinit, " swig_ptr_object_handlers.cast_object = swig_ptr_cast_object;\n");
while (ki.key) {
String *type = ki.key;
- if (!s_creation) {
- s_creation = NewStringEmpty();
- }
-
+ String *swig_wrapped = swig_wrapped_interface_ce();
Printf(s_creation, "/* class entry for pointer to %s */\n", type);
- Printf(s_creation, "zend_class_entry *SWIGTYPE_%s_ce;\n\n", type);
+ Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n", type);
Printf(s_oinit, " INIT_CLASS_ENTRY(internal_ce, \"%s\\\\%s\", NULL);\n", "SWIG", type);
- Printf(s_oinit, " SWIGTYPE_%s_ce = zend_register_internal_class(&internal_ce);\n", type);
- Printf(s_oinit, " SWIGTYPE_%s_ce->create_object = swig_ptr_object_new;\n", type);
- Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE%s,SWIGTYPE_%s_ce);\n", type, type);
+ Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", type);
+ Printf(s_oinit, " SWIG_Php_ce_%s->create_object = swig_ptr_object_new;\n", type);
+ Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", type, ", &", swig_wrapped, ");\n", NIL);
+ Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE%s,SWIG_Php_ce_%s);\n", type, type);
Printf(s_oinit, "\n");
ki = Next(ki);
}
}
+static Hash *create_php_type_flags() {
+ Hash *h = NewHash();
+ Setattr(h, "array", "MAY_BE_ARRAY");
+ Setattr(h, "bool", "MAY_BE_BOOL");
+ Setattr(h, "callable", "MAY_BE_CALLABLE");
+ Setattr(h, "float", "MAY_BE_DOUBLE");
+ Setattr(h, "int", "MAY_BE_LONG");
+ Setattr(h, "iterable", "MAY_BE_ITERABLE");
+ Setattr(h, "mixed", "MAY_BE_MIXED");
+ Setattr(h, "null", "MAY_BE_NULL");
+ Setattr(h, "object", "MAY_BE_OBJECT");
+ Setattr(h, "resource", "MAY_BE_RESOURCE");
+ Setattr(h, "string", "MAY_BE_STRING");
+ Setattr(h, "void", "MAY_BE_VOID");
+ return h;
+}
+
+static Hash *php_type_flags = create_php_type_flags();
+
+// php_class + ":" + php_method -> PHPTypes*
+// ":" + php_function -> PHPTypes*
+static Hash *all_phptypes = NewHash();
+
+// php_class_name -> php_parent_class_name
+static Hash *php_parent_class = NewHash();
+
+// Track if a method is directed in a descendent class.
+// php_class + ":" + php_method -> boolean (using SetFlag()/GetFlag()).
+static Hash *has_directed_descendent = NewHash();
+
+// Track required return type for parent class methods.
+// php_class + ":" + php_method -> List of php types.
+static Hash *parent_class_method_return_type = NewHash();
+
+// Class encapsulating the machinery to add PHP type declarations.
+class PHPTypes {
+ // List with an entry for each parameter and one for the return type.
+ //
+ // We assemble the types in here before emitting them so for an overloaded
+ // function we combine the type declarations from each overloaded form.
+ List *merged_types;
+
+ // List with an entry for each parameter which is passed "byref" in any
+ // overloaded form. We use this to pass such parameters by reference in
+ // the dispatch function. If NULL, no parameters are passed by reference.
+ List *byref;
+
+ // The id string used in the name of the arginfo for this object.
+ String *arginfo_id;
+
+ // The feature:php:type value: 0, 1 or -1 for "compatibility".
+ int php_type_flag;
+
+ // Does the node for this have directorNode set?
+ bool has_director_node;
+
+ // Used to clamp the required number of parameters in the arginfo to be
+ // compatible with any parent class version of the method.
+ int num_required;
+
+ int get_byref(int key) const {
+ return byref && key < Len(byref) && Getitem(byref, key) != None;
+ }
+
+ int size() const {
+ return std::max(Len(merged_types), Len(byref));
+ }
+
+ String *get_phptype(int key, String *classtypes, List *more_return_types = NULL) {
+ Clear(classtypes);
+ // We want to minimise the list of class types by not redundantly listing
+ // a class for which a super-class is also listed. This canonicalisation
+ // allows for more sharing of arginfo (which reduces module size), makes
+ // for a cleaner list if it's shown to the user, and also will speed up
+ // module load a bit.
+ Hash *classes = NewHash();
+ DOH *types = Getitem(merged_types, key);
+ String *result = NewStringEmpty();
+ if (more_return_types) {
+ if (types != None) {
+ merge_type_lists(types, more_return_types);
+ }
+ }
+ if (types != None) {
+ SortList(types, NULL);
+ String *prev = NULL;
+ for (Iterator i = First(types); i.item; i = Next(i)) {
+ if (prev && Equal(prev, i.item)) {
+ // Skip duplicates when merging.
+ continue;
+ }
+ String *c = Getattr(php_type_flags, i.item);
+ if (c) {
+ if (Len(result) > 0) Append(result, "|");
+ Append(result, c);
+ } else {
+ SetFlag(classes, i.item);
+ }
+ prev = i.item;
+ }
+ }
+
+ // Remove entries for which a super-class is also listed.
+ Iterator i = First(classes);
+ while (i.key) {
+ String *this_class = i.key;
+ // We must advance the iterator early so we don't delete the element it
+ // points to.
+ i = Next(i);
+ String *parent = this_class;
+ while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+ if (GetFlag(classes, parent)) {
+ Delattr(classes, this_class);
+ break;
+ }
+ }
+ }
+
+ List *sorted_classes = SortedKeys(classes, Strcmp);
+ for (i = First(sorted_classes); i.item; i = Next(i)) {
+ if (Len(classtypes) > 0) Append(classtypes, "|");
+ Append(classtypes, prefix);
+ Append(classtypes, i.item);
+ }
+ Delete(sorted_classes);
+
+ // Make the mask 0 if there are only class names specified.
+ if (Len(result) == 0) {
+ Append(result, "0");
+ }
+ return result;
+ }
+
+public:
+ PHPTypes(Node *n)
+ : merged_types(NewList()),
+ byref(NULL),
+ num_required(INT_MAX) {
+ String *php_type_feature = Getattr(n, "feature:php:type");
+ php_type_flag = 0;
+ if (php_type_feature != NULL) {
+ if (Equal(php_type_feature, "1")) {
+ php_type_flag = 1;
+ } else if (!Equal(php_type_feature, "0")) {
+ php_type_flag = -1;
+ }
+ }
+ arginfo_id = Copy(Getattr(n, "sym:name"));
+ has_director_node = (Getattr(n, "directorNode") != NULL);
+ }
+
+ ~PHPTypes() {
+ Delete(merged_types);
+ Delete(byref);
+ }
+
+ void adjust(int num_required_, bool php_constructor) {
+ num_required = std::min(num_required, num_required_);
+ if (php_constructor) {
+ // Don't add a return type declaration for a PHP __construct method
+ // (because there it has no return type as far as PHP is concerned).
+ php_type_flag = 0;
+ }
+ }
+
+ String *get_arginfo_id() const {
+ return arginfo_id;
+ }
+
+ // key is 0 for return type, or >= 1 for parameters numbered from 1
+ List *process_phptype(Node *n, int key, const String_or_char *attribute_name);
+
+ // Merge entries from o_merge_list into merge_list, skipping any entries
+ // already present.
+ //
+ // Both merge_list and o_merge_list should be in sorted order.
+ static void merge_type_lists(List *merge_list, List *o_merge_list);
+
+ void merge_from(const PHPTypes* o);
+
+ void set_byref(int key) {
+ if (!byref) {
+ byref = NewList();
+ }
+ while (Len(byref) <= key) {
+ Append(byref, None);
+ }
+ // If any overload takes a particular parameter by reference then the
+ // dispatch function also needs to take that parameter by reference so
+ // we can just set unconditionally here.
+ Setitem(byref, key, ""); // Just needs to be something != None.
+ }
+
+ void emit_arginfo(DOH *item, String *key) {
+ Setmark(item, 1);
+ char *colon_ptr = Strchr(key, ':');
+ assert(colon_ptr);
+ int colon = colon_ptr - Char(key);
+ if (colon > 0 && Strcmp(colon_ptr + 1, "__construct") != 0) {
+ // See if there's a parent class which implements this method, and if so
+ // emit its arginfo and then merge its PHPTypes into ours as we need to
+ // be compatible with it (whether it is virtual or not).
+ String *this_class = NewStringWithSize(Char(key), colon);
+ String *parent = this_class;
+ while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+ String *k = NewStringf("%s%s", parent, colon_ptr);
+ DOH *item = Getattr(all_phptypes, k);
+ if (item) {
+ PHPTypes *p = (PHPTypes*)Data(item);
+ if (!Getmark(item)) {
+ p->emit_arginfo(item, k);
+ }
+ merge_from(p);
+ Delete(k);
+ break;
+ }
+ Delete(k);
+ }
+ Delete(this_class);
+ }
+
+ // We want to only emit each different arginfo once, as that reduces the
+ // size of both the generated source code and the compiled extension
+ // module. The parameters at this level are just named arg1, arg2, etc
+ // so the arginfo will be the same for any function with the same number
+ // of parameters and (if present) PHP type declarations for parameters and
+ // return type.
+ //
+ // We generate the arginfo we want (taking care to normalise, e.g. the
+ // lists of types are unique and in sorted order), then use the
+ // arginfo_used Hash to see if we've already generated it.
+ String *out_phptype = NULL;
+ String *out_phpclasses = NewStringEmpty();
+
+ // We provide a simple way to generate PHP return type declarations
+ // except for directed methods. The point of directors is to allow
+ // subclassing in the target language, and if the wrapped method has
+ // a return type declaration then an overriding method in user code
+ // needs to have a compatible declaration.
+ //
+ // The upshot of this is that enabling return type declarations for
+ // existing bindings would break compatibility with user code written
+ // for an older version. For parameters however the situation is
+ // different because if the parent class declares types for parameters
+ // a subclass overriding the function will be compatible whether it
+ // declares them or not.
+ //
+ // directorNode being present seems to indicate if this method or one
+ // it inherits from is directed, which is what we care about here.
+ // Using (!is_member_director(n)) would get it wrong for testcase
+ // director_frob.
+ if (php_type_flag && (php_type_flag > 0 || !has_director_node)) {
+ if (!GetFlag(has_directed_descendent, key)) {
+ out_phptype = get_phptype(0, out_phpclasses, Getattr(parent_class_method_return_type, key));
+ }
+ }
+
+ // ### in arginfo_code will be replaced with the id once that is known.
+ String *arginfo_code = NewStringEmpty();
+ if (out_phptype) {
+ if (Len(out_phpclasses)) {
+ Replace(out_phpclasses, "\\", "\\\\", DOH_REPLACE_ANY);
+ Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s, %s)\n", num_required, out_phpclasses, out_phptype);
+ } else {
+ Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s)\n", num_required, out_phptype);
+ }
+ } else {
+ Printf(arginfo_code, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_###, 0, 0, %d)\n", num_required);
+ }
+
+ int phptypes_size = size();
+ for (int param_count = 1; param_count < phptypes_size; ++param_count) {
+ String *phpclasses = NewStringEmpty();
+ String *phptype = get_phptype(param_count, phpclasses);
+
+ int byref = get_byref(param_count);
+
+ // FIXME: Should we be doing byref for return value as well?
+
+ if (phptype) {
+ if (Len(phpclasses)) {
+ // We need to double any backslashes (which are PHP namespace
+ // separators) in the PHP class names as they get turned into
+ // C strings by the ZEND_ARG_OBJ_TYPE_MASK macro.
+ Replace(phpclasses, "\\", "\\\\", DOH_REPLACE_ANY);
+ Printf(arginfo_code, " ZEND_ARG_OBJ_TYPE_MASK(%d,arg%d,%s,%s,NULL)\n", byref, param_count, phpclasses, phptype);
+ } else {
+ Printf(arginfo_code, " ZEND_ARG_TYPE_MASK(%d,arg%d,%s,NULL)\n", byref, param_count, phptype);
+ }
+ } else {
+ Printf(arginfo_code, " ZEND_ARG_INFO(%d,arg%d)\n", byref, param_count);
+ }
+ }
+ Printf(arginfo_code, "ZEND_END_ARG_INFO()\n");
+
+ String *arginfo_id_same = Getattr(arginfo_used, arginfo_code);
+ if (arginfo_id_same) {
+ Printf(s_arginfo, "#define swig_arginfo_%s swig_arginfo_%s\n", arginfo_id, arginfo_id_same);
+ } else {
+ // Not had this arginfo before.
+ Setattr(arginfo_used, arginfo_code, arginfo_id);
+ arginfo_code = Copy(arginfo_code);
+ Replace(arginfo_code, "###", arginfo_id, DOH_REPLACE_FIRST);
+ Append(s_arginfo, arginfo_code);
+ }
+ Delete(arginfo_code);
+ arginfo_code = NULL;
+ }
+};
+
+static PHPTypes *phptypes = NULL;
+
class PHP : public Language {
public:
PHP() {
@@ -288,7 +567,7 @@ public:
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewStringEmpty();
@@ -299,6 +578,7 @@ public:
r_shutdown = NewStringEmpty();
s_header = NewString("/* header section */\n");
s_wrappers = NewString("/* wrapper section */\n");
+ s_creation = NewStringEmpty();
/* subsections of the init section */
s_vdecl = NewString("/* vdecl subsection */\n");
s_cinit = NewString(" /* cinit subsection */\n");
@@ -311,7 +591,7 @@ public:
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
@@ -329,12 +609,39 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGPHP\n#define SWIGPHP\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "PHP");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
}
+ // We need to include php.h before string.h gets included, at least with
+ // PHP 8.2. Otherwise string.h is included without _GNU_SOURCE being
+ // included and memrchr() doesn't get declared, and then inline code in
+ // the PHP headers defines _GNU_SOURCE, includes string.h (which is a
+ // no op thanks to the include gaurds), then tries to use memrchr() and
+ // fails.
+ //
+ // We also need to suppress -Wdeclaration-after-statement if enabled
+ // since with PHP 8.2 zend_operators.h contains inline code which triggers
+ // this warning and our testsuite uses with option and -Werror. I don't
+ // see a good way to only do this within our testsuite, but disabling
+ // it globally like this shouldn't be problematic.
+ Append(f_runtime,
+ "\n"
+ "#if defined __GNUC__ && !defined __cplusplus\n"
+ "# if __GNUC__ >= 4\n"
+ "# pragma GCC diagnostic push\n"
+ "# pragma GCC diagnostic ignored \"-Wdeclaration-after-statement\"\n"
+ "# endif\n"
+ "#endif\n"
+ "#include \"php.h\"\n"
+ "#if defined __GNUC__ && !defined __cplusplus\n"
+ "# if __GNUC__ >= 4\n"
+ "# pragma GCC diagnostic pop\n"
+ "# endif\n"
+ "#endif\n\n");
+
/* Set the module name */
module = Copy(Getattr(n, "name"));
cap_module = NewStringf("%(upper)s", module);
@@ -371,9 +678,6 @@ public:
Printf(s_header, "}\n");
Printf(s_header, "#endif\n\n");
- Printf(s_header, "#ifdef __cplusplus\n#define SWIG_remove(PTR) delete PTR\n");
- Printf(s_header, "#else\n#define SWIG_remove(PTR) free(PTR)\n#endif\n\n");
-
if (directorsEnabled()) {
// Insert director runtime
Swig_insert_file("director_common.swg", s_header);
@@ -386,7 +690,7 @@ public:
f_h = NewFile(filen, "w", SWIG_output_files());
if (!f_h) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Swig_banner(f_h);
@@ -415,21 +719,34 @@ public:
fake_cs_entry = NULL;
Printf(s_entry, "/* Every non-class user visible function must have an entry here */\n");
- Printf(s_entry, "static zend_function_entry module_%s_functions[] = {\n", module);
+ Printf(s_entry, "static const zend_function_entry module_%s_functions[] = {\n", module);
/* Emit all of the code */
Language::top(n);
- SwigPHP_emit_pointer_type_registrations();
- if (s_creation) {
- Dump(s_creation, s_header);
- Delete(s_creation);
- s_creation = NULL;
+ /* Emit all the arginfo. We sort the keys so the output order doesn't depend on
+ * hashkey order.
+ */
+ {
+ List *sorted_keys = SortedKeys(all_phptypes, Strcmp);
+ for (Iterator k = First(sorted_keys); k.item; k = Next(k)) {
+ DOH *val = Getattr(all_phptypes, k.item);
+ if (!Getmark(val)) {
+ PHPTypes *p = (PHPTypes*)Data(val);
+ p->emit_arginfo(val, k.item);
+ }
+ }
+ Delete(sorted_keys);
}
+ SwigPHP_emit_pointer_type_registrations();
+ Dump(s_creation, s_header);
+ Delete(s_creation);
+ s_creation = NULL;
+
/* start the init section */
{
- String * s_init_old = s_init;
+ String *s_init_old = s_init;
s_init = NewString("/* init section */\n");
Printv(s_init, "zend_module_entry ", module, "_module_entry = {\n", NIL);
Printf(s_init, " STANDARD_MODULE_HEADER,\n");
@@ -462,8 +779,7 @@ public:
Printf(s_init, " NO_VERSION_YET,\n");
}
Printf(s_init, " STANDARD_MODULE_PROPERTIES\n");
- Printf(s_init, "};\n");
- Printf(s_init, "zend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", module);
+ Printf(s_init, "};\n\n");
Printf(s_init, "#ifdef __cplusplus\n");
Printf(s_init, "extern \"C\" {\n");
@@ -486,7 +802,6 @@ public:
* things are being called in the wrong order
*/
- // Printv(s_init,s_resourcetypes,NIL);
Printf(s_oinit, " /* end oinit subsection */\n");
Printf(s_init, "%s\n", s_oinit);
@@ -603,7 +918,7 @@ public:
File *f_phpcode = NewFile(php_filename, "w", SWIG_output_files());
if (!f_phpcode) {
FileErrorDisplay(php_filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printf(f_phpcode, "<?php\n\n");
@@ -624,124 +939,54 @@ public:
}
/* Just need to append function names to function table to register with PHP. */
- void create_command(String *cname, String *fname, Node *n, bool overload, String *modes = NULL) {
+ void create_command(String *cname, String *fname, Node *n, bool dispatch, String *modes = NULL) {
// This is for the single main zend_function_entry record
- bool has_this = false;
- if (cname && Cmp(Getattr(n, "storage"), "friend") != 0) {
- Printf(f_h, "PHP_METHOD(%s%s,%s);\n", prefix, cname, fname);
- has_this = (wrapperType != staticmemberfn) &&
- (wrapperType != staticmembervar) &&
- (Cmp(fname, "__construct") != 0);
- } else {
- if (overload) {
- Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", fname);
- } else {
- Printf(f_h, "PHP_FUNCTION(%s);\n", fname);
- }
- }
- // We want to only emit each different arginfo once, as that reduces the
- // size of both the generated source code and the compiled extension
- // module. The parameters at this level are just named arg1, arg2, etc
- // so we generate an arginfo name with the number of parameters and a
- // bitmap value saying which (if any) are passed by reference.
ParmList *l = Getattr(n, "parms");
- unsigned long bitmap = 0, bit = 1;
- bool overflowed = false;
- bool skip_this = has_this;
- for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
- if (skip_this) {
- skip_this = false;
- continue;
- }
- String* tmap_in_numinputs = Getattr(p, "tmap:in:numinputs");
- // tmap:in:numinputs is unset for varargs, which we don't count here.
- if (!tmap_in_numinputs || Equal(tmap_in_numinputs, "0")) {
- /* Ignored parameter */
- continue;
- }
- if (GetFlag(p, "tmap:in:byref")) {
- bitmap |= bit;
- if (bit == 0) overflowed = true;
- }
- bit <<= 1;
- }
- int num_arguments = emit_num_arguments(l);
- int num_required = emit_num_required(l);
- if (has_this) {
- --num_arguments;
- --num_required;
- }
- String * arginfo_code;
- if (overflowed) {
- // We overflowed the bitmap so just generate a unique name - this only
- // happens for a function with more parameters than bits in a long
- // where a high numbered parameter is passed by reference, so should be
- // rare in practice.
- static int overflowed_counter = 0;
- arginfo_code = NewStringf("z%d", ++overflowed_counter);
- } else if (bitmap == 0) {
- // No parameters passed by reference.
- if (num_required == num_arguments) {
- arginfo_code = NewStringf("%d", num_arguments);
- } else {
- arginfo_code = NewStringf("%d_%d", num_required, num_arguments);
+ if (cname && !Equal(Getattr(n, "storage"), "friend")) {
+ Printf(f_h, "static PHP_METHOD(%s%s,%s);\n", prefix, cname, fname);
+ if (wrapperType != staticmemberfn &&
+ wrapperType != staticmembervar &&
+ !Equal(fname, "__construct")) {
+ // Skip the first entry in the parameter list which is the this pointer.
+ if (l) l = Getattr(l, "tmap:in:next");
+ // FIXME: does this throw the phptype key value off?
}
} else {
- if (num_required == num_arguments) {
- arginfo_code = NewStringf("%d_r%lx", num_arguments, bitmap);
+ if (dispatch) {
+ Printf(f_h, "static ZEND_NAMED_FUNCTION(%s);\n", fname);
} else {
- arginfo_code = NewStringf("%d_%d_r%lx", num_required, num_arguments, bitmap);
+ Printf(f_h, "static PHP_FUNCTION(%s);\n", fname);
}
}
- if (!GetFlag(arginfo_used, arginfo_code)) {
- // Not had this one before so emit it.
- SetFlag(arginfo_used, arginfo_code);
- Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, %d)\n", arginfo_code, num_required);
- bool skip_this = has_this;
- int param_count = 0;
- for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
- if (skip_this) {
- skip_this = false;
- continue;
- }
- String* tmap_in_numinputs = Getattr(p, "tmap:in:numinputs");
- // tmap:in:numinputs is unset for varargs, which we don't count here.
- if (!tmap_in_numinputs || Equal(tmap_in_numinputs, "0")) {
- /* Ignored parameter */
- continue;
- }
- Printf(s_arginfo, " ZEND_ARG_INFO(%d,arg%d)\n", GetFlag(p, "tmap:in:byref"), ++param_count);
- }
- Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
- }
+ phptypes->adjust(emit_num_required(l), Equal(fname, "__construct"));
- String * s = cs_entry;
+ String *arginfo_id = phptypes->get_arginfo_id();
+ String *s = cs_entry;
if (!s) s = s_entry;
- if (cname && Cmp(Getattr(n, "storage"), "friend") != 0) {
- Printf(all_cs_entry, " PHP_ME(%s%s,%s,swig_arginfo_%s,%s)\n", prefix, cname, fname, arginfo_code, modes);
+ if (cname && !Equal(Getattr(n, "storage"), "friend")) {
+ Printf(all_cs_entry, " PHP_ME(%s%s,%s,swig_arginfo_%s,%s)\n", prefix, cname, fname, arginfo_id, modes);
} else {
- if (overload) {
+ if (dispatch) {
if (wrap_nonclass_global) {
- Printf(s, " ZEND_NAMED_FE(%(lower)s,%s,swig_arginfo_%s)\n", Getattr(n, "sym:name"), fname, arginfo_code);
+ Printf(s, " ZEND_NAMED_FE(%(lower)s,%s,swig_arginfo_%s)\n", Getattr(n, "sym:name"), fname, arginfo_id);
}
if (wrap_nonclass_fake_class) {
(void)fake_class_name();
- Printf(fake_cs_entry, " ZEND_NAMED_ME(%(lower)s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", Getattr(n, "sym:name"), fname, arginfo_code);
+ Printf(fake_cs_entry, " ZEND_NAMED_ME(%(lower)s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", Getattr(n, "sym:name"), fname, arginfo_id);
}
} else {
if (wrap_nonclass_global) {
- Printf(s, " PHP_FE(%s,swig_arginfo_%s)\n", fname, arginfo_code);
+ Printf(s, " PHP_FE(%s,swig_arginfo_%s)\n", fname, arginfo_id);
}
if (wrap_nonclass_fake_class) {
String *fake_class = fake_class_name();
- Printf(fake_cs_entry, " PHP_ME(%s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", fake_class, fname, arginfo_code);
+ Printf(fake_cs_entry, " PHP_ME(%s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", fake_class, fname, arginfo_id);
}
}
}
- Delete(arginfo_code);
}
/* ------------------------------------------------------------
@@ -763,12 +1008,12 @@ public:
bool constructorRenameOverload = false;
if (constructor) {
- // Renamed constructor - turn into static factory method
- if (Cmp(class_name, Getattr(n, "constructorHandler:sym:name")) != 0) {
- constructorRenameOverload = true;
- wname = Copy(Getattr(n, "constructorHandler:sym:name"));
+ if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) {
+ // Renamed constructor - turn into static factory method
+ constructorRenameOverload = true;
+ wname = Copy(Getattr(n, "constructorHandler:sym:name"));
} else {
- wname = NewString("__construct");
+ wname = NewString("__construct");
}
} else if (class_name) {
wname = Getattr(n, "wrapper:method:name");
@@ -779,7 +1024,7 @@ public:
if (constructor) {
modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_CTOR");
if (constructorRenameOverload) {
- Append(modes, " | ZEND_ACC_STATIC");
+ Append(modes, " | ZEND_ACC_STATIC");
}
} else if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"), "static") == 0) {
modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_STATIC");
@@ -789,10 +1034,10 @@ public:
create_command(class_name, wname, n, true, modes);
- if (class_name && Cmp(Getattr(n, "storage"), "friend") != 0) {
- Printv(f->def, "PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
+ if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
+ Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
} else {
- Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
+ Printv(f->def, "static ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
}
Wrapper_add_local(f, "argc", "int argc");
@@ -823,77 +1068,43 @@ public:
* functionWrapper()
* ------------------------------------------------------------ */
- /* Helper method for PHP::functionWrapper */
- bool is_class(SwigType *t) {
- Node *n = classLookup(t);
- if (n) {
- String *r = Getattr(n, "php:proxy"); // Set by classDeclaration()
- if (!r)
- r = Getattr(n, "sym:name"); // Not seen by classDeclaration yet, but this is the name
- if (r)
- return true;
- }
- return false;
- }
-
- /* Helper method for PHP::functionWrapper to get class name for parameter*/
- String *get_class_name(SwigType *t) {
- Node *n = classLookup(t);
- String *r = NULL;
- if (n) {
- r = Getattr(n, "php:proxy"); // Set by classDeclaration()
- if (!r)
- r = Getattr(n, "sym:name"); // Not seen by classDeclaration yet, but this is the name
- }
- return r;
- }
-
/* Helper function to check if class is wrapped */
bool is_class_wrapped(String *className) {
if (!className)
return false;
- Node * n = symbolLookup(className);
+ Node *n = symbolLookup(className);
return n && Getattr(n, "classtype") != NULL;
}
- /* Is special return type */
- bool is_param_type_pointer(SwigType *t) {
-
- if (SwigType_ispointer(t) ||
- SwigType_ismemberpointer(t) ||
- SwigType_isreference(t) ||
- SwigType_isarray(t))
- return true;
-
- return false;
- }
-
- void generate_magic_property_methods(Node *class_node, String *base_class) {
- if (Equal(base_class, "Exception") || !is_class_wrapped(base_class)) {
- base_class = NULL;
+ void generate_magic_property_methods(Node *class_node) {
+ String *swig_base = base_class;
+ if (Equal(swig_base, "Exception") || !is_class_wrapped(swig_base)) {
+ swig_base = NULL;
}
- // Ensure arginfo_1 and arginfo_2 exist.
- if (!GetFlag(arginfo_used, "1")) {
- SetFlag(arginfo_used, "1");
+ static bool generated_magic_arginfo = false;
+ if (!generated_magic_arginfo) {
+ // Create arginfo entries for __get, __set and __isset.
Append(s_arginfo,
- "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_1, 0, 0, 1)\n"
- " ZEND_ARG_INFO(0,arg1)\n"
+ "ZEND_BEGIN_ARG_INFO_EX(swig_magic_arginfo_get, 0, 0, 1)\n"
+ " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n"
"ZEND_END_ARG_INFO()\n");
- }
- if (!GetFlag(arginfo_used, "2")) {
- SetFlag(arginfo_used, "2");
Append(s_arginfo,
- "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_2, 0, 0, 2)\n"
- " ZEND_ARG_INFO(0,arg1)\n"
+ "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_magic_arginfo_set, 0, 1, MAY_BE_VOID)\n"
+ " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n"
" ZEND_ARG_INFO(0,arg2)\n"
"ZEND_END_ARG_INFO()\n");
+ Append(s_arginfo,
+ "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_magic_arginfo_isset, 0, 1, MAY_BE_BOOL)\n"
+ " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n"
+ "ZEND_END_ARG_INFO()\n");
+ generated_magic_arginfo = true;
}
Wrapper *f = NewWrapper();
Printf(f_h, "PHP_METHOD(%s%s,__set);\n", prefix, class_name);
- Printf(all_cs_entry, " PHP_ME(%s%s,__set,swig_arginfo_2,ZEND_ACC_PUBLIC)\n", prefix, class_name);
+ Printf(all_cs_entry, " PHP_ME(%s%s,__set,swig_magic_arginfo_set,ZEND_ACC_PUBLIC)\n", prefix, class_name);
Printf(f->code, "PHP_METHOD(%s%s,__set) {\n", prefix, class_name);
Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n");
@@ -918,12 +1129,12 @@ public:
" if (director) director->swig_disown();\n",
"}\n", NIL);
}
- Printf(f->code, "} else {\n");
- if (base_class) {
- Printf(f->code, "PHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, base_class);
- } else {
- Printf(f->code, "add_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n}\n");
+ if (swig_base) {
+ Printf(f->code, "} else {\nPHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n", prefix, swig_base);
+ } else if (Getattr(class_node, "feature:php:allowdynamicproperties")) {
+ Printf(f->code, "} else {\nadd_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n");
}
+ Printf(f->code, "}\n");
Printf(f->code, "fail:\n");
Printf(f->code, "return;\n");
@@ -931,10 +1142,10 @@ public:
Printf(f_h, "PHP_METHOD(%s%s,__get);\n", prefix, class_name);
- Printf(all_cs_entry, " PHP_ME(%s%s,__get,swig_arginfo_1,ZEND_ACC_PUBLIC)\n", prefix, class_name);
+ Printf(all_cs_entry, " PHP_ME(%s%s,__get,swig_magic_arginfo_get,ZEND_ACC_PUBLIC)\n", prefix, class_name);
Printf(f->code, "PHP_METHOD(%s%s,__get) {\n",prefix, class_name);
- Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n", class_name);
+ Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n");
Printf(f->code, " zval args[1];\n zval tempZval;\n zend_string *arg2 = 0;\n\n");
Printf(f->code, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n");
@@ -951,8 +1162,8 @@ public:
Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n");
Printf(f->code, "if(arg->newobject) {\nRETVAL_LONG(1);\n}\nelse {\nRETVAL_LONG(0);\n}\n}\n\n");
Printf(f->code, "else {\n");
- if (base_class) {
- Printf(f->code, "PHP_MN(%s%s___get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, base_class);
+ if (swig_base) {
+ Printf(f->code, "PHP_MN(%s%s___get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
} else {
// __get is only called if the property isn't set on the zend_object.
Printf(f->code, "RETVAL_NULL();\n}\n");
@@ -964,15 +1175,16 @@ public:
Printf(f_h, "PHP_METHOD(%s%s,__isset);\n", prefix, class_name);
- Printf(all_cs_entry, " PHP_ME(%s%s,__isset,swig_arginfo_1,ZEND_ACC_PUBLIC)\n", prefix, class_name);
+ Printf(all_cs_entry, " PHP_ME(%s%s,__isset,swig_magic_arginfo_isset,ZEND_ACC_PUBLIC)\n", prefix, class_name);
Printf(f->code, "PHP_METHOD(%s%s,__isset) {\n",prefix, class_name);
- Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n", class_name);
+ Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n");
Printf(f->code, " zval args[1];\n zend_string *arg2 = 0;\n\n");
Printf(f->code, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n");
Printf(f->code, " if(!arg) {\n");
Printf(f->code, " zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
+ Printf(f->code, " return;\n");
Printf(f->code, " }\n");
Printf(f->code, " arg2 = Z_STR(args[0]);\n\n");
@@ -983,8 +1195,8 @@ public:
Append(f->code, magic_isset);
}
Printf(f->code, "else {\n");
- if (base_class) {
- Printf(f->code, "PHP_MN(%s%s___isset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, base_class);
+ if (swig_base) {
+ Printf(f->code, "PHP_MN(%s%s___isset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
} else {
// __isset is only called if the property isn't set on the zend_object.
Printf(f->code, "RETVAL_FALSE;\n}\n");
@@ -1016,27 +1228,25 @@ public:
}
bool is_setter_method(Node *n) {
-
const char *p = GetChar(n, "sym:name");
- if (strlen(p) > 4) {
- p += strlen(p) - 4;
- if (strcmp(p, "_set") == 0) {
- return true;
- }
+ if (strlen(p) > 4) {
+ p += strlen(p) - 4;
+ if (strcmp(p, "_set") == 0) {
+ return true;
}
- return false;
+ }
+ return false;
}
bool is_getter_method(Node *n) {
-
const char *p = GetChar(n, "sym:name");
- if (strlen(p) > 4) {
- p += strlen(p) - 4;
- if (strcmp(p, "_get") == 0) {
- return true;
- }
+ if (strlen(p) > 4) {
+ p += strlen(p) - 4;
+ if (strcmp(p, "_get") == 0) {
+ return true;
}
- return false;
+ }
+ return false;
}
virtual int functionWrapper(Node *n) {
@@ -1061,7 +1271,6 @@ public:
String *wname = NewStringEmpty();
String *overloadwname = NULL;
int overloaded = 0;
- String *overname = 0;
String *modes = NULL;
bool static_setter = false;
bool static_getter = false;
@@ -1070,7 +1279,7 @@ public:
if (constructor) {
Append(modes, " | ZEND_ACC_CTOR");
- }
+ }
if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"), "static") == 0) {
Append(modes, " | ZEND_ACC_STATIC");
}
@@ -1079,26 +1288,26 @@ public:
if (Getattr(n, "sym:overloaded")) {
overloaded = 1;
- overname = Getattr(n, "sym:overname");
+ overloadwname = NewString(Swig_name_wrapper(iname));
+ Printf(overloadwname, "%s", Getattr(n, "sym:overname"));
} else {
if (!addSymbol(iname, n))
return SWIG_ERROR;
}
- if (overname) {
- // Test for overloading
- overloadwname = NewString(Swig_name_wrapper(iname));
- Printf(overloadwname, "%s", overname);
- }
-
if (constructor) {
- wname = NewString("__construct");
+ if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) {
+ // Renamed constructor - turn into static factory method
+ wname = Copy(Getattr(n, "constructorHandler:sym:name"));
+ } else {
+ wname = NewString("__construct");
+ }
} else if (wrapperType == membervar) {
wname = Copy(Getattr(n, "membervariableHandler:sym:name"));
if (is_setter_method(n)) {
- Append(wname, "_set");
+ Append(wname, "_set");
} else if (is_getter_method(n)) {
- Append(wname, "_get");
+ Append(wname, "_get");
}
} else if (wrapperType == memberfn) {
wname = Getattr(n, "memberfunctionHandler:sym:name");
@@ -1107,38 +1316,62 @@ public:
wname = Getattr(n, "staticmembervariableHandler:sym:name");
/* We get called twice for getter and setter methods. But to maintain
- compatibility, Shape::nshapes() is being used for both setter and
- getter methods. So using static_setter and static_getter variables
- to generate half of the code each time.
+ compatibility, Shape::nshapes() is being used for both setter and
+ getter methods. So using static_setter and static_getter variables
+ to generate half of the code each time.
*/
static_setter = is_setter_method(n);
if (is_getter_method(n)) {
- // This is to overcome types that can't be set and hence no setter.
- if (Cmp(Getattr(n, "feature:immutable"), "1") != 0)
- static_getter = true;
+ // This is to overcome types that can't be set and hence no setter.
+ if (!Equal(Getattr(n, "feature:immutable"), "1"))
+ static_getter = true;
}
} else if (wrapperType == staticmemberfn) {
wname = Getattr(n, "staticmemberfunctionHandler:sym:name");
} else {
if (class_name) {
- if (Cmp(Getattr(n, "storage"), "friend") == 0 && Cmp(Getattr(n, "view"), "globalfunctionHandler") == 0) {
- wname = iname;
- } else {
- wname = Getattr(n, "destructorHandler:sym:name");
- }
+ if (Cmp(Getattr(n, "storage"), "friend") == 0 && Cmp(Getattr(n, "view"), "globalfunctionHandler") == 0) {
+ wname = iname;
+ } else {
+ wname = Getattr(n, "destructorHandler:sym:name");
+ }
} else {
- wname = iname;
+ wname = iname;
}
}
- if (Cmp(nodeType, "destructor") == 0) {
+ if (wrapperType == destructor) {
// We don't explicitly wrap the destructor for PHP - Zend manages the
// reference counting, and the user can just do `$obj = null;' or similar
// to remove a reference to an object.
+ Setattr(n, "wrap:name", wname);
+ (void)emit_action(n);
return SWIG_OK;
}
+ if (!static_getter) {
+ // Create or find existing PHPTypes.
+ phptypes = NULL;
+
+ String *key;
+ if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
+ key = NewStringf("%s:%s", class_name, wname);
+ } else {
+ key = NewStringf(":%s", wname);
+ }
+
+ PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, key);
+ if (p) {
+ // We already have an entry so use it.
+ phptypes = p;
+ Delete(key);
+ } else {
+ phptypes = new PHPTypes(n);
+ SetVoid(all_phptypes, key, phptypes);
+ }
+ }
+
f = NewWrapper();
if (static_getter) {
@@ -1150,32 +1383,28 @@ public:
if (!overloaded) {
if (!static_getter) {
- if (class_name && Cmp(Getattr(n, "storage"), "friend") != 0) {
- Printv(f->def, "PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
- } else {
+ if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
+ Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
+ } else {
if (wrap_nonclass_global) {
- Printv(f->def, "PHP_METHOD(", fake_class_name(), ",", wname, ") {\n",
+ Printv(f->def, "static PHP_METHOD(", fake_class_name(), ",", wname, ") {\n",
" PHP_FN(", wname, ")(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n",
"}\n\n", NIL);
}
if (wrap_nonclass_fake_class) {
- Printv(f->def, "PHP_FUNCTION(", wname, ") {\n", NIL);
+ Printv(f->def, "static PHP_FUNCTION(", wname, ") {\n", NIL);
}
- }
+ }
}
} else {
- Printv(f->def, "ZEND_NAMED_FUNCTION(", overloadwname, ") {\n", NIL);
+ Printv(f->def, "static ZEND_NAMED_FUNCTION(", overloadwname, ") {\n", NIL);
}
emit_parameter_variables(l, f);
/* Attach standard typemaps */
emit_attach_parmmaps(l, f);
- // Not issued for overloaded functions.
- if (!overloaded && !static_getter) {
- create_command(class_name, wname, n, false, modes);
- }
if (wrapperType == memberfn || wrapperType == membervar) {
// Assign "this" to arg1 and remove first entry from ParmList l.
@@ -1217,9 +1446,9 @@ public:
Printf(f->code, "\tWRONG_PARAM_COUNT;\n\n");
} else if (static_setter || static_getter) {
if (num_arguments == 0) {
- Printf(f->code, "if(ZEND_NUM_ARGS() == 0) {\n");
+ Printf(f->code, "if(ZEND_NUM_ARGS() == 0) {\n");
} else {
- Printf(f->code, "if(ZEND_NUM_ARGS() == %d && zend_get_parameters_array_ex(%d, args) == SUCCESS) {\n", num_arguments, num_arguments);
+ Printf(f->code, "if(ZEND_NUM_ARGS() == %d && zend_get_parameters_array_ex(%d, args) == SUCCESS) {\n", num_arguments, num_arguments);
}
} else {
if (num_arguments == 0) {
@@ -1241,59 +1470,52 @@ public:
// This may mean looking at Language::memberfunctionHandler
for (i = 0, p = l; i < num_arguments; i++) {
- String *source;
-
/* Skip ignored arguments */
- //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");}
while (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
}
- SwigType *pt = Getattr(p, "type");
-
- source = NewStringf("args[%d]", i);
-
/* Check if optional */
if (i >= num_required) {
Printf(f->code, "\tif(arg_count > %d) {\n", i);
}
- String *paramType_class = NULL;
- bool paramType_valid = is_class(pt);
-
- if (paramType_valid) {
- paramType_class = get_class_name(pt);
- Chop(paramType_class);
+ tm = Getattr(p, "tmap:in");
+ if (!tm) {
+ SwigType *pt = Getattr(p, "type");
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+ p = nextSibling(p);
+ continue;
}
- if ((tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source);
- Printf(f->code, "%s\n", tm);
- if (i == 0 && Getattr(p, "self")) {
- Printf(f->code, "\tif(!arg1) {\n");
- Printf(f->code, "\t zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
- Printf(f->code, "\t return;\n");
- Printf(f->code, "\t}\n");
- }
- p = Getattr(p, "tmap:in:next");
- if (i >= num_required) {
- Printf(f->code, "}\n");
- }
- continue;
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+ phptypes->process_phptype(p, i + 1, "tmap:in:phptype");
+ if (GetFlag(p, "tmap:in:byref")) phptypes->set_byref(i + 1);
+
+ String *source = NewStringf("args[%d]", i);
+ Replaceall(tm, "$input", source);
+ Setattr(p, "emit:input", source);
+ Printf(f->code, "%s\n", tm);
+ if (i == 0 && Getattr(p, "self")) {
+ Printf(f->code, "\tif(!arg1) {\n");
+ Printf(f->code, "\t zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
+ Printf(f->code, "\t return;\n");
+ Printf(f->code, "\t}\n");
}
+
if (i >= num_required) {
- Printf(f->code, "\t}\n");
+ Printf(f->code, "}\n");
}
+
+ p = Getattr(p, "tmap:in:next");
+
Delete(source);
}
if (is_member_director(n)) {
+ Wrapper_add_local(f, "director", "Swig::Director *director = 0");
+ Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
Wrapper_add_local(f, "upcall", "bool upcall = false");
- Printf(f->code, "upcall = !Swig::Director::swig_is_overridden_method(\"%s%s\", ZEND_THIS);\n",
- prefix, Swig_class_name(Swig_methodclass(n)));
+ Printf(f->code, "upcall = (director && (director->swig_get_self()==Z_OBJ_P(ZEND_THIS)));\n");
}
Swig_director_emit_dynamic_cast(n, f);
@@ -1353,11 +1575,39 @@ public:
}
emit_return_variable(n, d, f);
+ List *return_types = phptypes->process_phptype(n, 0, "tmap:out:phptype");
+
+ if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
+ if (is_member_director(n)) {
+ String *parent = class_name;
+ while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+ // Mark this method name as having no return type declaration for all
+ // classes we're derived from.
+ SetFlag(has_directed_descendent, NewStringf("%s:%s", parent, wname));
+ }
+ } else if (return_types) {
+ String *parent = class_name;
+ while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+ String *key = NewStringf("%s:%s", parent, wname);
+ // The parent class method needs to have a superset of the possible
+ // return types of methods with the same name in subclasses.
+ List *v = Getattr(parent_class_method_return_type, key);
+ if (!v) {
+ // New entry.
+ Setattr(parent_class_method_return_type, key, Copy(return_types));
+ } else {
+ // Update existing entry.
+ PHPTypes::merge_type_lists(v, return_types);
+ }
+ }
+ }
+ }
+
if (outarg) {
Printv(f->code, outarg, NIL);
}
- if (cleanup) {
+ if (static_setter && cleanup) {
Printv(f->code, cleanup, NIL);
}
@@ -1396,10 +1646,15 @@ public:
Wrapper_print(f, s_wrappers);
DelWrapper(f);
f = NULL;
- wname = NULL;
- if (overloaded && !Getattr(n, "sym:nextSibling")) {
- dispatchFunction(n, constructor);
+ if (overloaded) {
+ if (!Getattr(n, "sym:nextSibling")) {
+ dispatchFunction(n, constructor);
+ }
+ } else {
+ if (!static_setter) {
+ create_command(class_name, wname, n, false, modes);
+ }
}
return SWIG_OK;
@@ -1434,28 +1689,29 @@ public:
SwigType_remember(type);
+ String *wrapping_member_constant = Getattr(n, "memberconstantHandler:sym:name");
if (!wrapping_member_constant) {
{
tm = Swig_typemap_lookup("consttab", n, name, 0);
Replaceall(tm, "$value", value);
- if (Getattr(n, "tmap:consttab:rinit")) {
- Printf(r_init, "%s\n", tm);
- } else {
- Printf(s_cinit, "%s\n", tm);
- }
+ if (Getattr(n, "tmap:consttab:rinit")) {
+ Printf(r_init, "%s\n", tm);
+ } else {
+ Printf(s_cinit, "%s\n", tm);
+ }
}
{
- tm = Swig_typemap_lookup("classconsttab", n, name, 0);
+ tm = Swig_typemap_lookup("classconsttab", n, name, 0);
- Replaceall(tm, "$class", fake_class_name());
- Replaceall(tm, "$const_name", iname);
+ Replaceall(tm, "$class", fake_class_name());
+ Replaceall(tm, "$const_name", iname);
Replaceall(tm, "$value", value);
- if (Getattr(n, "tmap:classconsttab:rinit")) {
- Printf(r_init, "%s\n", tm);
- } else {
- Printf(s_cinit, "%s\n", tm);
- }
+ if (Getattr(n, "tmap:classconsttab:rinit")) {
+ Printf(r_init, "%s\n", tm);
+ } else {
+ Printf(s_cinit, "%s\n", tm);
+ }
}
} else {
tm = Swig_typemap_lookup("classconsttab", n, name, 0);
@@ -1463,9 +1719,9 @@ public:
Replaceall(tm, "$const_name", wrapping_member_constant);
Replaceall(tm, "$value", value);
if (Getattr(n, "tmap:classconsttab:rinit")) {
- Printf(r_init, "%s\n", tm);
+ Printf(r_init, "%s\n", tm);
} else {
- Printf(s_cinit, "%s\n", tm);
+ Printf(s_cinit, "%s\n", tm);
}
}
@@ -1518,11 +1774,6 @@ public:
* ------------------------------------------------------------ */
virtual int classDeclaration(Node *n) {
- if (!Getattr(n, "feature:onlychildren")) {
- String *symname = Getattr(n, "sym:name");
- Setattr(n, "php:proxy", symname);
- }
-
return Language::classDeclaration(n);
}
@@ -1532,11 +1783,12 @@ public:
virtual int classHandler(Node *n) {
String *symname = Getattr(n, "sym:name");
- String *base_class = NULL;
class_name = symname;
+ base_class = NULL;
+ destructor_action = NULL;
- Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", class_name);
+ Printf(all_cs_entry, "static const zend_function_entry class_%s_functions[] = {\n", class_name);
// namespace code to introduce namespaces into wrapper classes.
//if (nameSpace != NULL)
@@ -1585,16 +1837,28 @@ public:
}
if (Equal(base_class, "Exception")) {
- Printf(s_oinit, " SWIGTYPE_%s_ce = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name);
+ Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name);
} else if (is_class_wrapped(base_class)) {
- Printf(s_oinit, " SWIGTYPE_%s_ce = zend_register_internal_class_ex(&internal_ce, SWIGTYPE_%s_ce);\n", class_name, base_class);
+ Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class);
+ Setattr(php_parent_class, class_name, base_class);
} else {
- Printf(s_oinit, " SWIGTYPE_%s_ce = zend_register_internal_class(&internal_ce);\n", class_name);
+ Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
}
if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) {
- Printf(s_oinit, " SWIGTYPE_%s_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n", class_name);
+ Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n", class_name);
+ }
+ if (Getattr(n, "feature:php:allowdynamicproperties")) {
+ Append(s_oinit, "#ifdef ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES\n");
+ Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;\n", class_name);
+ Append(s_oinit, "#endif\n");
+ } else {
+ Append(s_oinit, "#ifdef ZEND_ACC_NO_DYNAMIC_PROPERTIES\n");
+ Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES;\n", class_name);
+ Append(s_oinit, "#endif\n");
}
+ String *swig_wrapped = swig_wrapped_interface_ce();
+ Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", &", swig_wrapped, ");\n", NIL);
{
Node *node = NewHash();
@@ -1626,7 +1890,7 @@ public:
String *interface = Getitem(interface_list, i);
// We generate conditional code in both minit and rinit - then we or the user
// just need to define SWIG_PHP_INTERFACE_xxx_CE (and optionally
- // SWIG_PHP_INTERFACE_xxx_CE) to handle interface `xxx` at minit-time.
+ // SWIG_PHP_INTERFACE_xxx_HEADER) to handle interface `xxx` at minit-time.
Printv(s_header,
"#ifdef SWIG_PHP_INTERFACE_", interface, "_HEADER\n",
"# include SWIG_PHP_INTERFACE_", interface, "_HEADER\n",
@@ -1634,15 +1898,17 @@ public:
NIL);
Printv(s_oinit,
"#ifdef SWIG_PHP_INTERFACE_", interface, "_CE\n",
- " zend_do_implement_interface(SWIGTYPE_", class_name, "_ce, SWIG_PHP_INTERFACE_", interface, "_CE);\n",
+ " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", SWIG_PHP_INTERFACE_", interface, "_CE);\n",
"#endif\n",
NIL);
Printv(r_init_prefix,
"#ifndef SWIG_PHP_INTERFACE_", interface, "_CE\n",
" {\n",
" zend_class_entry *swig_interface_ce = zend_lookup_class(zend_string_init(\"", interface, "\", sizeof(\"", interface, "\") - 1, 0));\n",
- " if (!swig_interface_ce) zend_throw_exception(zend_ce_error, \"Interface \\\"", interface, "\\\" not found\", 0);\n",
- " zend_do_implement_interface(SWIGTYPE_", class_name, "_ce, swig_interface_ce);\n",
+ " if (swig_interface_ce)\n",
+ " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", swig_interface_ce);\n",
+ " else\n",
+ " zend_throw_exception(zend_ce_error, \"Interface \\\"", interface, "\\\" not found\", 0);\n",
" }\n",
"#endif\n",
NIL);
@@ -1663,24 +1929,88 @@ public:
Delete(interfaces);
}
- Printf(s_oinit, " SWIGTYPE_%s_ce->create_object = %s_object_new;\n", class_name, class_name);
- Printf(s_oinit, " memcpy(&%s_object_handlers,zend_get_std_object_handlers(), sizeof(zend_object_handlers));\n", class_name);
- Printf(s_oinit, " %s_object_handlers.clone_obj = NULL;\n", class_name);
+ Language::classHandler(n);
+
+ static bool emitted_base_object_handlers = false;
+ if (!emitted_base_object_handlers) {
+ Printf(s_creation, "static zend_object_handlers Swig_Php_base_object_handlers;\n\n");
+
+ // Set up a base zend_object_handlers structure which we can use as-is
+ // for classes without a destructor, and copy as the basis for other
+ // classes.
+ Printf(s_oinit, " Swig_Php_base_object_handlers = *zend_get_std_object_handlers();\n");
+ Printf(s_oinit, " Swig_Php_base_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n");
+ Printf(s_oinit, " Swig_Php_base_object_handlers.clone_obj = NULL;\n");
+ emitted_base_object_handlers = true;
+ }
+
+ Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n", class_name);
+
+ if (Getattr(n, "has_destructor")) {
+ if (destructor_action ? Equal(destructor_action, "free((char *) arg1);") : !CPlusPlus) {
+ // We can use a single function if the destructor action calls free()
+ // (either explicitly or as the default in C-mode) since free() doesn't
+ // care about the object's type. We currently only check for the exact
+ // code that Swig_cdestructor_call() emits.
+ static bool emitted_common_cdestructor = false;
+ if (!emitted_common_cdestructor) {
+ Printf(s_creation, "static zend_object_handlers Swig_Php_common_c_object_handlers;\n\n");
+ Printf(s_creation, "static void SWIG_Php_common_c_free_obj(zend_object *object) {free(SWIG_Php_free_obj(object));}\n\n");
+ Printf(s_creation, "static zend_object *SWIG_Php_common_c_create_object(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &Swig_Php_common_c_object_handlers);}\n");
+
+ Printf(s_oinit, " Swig_Php_common_c_object_handlers = Swig_Php_base_object_handlers;\n");
+ Printf(s_oinit, " Swig_Php_common_c_object_handlers.free_obj = SWIG_Php_common_c_free_obj;\n");
+
+ emitted_common_cdestructor = true;
+ }
+
+ Printf(s_oinit, " SWIG_Php_ce_%s->create_object = SWIG_Php_common_c_create_object;\n", class_name);
+ } else {
+ Printf(s_creation, "static zend_object_handlers %s_object_handlers;\n", class_name);
+ Printf(s_creation, "static zend_object *SWIG_Php_create_object_%s(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &%s_object_handlers);}\n", class_name, class_name);
+
+ Printf(s_creation, "static void SWIG_Php_free_obj_%s(zend_object *object) {",class_name);
+ String *type = Getattr(n, "classtype");
+ // Special case handling the delete call generated by
+ // Swig_cppdestructor_call() and generate simpler code.
+ if (destructor_action && !Equal(destructor_action, "delete arg1;")) {
+ Printv(s_creation, "\n"
+ " ", type, " *arg1 = (" , type, " *)SWIG_Php_free_obj(object);\n"
+ " if (arg1) {\n"
+ " ", destructor_action, "\n"
+ " }\n", NIL);
+ } else {
+ Printf(s_creation, "delete (%s *)SWIG_Php_free_obj(object);", type);
+ }
+ Printf(s_creation, "}\n\n");
+
+ Printf(s_oinit, " SWIG_Php_ce_%s->create_object = SWIG_Php_create_object_%s;\n", class_name, class_name);
+ Printf(s_oinit, " %s_object_handlers = Swig_Php_base_object_handlers;\n", class_name);
+ Printf(s_oinit, " %s_object_handlers.free_obj = SWIG_Php_free_obj_%s;\n", class_name, class_name);
+ }
+ } else {
+ static bool emitted_destructorless_create_object = false;
+ if (!emitted_destructorless_create_object) {
+ emitted_destructorless_create_object = true;
+ Printf(s_creation, "static zend_object *SWIG_Php_create_object(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &Swig_Php_base_object_handlers);}\n", class_name);
+ }
+
+ Printf(s_oinit, " SWIG_Php_ce_%s->create_object = SWIG_Php_create_object;\n", class_name);
+ }
+
// If not defined we aren't wrapping any functions which use this type as a
// parameter or return value, in which case we don't need the clientdata
// set.
Printf(s_oinit, "#ifdef SWIGTYPE_p%s\n", SwigType_manglestr(Getattr(n, "classtypeobj")));
- Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE_p%s,SWIGTYPE_%s_ce);\n", SwigType_manglestr(Getattr(n, "classtypeobj")), class_name);
+ Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE_p%s,SWIG_Php_ce_%s);\n", SwigType_manglestr(Getattr(n, "classtypeobj")), class_name);
Printf(s_oinit, "#endif\n");
Printf(s_oinit, "\n");
- Language::classHandler(n);
-
- print_creation_free_wrapper(n);
- generate_magic_property_methods(n, base_class);
+ generate_magic_property_methods(n);
Printf(all_cs_entry, " ZEND_FE_END\n};\n\n");
class_name = NULL;
+ base_class = NULL;
return SWIG_OK;
}
@@ -1785,8 +2115,8 @@ public:
Delete(director_ctor_code);
director_ctor_code = NewStringEmpty();
director_prot_ctor_code = NewStringEmpty();
- Printf(director_ctor_code, "if (Swig::Director::swig_is_overridden_method(\"%s\", arg0)) { /* not subclassed */\n", class_name);
- Printf(director_prot_ctor_code, "if (Swig::Director::swig_is_overridden_method(\"%s\", arg0)) { /* not subclassed */\n", class_name);
+ Printf(director_ctor_code, "if (Z_OBJCE_P(arg0) == SWIG_Php_ce_%s) { /* not subclassed */\n", class_name);
+ Printf(director_prot_ctor_code, "if (Z_OBJCE_P(arg0) == SWIG_Php_ce_%s) { /* not subclassed */\n", class_name);
Printf(director_ctor_code, " %s = new %s(%s);\n", Swig_cresult_name(), ctype, args);
Printf(director_prot_ctor_code,
" zend_throw_exception(zend_ce_type_error, \"accessing abstract class or protected constructor\", 0);\n"
@@ -1811,17 +2141,11 @@ public:
/* ------------------------------------------------------------
* destructorHandler()
* ------------------------------------------------------------ */
- //virtual int destructorHandler(Node *n) {
- //}
-
- /* ------------------------------------------------------------
- * memberconstantHandler()
- * ------------------------------------------------------------ */
-
- virtual int memberconstantHandler(Node *n) {
- wrapping_member_constant = Getattr(n, "sym:name");
- Language::memberconstantHandler(n);
- wrapping_member_constant = NULL;
+ virtual int destructorHandler(Node *n) {
+ wrapperType = destructor;
+ Language::destructorHandler(n);
+ destructor_action = Getattr(n, "wrap:action");
+ wrapperType = standard;
return SWIG_OK;
}
@@ -1966,7 +2290,7 @@ public:
Append(w->def, " {");
Append(declaration, ";\n");
- /* declare method return value
+ /* declare method return value
* if the return value is a reference or const reference, a specialized typemap must
* handle it, including declaration of c_result ($result).
*/
@@ -2008,10 +2332,6 @@ public:
Parm *p;
- int outputs = 0;
- if (!is_void)
- outputs++;
-
/* build argument list and type conversion string */
idx = 0;
p = l;
@@ -2021,9 +2341,6 @@ public:
continue;
}
- if (Getattr(p, "tmap:directorargout") != 0)
- outputs++;
-
String *pname = Getattr(p, "name");
String *ptype = Getattr(p, "type");
@@ -2069,7 +2386,7 @@ public:
/* wrap complex arguments to zvals */
Append(w->code, wrap_args);
- const char * funcname = GetChar(n, "sym:name");
+ const char *funcname = GetChar(n, "sym:name");
Append(w->code, "{\n");
Append(w->code, "#if PHP_MAJOR_VERSION < 8\n");
Printf(w->code, "zval swig_funcname;\n");
@@ -2089,11 +2406,13 @@ public:
if (tm)
tm = Copy(tm);
}
- if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
- Replaceall(tm, "$error", "EG(exception)");
- Printv(w->code, Str(tm), "\n", NIL);
+ if (!tm || Len(tm) == 0 || Equal(tm, "1")) {
+ // Skip marshalling the return value as there isn't one.
+ tm = NewString("if ($error) SWIG_fail;");
}
- Append(w->code, "}\n");
+
+ Replaceall(tm, "$error", "EG(exception)");
+ Printv(w->code, Str(tm), "\n}\n{\n", NIL);
Delete(tm);
/* marshal return value from PHP to C/C++ type */
@@ -2141,6 +2460,8 @@ public:
}
}
+ Append(w->code, "}\n");
+
Delete(cleanup);
Delete(outarg);
}
@@ -2201,18 +2522,155 @@ public:
static PHP *maininstance = 0;
+List *PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute_name) {
+
+ while (Len(merged_types) <= key) {
+ Append(merged_types, NewList());
+ }
+
+ String *phptype = Getattr(n, attribute_name);
+ if (!phptype || Len(phptype) == 0) {
+ // There's no type declaration, so any merged version has no type declaration.
+ //
+ // Use a DOH None object as a marker to indicate there's no type
+ // declaration for this parameter/return value (you can't store NULL as a
+ // value in a DOH List).
+ Setitem(merged_types, key, None);
+ return NULL;
+ }
+
+ DOH *merge_list = Getitem(merged_types, key);
+ if (merge_list == None) return NULL;
+
+ List *types = Split(phptype, '|', -1);
+ String *first_type = Getitem(types, 0);
+ if (Char(first_type)[0] == '?') {
+ if (Len(types) > 1) {
+ Printf(stderr, "warning: Invalid phptype: '%s' (can't use ? and | together)\n", phptype);
+ }
+ // Treat `?foo` just like `foo|null`.
+ Append(types, "null");
+ Setitem(types, 0, NewString(Char(first_type) + 1));
+ }
+
+ SortList(types, NULL);
+ String *prev = NULL;
+ for (Iterator i = First(types); i.item; i = Next(i)) {
+ if (prev && Equal(prev, i.item)) {
+ Printf(stderr, "warning: Invalid phptype: '%s' (duplicate entry for '%s')\n", phptype, i.item);
+ continue;
+ }
+
+ if (key > 0 && Equal(i.item, "void")) {
+ // Reject void for parameter type.
+ Printf(stderr, "warning: Invalid phptype: '%s' ('%s' can't be used as a parameter phptype)\n", phptype, i.item);
+ continue;
+ }
+
+ if (Equal(i.item, "SWIGTYPE")) {
+ String *type = Getattr(n, "type");
+ Node *class_node = maininstance->classLookup(type);
+ if (class_node) {
+ // FIXME: Prefix classname with a backslash to prevent collisions
+ // with built-in types? Or are non of those valid anyway and so will
+ // have been renamed at this point?
+ Append(merge_list, Getattr(class_node, "sym:name"));
+ } else {
+ // SWIG wraps a pointer to a non-object type as an object in a PHP
+ // class named based on the SWIG-mangled C/C++ type.
+ //
+ // FIXME: We should check this is actually a known pointer to
+ // non-object type so we complain about `phptype="SWIGTYPE"` being
+ // used for PHP types like `int` or `string` (currently this only
+ // fails at runtime and the error isn't very helpful). We could
+ // check the condition
+ //
+ // raw_pointer_types && Getattr(raw_pointer_types, SwigType_manglestr(type))
+ //
+ // except that raw_pointer_types may not have been fully filled in when
+ // we are called.
+ Append(merge_list, NewStringf("SWIG\\%s", SwigType_manglestr(type)));
+ }
+ } else {
+ Append(merge_list, i.item);
+ }
+ prev = i.item;
+ }
+ SortList(merge_list, NULL);
+ return merge_list;
+}
+
+void PHPTypes::merge_type_lists(List *merge_list, List *o_merge_list) {
+ int i = 0, j = 0;
+ while (j < Len(o_merge_list)) {
+ String *candidate = Getitem(o_merge_list, j);
+ while (i < Len(merge_list)) {
+ int cmp = Cmp(Getitem(merge_list, i), candidate);
+ if (cmp == 0)
+ goto handled;
+ if (cmp > 0)
+ break;
+ ++i;
+ }
+ Insert(merge_list, i, candidate);
+ ++i;
+handled:
+ ++j;
+ }
+}
+
+void PHPTypes::merge_from(const PHPTypes* o) {
+ num_required = std::min(num_required, o->num_required);
+
+ if (o->byref) {
+ if (byref == NULL) {
+ byref = Copy(o->byref);
+ } else {
+ int len = std::min(Len(byref), Len(o->byref));
+ // Start at 1 because we only want to merge parameter types, and key 0 is
+ // the return type.
+ for (int key = 1; key < len; ++key) {
+ if (Getitem(byref, key) == None &&
+ Getitem(o->byref, key) != None) {
+ Setitem(byref, key, "");
+ }
+ }
+ for (int key = len; key < Len(o->byref); ++key) {
+ Append(byref, Getitem(o->byref, key));
+ }
+ }
+ }
+
+ int len = std::min(Len(merged_types), Len(o->merged_types));
+ for (int key = 0; key < len; ++key) {
+ DOH *merge_list = Getitem(merged_types, key);
+ // None trumps anything else in the merge.
+ if (merge_list == None) continue;
+ DOH *o_merge_list = Getitem(o->merged_types, key);
+ if (o_merge_list == None) {
+ Setitem(merged_types, key, None);
+ continue;
+ }
+ merge_type_lists(merge_list, o_merge_list);
+ }
+ // Copy over any additional entries.
+ for (int key = len; key < Len(o->merged_types); ++key) {
+ Append(merged_types, Copy(Getitem(o->merged_types, key)));
+ }
+}
+
// Collect non-class pointer types from the type table so we can set up PHP
-// resource types for them later.
+// classes for them later.
//
// NOTE: it's a function NOT A PHP::METHOD
extern "C" {
static void typetrace(const SwigType *ty, String *mangled, String *clientdata) {
if (maininstance->classLookup(ty) == NULL) {
// a non-class pointer
- if (!zend_types) {
- zend_types = NewHash();
+ if (!raw_pointer_types) {
+ raw_pointer_types = NewHash();
}
- Setattr(zend_types, mangled, mangled);
+ Setattr(raw_pointer_types, mangled, mangled);
}
if (r_prevtracefunc)
(*r_prevtracefunc) (ty, mangled, clientdata);
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index 7d618635e..6f30c1faa 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* 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
@@ -69,12 +68,12 @@ static int no_header_file = 0;
static int max_bases = 0;
static int builtin_bases_needed = 0;
-static int py3 = 0;
-
/* C++ Support + Shadow Classes */
-static int have_constructor;
-static int have_repr;
+static int have_constructor = 0;
+static int have_repr = 0;
+static bool have_builtin_static_member_method_callback = false;
+static bool have_fast_proxy_static_member_method_callback = false;
static String *real_classname;
/* Thread Support */
@@ -91,6 +90,7 @@ static int castmode = 0;
static int extranative = 0;
static int nortti = 0;
static int relativeimport = 0;
+static int flat_static_method = 0;
/* flags for the make_autodoc function */
namespace {
@@ -116,6 +116,7 @@ Python Options (available with -python)\n\
-doxygen - Convert C++ doxygen comments to pydoc comments in proxy classes\n\
-extranative - Return extra native wrappers for C++ std containers wherever possible\n\
-fastproxy - Use fast proxy mechanism for member methods\n\
+ -flatstaticmethod - Generate additional flattened Python methods for C++ static methods\n\
-globals <name> - Set <name> used to access C global variable (default: 'cvar')\n\
-interface <mod>- Set low-level C/C++ module name to <mod> (default: module name prefixed by '_')\n\
-keyword - Use keyword arguments\n";
@@ -127,7 +128,6 @@ static const char *usage3 = "\
-nortti - Disable the use of the native C++ RTTI with directors\n\
-nothreads - Disable thread support for the entire interface\n\
-olddefs - Keep the old method definitions when using -fastproxy\n\
- -py3 - Generate code with Python 3 specific features and syntax\n\
-relativeimport - Use relative Python imports\n\
-threads - Add thread support for all the interface\n\
-O - Enable the following optimization options:\n\
@@ -314,7 +314,6 @@ public:
} else {
Swig_arg_error();
}
- /* end added */
} else if (strcmp(argv[i], "-globals") == 0) {
if (argv[i + 1]) {
global_name = NewString(argv[i + 1]);
@@ -372,6 +371,9 @@ public:
} else if (strcmp(argv[i], "-extranative") == 0) {
extranative = 1;
Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-flatstaticmethod") == 0) {
+ flat_static_method = 1;
+ Swig_mark_arg(i);
} else if (strcmp(argv[i], "-noh") == 0) {
no_header_file = 1;
Swig_mark_arg(i);
@@ -390,10 +392,6 @@ public:
fputs(usage1, stdout);
fputs(usage2, stdout);
fputs(usage3, stdout);
- } else if (strcmp(argv[i], "-py3") == 0) {
- py3 = 1;
- Preprocessor_define("SWIGPYTHON_PY3", 0);
- Swig_mark_arg(i);
} else if (strcmp(argv[i], "-builtin") == 0) {
builtin = 1;
Preprocessor_define("SWIGPYTHON_BUILTIN", 0);
@@ -409,7 +407,10 @@ public:
strcmp(argv[i], "-modernargs") == 0 ||
strcmp(argv[i], "-noproxydel") == 0 ||
strcmp(argv[i], "-safecstrings") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
+ Printf(stderr, "Deprecated command line option: %s. Ignored, this option is now always on.\n", argv[i]);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-py3") == 0) {
+ Printf(stderr, "Deprecated command line option: %s. Ignored, this option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-aliasobj0") == 0 ||
strcmp(argv[i], "-buildnone") == 0 ||
@@ -437,14 +438,23 @@ public:
strcmp(argv[i], "-oldrepr") == 0 ||
strcmp(argv[i], "-outputtuple") == 0 ||
strcmp(argv[i], "-proxydel") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
+ Printf(stderr, "Deprecated command line option: %s. This option is no longer available.\n", argv[i]);
Swig_mark_arg(i);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
}
+ if (builtin && !shadow) {
+ Printf(stderr, "Incompatible options -builtin and -noproxy specified.\n");
+ Exit(EXIT_FAILURE);
+ }
+
+ if (fastproxy) {
+ Preprocessor_define("SWIGPYTHON_FASTPROXY", 0);
+ }
+
if (doxygen)
doxygenTranslator = new PyDocConverter(doxygen_translator_flags);
@@ -497,22 +507,22 @@ public:
}
if (Getattr(options, "nocastmode")) {
Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nocastmode");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (Getattr(options, "extranative")) {
extranative = 1;
}
if (Getattr(options, "noextranative")) {
Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "noextranative");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (Getattr(options, "outputtuple")) {
Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "outputtuple");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (Getattr(options, "nooutputtuple")) {
Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nooutputtuple");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
mod_docstring = Getattr(options, "docstring");
package = Getattr(options, "package");
@@ -531,7 +541,7 @@ public:
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
@@ -555,7 +565,7 @@ public:
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
} else {
f_runtime_h = f_runtime;
@@ -577,7 +587,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGPYTHON\n#define SWIGPYTHON\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "PYTHON");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@@ -612,6 +622,10 @@ public:
Printf(f_runtime, "#define SWIGPYTHON_BUILTIN\n");
}
+ if (fastproxy) {
+ Printf(f_runtime, "#define SWIGPYTHON_FASTPROXY\n");
+ }
+
Printf(f_runtime, "\n");
Printf(f_header, "#ifdef SWIG_TypeQuery\n");
@@ -656,7 +670,7 @@ public:
Insert(module, 0, "_");
if ((f_shadow_py = NewFile(filen, "w", SWIG_output_files())) == 0) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(filen);
filen = NULL;
@@ -697,9 +711,11 @@ public:
Printv(default_import_code, tab4, "from ", module, " import *\n", NULL);
}
- /* Need builtins to qualify names like Exception that might also be
- defined in this module (try both Python 3 and Python 2 names) */
- Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL);
+ if (!builtin) {
+ /* Need builtins to qualify names like Exception that might also be
+ defined in this module (try both Python 3 and Python 2 names) */
+ Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL);
+ }
if (!builtin && fastproxy) {
Printf(f_shadow, "\n");
@@ -707,58 +723,54 @@ public:
Printf(f_shadow, "_swig_new_static_method = %s.SWIG_PyStaticMethod_New\n", module);
}
- Printv(f_shadow, "\n",
- "def _swig_repr(self):\n",
- tab4, "try:\n",
- tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n",
- tab4, "except __builtin__.Exception:\n",
- tab4, tab4, "strthis = \"\"\n",
- tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
-
- Printv(f_shadow, "\n",
- "def _swig_setattr_nondynamic_instance_variable(set):\n",
- tab4, "def set_instance_attr(self, name, value):\n",
-#ifdef USE_THISOWN
- tab4, tab4, "if name in (\"this\", \"thisown\"):\n",
- tab4, tab4, tab4, "set(self, name, value)\n",
-#else
- tab4, tab4, "if name == \"thisown\":\n",
- tab4, tab4, tab4, "self.this.own(value)\n",
- tab4, tab4, "elif name == \"this\":\n",
- tab4, tab4, tab4, "set(self, name, value)\n",
-#endif
- tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
- tab4, tab4, tab4, "set(self, name, value)\n",
- tab4, tab4, "else:\n",
- tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n",
- tab4, "return set_instance_attr\n\n", NIL);
-
- Printv(f_shadow, "\n",
- "def _swig_setattr_nondynamic_class_variable(set):\n",
- tab4, "def set_class_attr(cls, name, value):\n",
- tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n",
- tab4, tab4, tab4, "set(cls, name, value)\n",
- tab4, tab4, "else:\n",
- tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n",
- tab4, "return set_class_attr\n\n", NIL);
-
- Printv(f_shadow, "\n",
- "def _swig_add_metaclass(metaclass):\n",
- tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n",
- tab4, "def wrapper(cls):\n",
- tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n",
- tab4, "return wrapper\n\n", NIL);
-
- Printv(f_shadow, "\n",
- "class _SwigNonDynamicMeta(type):\n",
- tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n",
- tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n",
- "\n", NIL);
-
- Printv(f_shadow, "\n", NIL);
-
- if (directorsEnabled()) {
- Printv(f_shadow, "import weakref\n\n", NIL);
+ if (!builtin) {
+ Printv(f_shadow, "\n",
+ "def _swig_repr(self):\n",
+ tab4, "try:\n",
+ tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n",
+ tab4, "except __builtin__.Exception:\n",
+ tab4, tab4, "strthis = \"\"\n",
+ tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
+
+ Printv(f_shadow, "\n",
+ "def _swig_setattr_nondynamic_instance_variable(set):\n",
+ tab4, "def set_instance_attr(self, name, value):\n",
+ tab4, tab4, "if name == \"this\":\n",
+ tab4, tab4, tab4, "set(self, name, value)\n",
+ tab4, tab4, "elif name == \"thisown\":\n",
+ tab4, tab4, tab4, "self.this.own(value)\n",
+ tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
+ tab4, tab4, tab4, "set(self, name, value)\n",
+ tab4, tab4, "else:\n",
+ tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n",
+ tab4, "return set_instance_attr\n\n", NIL);
+
+ Printv(f_shadow, "\n",
+ "def _swig_setattr_nondynamic_class_variable(set):\n",
+ tab4, "def set_class_attr(cls, name, value):\n",
+ tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n",
+ tab4, tab4, tab4, "set(cls, name, value)\n",
+ tab4, tab4, "else:\n",
+ tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n",
+ tab4, "return set_class_attr\n\n", NIL);
+
+ Printv(f_shadow, "\n",
+ "def _swig_add_metaclass(metaclass):\n",
+ tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n",
+ tab4, "def wrapper(cls):\n",
+ tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n",
+ tab4, "return wrapper\n\n", NIL);
+
+ Printv(f_shadow, "\n",
+ "class _SwigNonDynamicMeta(type):\n",
+ tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n",
+ tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n",
+ "\n", NIL);
+
+ Printv(f_shadow, "\n", NIL);
+
+ if (directorsEnabled())
+ Printv(f_shadow, "import weakref\n\n", NIL);
}
}
// Include some information in the code
@@ -805,7 +817,8 @@ public:
Printf(f_wrappers, "%s\n", methods);
Append(methods_proxydocs, "\t { NULL, NULL, 0, NULL }\n");
Append(methods_proxydocs, "};\n");
- Printf(f_wrappers, "%s\n", methods_proxydocs);
+ if ((fastproxy && !builtin) || have_fast_proxy_static_member_method_callback)
+ Printf(f_wrappers, "%s\n", methods_proxydocs);
if (builtin) {
Dump(f_builtins, f_wrappers);
@@ -815,6 +828,10 @@ public:
Append(const_code, "{0, 0, 0, 0.0, 0, 0}};\n");
Printf(f_wrappers, "%s\n", const_code);
+
+ if (have_fast_proxy_static_member_method_callback)
+ Printf(f_init, " SWIG_Python_FixMethods(SwigMethods_proxydocs, swig_const_table, swig_types, swig_type_initial);\n\n");
+
initialize_threads(f_init);
Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n");
@@ -847,13 +864,6 @@ public:
Printv(f_shadow_py, "\n", f_shadow_begin, "\n", NIL);
Printv(f_shadow_py, "\nfrom sys import version_info as _swig_python_version_info\n", NULL);
- if (py3) {
- Printv(f_shadow_py, "if _swig_python_version_info < (3, 0):\n", NULL);
- Printv(f_shadow_py, tab4, "raise RuntimeError(\"Python 3.x or later required\")\n\n", NULL);
- } else {
- Printv(f_shadow_py, "if _swig_python_version_info < (2, 7, 0):\n", NULL);
- Printv(f_shadow_py, tab4, "raise RuntimeError(\"Python 2.7 or later required\")\n\n", NULL);
- }
if (Len(f_shadow_after_begin) > 0)
Printv(f_shadow_py, f_shadow_after_begin, "\n", NIL);
@@ -865,8 +875,10 @@ public:
Printv(f_shadow_py, default_import_code, NIL);
}
- Printv(f_shadow_py, "\n", f_shadow, "\n", NIL);
- Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
+ if (Len(f_shadow) > 0)
+ Printv(f_shadow_py, "\n", f_shadow, "\n", NIL);
+ if (Len(f_shadow_stubs) > 0)
+ Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
Delete(f_shadow_py);
}
@@ -911,15 +923,15 @@ public:
* as a replacement of new.instancemethod in Python 3.
* ------------------------------------------------------------ */
int add_pyinstancemethod_new() {
- String *name = NewString("SWIG_PyInstanceMethod_New");
- String *line = NewString("");
- Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
- Append(methods, line);
- if (fastproxy) {
+ if (!builtin && fastproxy) {
+ String *name = NewString("SWIG_PyInstanceMethod_New");
+ String *line = NewString("");
+ Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
+ Append(methods, line);
Append(methods_proxydocs, line);
+ Delete(line);
+ Delete(name);
}
- Delete(line);
- Delete(name);
return 0;
}
@@ -929,7 +941,7 @@ public:
* generated for static methods when using -fastproxy
* ------------------------------------------------------------ */
int add_pystaticmethod_new() {
- if (fastproxy) {
+ if (!builtin && fastproxy) {
String *name = NewString("SWIG_PyStaticMethod_New");
String *line = NewString("");
Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
@@ -1479,16 +1491,18 @@ public:
/* ------------------------------------------------------------
* build_combined_docstring()
*
- * Build the full docstring which may be a combination of the
- * explicit docstring and autodoc string or, if none of them
- * is specified, obtained by translating Doxygen comment to
- * Python.
+ * Build the full docstring:
+ * Use the docstring if there is one present otherwise
+ * use the Doxygen comment if there is one present.
+ * Ignore autodoc if there is a Doxygen comment, otherwise
+ * create the autodoc string and append to any docstring.
*
* Return new string to be deleted by caller (never NIL but
* may be empty if there is no docstring).
* ------------------------------------------------------------ */
String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) {
+ bool add_autodoc = true;
String *docstr = Getattr(n, "feature:docstring");
if (docstr) {
// Simplify the code below by just ignoring empty docstrings.
@@ -1506,26 +1520,10 @@ public:
}
}
- if (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
- String *autodoc = make_autodoc(n, ad_type, low_level);
- if (autodoc && Len(autodoc) > 0) {
- if (docstr) {
- Append(autodoc, "\n");
- Append(autodoc, docstr);
- }
-
- String *tmp = autodoc;
- autodoc = docstr;
- docstr = tmp;
- }
-
- Delete(autodoc);
- }
-
if (!docstr) {
- if (doxygen) {
+ if (doxygen && doxygenTranslator->hasDocumentation(n)) {
docstr = Getattr(n, "python:docstring");
- if (!docstr && doxygenTranslator->hasDocumentation(n)) {
+ if (!docstr) {
docstr = doxygenTranslator->getDocumentation(n, 0);
// Avoid rebuilding it again the next time: notice that we can't do
@@ -1541,9 +1539,26 @@ public:
// the cached object!
docstr = Copy(docstr);
}
+ add_autodoc = false;
}
}
+ if (add_autodoc && Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
+ String *autodoc = make_autodoc(n, ad_type, low_level);
+ if (autodoc && Len(autodoc) > 0) {
+ if (docstr) {
+ Append(autodoc, "\n");
+ Append(autodoc, docstr);
+ }
+
+ String *tmp = autodoc;
+ autodoc = docstr;
+ docstr = tmp;
+ }
+
+ Delete(autodoc);
+ }
+
if (!docstr)
docstr = NewString("");
@@ -2256,7 +2271,7 @@ public:
return parms;
}
- bool funcanno = py3 ? true : false;
+ bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
String *params = NewString("");
String *_params = make_autodocParmList(n, false, ((in_class || has_self_for_count)? 2 : 1), is_calling, funcanno);
@@ -2372,8 +2387,25 @@ public:
if (ret)
ret = SwigType_str(ret, 0);
}
- return (ret && py3) ? NewStringf(" -> \"%s\"", ret)
- : NewString("");
+ bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
+ return (ret && funcanno) ? NewStringf(" -> \"%s\"", ret) : NewString("");
+ }
+
+ /* ------------------------------------------------------------
+ * variableAnnotation()
+ *
+ * Helper function for constructing a variable annotation
+ * ------------------------------------------------------------ */
+
+ String *variableAnnotation(Node *n) {
+ String *type = Getattr(n, "type");
+ if (type)
+ type = SwigType_str(type, 0);
+ bool anno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
+ anno = GetFlag(n, "feature:python:annotations:novar") ? false : anno;
+ String *annotation = (type && anno) ? NewStringf(": \"%s\"", type) : NewString("");
+ Delete(type);
+ return annotation;
}
/* ------------------------------------------------------------
@@ -2478,6 +2510,7 @@ public:
Printf(methods, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
if (fastproxy) {
Printf(methods_proxydocs, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
+ have_fast_proxy_static_member_method_callback = true;
}
} else {
Append(methods, "NULL");
@@ -2495,7 +2528,7 @@ public:
/* ------------------------------------------------------------
* dispatchFunction()
* ------------------------------------------------------------ */
- void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false) {
+ void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false, bool use_static_method = false) {
/* Last node in overloaded chain */
bool add_self = builtin_self && (!builtin_ctor || director_class);
@@ -2533,6 +2566,11 @@ public:
const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
+ if (builtin) {
+ /* Avoid warning if the self parameter is not used. */
+ Append(f->code, "(void)self;\n");
+ }
+
Wrapper_add_local(f, "argc", "Py_ssize_t argc");
Printf(tmp, "PyObject *argv[%d] = {0}", maxargs + 1);
Wrapper_add_local(f, "argv", tmp);
@@ -2594,11 +2632,11 @@ public:
Printv(f->code, "}\n", NIL);
Wrapper_print(f, f_wrappers);
Node *p = Getattr(n, "sym:previousSibling");
- if (!builtin_self)
+ if (!builtin_self && (use_static_method || !builtin))
add_method(symname, wname, 0, p);
/* Create a shadow for this function (if enabled and not in a member function) */
- if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, symname, 0);
}
DelWrapper(f);
@@ -2702,7 +2740,6 @@ public:
bool add_self = builtin_self && (!builtin_ctor || director_class);
bool builtin_getter = (builtin && GetFlag(n, "memberget"));
bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter);
- char const *self_param = builtin ? "self" : "SWIGUNUSEDPARM(self)";
char const *wrap_return = builtin_ctor ? "int " : "PyObject *";
String *linkage = NewString("SWIGINTERN ");
String *wrapper_name = Swig_name_wrapper(iname);
@@ -2757,9 +2794,9 @@ public:
const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
if (!allow_kwargs || overname) {
if (!varargs) {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
} else {
- Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *", self_param, ", PyObject *args, PyObject *varargs", builtin_kwargs, ") {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *self, PyObject *args, PyObject *varargs", builtin_kwargs, ") {", NIL);
}
if (allow_kwargs) {
Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, "Can't use keyword arguments with overloaded functions (%s).\n", Swig_name_decl(n));
@@ -2770,8 +2807,14 @@ public:
Swig_warning(WARN_LANG_VARARGS_KEYWORD, input_file, line_number, "Can't wrap varargs with keyword arguments enabled\n");
varargs = 0;
}
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args, PyObject *kwargs) {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args, PyObject *kwargs) {", NIL);
+ }
+
+ if (builtin) {
+ /* Avoid warning if the self parameter is not used. */
+ Append(f->code, "(void)self;\n");
}
+
if (!builtin || !in_class || tuple_arguments > 0 || builtin_ctor) {
if (!allow_kwargs) {
Append(parse_args, " if (!PyArg_ParseTuple(args, \"");
@@ -2798,7 +2841,7 @@ public:
/* Generate code for argument marshalling */
if (funpack) {
- if (num_arguments > 0 && !overname) {
+ if (num_arguments > (builtin_self && !constructor ? 1 : 0) && !overname) {
sprintf(source, "PyObject *swig_obj[%d]", num_arguments);
Wrapper_add_localv(f, "swig_obj", source, NIL);
}
@@ -2930,14 +2973,14 @@ public:
Clear(f->def);
if (overname) {
if (noargs) {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
} else {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
}
Printf(parse_args, "if ((nobjs < %d) || (nobjs > %d)) SWIG_fail;\n", num_required, num_arguments);
} else {
int is_tp_call = Equal(Getattr(n, "feature:python:slot"), "tp_call");
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
if (builtin_ctor)
Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname);
if (onearg && !builtin_ctor && !is_tp_call) {
@@ -3107,27 +3150,9 @@ public:
Replaceall(tm, "$owner", "0");
}
}
- // FIXME: this will not try to unwrap directors returned as non-director
- // base class pointers!
- /* New addition to unwrap director return values so that the original
- * python object is returned instead.
- */
-#if 1
- int unwrap = 0;
- String *decl = Getattr(n, "decl");
- int is_pointer = SwigType_ispointer_return(decl);
- int is_reference = SwigType_isreference_return(decl);
- if (is_pointer || is_reference) {
- String *type = Getattr(n, "type");
- //Node *classNode = Swig_methodclass(n);
- //Node *module = Getattr(classNode, "module");
- Node *module = Getattr(parent, "module");
- Node *target = Swig_directormap(module, type);
- if (target)
- unwrap = 1;
- }
- if (unwrap) {
+ // Unwrap return values that are director classes so that the original Python object is returned instead.
+ if (!constructor && Swig_director_can_unwrap(n)) {
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Printf(f->code, "director = SWIG_DIRECTOR_CAST(%s);\n", Swig_cresult_name());
Append(f->code, "if (director) {\n");
@@ -3139,9 +3164,7 @@ public:
} else {
Printf(f->code, "%s\n", tm);
}
-#else
- Printf(f->code, "%s\n", tm);
-#endif
+
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
@@ -3229,9 +3252,9 @@ public:
f = NewWrapper();
if (funpack) {
// Note: funpack is currently always false for varargs
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
} else {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
}
Wrapper_add_local(f, "resultobj", builtin_ctor ? "int resultobj" : "PyObject *resultobj");
Wrapper_add_local(f, "varargs", "PyObject *varargs");
@@ -3260,18 +3283,20 @@ public:
Wrapper_print(f, f_wrappers);
}
+ bool use_static_method = flat_static_method || !Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage");
/* Now register the function with the interpreter. */
if (!Getattr(n, "sym:overloaded")) {
- if (!builtin_self)
+ if (!builtin_self && (use_static_method || !builtin))
add_method(iname, wname, allow_kwargs, n, funpack, num_required, num_arguments);
/* Create a shadow for this function (if enabled and not in a member function) */
- if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs);
}
+
} else {
if (!Getattr(n, "sym:nextSibling")) {
- dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class);
+ dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class, use_static_method);
}
}
@@ -3424,11 +3449,10 @@ public:
Printf(f_init, "#endif\n");
Printf(f_init, "\t }\n");
Printf(f_init, "\t PyDict_SetItemString(md, \"%s\", globals);\n", global_name);
- Printf(f_init, "\t Py_DECREF(globals);\n");
if (builtin)
Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", global_name);
have_globals = 1;
- if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
Printf(f_shadow_stubs, "%s = %s.%s\n", global_name, module, global_name);
}
}
@@ -3586,7 +3610,7 @@ public:
if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
Replaceall(tm, "$value", value);
- if (needs_swigconstant(n) && !builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER)) && (!in_class || !Getattr(n, "feature:python:callback"))) {
+ if (needs_swigconstant(n) && !builtin && shadow && !(shadow & PYSHADOW_MEMBER) && (!in_class || !Getattr(n, "feature:python:callback"))) {
// Generate `*_swigconstant()` method which registers the new constant.
//
// *_swigconstant methods are required for constants of class type.
@@ -3624,7 +3648,7 @@ public:
return SWIG_NOWRAP;
}
- if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
String *f_s;
if (!in_class) {
f_s = f_shadow;
@@ -3859,11 +3883,7 @@ public:
String *symname = Getattr(n, "sym:name");
String *mrename = Swig_name_disown(NSPACE_TODO, symname); //Getattr(n, "name"));
Printv(f_shadow, tab4, "def __disown__(self):\n", NIL);
-#ifdef USE_THISOWN
- Printv(f_shadow, tab8, "self.thisown = 0\n", NIL);
-#else
Printv(f_shadow, tab8, "self.this.disown()\n", NIL);
-#endif
Printv(f_shadow, tab8, module, ".", mrename, "(self)\n", NIL);
Printv(f_shadow, tab8, "return weakref.proxy(self)\n", NIL);
Delete(mrename);
@@ -3936,6 +3956,10 @@ public:
int funpack = fastunpack;
static String *tp_new = NewString("PyType_GenericNew");
+ if (have_builtin_static_member_method_callback) {
+ Printf(f_init, " SWIG_Python_FixMethods(SwigPyBuiltin_%s_methods, swig_const_table, swig_types, swig_type_initial);\n", mname);
+ }
+
Printv(f_init, " SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);\n", NIL);
// We can’t statically initialize a structure member with a function defined in another C module
@@ -4029,14 +4053,16 @@ public:
Printf(f, " PyTuple_SET_ITEM(tuple, 0, other);\n");
Printf(f, " Py_XINCREF(other);\n");
}
- Iterator rich_iter = First(richcompare);
+ List *richcompare_list = SortedKeys(richcompare, 0);
+ Iterator rich_iter = First(richcompare_list);
if (rich_iter.item) {
Printf(f, " switch (op) {\n");
for (; rich_iter.item; rich_iter = Next(rich_iter))
- Printf(f, " case %s : result = %s(self, %s); break;\n", rich_iter.key, rich_iter.item, funpack ? "other" : "tuple");
+ Printf(f, " case %s : result = %s(self, %s); break;\n", rich_iter.item, Getattr(richcompare, rich_iter.item), funpack ? "other" : "tuple");
Printv(f, " default : break;\n", NIL);
Printf(f, " }\n");
}
+ Delete(richcompare_list);
Printv(f, " if (!result) {\n", NIL);
Printv(f, " if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {\n", NIL);
Printv(f, " result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);\n", NIL);
@@ -4100,7 +4126,11 @@ public:
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);
@@ -4184,6 +4214,9 @@ public:
printSlot(f, getSlot(n, "feature:python:am_await"), "am_await", "unaryfunc");
printSlot(f, getSlot(n, "feature:python:am_aiter"), "am_aiter", "unaryfunc");
printSlot(f, getSlot(n, "feature:python:am_anext"), "am_anext", "unaryfunc");
+ Printv(f, "# if PY_VERSION_HEX >= 0x030a0000\n", NIL);
+ printSlot(f, getSlot(n, "feature:python:am_send"), "am_send", "sendfunc");
+ Printv(f, "# endif\n", NIL);
Printf(f, " },\n");
Printv(f, "#endif\n", NIL);
@@ -4297,9 +4330,20 @@ public:
printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys");
Printv(f, "#endif\n", NIL);
+ // PyObject *ht_module;
Printv(f, "#if PY_VERSION_HEX >= 0x03090000\n", NIL);
printSlot(f, getSlot(n, "feature:python:ht_module"), "ht_module", "PyObject *");
Printv(f, "#endif\n", NIL);
+
+ // char *_ht_tpname;
+ Printv(f, "#if PY_VERSION_HEX >= 0x030b0000\n", NIL);
+ printSlot(f, getSlot(n, "feature:python:_ht_tpname"), "_ht_tpname", "char *");
+
+ // struct _specialization_cache _spec_cache;
+ Printf(f, " {\n");
+ printSlot(f, getSlot(n, "feature:python:getitem"), "getitem", "PyObject *");
+ Printf(f, " }\n");
+ Printv(f, "#endif\n", NIL);
Printf(f, "};\n\n");
String *clientdata = NewString("");
@@ -4366,6 +4410,7 @@ public:
/* Create new strings for building up a wrapper function */
have_constructor = 0;
have_repr = 0;
+ have_builtin_static_member_method_callback = false;
class_name = Getattr(n, "sym:name");
real_classname = Getattr(n, "name");
@@ -4423,10 +4468,9 @@ public:
/* dealing with abstract base class */
String *abcs = Getattr(n, "feature:python:abc");
- if (py3 && abcs) {
- if (Len(base_class)) {
+ if (abcs) {
+ if (Len(base_class) > 0)
Printv(base_class, ", ", NIL);
- }
Printv(base_class, abcs, NIL);
}
@@ -4442,10 +4486,8 @@ public:
Delete(rname);
}
} else {
- if (!py3) {
- if (GetFlag(n, "feature:python:nondynamic"))
- Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL);
- }
+ if (GetFlag(n, "feature:python:nondynamic"))
+ Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL);
Printv(f_shadow, "class ", class_name, NIL);
if (Len(base_class)) {
@@ -4455,9 +4497,11 @@ public:
Printf(f_shadow, "(Exception)");
} else {
Printf(f_shadow, "(object");
- if (py3 && GetFlag(n, "feature:python:nondynamic")) {
+ /* Replace @_swig_add_metaclass above with below when support for python 2.7 is dropped
+ if (GetFlag(n, "feature:python:nondynamic")) {
Printf(f_shadow, ", metaclass=_SwigNonDynamicMeta");
}
+ */
Printf(f_shadow, ")");
}
}
@@ -4572,7 +4616,8 @@ public:
}
shadow_indent = 0;
- Printf(f_shadow_file, "%s\n", f_shadow_stubs);
+ if (Len(f_shadow_stubs) > 0)
+ Printf(f_shadow_file, "%s\n", f_shadow_stubs);
Clear(f_shadow_stubs);
}
@@ -4728,6 +4773,7 @@ public:
Swig_restore(n);
}
+ int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
if (builtin && in_class) {
if ((GetFlagAttr(n, "feature:extend") || checkAttribute(n, "access", "public"))
&& !Getattr(class_members, symname)) {
@@ -4742,7 +4788,7 @@ public:
else if (funpack && argcount == 1)
Append(pyflags, "METH_O");
else
- Append(pyflags, "METH_VARARGS");
+ Append(pyflags, kw ? "METH_VARARGS|METH_KEYWORDS" : "METH_VARARGS");
// Cast via void(*)(void) to suppress GCC -Wcast-function-type warning.
// Python should always call the function correctly, but the Python C
// API requires us to store it in function pointer of a different type.
@@ -4750,6 +4796,11 @@ public:
String *ds = cdocstring(n, AUTODOC_STATICFUNC);
Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds);
Delete(ds);
+ } else if (Getattr(n, "feature:callback")) {
+ String *ds = NewStringf("swig_ptr: %s", Getattr(n, "feature:callback:name"));
+ Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds);
+ Delete(ds);
+ have_builtin_static_member_method_callback = true;
} else {
Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"\" },\n", symname, wname, pyflags);
}
@@ -4768,7 +4819,6 @@ public:
String *staticfunc_name = NewString(fastproxy ? "_swig_new_static_method" : "staticmethod");
bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
if (!fast || olddefs) {
- int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
String *parms = make_pyParmList(n, false, false, kw);
String *callParms = make_pyParmList(n, false, true, kw);
Printv(f_shadow, "\n", tab4, "@staticmethod", NIL);
@@ -4913,9 +4963,6 @@ public:
if (have_pythonprepend(n))
Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL);
-#ifdef USE_THISOWN
- Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
-#endif
if (have_pythonappend(n))
Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow_stubs, tab4, "return val\n", NIL);
@@ -4971,12 +5018,6 @@ public:
Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
-#ifdef USE_THISOWN
- Printv(f_shadow, tab8, "try:\n", NIL);
- Printv(f_shadow, tab8, tab4, "if self.thisown:", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL);
- Printv(f_shadow, tab8, "except __builtin__.Exception: pass\n", NIL);
-#else
-#endif
if (have_pythonappend(n))
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow, tab8, "pass\n", NIL);
@@ -5004,12 +5045,17 @@ public:
String *setname = Swig_name_set(NSPACE_TODO, mname);
String *getname = Swig_name_get(NSPACE_TODO, mname);
int assignable = is_assignable(n);
- Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
+ String *variable_annotation = variableAnnotation(n);
+ Printv(f_shadow, tab4, symname, variable_annotation, " = property(", module, ".", getname, NIL);
if (assignable)
Printv(f_shadow, ", ", module, ".", setname, NIL);
- if (have_docstring(n))
- Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
+ if (have_docstring(n)) {
+ String *s = docstring(n, AUTODOC_VAR, tab4);
+ if (Len(s))
+ Printv(f_shadow, ", doc=", s, NIL);
+ }
Printv(f_shadow, ")\n", NIL);
+ Delete(variable_annotation);
Delete(mname);
Delete(setname);
Delete(getname);
@@ -5074,8 +5120,11 @@ public:
Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
if (assignable)
Printv(f_shadow, ", ", module, ".", setname, NIL);
- if (have_docstring(n))
- Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
+ if (have_docstring(n)) {
+ String *s = docstring(n, AUTODOC_VAR, tab4);
+ if (Len(s))
+ Printv(f_shadow, ", doc=", s, NIL);
+ }
Printv(f_shadow, ")\n", NIL);
}
String *getter = Getattr(n, "pybuiltin:getter");
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
index 99db2275f..526d959f4 100644
--- a/Source/Modules/r.cxx
+++ b/Source/Modules/r.cxx
@@ -5,7 +5,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* r.cxx
*
@@ -740,8 +740,7 @@ int R::top(Node *n) {
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGR\n#define SWIGR\n#endif\n\n");
-
+ Swig_obligatory_macros(f_runtime, "R");
Swig_banner_target_lang(s_init, "#");
outputCommandLineArguments(s_init);
@@ -805,7 +804,7 @@ int R::DumpCode(Node *n) {
File *scode = NewFile(output_filename, "w", SWIG_output_files());
if (!scode) {
FileErrorDisplay(output_filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(output_filename);
@@ -820,7 +819,7 @@ int R::DumpCode(Node *n) {
File *runtime = NewFile(outfile,"w", SWIG_output_files());
if (!runtime) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printf(runtime, "%s", f_begin);
@@ -837,7 +836,7 @@ int R::DumpCode(Node *n) {
File *ns = NewFile(output_filename, "w", SWIG_output_files());
if (!ns) {
FileErrorDisplay(output_filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Delete(output_filename);
@@ -940,7 +939,7 @@ int R::OutputClassMethodsTable(File *) {
* The entries are indexed by <class name>_set and
* <class_name>_get. Each entry is a List *.
- * out - the stram where the code is to be written. This is the S
+ * out - the stream where the code is to be written. This is the S
* code stream as we generate only S code here.
* --------------------------------------------------------------*/
@@ -1542,8 +1541,6 @@ List * R::Swig_overload_rank(Node *n,
if (nodes[i].error)
Setattr(nodes[i].n, "overload:ignore", "1");
Append(result,nodes[i].n);
- // Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
- // Swig_print_node(nodes[i].n);
}
}
return result;
@@ -1973,6 +1970,13 @@ int R::functionWrapper(Node *n) {
}
Printv(f->def, ")\n{\n", NIL);
+ // SWIG_fail in R leads to a call to Rf_error() which calls longjmp()
+ // which means the destructors of any live function-local C++ objects won't
+ // get run. To avoid this happening, we wrap almost everything in the
+ // function in a block, and end that right before Rf_error() at which
+ // point those destructors will get called.
+ if (CPlusPlus) Append(f->def, "{\n");
+
Printv(sfun->def, ")\n{\n", NIL);
@@ -2126,6 +2130,7 @@ int R::functionWrapper(Node *n) {
if (need_cleanup) {
Printv(f->code, cleanup, NIL);
}
+ if (CPlusPlus) Append(f->code, "}\n");
Printv(f->code, " Rf_error(\"%s %s\", SWIG_ErrorType(SWIG_lasterror_code), SWIG_lasterror_msg);\n", NIL);
Printv(f->code, " return R_NilValue;\n", NIL);
Delete(cleanup);
@@ -2569,7 +2574,7 @@ int R::generateCopyRoutines(Node *n) {
Printf(sfile, "# Start definition of copy methods for %s\n", rclassName);
- Printf(sfile, "setMethod('copyToR', '_p_%s', CopyToR%s);\n", rclassName,
+ Printf(sfile, "setMethod('copyToR', '_p%s', CopyToR%s);\n", mangledName,
mangledName);
Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s);\n\n", rclassName,
mangledName);
@@ -2740,7 +2745,7 @@ void R::main(int argc, char *argv[]) {
} else if (strcmp(argv[i], "-nocppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (debugMode) {
diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx
index ec4a75dbd..0208435f0 100644
--- a/Source/Modules/ruby.cxx
+++ b/Source/Modules/ruby.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* ruby.cxx
*
@@ -106,9 +106,10 @@ public:
char *strip(const_String_or_char_ptr s) {
Clear(temp);
- Append(temp, s);
if (Strncmp(s, prefix, Len(prefix)) == 0) {
- Replaceall(temp, prefix, "");
+ Append(temp, Char(s) + Len(prefix));
+ } else {
+ Append(temp, s);
}
return Char(temp);
}
@@ -897,7 +898,7 @@ public:
} else if (strcmp(argv[i], "-nocppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
}
@@ -1036,13 +1037,13 @@ public:
if (!outfile) {
Printf(stderr, "Unable to determine outfile\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
@@ -1057,12 +1058,12 @@ public:
if (directorsEnabled()) {
if (!outfile_h) {
Printf(stderr, "Unable to determine outfile_h\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
@@ -1086,7 +1087,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGRUBY\n#define SWIGRUBY\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "RUBY");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@@ -1870,26 +1871,8 @@ public:
else
Replaceall(tm, "$owner", "0");
-#if 1
- // FIXME: this will not try to unwrap directors returned as non-director
- // base class pointers!
-
- /* New addition to unwrap director return values so that the original
- * Ruby object is returned instead.
- */
- bool unwrap = false;
- String *decl = Getattr(n, "decl");
- int is_pointer = SwigType_ispointer_return(decl);
- int is_reference = SwigType_isreference_return(decl);
- if (is_pointer || is_reference) {
- String *type = Getattr(n, "type");
- Node *parent = Swig_methodclass(n);
- Node *modname = Getattr(parent, "module");
- Node *target = Swig_directormap(modname, type);
- if (target)
- unwrap = true;
- }
- if (unwrap) {
+ // Unwrap return values that are director classes so that the original Ruby object is returned instead.
+ if (Swig_director_can_unwrap(n)) {
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Printf(f->code, "director = dynamic_cast<Swig::Director *>(%s);\n", Swig_cresult_name());
Printf(f->code, "if (director) {\n");
@@ -1901,9 +1884,7 @@ public:
} else {
Printf(f->code, "%s\n", tm);
}
-#else
- Printf(f->code, "%s\n", tm);
-#endif
+
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s.\n", SwigType_str(t, 0));
diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx
index 697284a77..aabd2d842 100644
--- a/Source/Modules/scilab.cxx
+++ b/Source/Modules/scilab.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* scilab.cxx
*
@@ -12,9 +12,10 @@
* --------------------------------------------------------------------------*/
#include "swigmod.h"
+#include <cstddef>
+#include <cstdlib>
static const int SCILAB_IDENTIFIER_NAME_CHAR_MAX = 24;
-static const int SCILAB_VARIABLE_NAME_CHAR_MAX = SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4;
static const char *usage = (char *) " \
Scilab options (available with -scilab)\n \
@@ -25,7 +26,6 @@ Scilab options (available with -scilab)\n \
-buildersources <files> - Add the (comma separated) files <files> to the builder sources\n \
-builderverbositylevel <level> - Set the builder verbosity level to <level> (default 0: off, 2: high)\n \
-gatewayxml <gateway_id> - Generate gateway xml with the given <gateway_id>\n \
- -targetversion <scilab_major_version> - Generate for Scilab target (major) version (default: 5)\n \
\n";
@@ -40,11 +40,11 @@ protected:
String *variablesCode;
- int targetVersion;
-
bool generateBuilder;
File *builderFile;
String *builderCode;
+ String *builderCode5;
+ String *builderCode6;
int builderFunctionCount;
List *sourceFileList;
@@ -67,6 +67,9 @@ protected:
bool createLoader;
File *loaderFile;
String *loaderScript;
+ String *loaderScript5;
+ String *loaderScript6;
+ int loaderFunctionCount;
public:
/* ------------------------------------------------------------------------
@@ -74,8 +77,6 @@ public:
* ----------------------------------------------------------------------*/
virtual void main(int argc, char *argv[]) {
- targetVersion = 5;
-
generateBuilder = false;
sourceFileList = NewList();
cflags = NewList();
@@ -99,23 +100,23 @@ public:
/* Manage command line arguments */
for (int argIndex = 1; argIndex < argc; argIndex++) {
if (argv[argIndex] != NULL) {
- if (strcmp(argv[argIndex], "-help") == 0) {
- Printf(stdout, "%s\n", usage);
- } else if (strcmp(argv[argIndex], "-builder") == 0) {
- Swig_mark_arg(argIndex);
- generateBuilder = true;
- createLoader = false;
- } else if (strcmp(argv[argIndex], "-buildersources") == 0) {
- if (argv[argIndex + 1] != NULL) {
- Swig_mark_arg(argIndex);
- char *sourceFile = strtok(argv[argIndex + 1], ",");
- while (sourceFile != NULL) {
- Insert(sourceFileList, Len(sourceFileList), sourceFile);
- sourceFile = strtok(NULL, ",");
- }
- Swig_mark_arg(argIndex + 1);
- }
- } else if (strcmp(argv[argIndex], "-buildercflags") == 0) {
+ if (strcmp(argv[argIndex], "-help") == 0) {
+ Printf(stdout, "%s\n", usage);
+ } else if (strcmp(argv[argIndex], "-builder") == 0) {
+ Swig_mark_arg(argIndex);
+ generateBuilder = true;
+ createLoader = false;
+ } else if (strcmp(argv[argIndex], "-buildersources") == 0) {
+ if (argv[argIndex + 1] != NULL) {
+ Swig_mark_arg(argIndex);
+ char *sourceFile = strtok(argv[argIndex + 1], ",");
+ while (sourceFile != NULL) {
+ Insert(sourceFileList, Len(sourceFileList), sourceFile);
+ sourceFile = strtok(NULL, ",");
+ }
+ Swig_mark_arg(argIndex + 1);
+ }
+ } else if (strcmp(argv[argIndex], "-buildercflags") == 0) {
Swig_mark_arg(argIndex);
if (argv[argIndex + 1] != NULL) {
Insert(cflags, Len(cflags), argv[argIndex + 1]);
@@ -140,12 +141,6 @@ public:
createGatewayXML = true;
gatewayID = NewString(argv[argIndex + 1]);
Swig_mark_arg(argIndex + 1);
- } else if (strcmp(argv[argIndex], "-targetversion") == 0) {
- if (argv[argIndex + 1] != NULL) {
- Swig_mark_arg(argIndex);
- targetVersion = atoi(argv[argIndex + 1]);
- Swig_mark_arg(argIndex + 1);
- }
}
}
}
@@ -188,7 +183,7 @@ public:
beginSection = NewFile(outputFilename, "w", SWIG_output_files());
if (!beginSection) {
FileErrorDisplay(outputFilename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
runtimeSection = NewString("");
initSection = NewString("");
@@ -205,7 +200,7 @@ public:
/* Output module initialization code */
Swig_banner(beginSection);
- Printf(runtimeSection, "\n\n#ifndef SWIGSCILAB\n#define SWIGSCILAB\n#endif\n\n");
+ Swig_obligatory_macros(runtimeSection, "SCILAB");
// Gateway header source merged with wrapper source in nobuilder mode
if (!generateBuilder)
@@ -227,10 +222,13 @@ public:
}
// Module initialization function
+ String *smallFunctionName = createSmallIdentifierName(gatewayName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 5);
String *gatewayInitFunctionName = NewStringf("%s_Init", gatewayName);
+ String *gatewayInitSmallFunctionName = NewStringf("%s_Init", smallFunctionName);
+ String *wrapperFunctionName = NewStringf("SWIG_%s_Init", gatewayName);
/* Add initialization function to builder table */
- addFunctionToScilab(gatewayInitFunctionName, gatewayInitFunctionName);
+ addFunctionToScilab(gatewayInitFunctionName, gatewayInitSmallFunctionName, wrapperFunctionName);
// Add helper functions to builder table
addHelperFunctions();
@@ -254,7 +252,7 @@ public:
// Add Builder footer code and save
if (generateBuilder) {
- saveBuilderFile(gatewayName);
+ saveBuilderFile(gatewayLibraryName);
}
/* Close the init function and rename with module name */
@@ -316,6 +314,8 @@ public:
/* Get some useful attributes of this function */
String *functionName = Getattr(node, "sym:name");
+ String *smallFunctionName = createSmallIdentifierName(functionName);
+
SwigType *functionReturnType = Getattr(node, "type");
ParmList *functionParamsList = Getattr(node, "parms");
@@ -345,7 +345,7 @@ public:
}
/* Write the wrapper function definition (standard Scilab gateway function prototype) */
- Printv(wrapper->def, "int ", overloadedName, "(SWIG_GatewayParameters) {", NIL);
+ Printv(wrapper->def, "SWIGEXPORT int ", overloadedName, "(SWIG_GatewayParameters) {", NIL);
/* Emit all of the local variables for holding arguments */
// E.g.: double arg1;
@@ -360,7 +360,7 @@ public:
int maxInputArguments = emit_num_arguments(functionParamsList);
int minInputArguments = emit_num_required(functionParamsList);
int minOutputArguments = 0;
- int maxOutputArguments = 0;
+ int maxOutputArguments = 1;
if (!emit_isvarargs(functionParamsList)) {
Printf(wrapper->code, "SWIG_CheckInputArgument(pvApiCtx, $mininputarguments, $maxinputarguments);\n");
@@ -498,10 +498,12 @@ public:
Replaceall(wrapper->code, "$symname", functionName);
/* Set CheckInputArgument and CheckOutputArgument input arguments */
- /* In Scilab there is always one output even if not defined */
- if (minOutputArguments == 0) {
+ if (maxOutputArguments < 1) {
maxOutputArguments = 1;
}
+ if (minOutputArguments == 1) {
+ minOutputArguments = 0;
+ }
String *argnumber = NewString("");
Printf(argnumber, "%d", minInputArguments);
Replaceall(wrapper->code, "$mininputarguments", argnumber);
@@ -521,16 +523,14 @@ public:
/* Dump the function out */
Wrapper_print(wrapper, wrappersSection);
- String *scilabFunctionName = checkIdentifierName(functionName, SCILAB_IDENTIFIER_NAME_CHAR_MAX);
-
/* Update builder.sce contents */
if (isLastOverloaded) {
- addFunctionToScilab(scilabFunctionName, wrapperName);
+ addFunctionToScilab(functionName, smallFunctionName, wrapperName);
dispatchFunction(node);
}
if (!isOverloaded) {
- addFunctionToScilab(scilabFunctionName, wrapperName);
+ addFunctionToScilab(functionName, smallFunctionName, wrapperName);
}
/* tidy up */
@@ -556,7 +556,7 @@ public:
String *dispatch = Swig_overload_dispatch(node, "return %s(SWIG_GatewayArguments);", &maxargs);
String *tmp = NewString("");
- Printv(wrapper->def, "int ", wrapperName, "(SWIG_GatewayParameters) {\n", NIL);
+ Printv(wrapper->def, "SWIGEXPORT int ", wrapperName, "(SWIG_GatewayParameters) {\n", NIL);
/* Get the number of the parameters */
Wrapper_add_local(wrapper, "argc", "int argc = SWIG_NbInputArgument(pvApiCtx)");
@@ -591,21 +591,20 @@ public:
/* Get information about variable */
String *origVariableName = Getattr(node, "name"); // Ex: Shape::nshapes
String *variableName = Getattr(node, "sym:name"); // Ex; Shape_nshapes (can be used for function names, ...)
-
- // Variable names can have SCILAB_VARIABLE_NAME_CHAR_MAX because of suffixes "_get" or "_set" added to function
- String *scilabVariableName = checkIdentifierName(variableName, SCILAB_VARIABLE_NAME_CHAR_MAX);
+ String *smallVariableName = createSmallIdentifierName(variableName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4);
/* Manage GET function */
Wrapper *getFunctionWrapper = NewWrapper();
String *getFunctionName = Swig_name_get(NSPACE_TODO, variableName);
- String *scilabGetFunctionName = Swig_name_get(NSPACE_TODO, scilabVariableName);
+ String *scilabGetFunctionName = Swig_name_get(NSPACE_TODO, variableName);
+ String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallVariableName);
Setattr(node, "wrap:name", getFunctionName);
- Printv(getFunctionWrapper->def, "int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
+ Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
/* Check the number of input and output */
Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n");
- Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 1, 1);\n");
+ Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n");
Printf(getFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
String *varoutTypemap = Swig_typemap_lookup("varout", node, origVariableName, 0);
@@ -621,20 +620,21 @@ public:
Wrapper_print(getFunctionWrapper, wrappersSection);
/* Add function to builder table */
- addFunctionToScilab(scilabGetFunctionName, getFunctionName);
+ addFunctionToScilab(scilabGetFunctionName, scilabGetSmallFunctionName, getFunctionName);
/* Manage SET function */
if (is_assignable(node)) {
Wrapper *setFunctionWrapper = NewWrapper();
String *setFunctionName = Swig_name_set(NSPACE_TODO, variableName);
- String *scilabSetFunctionName = Swig_name_set(NSPACE_TODO, scilabVariableName);
+ String *scilabSetFunctionName = Swig_name_set(NSPACE_TODO, variableName);
+ String *scilabSetSmallFunctionName = Swig_name_set(NSPACE_TODO, smallVariableName);
Setattr(node, "wrap:name", setFunctionName);
- Printv(setFunctionWrapper->def, "int ", setFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
+ Printv(setFunctionWrapper->def, "SWIGEXPORT int ", setFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
/* Check the number of input and output */
Printf(setFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 1, 1);\n");
- Printf(setFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 1, 1);\n");
+ Printf(setFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n");
Printf(setFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
String *varinTypemap = Swig_typemap_lookup("varin", node, origVariableName, 0);
@@ -648,7 +648,7 @@ public:
Wrapper_print(setFunctionWrapper, wrappersSection);
/* Add function to builder table */
- addFunctionToScilab(scilabSetFunctionName, setFunctionName);
+ addFunctionToScilab(scilabSetFunctionName, scilabSetSmallFunctionName, setFunctionName);
DelWrapper(setFunctionWrapper);
}
@@ -684,10 +684,9 @@ public:
constantTypemap = Swig_typemap_lookup("scilabconstcode", node, nodeName, 0);
if (constantTypemap != NULL) {
- String *scilabConstantName = checkIdentifierName(constantName, SCILAB_IDENTIFIER_NAME_CHAR_MAX);
Setattr(node, "wrap:name", constantName);
- Replaceall(constantTypemap, "$result", scilabConstantName);
+ Replaceall(constantTypemap, "$result", constantName);
Replaceall(constantTypemap, "$value", constantValue);
emit_action_code(node, variablesCode, constantTypemap);
@@ -705,19 +704,21 @@ public:
Delete(str);
constantValue = wname;
}
+
// Constant names can have SCILAB_VARIABLE_NAME_CHAR_MAX because of suffixes "_get" added to function
- String *scilabConstantName = checkIdentifierName(constantName, SCILAB_VARIABLE_NAME_CHAR_MAX);
+ String *smallConstantName = createSmallIdentifierName(constantName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4);
/* Create GET function to get the constant value */
Wrapper *getFunctionWrapper = NewWrapper();
String *getFunctionName = Swig_name_get(NSPACE_TODO, constantName);
- String *scilabGetFunctionName = Swig_name_get(NSPACE_TODO, scilabConstantName);
+ String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallConstantName);
+ Setattr(node, "wrap:name", getFunctionName);
Setattr(node, "wrap:name", getFunctionName);
- Printv(getFunctionWrapper->def, "int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
+ Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
/* Check the number of input and output */
Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n");
- Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 1, 1);\n");
+ Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n");
Printf(getFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
constantTypemap = Swig_typemap_lookup("constcode", node, nodeName, 0);
@@ -735,7 +736,7 @@ public:
Wrapper_print(getFunctionWrapper, wrappersSection);
/* Add the function to Scilab */
- addFunctionToScilab(scilabGetFunctionName, getFunctionName);
+ addFunctionToScilab(getFunctionName, scilabGetSmallFunctionName, getFunctionName);
DelWrapper(getFunctionWrapper);
@@ -782,78 +783,13 @@ public:
return Language::enumvalueDeclaration(node);
}
- /* ---------------------------------------------------------------------
- * membervariableHandler()
- * --------------------------------------------------------------------- */
- virtual int membervariableHandler(Node *node) {
- checkMemberIdentifierName(node, SCILAB_VARIABLE_NAME_CHAR_MAX);
- return Language::membervariableHandler(node);
- }
-
- /* -----------------------------------------------------------------------
- * checkIdentifierName()
- * If Scilab target version is lower than 6:
- * truncates (and displays a warning) too long member identifier names
- * (applies on members of structs, classes...)
- * (Scilab 5 identifier names are limited to 24 chars max)
- * ----------------------------------------------------------------------- */
-
- String *checkIdentifierName(String *name, int char_size_max) {
- String *scilabIdentifierName;
- if (targetVersion <= 5) {
- if (Len(name) > char_size_max) {
- scilabIdentifierName = DohNewStringWithSize(name, char_size_max);
- Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number,
- "Identifier name '%s' exceeds 24 characters and has been truncated to '%s'.\n", name, scilabIdentifierName);
- } else
- scilabIdentifierName = name;
- } else {
- scilabIdentifierName = DohNewString(name);
- }
- return scilabIdentifierName;
- }
-
- /* -----------------------------------------------------------------------
- * checkMemberIdentifierName()
- * If Scilab target version is lower than 6:
- * truncates (and displays a warning) too long member identifier names
- * (applies on members of structs, classes...)
- * (Scilab 5 identifier names are limited to 24 chars max)
- * ----------------------------------------------------------------------- */
-
- void checkMemberIdentifierName(Node *node, int char_size_max) {
- if (targetVersion <= 5) {
- String *memberName = Getattr(node, "sym:name");
- Node *containerNode = parentNode(node);
- String *containerName = Getattr(containerNode, "sym:name");
- int lenContainerName = Len(containerName);
- int lenMemberName = Len(memberName);
-
- if (lenContainerName + lenMemberName + 1 > char_size_max) {
- int lenScilabMemberName = char_size_max - lenContainerName - 1;
-
- if (lenScilabMemberName > 0) {
- String *scilabMemberName = DohNewStringWithSize(memberName, lenScilabMemberName);
- Setattr(node, "sym:name", scilabMemberName);
- Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number,
- "Wrapping functions names for member '%s.%s' will exceed 24 characters, "
- "so member name has been truncated to '%s'.\n", containerName, memberName, scilabMemberName);
- } else {
- Swig_error(input_file, line_number,
- "Wrapping functions names for member '%s.%s' will exceed 24 characters, "
- "please rename the container of member '%s'.\n", containerName, memberName, containerName);
- }
- }
- }
- }
-
/* -----------------------------------------------------------------------
* addHelperFunctions()
* ----------------------------------------------------------------------- */
void addHelperFunctions() {
- addFunctionToScilab("SWIG_this", "SWIG_this");
- addFunctionToScilab("SWIG_ptr", "SWIG_ptr");
+ addFunctionToScilab("SWIG_this", "SWIG_this", "SWIG_this");
+ addFunctionToScilab("SWIG_ptr", "SWIG_ptr", "SWIG_ptr");
}
/* -----------------------------------------------------------------------
@@ -861,20 +797,20 @@ public:
* Declare a wrapped function in Scilab (builder, gateway, XML, ...)
* ----------------------------------------------------------------------- */
- void addFunctionToScilab(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr wrapperFunctionName) {
+ void addFunctionToScilab(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName) {
if (!generateBuilder)
- addFunctionInGatewayHeader(scilabFunctionName, wrapperFunctionName);
+ addFunctionInGatewayHeader(scilabFunctionName, scilabSmallFunctionName, wrapperFunctionName);
if (generateBuilder) {
- addFunctionInScriptTable(scilabFunctionName, wrapperFunctionName, builderCode);
+ addFunctionInScriptTable(scilabFunctionName, scilabSmallFunctionName, wrapperFunctionName, builderCode5, builderCode6);
}
if (createLoader) {
- addFunctionInLoader(scilabFunctionName);
+ addFunctionInLoader(scilabFunctionName, scilabSmallFunctionName);
}
if (gatewayXMLFile) {
- Printf(gatewayXML, "<PRIMITIVE gatewayId=\"%s\" primitiveId=\"%d\" primitiveName=\"%s\"/>\n", gatewayID, primitiveID++, scilabFunctionName);
+ Printf(gatewayXML, "<PRIMITIVE gatewayId=\"%s\" primitiveId=\"%d\" primitiveName=\"%s\"/>\n", gatewayID, primitiveID++, scilabSmallFunctionName);
}
}
@@ -888,12 +824,14 @@ public:
builderFile = NewFile(builderFilename, "w", SWIG_output_files());
if (!builderFile) {
FileErrorDisplay(builderFilename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
emitBanner(builderFile);
builderFunctionCount = 0;
builderCode = NewString("");
+ builderCode5 = NewString("");
+ builderCode6 = NewString("");
Printf(builderCode, "mode(-1);\n");
Printf(builderCode, "lines(0);\n"); /* Useful for automatic tests */
@@ -943,7 +881,8 @@ public:
}
}
- Printf(builderCode, "table = [");
+ Printf(builderCode5, "table = [ ..\n");
+ Printf(builderCode6, "table = [ ..\n");
}
/* -----------------------------------------------------------------------
@@ -951,11 +890,13 @@ public:
* Add a function wrapper in the function table of generated builder script
* ----------------------------------------------------------------------- */
- void addFunctionInScriptTable(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr wrapperFunctionName, String *scriptCode) {
+ void addFunctionInScriptTable(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName, String *scriptCode5, String *scriptCode6) {
if (++builderFunctionCount % 10 == 0) {
- Printf(scriptCode, "];\ntable = [table;");
+ Printf(scriptCode5, "];\ntable = [table; ..\n");
+ Printf(scriptCode6, "];\ntable = [table; ..\n");
}
- Printf(scriptCode, "\"%s\",\"%s\";", scilabFunctionName, wrapperFunctionName);
+ Printf(scriptCode5, "\"%s\",\"%s\"; ..\n", scilabSmallFunctionName, wrapperFunctionName);
+ Printf(scriptCode6, "\"%s\",\"%s\"; ..\n", scilabFunctionName, wrapperFunctionName);
}
/* -----------------------------------------------------------------------
@@ -963,7 +904,26 @@ public:
* ----------------------------------------------------------------------- */
void saveBuilderFile(String *gatewayName) {
- Printf(builderCode, "];\n");
+ Printf(builderCode5, "];\n");
+ Printf(builderCode6, "];\n");
+
+ if (Equal(builderCode5, builderCode6)) {
+ Append(builderCode, builderCode6);
+ } else {
+ Printf(builderCode, "ver = getversion('scilab');\n");
+ Printf(builderCode, "if ver(1) < 6 then\n");
+ Printf(builderCode, " // version is less or equal to 5.5.2\n");
+ Printf(builderCode, " \n");
+ Append(builderCode, builderCode5);
+ Printf(builderCode, " \n");
+ Printf(builderCode, "else\n");
+ Printf(builderCode, " // version is 6.0.0 or more\n");
+ Printf(builderCode, " \n");
+ Append(builderCode, builderCode6);
+ Printf(builderCode, " \n");
+ Printf(builderCode, "end\n");
+ }
+
Printf(builderCode, "ierr = 0;\n");
Printf(builderCode, "if ~isempty(table) then\n");
Printf(builderCode, " ierr = execstr(\"ilib_build(''%s'', table, files, libs, [], ldflags, cflags);\", 'errcatch');\n", gatewayName);
@@ -976,6 +936,8 @@ public:
Printf(builderCode, " error(ierr, err_msg);\n");
Printf(builderCode, "end\n");
Printv(builderFile, builderCode, NIL);
+
+ Delete(builderCode);
Delete(builderFile);
}
@@ -989,17 +951,13 @@ public:
gatewayXMLFile = NewFile(gatewayXMLFilename, "w", SWIG_output_files());
if (!gatewayXMLFile) {
FileErrorDisplay(gatewayXMLFilename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
// Add a slightly modified SWIG banner to the gateway XML ("--modify" is illegal in XML)
gatewayXML = NewString("");
Printf(gatewayXML, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
Printf(gatewayXML, "<!--\n");
- Printf(gatewayXML, "This file was automatically generated by SWIG (http://www.swig.org).\n");
- Printf(gatewayXML, "Version %s\n", Swig_package_version());
- Printf(gatewayXML, "\n");
- Printf(gatewayXML, "Do not make changes to this file unless you know what you are doing - modify\n");
- Printf(gatewayXML, "the SWIG interface file instead.\n");
+ Swig_banner_target_lang(gatewayXML, "");
Printf(gatewayXML, "-->\n");
Printf(gatewayXML, "<GATEWAY name=\"%s\">\n", gatewayName);
@@ -1038,7 +996,7 @@ public:
Printf(gatewayHeaderV6, "#ifdef __cplusplus\n");
Printf(gatewayHeaderV6, "extern \"C\"\n");
Printf(gatewayHeaderV6, "#endif\n");
- Printf(gatewayHeaderV6, "int %s(wchar_t *pwstFuncName) {\n", gatewayLibraryName);
+ Printf(gatewayHeaderV6, "SWIGEXPORT int %s(wchar_t *pwstFuncName) {\n", gatewayLibraryName);
Printf(gatewayHeaderV6, "\n");
}
@@ -1047,13 +1005,13 @@ public:
* Add a function in the gateway header
* ----------------------------------------------------------------------- */
- void addFunctionInGatewayHeader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr wrapperFunctionName) {
+ void addFunctionInGatewayHeader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName) {
if (gatewayHeaderV5 == NULL) {
gatewayHeaderV5 = NewString("");
Printf(gatewayHeaderV5, "static GenericTable Tab[] = {\n");
} else
Printf(gatewayHeaderV5, ",\n");
- Printf(gatewayHeaderV5, " {(Myinterfun)sci_gateway, (GT)%s, (char *)\"%s\"}", wrapperFunctionName, scilabFunctionName);
+ Printf(gatewayHeaderV5, " {(Myinterfun)sci_gateway, (GT)%s, (char *)\"%s\"}", wrapperFunctionName, scilabSmallFunctionName);
Printf(gatewayHeaderV6, "if (wcscmp(pwstFuncName, L\"%s\") == 0) { addCStackFunction((wchar_t *)L\"%s\", &%s, (wchar_t *)MODULE_NAME); }\n", scilabFunctionName, scilabFunctionName, wrapperFunctionName);
}
@@ -1069,7 +1027,7 @@ public:
Printf(gatewayHeaderV5, "#ifdef __cplusplus\n");
Printf(gatewayHeaderV5, "extern \"C\" {\n");
Printf(gatewayHeaderV5, "#endif\n");
- Printf(gatewayHeaderV5, "int C2F(%s)() {\n", gatewayLibraryName);
+ Printf(gatewayHeaderV5, "SWIGEXPORT int C2F(%s)() {\n", gatewayLibraryName);
Printf(gatewayHeaderV5, " Rhs = Max(0, Rhs);\n");
Printf(gatewayHeaderV5, " if (*(Tab[Fin-1].f) != NULL) {\n");
Printf(gatewayHeaderV5, " if(pvApiCtx == NULL) {\n");
@@ -1106,18 +1064,20 @@ public:
loaderFile = NewFile(loaderFilename, "w", SWIG_output_files());
if (!loaderFile) {
FileErrorDisplay(loaderFilename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
emitBanner(loaderFile);
- loaderScript = NewString("");
- Printf(loaderScript, "%s_path = get_absolute_file_path('loader.sce');\n", gatewayLibraryName);
- Printf(loaderScript, "[bOK, ilib] = c_link('%s');\n", gatewayLibraryName);
- Printf(loaderScript, "if bOK then\n");
- Printf(loaderScript, " ulink(ilib);\n");
- Printf(loaderScript, "end\n");
- Printf(loaderScript, "list_functions = [..\n");
+ loaderFunctionCount = 0;
+ loaderScript = NewString("function loader_function()\n");
+ Printf(loaderScript, " p = get_absolute_file_path('loader.sce');\n", gatewayLibraryName);
+ Printf(loaderScript, " [bOK, ilib] = c_link('%s');\n", gatewayLibraryName);
+ Printf(loaderScript, " if bOK then\n");
+ Printf(loaderScript, " ulink(ilib);\n");
+ Printf(loaderScript, " end\n");
+ loaderScript5 = NewString(" list_functions = [ ..\n");
+ loaderScript6 = NewString(" list_functions = [ ..\n");
}
/* -----------------------------------------------------------------------
@@ -1125,8 +1085,13 @@ public:
* Add a function in the loader script table
* ----------------------------------------------------------------------- */
- void addFunctionInLoader(const_String_or_char_ptr scilabFunctionName) {
- Printf(loaderScript, " '%s'; ..\n", scilabFunctionName);
+ void addFunctionInLoader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName) {
+ if (++loaderFunctionCount % 10 == 0) {
+ Printf(loaderScript5, " ];\n list_functions = [list_functions; ..\n");
+ Printf(loaderScript6, " ];\n list_functions = [list_functions; ..\n");
+ }
+ Printf(loaderScript5, " '%s'; ..\n", scilabSmallFunctionName);
+ Printf(loaderScript6, " '%s'; ..\n", scilabFunctionName);
}
/* -----------------------------------------------------------------------
@@ -1135,18 +1100,66 @@ public:
* ----------------------------------------------------------------------- */
void saveLoaderFile(String *gatewayLibraryName) {
- Printf(loaderScript, "];\n");
- Printf(loaderScript, "addinter(fullfile(%s_path, '%s' + getdynlibext()), '%s', list_functions);\n",
- gatewayLibraryName, gatewayLibraryName, gatewayLibraryName);
- Printf(loaderScript, "clear %s_path;\n", gatewayLibraryName);
- Printf(loaderScript, "clear bOK;\n");
- Printf(loaderScript, "clear ilib;\n");
- Printf(loaderScript, "clear list_functions;\n");
+ Printf(loaderScript5, " ];\n");
+ Printf(loaderScript6, " ];\n");
+
+ if (Equal(loaderScript5, loaderScript6)) {
+ Append(loaderScript, loaderScript6);
+ } else {
+ Printf(loaderScript, " ver = getversion('scilab');\n");
+ Printf(loaderScript, " if ver(1) < 6 then\n");
+ Printf(loaderScript, " // version is less or equal to 5.5.2\n");
+ Printf(loaderScript, " \n");
+ Append(loaderScript, loaderScript5);
+ Delete(loaderScript5);
+ Printf(loaderScript, " \n");
+ Printf(loaderScript, " else\n");
+ Printf(loaderScript, " // version is 6.0.0 or more\n");
+ Printf(loaderScript, " \n");
+ Append(loaderScript, loaderScript6);
+ Delete(loaderScript6);
+ Printf(loaderScript, " \n");
+ Printf(loaderScript, " end\n");
+ }
+
+ Printf(loaderScript, " addinter(p + '%s' + getdynlibext(), '%s', list_functions);\n", gatewayLibraryName, gatewayLibraryName);
+ Printf(loaderScript, "endfunction\n");
+ Printf(loaderScript, "loader_function();\n");
+ Printf(loaderScript, "clear loader_function;\n");
Printv(loaderFile, loaderScript, NIL);
+ Delete(loaderScript);
Delete(loaderFile);
}
+ /* -----------------------------------------------------------------------
+ * createSmallIdentifierName()
+ * Create a Scilab small identifier to be used by Scilab 5
+ * ----------------------------------------------------------------------- */
+
+ String* createSmallIdentifierName(String* name, int outputLen = SCILAB_IDENTIFIER_NAME_CHAR_MAX) {
+ char* s = Char(name);
+ int nameLen = Len(s);
+
+ // truncate and preserve common suffix
+ if (outputLen > 4 && nameLen > outputLen) {
+ String* smallName = NewStringWithSize(name, outputLen);
+ char* smallNameStr = (char*) Data(smallName);
+
+ if (s[nameLen-4] == '_' && s[nameLen - 3] == 'g' && s[nameLen - 2] == 'e' && s[nameLen - 1] == 't') {
+ // get
+ memcpy(&smallNameStr[outputLen - 4], &s[nameLen - 4], 4);
+ } else if (s[nameLen-4] == '_' && s[nameLen - 3] == 's' && s[nameLen - 2] == 'e' && s[nameLen - 1] == 't') {
+ // set
+ memcpy(&smallNameStr[outputLen - 4], &s[nameLen - 4], 4);
+ }
+
+ return smallName;
+ }
+
+ return name;
+ }
+
};
extern "C" Language *swig_scilab(void) {
diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx
index 84ac74294..ad24d0fee 100644
--- a/Source/Modules/swigmain.cxx
+++ b/Source/Modules/swigmain.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swigmain.cxx
*
@@ -84,11 +84,6 @@ static TargetLanguageModule modules[] = {
{NULL, NULL, NULL, Disabled}
};
-#ifdef MACSWIG
-#include <console.h>
-#include <SIOUX.h>
-#endif
-
//-----------------------------------------------------------------
// main()
//
@@ -98,15 +93,15 @@ static TargetLanguageModule modules[] = {
void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, char ***nargv) {
if (!env) {
*nargc = oargc;
- *nargv = (char **)malloc(sizeof(char *) * (oargc + 1));
+ *nargv = (char **)Malloc(sizeof(char *) * (oargc + 1));
memcpy(*nargv, oargv, sizeof(char *) * (oargc + 1));
return;
}
int argc = 1;
int arge = oargc + 1024;
- char **argv = (char **) malloc(sizeof(char *) * (arge + 1));
- char *buffer = (char *) malloc(2048);
+ char **argv = (char **) Malloc(sizeof(char *) * (arge + 1));
+ char *buffer = (char *) Malloc(2048);
char *b = buffer;
char *be = b + 1023;
const char *c = env;
@@ -139,11 +134,11 @@ static void insert_option(int *argc, char ***argv, int index, char const *start,
size_t option_len = end - start;
// Preserve the NULL pointer at argv[argc]
- new_argv = (char **)realloc(new_argv, (new_argc + 2) * sizeof(char *));
+ new_argv = (char **)Realloc(new_argv, (new_argc + 2) * sizeof(char *));
memmove(&new_argv[index + 1], &new_argv[index], sizeof(char *) * (new_argc + 1 - index));
new_argc++;
- new_argv[index] = (char *)malloc(option_len + 1);
+ new_argv[index] = (char *)Malloc(option_len + 1);
memcpy(new_argv[index], start, option_len);
new_argv[index][option_len] = '\0';
@@ -222,11 +217,6 @@ int main(int margc, char **margv) {
SWIG_merge_envopt(getenv("SWIG_FEATURES"), margc, margv, &argc, &argv);
merge_options_files(&argc, &argv);
-#ifdef MACSWIG
- SIOUXSettings.asktosaveonclose = false;
- argc = ccommand(&argv);
-#endif
-
Swig_init_args(argc, argv);
/* Get options */
@@ -247,7 +237,7 @@ int main(int margc, char **margv) {
Printf(stderr, "Target language option %s (%s) is no longer supported.\n", language_module->name, language_module->help);
else
Printf(stderr, "Target language option %s is no longer supported.\n", language_module->name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
} else if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
if (strcmp(argv[i], "--help") == 0)
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
index bfb93d1a7..c605edf9d 100644
--- a/Source/Modules/swigmod.h
+++ b/Source/Modules/swigmod.h
@@ -4,15 +4,15 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swigmod.h
*
* Main header file for SWIG modules.
* ----------------------------------------------------------------------------- */
-#ifndef SWIG_SWIGMOD_H_
-#define SWIG_SWIGMOD_H_
+#ifndef SWIG_SWIGMOD_H
+#define SWIG_SWIGMOD_H
#include "swig.h"
#include "preprocessor.h"
@@ -196,7 +196,7 @@ public:
virtual int classDirector(Node *n);
virtual int classDirectorInit(Node *n);
virtual int classDirectorEnd(Node *n);
- virtual int unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase = 0);
+ virtual int unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase = 0);
virtual int classDirectorConstructor(Node *n);
virtual int classDirectorDefaultConstructor(Node *n);
virtual int classDirectorMethod(Node *n, Node *parent, String *super);
@@ -346,6 +346,8 @@ protected:
class DoxygenTranslator *doxygenTranslator;
private:
+ void unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase);
+
Hash *symtabs; /* symbol tables */
int overloading;
int multiinput;
@@ -403,6 +405,7 @@ String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_Strin
String *Swig_director_declaration(Node *n);
void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f);
void Swig_director_parms_fixup(ParmList *parms);
+bool Swig_director_can_unwrap(Node *n);
/* directors.cxx end */
/* Utilities */
@@ -428,16 +431,14 @@ extern "C" {
void Swig_print_with_location(DOH *object, int count = -1);
}
+void Swig_default_allocators(Node *n);
+void Swig_process_types(Node *n);
+
/* Contracts */
void Swig_contracts(Node *n);
void Swig_contract_mode_set(int flag);
int Swig_contract_mode_get();
-/* Browser */
-void Swig_browser(Node *n, int);
-void Swig_default_allocators(Node *n);
-void Swig_process_types(Node *n);
-
/* Nested classes */
void Swig_nested_process_classes(Node *n);
void Swig_nested_name_unnamed_c_structs(Node *n);
diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx
index fcf36d17d..975230e84 100644
--- a/Source/Modules/tcl8.cxx
+++ b/Source/Modules/tcl8.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* tcl8.cxx
*
@@ -113,7 +113,7 @@ public:
} else if (strcmp(argv[i], "-nocppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
}
@@ -138,7 +138,7 @@ public:
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime = NewString("");
f_init = NewString("");
@@ -161,7 +161,7 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGTCL\n#define SWIGTCL\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "TCL");
/* Set the module name, namespace, and prefix */
@@ -182,7 +182,7 @@ public:
if ((f_shadow = NewFile(filen, "w", SWIG_output_files())) == 0) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_shadow_stubs = NewString("");
@@ -825,6 +825,7 @@ public:
//Printf(f_init,"/* Register base : %s */\n", bmangle);
//Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname));
+ (void)index;
b = Next(b);
index++;
Putc(',', base_class);
@@ -889,7 +890,7 @@ public:
// Add methods
if (have_methods) {
Printv(ptrclass, imethods, NIL);
- };
+ }
// Close out the pointer class
Printv(ptrclass, "}\n\n", NIL);
@@ -947,7 +948,7 @@ public:
if (!itcl) {
Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, (ClientData)&_wrap_class_", mangled_classname,
"},\n", NIL);
- };
+ }
Delete(t);
Delete(mangled_classname);
@@ -1023,7 +1024,7 @@ public:
Printv(imethods, "{ ", ns_name, "::", class_name, "_", realname, " $swigobj", NIL);
} else {
Printv(imethods, "{ ", class_name, "_", realname, " $swigobj", NIL);
- };
+ }
pnum = 0;
for (p = l; p; p = nextSibling(p)) {
diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx
index dc84cf94a..2a1dadf73 100644
--- a/Source/Modules/typepass.cxx
+++ b/Source/Modules/typepass.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* typepass.cxx
*
@@ -969,7 +969,7 @@ class TypePass:private Dispatcher {
if (Getattr(c, "sym:overloaded") != checkoverloaded) {
Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
Swig_print_node(c);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
@@ -977,7 +977,7 @@ class TypePass:private Dispatcher {
if (!Getattr(c, "sym:overloaded")) {
Printf(stdout, "sym:overloaded error.....%p\n", c);
Swig_print_node(c);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
c = Getattr(c, "sym:nextSibling");
}
@@ -1039,6 +1039,21 @@ class TypePass:private Dispatcher {
Node *unodes = 0, *last_unodes = 0;
int ccount = 0;
String *symname = Getattr(n, "sym:name");
+
+ // The overloaded functions in scope may not yet have had their parameters normalized yet (in cDeclaration).
+ // Happens if the functions were declared after the using declaration. So use a normalized copy.
+ List *n_decl_list = NewList();
+ Node *over = Getattr(n, "sym:overloaded");
+ while (over) {
+ String *odecl = Copy(Getattr(over, "decl"));
+ if (odecl) {
+ normalize_type(odecl);
+ Append(n_decl_list, odecl);
+ Delete(odecl);
+ }
+ over = Getattr(over, "sym:nextSibling");
+ }
+
while (c) {
if (Strcmp(nodeType(c), "cdecl") == 0) {
if (!(Swig_storage_isstatic(c)
@@ -1047,37 +1062,40 @@ class TypePass:private Dispatcher {
|| (Getattr(c, "feature:extend") && !Getattr(c, "code"))
|| GetFlag(c, "feature:ignore"))) {
- /* Don't generate a method if the method is overridden in this class,
- * for example don't generate another m(bool) should there be a Base::m(bool) :
- * struct Derived : Base {
- * void m(bool);
- * using Base::m;
- * };
- */
String *csymname = Getattr(c, "sym:name");
if (!csymname || (Strcmp(csymname, symname) == 0)) {
- {
- String *decl = Getattr(c, "decl");
- Node *over = Getattr(n, "sym:overloaded");
- int match = 0;
- while (over) {
- String *odecl = Getattr(over, "decl");
- if (Cmp(decl, odecl) == 0) {
- match = 1;
- break;
- }
- over = Getattr(over, "sym:nextSibling");
- }
- if (match) {
- c = Getattr(c, "csym:nextSibling");
- continue;
+ String *decl = Getattr(c, "decl");
+ int match = 0;
+
+ for (Iterator it = First(n_decl_list); it.item; it = Next(it)) {
+ String *odecl = it.item;
+ if (Cmp(decl, odecl) == 0) {
+ match = 1;
+ break;
}
}
+ if (match) {
+ /* Don't generate a method if the method is overridden in this class,
+ * for example don't generate another m(bool) should there be a Base::m(bool) :
+ * struct Derived : Base {
+ * void m(bool);
+ * using Base::m;
+ * };
+ */
+ c = Getattr(c, "csym:nextSibling");
+ continue;
+ }
+
Node *nn = copyNode(c);
+ Setfile(nn, Getfile(n));
+ Setline(nn, Getline(n));
Delattr(nn, "access"); // access might be different from the method in the base class
Setattr(nn, "access", Getattr(n, "access"));
if (!Getattr(nn, "sym:name"))
Setattr(nn, "sym:name", symname);
+ Symtab *st = Getattr(n, "sym:symtab");
+ assert(st);
+ Setattr(nn, "sym:symtab", st);
if (!GetFlag(nn, "feature:ignore")) {
ParmList *parms = CopyParmList(Getattr(c, "parms"));
@@ -1117,6 +1135,9 @@ class TypePass:private Dispatcher {
} else {
Delete(nn);
}
+ } else {
+ Swig_warning(WARN_LANG_USING_NAME_DIFFERENT, Getfile(n), Getline(n), "Using declaration %s, with name '%s', is not actually using\n", SwigType_namestr(Getattr(n, "uname")), symname);
+ Swig_warning(WARN_LANG_USING_NAME_DIFFERENT, Getfile(c), Getline(c), "the method from %s, with name '%s', as the names are different.\n", Swig_name_decl(c), csymname);
}
}
}
@@ -1138,14 +1159,30 @@ class TypePass:private Dispatcher {
* which is hacked. */
if (Getattr(n, "sym:overloaded")) {
int cnt = 0;
+ Node *ps = Getattr(n, "sym:previousSibling");
+ Node *ns = Getattr(n, "sym:nextSibling");
+ Node *fc = firstChild(n);
+ Node *firstoverloaded = Getattr(n, "sym:overloaded");
#ifdef DEBUG_OVERLOADED
- Node *debugnode = n;
- show_overloaded(n);
+ show_overloaded(firstoverloaded);
#endif
- if (!firstChild(n)) {
+
+ if (firstoverloaded == n) {
+ // This 'using' node we are cutting out was the first node in the overloaded list.
+ // Change the first node in the list
+ Delattr(firstoverloaded, "sym:overloaded");
+ firstoverloaded = fc ? fc : ns;
+
+ // Correct all the sibling overloaded methods (before adding in new methods)
+ Node *nnn = ns;
+ while (nnn) {
+ Setattr(nnn, "sym:overloaded", firstoverloaded);
+ nnn = Getattr(nnn, "sym:nextSibling");
+ }
+ }
+
+ if (!fc) {
// Remove from overloaded list ('using' node does not actually end up adding in any methods)
- Node *ps = Getattr(n, "sym:previousSibling");
- Node *ns = Getattr(n, "sym:nextSibling");
if (ps) {
Setattr(ps, "sym:nextSibling", ns);
}
@@ -1153,24 +1190,8 @@ class TypePass:private Dispatcher {
Setattr(ns, "sym:previousSibling", ps);
}
} else {
- // The 'using' node results in methods being added in - slot in the these methods here
- Node *ps = Getattr(n, "sym:previousSibling");
- Node *ns = Getattr(n, "sym:nextSibling");
- Node *fc = firstChild(n);
+ // The 'using' node results in methods being added in - slot in these methods here
Node *pp = fc;
-
- Node *firstoverloaded = Getattr(n, "sym:overloaded");
- if (firstoverloaded == n) {
- // This 'using' node we are cutting out was the first node in the overloaded list.
- // Change the first node in the list to its first sibling
- Delattr(firstoverloaded, "sym:overloaded");
- Node *nnn = Getattr(firstoverloaded, "sym:nextSibling");
- firstoverloaded = fc;
- while (nnn) {
- Setattr(nnn, "sym:overloaded", firstoverloaded);
- nnn = Getattr(nnn, "sym:nextSibling");
- }
- }
while (pp) {
Node *ppn = Getattr(pp, "sym:nextSibling");
Setattr(pp, "sym:overloaded", firstoverloaded);
@@ -1188,19 +1209,17 @@ class TypePass:private Dispatcher {
Setattr(ns, "sym:previousSibling", pp);
Setattr(pp, "sym:nextSibling", ns);
}
-#ifdef DEBUG_OVERLOADED
- debugnode = firstoverloaded;
-#endif
}
Delattr(n, "sym:previousSibling");
Delattr(n, "sym:nextSibling");
Delattr(n, "sym:overloaded");
Delattr(n, "sym:overname");
+ clean_overloaded(firstoverloaded);
#ifdef DEBUG_OVERLOADED
- show_overloaded(debugnode);
+ show_overloaded(firstoverloaded);
#endif
- clean_overloaded(n); // Needed?
}
+ Delete(n_decl_list);
}
}
} else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) {
diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx
index 2964ed3a6..de6f87d8c 100644
--- a/Source/Modules/utils.cxx
+++ b/Source/Modules/utils.cxx
@@ -4,14 +4,14 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* utils.cxx
*
* Various utility functions.
* ----------------------------------------------------------------------------- */
-#include <swigmod.h>
+#include "swigmod.h"
int is_public(Node *n) {
String *access = Getattr(n, "access");
diff --git a/Source/Modules/xml.cxx b/Source/Modules/xml.cxx
index 5f090561a..ed4213cc5 100644
--- a/Source/Modules/xml.cxx
+++ b/Source/Modules/xml.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* xml.cxx
*
@@ -52,7 +52,7 @@ public:
out = NewFile(outfile, "w", SWIG_output_files());
if (!out) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
continue;
}
@@ -89,7 +89,7 @@ public:
out = NewFile(outfile, "w", SWIG_output_files());
if (!out) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
Printf(out, "<?xml version=\"1.0\" ?> \n");
@@ -118,7 +118,7 @@ public:
String *k;
indent_level += 4;
print_indent(0);
- Printf(out, "<attributelist id=\"%ld\" addr=\"%p\" >\n", ++id, obj);
+ Printf(out, "<attributelist id=\"%ld\" addr=\"%p\">\n", ++id, obj);
indent_level += 4;
Iterator ki;
ki = First(obj);
@@ -175,7 +175,7 @@ public:
}
indent_level -= 4;
print_indent(0);
- Printf(out, "</attributelist >\n");
+ Printf(out, "</attributelist>\n");
indent_level -= 4;
}
@@ -183,7 +183,7 @@ public:
Node *cobj;
print_indent(0);
- Printf(out, "<%s id=\"%ld\" addr=\"%p\" >\n", nodeType(obj), ++id, obj);
+ Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", nodeType(obj), ++id, obj);
Xml_print_attributes(obj);
cobj = firstChild(obj);
if (cobj) {
@@ -196,32 +196,32 @@ public:
Printf(out, "\n");
}
print_indent(0);
- Printf(out, "</%s >\n", nodeType(obj));
+ Printf(out, "</%s>\n", nodeType(obj));
}
void Xml_print_parmlist(ParmList *p, const char* markup = "parmlist") {
print_indent(0);
- Printf(out, "<%s id=\"%ld\" addr=\"%p\" >\n", markup, ++id, p);
+ Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p);
indent_level += 4;
while (p) {
print_indent(0);
Printf(out, "<parm id=\"%ld\">\n", ++id);
Xml_print_attributes(p);
print_indent(0);
- Printf(out, "</parm >\n");
+ Printf(out, "</parm>\n");
p = nextSibling(p);
}
indent_level -= 4;
print_indent(0);
- Printf(out, "</%s >\n", markup);
+ Printf(out, "</%s>\n", markup);
}
void Xml_print_baselist(List *p) {
print_indent(0);
- Printf(out, "<baselist id=\"%ld\" addr=\"%p\" >\n", ++id, p);
+ Printf(out, "<baselist id=\"%ld\" addr=\"%p\">\n", ++id, p);
indent_level += 4;
Iterator s;
for (s = First(p); s.item; s = Next(s)) {
@@ -232,7 +232,7 @@ public:
}
indent_level -= 4;
print_indent(0);
- Printf(out, "</baselist >\n");
+ Printf(out, "</baselist>\n");
}
String *Xml_escape_string(String *str) {
@@ -272,21 +272,21 @@ public:
void Xml_print_hash(Hash *p, const char *markup) {
print_indent(0);
- Printf(out, "<%s id=\"%ld\" addr=\"%p\" >\n", markup, ++id, p);
+ Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p);
Xml_print_attributes(p);
indent_level += 4;
Iterator n = First(p);
while (n.key) {
print_indent(0);
- Printf(out, "<%ssitem id=\"%ld\" addr=\"%p\" >\n", markup, ++id, n.item);
+ Printf(out, "<%ssitem id=\"%ld\" addr=\"%p\">\n", markup, ++id, n.item);
Xml_print_attributes(n.item);
print_indent(0);
- Printf(out, "</%ssitem >\n", markup);
+ Printf(out, "</%ssitem>\n", markup);
n = Next(n);
}
indent_level -= 4;
print_indent(0);
- Printf(out, "</%s >\n", markup);
+ Printf(out, "</%s>\n", markup);
}
};
@@ -310,7 +310,7 @@ void Swig_print_xml(DOH *obj, String *filename) {
out = NewFile(filename, "w", SWIG_output_files());
if (!out) {
FileErrorDisplay(filename);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c
index 75bec61fd..a80434323 100644
--- a/Source/Preprocessor/cpp.c
+++ b/Source/Preprocessor/cpp.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* cpp.c
*
@@ -741,14 +741,35 @@ static String *get_options(String *str) {
opt = NewString("(");
while (((c = Getc(str)) != EOF)) {
Putc(c, opt);
- if (c == ')') {
- level--;
- if (!level)
- return opt;
+ switch (c) {
+ case ')':
+ level--;
+ if (!level)
+ return opt;
+ break;
+ case '(':
+ level++;
+ break;
+ case '"':
+ /* Skip over quoted strings */
+ while (1) {
+ c = Getc(str);
+ if (c == EOF)
+ goto bad;
+ Putc(c, opt);
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ c = Getc(str);
+ if (c == EOF)
+ goto bad;
+ Putc(c, opt);
+ }
+ }
+ break;
}
- if (c == '(')
- level++;
}
+bad:
Delete(opt);
return 0;
} else {
@@ -1335,14 +1356,14 @@ static void add_chunk(DOH *ns, DOH *chunk, int allow) {
push/pop_imported(): helper functions for defining and undefining
SWIGIMPORTED (when %importing a file).
*/
-static void push_imported() {
+static void push_imported(void) {
if (imported_depth == 0) {
Preprocessor_define("SWIGIMPORTED 1", 0);
}
++imported_depth;
}
-static void pop_imported() {
+static void pop_imported(void) {
--imported_depth;
if (imported_depth == 0) {
Preprocessor_undef("SWIGIMPORTED");
@@ -1686,7 +1707,7 @@ String *Preprocessor_parse(String *s) {
Seek(value, 0, SEEK_SET);
Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate expression '%s'\n", value);
if (msg)
- Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Error: '%s'\n", msg);
+ Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "%s\n", msg);
allow = 0;
} else {
if (val == 0)
@@ -1720,7 +1741,7 @@ String *Preprocessor_parse(String *s) {
Seek(value, 0, SEEK_SET);
Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate expression '%s'\n", value);
if (msg)
- Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Error: '%s'\n", msg);
+ Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "%s\n", msg);
allow = 0;
} else {
if (val)
@@ -2055,8 +2076,7 @@ String *Preprocessor_parse(String *s) {
break;
default:
Printf(stderr, "cpp: Invalid parser state %d\n", state);
- abort();
- break;
+ Exit(EXIT_FAILURE);
}
}
while (level > 0) {
diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c
index a36588983..95e05cf56 100644
--- a/Source/Preprocessor/expr.c
+++ b/Source/Preprocessor/expr.c
@@ -4,12 +4,17 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* expr.c
*
* Integer arithmetic expression evaluator used to handle expressions
* encountered during preprocessing.
+ *
+ * Note that this is used for expressions in `#if` and the like, but not
+ * for expressions in `#define` which SWIG wraps as constants - for those
+ * we inject a `%constant` directive which is handled by the parser in
+ * `Source/CParse/parser.y`.
* ----------------------------------------------------------------------------- */
#include "swig.h"
@@ -18,8 +23,19 @@
static Scanner *scan = 0;
typedef struct {
+ /* One of the EXPR_xxx values defined below. */
int op;
+ /* op == EXPR_OP: value is the token specifying which operator.
+ *
+ * op == EXPR_VALUE && svalue == NULL: Numeric expression value.
+ *
+ * Otherwise unused.
+ */
long value;
+ /* op == EXPR_VALUE: If non-NULL, string expression value; if NULL see value.
+ *
+ * Otherwise unused.
+ */
String *svalue;
} exprval;
@@ -27,7 +43,12 @@ typedef struct {
#define EXPR_VALUE 2
#define EXPR_OP 3
#define EXPR_GROUP 4
-#define EXPR_UMINUS 100
+
+/* Special token values used here to distinguish from SWIG_TOKEN_MINUS
+ * and SWIG_TOKEN_PLUS (which we use here for a two argument versions).
+ */
+#define OP_UMINUS 100
+#define OP_UPLUS 101
static exprval stack[256]; /* Parsing stack */
static int sp = 0; /* Stack pointer */
@@ -36,9 +57,11 @@ static int expr_init = 0; /* Initialization flag */
static const char *errmsg = 0; /* Parsing error */
/* Initialize the precedence table for various operators. Low values have higher precedence */
-static void init_precedence() {
+static void init_precedence(void) {
prec[SWIG_TOKEN_NOT] = 10;
- prec[EXPR_UMINUS] = 10;
+ prec[SWIG_TOKEN_LNOT] = 10;
+ prec[OP_UMINUS] = 10;
+ prec[OP_UPLUS] = 10;
prec[SWIG_TOKEN_STAR] = 20;
prec[SWIG_TOKEN_SLASH] = 20;
prec[SWIG_TOKEN_PERCENT] = 20;
@@ -46,16 +69,15 @@ static void init_precedence() {
prec[SWIG_TOKEN_MINUS] = 30;
prec[SWIG_TOKEN_LSHIFT] = 40;
prec[SWIG_TOKEN_RSHIFT] = 40;
- prec[SWIG_TOKEN_AND] = 50;
- prec[SWIG_TOKEN_XOR] = 60;
- prec[SWIG_TOKEN_OR] = 70;
- prec[SWIG_TOKEN_EQUALTO] = 80;
- prec[SWIG_TOKEN_NOTEQUAL] = 80;
- prec[SWIG_TOKEN_LESSTHAN] = 80;
- prec[SWIG_TOKEN_GREATERTHAN] = 80;
- prec[SWIG_TOKEN_LTEQUAL] = 80;
- prec[SWIG_TOKEN_GTEQUAL] = 80;
- prec[SWIG_TOKEN_LNOT] = 90;
+ prec[SWIG_TOKEN_LESSTHAN] = 50;
+ prec[SWIG_TOKEN_GREATERTHAN] = 50;
+ prec[SWIG_TOKEN_LTEQUAL] = 50;
+ prec[SWIG_TOKEN_GTEQUAL] = 50;
+ prec[SWIG_TOKEN_EQUALTO] = 60;
+ prec[SWIG_TOKEN_NOTEQUAL] = 60;
+ prec[SWIG_TOKEN_AND] = 70;
+ prec[SWIG_TOKEN_XOR] = 80;
+ prec[SWIG_TOKEN_OR] = 90;
prec[SWIG_TOKEN_LAND] = 100;
prec[SWIG_TOKEN_LOR] = 110;
expr_init = 1;
@@ -63,11 +85,12 @@ static void init_precedence() {
#define UNARY_OP(token) (((token) == SWIG_TOKEN_NOT) || \
((token) == SWIG_TOKEN_LNOT) || \
- ((token) == EXPR_UMINUS))
+ ((token) == OP_UMINUS) || \
+ ((token) == OP_UPLUS))
/* Reduce a single operator on the stack */
/* return 0 on failure, 1 on success */
-static int reduce_op() {
+static int reduce_op(void) {
long op_token = stack[sp - 1].value;
assert(sp > 0);
assert(stack[sp - 1].op == EXPR_OP);
@@ -183,10 +206,14 @@ static int reduce_op() {
stack[sp - 1].value = !stack[sp].value;
sp--;
break;
- case EXPR_UMINUS:
+ case OP_UMINUS:
stack[sp - 1].value = -stack[sp].value;
sp--;
break;
+ case OP_UPLUS:
+ stack[sp - 1].value = stack[sp].value;
+ sp--;
+ break;
case SWIG_TOKEN_SLASH:
if (stack[sp].value != 0) {
stack[sp - 2].value = stack[sp - 2].value / stack[sp].value;
@@ -278,13 +305,15 @@ int Preprocessor_expr(DOH *s, int *error) {
/* Put initial state onto the stack */
stack[sp].op = EXPR_TOP;
- stack[sp].value = 0;
while (1) {
/* Look at the top of the stack */
switch (stack[sp].op) {
case EXPR_TOP:
- /* An expression. Can be a number or another expression enclosed in parens */
+ /* EXPR_TOP is a place-holder which can only appear on the top of the
+ * stack. We can reduce it to any expression - a number, a string, an
+ * unary operator, or another expression enclosed in parentheses.
+ */
token = expr_token(scan);
if (!token) {
errmsg = "Expected an expression";
@@ -294,28 +323,35 @@ int Preprocessor_expr(DOH *s, int *error) {
if ((token == SWIG_TOKEN_INT) || (token == SWIG_TOKEN_UINT) || (token == SWIG_TOKEN_LONG) || (token == SWIG_TOKEN_ULONG)) {
/* A number. Reduce EXPR_TOP to an EXPR_VALUE */
char *c = Char(Scanner_text(scan));
- stack[sp].value = (long) strtol(c, 0, 0);
+ if (c[0] == '0' && (c[1] == 'b' || c[1] == 'B')) {
+ /* strtol() doesn't handle binary constants */
+ stack[sp].value = (long) strtol(c + 2, 0, 2);
+ } else {
+ stack[sp].value = (long) strtol(c, 0, 0);
+ }
stack[sp].svalue = 0;
- /* stack[sp].value = (long) atol(Char(Scanner_text(scan))); */
stack[sp].op = EXPR_VALUE;
- } else if (token == SWIG_TOKEN_PLUS) {
- } else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_LNOT) || (token == SWIG_TOKEN_NOT)) {
+ } else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_PLUS) || (token == SWIG_TOKEN_LNOT) || (token == SWIG_TOKEN_NOT)) {
if (token == SWIG_TOKEN_MINUS)
- token = EXPR_UMINUS;
+ token = OP_UMINUS;
+ else if (token == SWIG_TOKEN_PLUS)
+ token = OP_UPLUS;
stack[sp].value = token;
- stack[sp++].op = EXPR_OP;
+ stack[sp].op = EXPR_OP;
+ sp++;
stack[sp].op = EXPR_TOP;
- stack[sp].svalue = 0;
} else if (token == SWIG_TOKEN_LPAREN) {
- stack[sp++].op = EXPR_GROUP;
+ stack[sp].op = EXPR_GROUP;
+ sp++;
stack[sp].op = EXPR_TOP;
- stack[sp].value = 0;
- stack[sp].svalue = 0;
} else if (token == SWIG_TOKEN_ENDLINE) {
} else if (token == SWIG_TOKEN_STRING) {
stack[sp].svalue = NewString(Scanner_text(scan));
stack[sp].op = EXPR_VALUE;
} else if (token == SWIG_TOKEN_ID) {
+ /* Defined macros have been expanded already so this is an unknown
+ * macro, which gets treated as zero.
+ */
stack[sp].value = 0;
stack[sp].svalue = 0;
stack[sp].op = EXPR_VALUE;
@@ -327,7 +363,9 @@ int Preprocessor_expr(DOH *s, int *error) {
goto syntax_error;
break;
case EXPR_VALUE:
- /* A value is on the stack. We may reduce or evaluate depending on what the next token is */
+ /* A value is on top of the stack. We may reduce or evaluate depending
+ * on what the next token is.
+ */
token = expr_token(scan);
if (!token) {
/* End of input. Might have to reduce if an operator is on stack */
@@ -371,7 +409,6 @@ int Preprocessor_expr(DOH *s, int *error) {
stack[sp].value = token;
sp++;
stack[sp].op = EXPR_TOP;
- stack[sp].value = 0;
} else {
if (stack[sp - 1].op != EXPR_OP)
goto syntax_error_expected_operator;
@@ -390,7 +427,6 @@ int Preprocessor_expr(DOH *s, int *error) {
stack[sp].value = token;
sp++;
stack[sp].op = EXPR_TOP;
- stack[sp].value = 0;
}
break;
case SWIG_TOKEN_RPAREN:
@@ -406,8 +442,11 @@ int Preprocessor_expr(DOH *s, int *error) {
goto extra_rparen;
stack[sp - 1].op = EXPR_VALUE;
stack[sp - 1].value = stack[sp].value;
+ stack[sp - 1].svalue = stack[sp].svalue;
sp--;
break;
+ case SWIG_TOKEN_LTEQUALGT:
+ goto spaceship_not_allowed;
default:
goto syntax_error_expected_operator;
break;
@@ -416,7 +455,7 @@ int Preprocessor_expr(DOH *s, int *error) {
default:
fprintf(stderr, "Internal error in expression evaluator.\n");
- abort();
+ Exit(EXIT_FAILURE);
}
}
@@ -439,6 +478,11 @@ extra_rparen:
errmsg = "Extra \')\'";
*error = 1;
return 0;
+
+spaceship_not_allowed:
+ errmsg = "Spaceship operator (<=>) not allowed in preprocessor expression";
+ *error = 1;
+ return 0;
}
/* -----------------------------------------------------------------------------
@@ -447,6 +491,6 @@ extra_rparen:
* Return error message set by the evaluator (if any)
* ----------------------------------------------------------------------------- */
-const char *Preprocessor_expr_error() {
+const char *Preprocessor_expr_error(void) {
return errmsg;
}
diff --git a/Source/Preprocessor/preprocessor.h b/Source/Preprocessor/preprocessor.h
index 4c24f48d0..c1a30da79 100644
--- a/Source/Preprocessor/preprocessor.h
+++ b/Source/Preprocessor/preprocessor.h
@@ -4,15 +4,15 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* preprocessor.h
*
* SWIG preprocessor module.
* ----------------------------------------------------------------------------- */
-#ifndef SWIG_PREPROCESSOR_H_
-#define SWIG_PREPROCESSOR_H_
+#ifndef SWIG_PREPROCESSOR_H
+#define SWIG_PREPROCESSOR_H
#include "swigwarn.h"
diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c
index 7bf6641c8..36d207050 100644
--- a/Source/Swig/cwrap.c
+++ b/Source/Swig/cwrap.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* cwrap.c
*
@@ -15,6 +15,8 @@
#include "swig.h"
#include "cparse.h"
+extern int UseWrapperSuffix; // from main.cxx
+
static const char *cresult_variable_name = "result";
static Parm *nonvoid_parms(Parm *p) {
@@ -427,10 +429,14 @@ String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms) {
String *rcaststr = SwigType_rcaststr(rpt, pname);
if (comma) {
- Printv(func, ",", rcaststr, NIL);
- } else {
- Append(func, rcaststr);
+ Append(func, ",");
}
+
+ if (cparse_cplusplus && SwigType_type(rpt) == T_USER)
+ Printv(func, "SWIG_STD_MOVE(", rcaststr, ")", NIL);
+ else
+ Printv(func, rcaststr, NIL);
+
Delete(rpt);
Delete(pname);
Delete(rcaststr);
@@ -1076,9 +1082,18 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas
/* Check if the method is overloaded. If so, and it has code attached, we append an extra suffix
to avoid a name-clash in the generated wrappers. This allows overloaded methods to be defined
- in C. */
- if (Getattr(n, "sym:overloaded") && code) {
- Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
+ in C.
+
+ But when not using the suffix used for overloaded functions, we still need to ensure that the
+ wrapper name doesn't conflict with any wrapper functions for some languages, so optionally make
+ it sufficiently unique by appending a suffix similar to the one used for overloaded functions to it.
+ */
+ if (code) {
+ if (Getattr(n, "sym:overloaded")) {
+ Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
+ } else if (UseWrapperSuffix) {
+ Append(mangled, "__SWIG");
+ }
}
/* See if there is any code that we need to emit */
diff --git a/Source/Swig/deprecate.c b/Source/Swig/deprecate.c
index 08dc06a66..5783455e5 100644
--- a/Source/Swig/deprecate.c
+++ b/Source/Swig/deprecate.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* deprecate.c
*
diff --git a/Source/Swig/error.c b/Source/Swig/error.c
index 1dde06652..efd644f9a 100644
--- a/Source/Swig/error.c
+++ b/Source/Swig/error.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* error.c
*
@@ -209,14 +209,14 @@ void Swig_warnfilter(const_String_or_char_ptr wlist, int add) {
Insert(filter, 0, "-");
}
} else {
- char *temp = (char *)malloc(sizeof(char)*strlen(c) + 2);
+ char *temp = (char *)Malloc(sizeof(char)*strlen(c) + 2);
if (isdigit((int) *c)) {
sprintf(temp, "-%s", c);
} else {
strcpy(temp, c);
}
Replace(filter, temp, "", DOH_REPLACE_FIRST);
- free(temp);
+ Free(temp);
}
}
c = strtok(NULL, ", ");
diff --git a/Source/Swig/extend.c b/Source/Swig/extend.c
index 70355a245..23660c0ad 100644
--- a/Source/Swig/extend.c
+++ b/Source/Swig/extend.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* extend.c
*
diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c
index 4ec26f955..03b231fa1 100644
--- a/Source/Swig/fragment.c
+++ b/Source/Swig/fragment.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* fragment.c
*
diff --git a/Source/Swig/getopt.c b/Source/Swig/getopt.c
index 6970dc177..7791d13f7 100644
--- a/Source/Swig/getopt.c
+++ b/Source/Swig/getopt.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* getopt.c
*
@@ -32,16 +32,12 @@ static int *marked;
* ----------------------------------------------------------------------------- */
void Swig_init_args(int argc, char **argv) {
- int i;
assert(argc > 0);
assert(argv);
numargs = argc;
args = argv;
- marked = (int *) malloc(numargs * sizeof(int));
- for (i = 0; i < argc; i++) {
- marked[i] = 0;
- }
+ marked = (int *) Calloc(numargs, sizeof(int));
marked[0] = 1;
}
@@ -87,11 +83,11 @@ void Swig_check_options(int check_input) {
}
if (error) {
Printf(stderr, "Use 'swig -help' for available options.\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (check_input && marked[numargs - 1]) {
Printf(stderr, "Must specify an input file. Use -help for available options.\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
@@ -104,5 +100,5 @@ void Swig_check_options(int check_input) {
void Swig_arg_error(void) {
Printf(stderr, "SWIG : Unable to parse command line options.\n");
Printf(stderr, "Use 'swig -help' for available options.\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
diff --git a/Source/Swig/include.c b/Source/Swig/include.c
index 94df338f0..c153ac9b7 100644
--- a/Source/Swig/include.c
+++ b/Source/Swig/include.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* include.c
*
@@ -110,11 +110,7 @@ static List *Swig_search_path_any(int syspath) {
assert(slist);
filename = NewStringEmpty();
assert(filename);
-#ifdef MACSWIG
- Printf(filename, "%s", SWIG_FILE_DELIMITER);
-#else
Printf(filename, ".%s", SWIG_FILE_DELIMITER);
-#endif
Append(slist, filename);
Delete(filename);
@@ -145,7 +141,7 @@ static List *Swig_search_path_any(int syspath) {
return slist;
}
-List *Swig_search_path() {
+List *Swig_search_path(void) {
return Swig_search_path_any(0);
}
@@ -376,6 +372,6 @@ String *Swig_file_dirname(const_String_or_char_ptr filename) {
/*
* Swig_file_debug()
*/
-void Swig_file_debug_set() {
+void Swig_file_debug_set(void) {
file_debug = 1;
}
diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c
index ef6fcc02f..18c29f76a 100644
--- a/Source/Swig/misc.c
+++ b/Source/Swig/misc.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* misc.c
*
@@ -36,7 +36,7 @@ static char *fake_version = 0;
char *Swig_copy_string(const char *s) {
char *c = 0;
if (s) {
- c = (char *) malloc(strlen(s) + 1);
+ c = (char *) Malloc(strlen(s) + 1);
strcpy(c, s);
}
return c;
@@ -63,21 +63,52 @@ const char *Swig_package_version(void) {
}
/* -----------------------------------------------------------------------------
+ * Swig_package_version_hex()
+ *
+ * Return the package version in hex format "0xAABBCC" such as "0x040200" for 4.2.0
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_package_version_hex(void) {
+ String *package_version = NewString(Swig_package_version());
+ char *token = strtok(Char(package_version), ".");
+ String *vers = NewString("SWIG_VERSION 0x");
+ int count = 0;
+ while (token) {
+ int len = (int)strlen(token);
+ assert(len == 1 || len == 2);
+ Printf(vers, "%s%s", (len == 1) ? "0" : "", token);
+ token = strtok(NULL, ".");
+ count++;
+ }
+ Delete(package_version);
+ assert(count == 3); // Check version format is correct
+ return vers;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_obligatory_macros()
+ *
+ * Generates the SWIG_VERSION and SWIGXXX macros where XXX is the target language
+ * name (must be provided uppercase).
+ * ----------------------------------------------------------------------------- */
+
+void Swig_obligatory_macros(String *f_runtime, const char *language) {
+ String *version_hex = Swig_package_version_hex();
+ Printf(f_runtime, "\n\n");
+ Printf(f_runtime, "#define %s\n", version_hex);
+ Printf(f_runtime, "#define SWIG%s\n", language);
+ Delete(version_hex);
+}
+
+/* -----------------------------------------------------------------------------
* Swig_banner()
*
* Emits the SWIG identifying banner for the C/C++ wrapper file.
* ----------------------------------------------------------------------------- */
void Swig_banner(File *f) {
- Printf(f, "/* ----------------------------------------------------------------------------\n\
- * This file was automatically generated by SWIG (http://www.swig.org).\n\
- * Version %s\n\
- *\n\
- * This file is not intended to be easily readable and contains a number of\n\
- * coding conventions designed to improve portability and efficiency. Do not make\n\
- * changes to this file unless you know what you are doing--modify the SWIG\n\
- * interface file instead.\n", Swig_package_version());
- /* String too long for ISO compliance */
+ Printf(f, "/* ----------------------------------------------------------------------------\n");
+ Swig_banner_target_lang(f, " *");
Printf(f, " * ----------------------------------------------------------------------------- */\n");
}
@@ -89,10 +120,10 @@ void Swig_banner(File *f) {
* ----------------------------------------------------------------------------- */
void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar) {
- Printf(f, "%s This file was automatically generated by SWIG (http://www.swig.org).\n", commentchar);
+ Printf(f, "%s This file was automatically generated by SWIG (https://www.swig.org).\n", commentchar);
Printf(f, "%s Version %s\n", commentchar, Swig_package_version());
Printf(f, "%s\n", commentchar);
- Printf(f, "%s Do not make changes to this file unless you know what you are doing--modify\n", commentchar);
+ Printf(f, "%s Do not make changes to this file unless you know what you are doing - modify\n", commentchar);
Printf(f, "%s the SWIG interface file instead.\n", commentchar);
}
@@ -218,7 +249,7 @@ void Swig_filename_correct(String *filename) {
if (fname[0] == '/' && fname[1] == '/')
network_path = 1;
}
-#if defined(_WIN32) || defined(MACSWIG)
+#if defined(_WIN32)
/* accept Unix path separator on non-Unix systems */
Replaceall(filename, "/", SWIG_FILE_DELIMITER);
#endif
@@ -1157,47 +1188,15 @@ int Swig_scopename_check(const String *s) {
/* -----------------------------------------------------------------------------
* Swig_string_command()
*
- * Executes a external command via popen with the string as a command
- * line parameter. For example:
- *
- * Printf(stderr,"%(command:sed 's/[a-z]/\U\\1/' <<<)s","hello") -> Hello
+ * Feature removed in SWIG 4.1.0.
* ----------------------------------------------------------------------------- */
-#if defined(_MSC_VER)
-# define popen _popen
-# define pclose _pclose
-# if !defined(HAVE_POPEN)
-# define HAVE_POPEN 1
-# endif
-#else
-# if !defined(_WIN32)
-/* These Posix functions are not ISO C and so are not always defined in stdio.h */
-extern FILE *popen(const char *command, const char *type);
-extern int pclose(FILE *stream);
-# endif
-#endif
String *Swig_string_command(String *s) {
- String *res = NewStringEmpty();
-#if defined(HAVE_POPEN)
- if (Len(s)) {
- char *command = Char(s);
- FILE *fp = popen(command, "r");
- if (fp) {
- char buffer[1025];
- while (fscanf(fp, "%1024s", buffer) != EOF) {
- Append(res, buffer);
- }
- pclose(fp);
- } else {
- Swig_error("SWIG", Getline(s), "Command encoder fails attempting '%s'.\n", s);
- SWIG_exit(EXIT_FAILURE);
- }
- }
-#endif
- return res;
+ Swig_error("SWIG", Getline(s), "Command encoder no longer supported - use regex encoder instead.\n");
+ Exit(EXIT_FAILURE);
+ return 0;
}
-
/* -----------------------------------------------------------------------------
* Swig_string_strip()
*
@@ -1283,7 +1282,7 @@ void Swig_offset_string(String *s, int number) {
if ((Char(s))[len-1] == '\n')
--lines;
/* allocate a temporary storage for a padded string */
- res = (char*)malloc(len + lines * number * 2 + 1);
+ res = (char*)Malloc(len + lines * number * 2 + 1);
res[len + lines * number * 2] = 0;
/* copy lines to res, prepending tabs to each line */
@@ -1307,12 +1306,13 @@ void Swig_offset_string(String *s, int number) {
/* replace 's' contents with 'res' */
Clear(s);
Append(s, res);
- free(res);
+ Free(res);
}
#ifdef HAVE_PCRE
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
static int split_regex_pattern_subst(String *s, String **pattern, String **subst, const char **input)
{
@@ -1340,7 +1340,7 @@ static int split_regex_pattern_subst(String *s, String **pattern, String **subst
err_out:
Swig_error("SWIG", Getline(s), "Invalid regex substitution: '%s'.\n", s);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
return 0;
}
@@ -1375,7 +1375,7 @@ static void copy_with_maybe_case_conversion(String *dst, const char *src, int le
}
}
-String *replace_captures(int num_captures, const char *input, String *subst, int captures[], String *pattern, String *s)
+String *replace_captures(int num_captures, const char *input, String *subst, size_t captures[], String *pattern, String *s)
{
int convertCase = 0, convertNextOnly = 0;
String *result = NewStringEmpty();
@@ -1397,7 +1397,7 @@ String *replace_captures(int num_captures, const char *input, String *subst, int
} else if (isdigit((unsigned char)*p)) {
int group = *p++ - '0';
if (group < num_captures) {
- int l = captures[group*2], r = captures[group*2 + 1];
+ int l = (int)captures[group*2], r = (int)captures[group*2 + 1];
if (l != -1) {
copy_with_maybe_case_conversion(result, input + l, r - l, &convertCase, convertNextOnly);
}
@@ -1449,47 +1449,59 @@ String *Swig_string_regex(String *s) {
const int pcre_options = 0;
String *res = 0;
- pcre *compiled_pat = 0;
- const char *pcre_error, *input;
- int pcre_errorpos;
+ pcre2_code *compiled_pat = 0;
+ const char *input;
+ PCRE2_UCHAR pcre_error[256];
+ int pcre_errornum;
+ size_t pcre_errorpos;
String *pattern = 0, *subst = 0;
- int captures[30];
-
+ size_t *captures = 0;
+ pcre2_match_data *match_data = 0;
if (split_regex_pattern_subst(s, &pattern, &subst, &input)) {
int rc;
- compiled_pat = pcre_compile(
- Char(pattern), pcre_options, &pcre_error, &pcre_errorpos, NULL);
+ compiled_pat = pcre2_compile(
+ (PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, pcre_options, &pcre_errornum, &pcre_errorpos, NULL);
if (!compiled_pat) {
+ pcre2_get_error_message (pcre_errornum, pcre_error, sizeof pcre_error);
Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n",
pcre_error, Char(pattern), pcre_errorpos);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
- rc = pcre_exec(compiled_pat, NULL, input, (int)strlen(input), 0, 0, captures, 30);
+ match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL);
+ rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)input, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL);
+ captures = pcre2_get_ovector_pointer (match_data);
if (rc >= 0) {
res = replace_captures(rc, input, subst, captures, pattern, s);
- } else if (rc != PCRE_ERROR_NOMATCH) {
+ } else if (rc != PCRE2_ERROR_NOMATCH) {
Swig_error("SWIG", Getline(s), "PCRE execution failed: error %d while matching \"%s\" using \"%s\".\n",
rc, Char(pattern), input);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
DohDelete(pattern);
DohDelete(subst);
- pcre_free(compiled_pat);
+ pcre2_code_free(compiled_pat);
+ pcre2_match_data_free(match_data);
return res ? res : NewStringEmpty();
}
String *Swig_pcre_version(void) {
- return NewStringf("PCRE Version: %s", pcre_version());
+ int len = pcre2_config(PCRE2_CONFIG_VERSION, NULL);
+ char *buf = Malloc(len);
+ String *result;
+ pcre2_config(PCRE2_CONFIG_VERSION, buf);
+ result = NewStringf("PCRE2 Version: %s", buf);
+ Free(buf);
+ return result;
}
#else
String *Swig_string_regex(String *s) {
Swig_error("SWIG", Getline(s), "PCRE regex support not enabled in this SWIG build.\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
return 0;
}
@@ -1516,7 +1528,7 @@ int Swig_is_generated_overload(Node *n) {
* Initialize the SWIG core
* ----------------------------------------------------------------------------- */
-void Swig_init() {
+void Swig_init(void) {
/* Set some useful string encoding methods */
DohEncoding("escape", Swig_string_escape);
DohEncoding("hexescape", Swig_string_hexescape);
diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c
index 871a9e5bb..c4613f6c6 100644
--- a/Source/Swig/naming.c
+++ b/Source/Swig/naming.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* naming.c
*
@@ -744,28 +744,28 @@ void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *d
* ----------------------------------------------------------------------------- */
static Hash *namewarn_hash = 0;
-static Hash *name_namewarn_hash() {
+static Hash *name_namewarn_hash(void) {
if (!namewarn_hash)
namewarn_hash = NewHash();
return namewarn_hash;
}
static Hash *rename_hash = 0;
-static Hash *name_rename_hash() {
+static Hash *name_rename_hash(void) {
if (!rename_hash)
rename_hash = NewHash();
return rename_hash;
}
static List *namewarn_list = 0;
-static List *name_namewarn_list() {
+static List *name_namewarn_list(void) {
if (!namewarn_list)
namewarn_list = NewList();
return namewarn_list;
}
static List *rename_list = 0;
-static List *name_rename_list() {
+static List *name_rename_list(void) {
if (!rename_list)
rename_list = NewList();
return rename_list;
@@ -1092,33 +1092,39 @@ static DOH *get_lattr(Node *n, List *lattr) {
}
#ifdef HAVE_PCRE
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
static int name_regexmatch_value(Node *n, String *pattern, String *s) {
- pcre *compiled_pat;
- const char *err;
- int errpos;
+ pcre2_code *compiled_pat;
+ PCRE2_UCHAR err[256];
+ int errornum;
+ size_t errpos;
int rc;
+ pcre2_match_data *match_data = 0;
- compiled_pat = pcre_compile(Char(pattern), 0, &err, &errpos, NULL);
+ compiled_pat = pcre2_compile((PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, 0, &errornum, &errpos, NULL);
if (!compiled_pat) {
+ pcre2_get_error_message (errornum, err, sizeof err);
Swig_error("SWIG", Getline(n),
"Invalid regex \"%s\": compilation failed at %d: %s\n",
Char(pattern), errpos, err);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
- rc = pcre_exec(compiled_pat, NULL, Char(s), Len(s), 0, 0, NULL, 0);
- pcre_free(compiled_pat);
+ match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL);
+ rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)Char(s), PCRE2_ZERO_TERMINATED, 0, 0, match_data, 0);
+ pcre2_code_free(compiled_pat);
+ pcre2_match_data_free(match_data);
- if (rc == PCRE_ERROR_NOMATCH)
+ if (rc == PCRE2_ERROR_NOMATCH)
return 0;
if (rc < 0 ) {
Swig_error("SWIG", Getline(n),
"Matching \"%s\" against regex \"%s\" failed: %d\n",
Char(s), Char(pattern), rc);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
return 1;
@@ -1131,7 +1137,7 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) {
(void)s;
Swig_error("SWIG", Getline(n),
"PCRE regex matching is not available in this SWIG build.\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
return 0;
}
@@ -1511,6 +1517,15 @@ String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname,
result = apply_rename(n, rename, fullname, prefix, name);
if ((msg) && (Len(msg))) {
if (!Getmeta(nname, "already_warned")) {
+ String* suffix = 0;
+ if (Strcmp(result, "$ignore") == 0) {
+ suffix = NewStringf(": ignoring '%s'\n", name);
+ } else if (Strcmp(result, name) != 0) {
+ suffix = NewStringf(", renaming to '%s'\n", result);
+ } else {
+ /* No rename was performed */
+ suffix = NewString("\n");
+ }
if (n) {
/* Parameter renaming is not fully implemented. Mainly because there is no C/C++ syntax to
* for %rename to fully qualify a function's parameter name from outside the function. Hence it
@@ -1518,13 +1533,14 @@ String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname,
int suppress_parameter_rename_warning = Equal(nodeType(n), "parm");
if (!suppress_parameter_rename_warning) {
SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(0, Getfile(n), Getline(n), "%s\n", msg);
+ Swig_warning(0, Getfile(n), Getline(n), "%s%s", msg, suffix);
SWIG_WARN_NODE_END(n);
}
} else {
- Swig_warning(0, Getfile(name), Getline(name), "%s\n", msg);
+ Swig_warning(0, Getfile(name), Getline(name), "%s%s", msg, suffix);
}
Setmeta(nname, "already_warned", "1");
+ Delete(suffix);
}
}
}
diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c
index 3e832c361..11071ce0c 100644
--- a/Source/Swig/parms.c
+++ b/Source/Swig/parms.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* parms.c
*
@@ -149,7 +149,7 @@ int ParmList_len(ParmList *p) {
* get_empty_type()
* ---------------------------------------------------------------------- */
-static SwigType *get_empty_type() {
+static SwigType *get_empty_type(void) {
return NewStringEmpty();
}
diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c
index e5a267ae5..9dbb35364 100644
--- a/Source/Swig/scanner.c
+++ b/Source/Swig/scanner.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* scanner.c
*
@@ -56,7 +56,7 @@ static void brackets_clear(Scanner *);
Scanner *NewScanner(void) {
Scanner *s;
- s = (Scanner *) malloc(sizeof(Scanner));
+ s = (Scanner *) Malloc(sizeof(Scanner));
s->line = 1;
s->file = 0;
s->nexttoken = -1;
@@ -88,8 +88,8 @@ void DelScanner(Scanner *s) {
Delete(s->file);
Delete(s->error);
Delete(s->str);
- free(s->idstart);
- free(s);
+ Free(s->idstart);
+ Free(s);
}
/* -----------------------------------------------------------------------------
@@ -202,7 +202,7 @@ int Scanner_start_line(Scanner *s) {
* ----------------------------------------------------------------------------- */
void Scanner_idstart(Scanner *s, const char *id) {
- free(s->idstart);
+ Free(s->idstart);
s->idstart = Swig_copy_string(id);
}
@@ -336,9 +336,9 @@ static void brackets_reset(Scanner *s) {
* Usually called when '(' is found.
* ----------------------------------------------------------------------------- */
static void brackets_push(Scanner *s) {
- int *newInt = (int *)malloc(sizeof(int));
+ int *newInt = (int *)Malloc(sizeof(int));
*newInt = 0;
- Push(s->brackets, NewVoid(newInt, free));
+ Push(s->brackets, NewVoid(newInt, Free));
}
/* -----------------------------------------------------------------------------
@@ -596,10 +596,6 @@ static int look(Scanner *s) {
state = 3;
else if (c == '\\')
return SWIG_TOKEN_BACKSLASH;
- else if (c == '[')
- return SWIG_TOKEN_LBRACKET;
- else if (c == ']')
- return SWIG_TOKEN_RBRACKET;
else if (c == '@')
return SWIG_TOKEN_AT;
else if (c == '$')
@@ -636,7 +632,11 @@ static int look(Scanner *s) {
}
else if (c == '.')
- state = 100; /* Maybe a number, maybe just a period */
+ state = 100; /* Maybe a number, maybe ellipsis, just a period */
+ else if (c == '[')
+ state = 102; /* Maybe a bracket or a double bracket */
+ else if (c == ']')
+ state = 103; /* Maybe a bracket or a double bracket */
else if (isdigit(c))
state = 8; /* A numerical value */
else
@@ -833,7 +833,7 @@ static int look(Scanner *s) {
return SWIG_TOKEN_MODEQUAL;
} else if (c == '}') {
Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '%%}'\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
} else {
retract(s, 1);
return SWIG_TOKEN_PERCENT;
@@ -893,9 +893,16 @@ static int look(Scanner *s) {
}
if (c == '<')
state = 240;
- else if (c == '=')
- return SWIG_TOKEN_LTEQUAL;
- else {
+ else if (c == '=') {
+ if ((c = nextchar(s)) == 0) {
+ return SWIG_TOKEN_LTEQUAL;
+ } else if (c == '>' && cparse_cplusplus) { /* Spaceship operator */
+ return SWIG_TOKEN_LTEQUALGT;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_LTEQUAL;
+ }
+ } else {
retract(s, 1);
brackets_increment(s);
return SWIG_TOKEN_LESSTHAN;
@@ -1330,19 +1337,59 @@ static int look(Scanner *s) {
}
break;
- /* A period or maybe a floating point number */
+ /* A period or an ellipsis or maybe a floating point number */
case 100:
if ((c = nextchar(s)) == 0)
return (0);
if (isdigit(c))
state = 81;
+ else if (c == '.')
+ state = 101;
else {
retract(s, 1);
return SWIG_TOKEN_PERIOD;
}
break;
+ /* An ellipsis */
+
+ case 101:
+ if ((c = nextchar(s)) == 0)
+ return (0);
+ if (c == '.') {
+ return SWIG_TOKEN_ELLIPSIS;
+ } else {
+ retract(s, 2);
+ return SWIG_TOKEN_PERIOD;
+ }
+ break;
+
+ /* A left bracket or a double left bracket */
+ case 102:
+
+ if ((c = nextchar(s)) == 0) {
+ return SWIG_TOKEN_LBRACKET;
+ } else if (c == '[') {
+ return SWIG_TOKEN_LLBRACKET;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_LBRACKET;
+ }
+ break;
+
+ /* a right bracket or a double right bracket */
+ case 103:
+ if ((c = nextchar(s)) == 0) {
+ return SWIG_TOKEN_RBRACKET;
+ } else if (c == ']') {
+ return SWIG_TOKEN_RRBRACKET;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_RBRACKET;
+ }
+ break;
+
case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */
if ((c = nextchar(s)) == 0)
return SWIG_TOKEN_PLUS;
@@ -1796,14 +1843,14 @@ void Scanner_locator(Scanner *s, String *loc) {
cparse_file = locs->filename;
cparse_line = locs->line_number;
l = locs->next;
- free(locs);
+ Free(locs);
locs = l;
}
return;
}
/* We're going to push a new location */
- l = (Locator *) malloc(sizeof(Locator));
+ l = (Locator *) Malloc(sizeof(Locator));
l->filename = cparse_file;
l->line_number = cparse_line;
l->next = locs;
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c
index 5f876ff04..f227778f6 100644
--- a/Source/Swig/stype.c
+++ b/Source/Swig/stype.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* stype.c
*
diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
index 76691269e..19e61b455 100644
--- a/Source/Swig/swig.h
+++ b/Source/Swig/swig.h
@@ -4,19 +4,17 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swig.h
*
* Header file for the SWIG core.
* ----------------------------------------------------------------------------- */
-#ifndef SWIGCORE_H_
-#define SWIGCORE_H_
+#ifndef SWIG_SWIG_H
+#define SWIG_SWIG_H
-#ifndef MACSWIG
#include "swigconfig.h"
-#endif
#include <stdio.h>
#include <string.h>
@@ -141,6 +139,7 @@ extern "C" {
extern List *SwigType_split(const SwigType *t);
extern String *SwigType_pop(SwigType *t);
extern void SwigType_push(SwigType *t, String *s);
+ extern SwigType *SwigType_last(SwigType *t);
extern List *SwigType_parmlist(const SwigType *p);
extern String *SwigType_parm(const SwigType *p);
extern String *SwigType_str(const SwigType *s, const_String_or_char_ptr id);
@@ -309,6 +308,8 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern char *Swig_copy_string(const char *c);
extern void Swig_set_fakeversion(const char *version);
extern const char *Swig_package_version(void);
+ extern String *Swig_package_version_hex(void);
+ extern void Swig_obligatory_macros(String *f_runtime, const char *language);
extern void Swig_banner(File *f);
extern void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar);
extern String *Swig_strip_c_comments(const String *s);
@@ -439,8 +440,6 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern void Language_replace_special_variables(String *method, String *tm, Parm *parm);
extern void Swig_print(DOH *object, int count);
extern void Swig_print_with_location(DOH *object, int count);
- extern void SWIG_exit(int exit_code);
-
/* -- template init -- */
extern void SwigType_template_init(void);
diff --git a/Source/Swig/swigfile.h b/Source/Swig/swigfile.h
index f12b33081..009599a11 100644
--- a/Source/Swig/swigfile.h
+++ b/Source/Swig/swigfile.h
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swigfile.h
*
@@ -30,13 +30,11 @@ extern String *Swig_file_extension(const_String_or_char_ptr filename);
extern String *Swig_file_basename(const_String_or_char_ptr filename);
extern String *Swig_file_filename(const_String_or_char_ptr filename);
extern String *Swig_file_dirname(const_String_or_char_ptr filename);
-extern void Swig_file_debug_set();
+extern void Swig_file_debug_set(void);
/* Delimiter used in accessing files and directories */
-#if defined(MACSWIG)
-# define SWIG_FILE_DELIMITER ":"
-#elif defined(_WIN32)
+#if defined(_WIN32)
# define SWIG_FILE_DELIMITER "\\"
#else
# define SWIG_FILE_DELIMITER "/"
diff --git a/Source/Swig/swigopt.h b/Source/Swig/swigopt.h
index 543bfb819..86a477b8f 100644
--- a/Source/Swig/swigopt.h
+++ b/Source/Swig/swigopt.h
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swigopt.h
*
diff --git a/Source/Swig/swigparm.h b/Source/Swig/swigparm.h
index 7b27df5f6..7b63546ec 100644
--- a/Source/Swig/swigparm.h
+++ b/Source/Swig/swigparm.h
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swigparm.h
*
diff --git a/Source/Swig/swigscan.h b/Source/Swig/swigscan.h
index 740a93610..6c9d1ff7f 100644
--- a/Source/Swig/swigscan.h
+++ b/Source/Swig/swigscan.h
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swigscan.h
*
@@ -70,6 +70,9 @@ extern void Scanner_locator(Scanner *, String *loc);
#define SWIG_TOKEN_BOOL 32 /* true or false */
#define SWIG_TOKEN_WSTRING 33 /* L"str" */
#define SWIG_TOKEN_WCHAR 34 /* L'c' */
+#define SWIG_TOKEN_ELLIPSIS 35 /* ... */
+#define SWIG_TOKEN_LLBRACKET 36 /* [[ */
+#define SWIG_TOKEN_RRBRACKET 37 /* ]] */
#define SWIG_TOKEN_ILLEGAL 99
#define SWIG_TOKEN_ERROR -1
@@ -113,3 +116,4 @@ extern void Scanner_locator(Scanner *, String *loc);
#define SWIG_TOKEN_MODEQUAL 134 /* %= */
#define SWIG_TOKEN_ARROW 135 /* -> */
#define SWIG_TOKEN_ARROWSTAR 136 /* ->* */
+#define SWIG_TOKEN_LTEQUALGT 137 /* <=> */
diff --git a/Source/Swig/swigtree.h b/Source/Swig/swigtree.h
index acd0e5e90..8d63d8fd3 100644
--- a/Source/Swig/swigtree.h
+++ b/Source/Swig/swigtree.h
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swigtree.h
*
@@ -51,3 +51,4 @@ extern void Swig_restore(Node *node);
extern void Swig_print_tags(File *obj, Node *root);
extern void Swig_print_tree(Node *obj);
extern void Swig_print_node(Node *obj);
+extern int Swig_print_quiet(int quiet);
diff --git a/Source/Swig/swigwrap.h b/Source/Swig/swigwrap.h
index e44cb5344..b584ca495 100644
--- a/Source/Swig/swigwrap.h
+++ b/Source/Swig/swigwrap.h
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* swigwrap.h
*
diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
index aacaf24be..d39696f5b 100644
--- a/Source/Swig/symbol.c
+++ b/Source/Swig/symbol.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* symbol.c
*
@@ -12,7 +12,7 @@
* ----------------------------------------------------------------------------- */
#include "swig.h"
-#include "swigwarn.h"
+#include "cparse.h"
#include <ctype.h>
/* #define SWIG_DEBUG*/
@@ -641,10 +641,11 @@ void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) {
{
Node *td = n;
- while (td && Checkattr(td, "nodeType", "cdecl") && Checkattr(td, "storage", "typedef")) {
+ while (td && ((Equal(nodeType(td), "cdecl") && Checkattr(td, "storage", "typedef")) || (Equal(nodeType(td), "using") && !Getattr(n, "namespace")))) {
SwigType *type;
Node *td1;
- type = Copy(Getattr(td, "type"));
+ int using_not_typedef = Equal(nodeType(td), "using");
+ type = Copy(Getattr(td, using_not_typedef ? "uname" : "type"));
SwigType_push(type, Getattr(td, "decl"));
td1 = Swig_symbol_clookup(type, 0);
@@ -665,9 +666,13 @@ void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) {
ie, when Foo -> FooBar -> Foo, jump one scope up when possible.
*/
- if (td1 && Checkattr(td1, "storage", "typedef")) {
- String *st = Getattr(td1, "type");
+ if (td1) {
+ String *st = 0;
String *sn = Getattr(td, "name");
+ if (Equal(nodeType(td1), "cdecl") && Checkattr(td1, "storage", "typedef"))
+ st = Getattr(td1, "type");
+ else if (Equal(nodeType(td1), "using") && !Getattr(td1, "namespace"))
+ st = Getattr(td1, "uname");
if (st && sn && Equal(st, sn)) {
Symtab *sc = Getattr(current_symtab, "parentNode");
if (sc)
@@ -1177,7 +1182,9 @@ Node *Swig_symbol_clookup(const_String_or_char_ptr name, Symtab *n) {
Symtab *un = Getattr(s, "sym:symtab");
Node *ss = (!Equal(name, uname) || (un != n)) ? Swig_symbol_clookup(uname, un) : 0; /* avoid infinity loop */
if (!ss) {
+ SWIG_WARN_NODE_BEGIN(s);
Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
+ SWIG_WARN_NODE_END(s);
}
s = ss;
}
@@ -1249,7 +1256,9 @@ Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*
Node *ss;
ss = Swig_symbol_clookup(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
if (!ss && !checkfunc) {
+ SWIG_WARN_NODE_BEGIN(s);
Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
+ SWIG_WARN_NODE_END(s);
}
s = ss;
}
@@ -1300,7 +1309,9 @@ Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) {
while (s && Checkattr(s, "nodeType", "using")) {
Node *ss = Swig_symbol_clookup_local(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
if (!ss) {
+ SWIG_WARN_NODE_BEGIN(s);
Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
+ SWIG_WARN_NODE_END(s);
}
s = ss;
}
@@ -1348,7 +1359,9 @@ Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n,
while (s && Checkattr(s, "nodeType", "using")) {
Node *ss = Swig_symbol_clookup_local_check(Getattr(s, "uname"), Getattr(s, "sym:symtab"), checkfunc);
if (!ss && !checkfunc) {
+ SWIG_WARN_NODE_BEGIN(s);
Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
+ SWIG_WARN_NODE_END(s);
}
s = ss;
}
diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c
index 46571fc09..438e8b73d 100644
--- a/Source/Swig/tree.c
+++ b/Source/Swig/tree.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* tree.c
*
@@ -16,6 +16,20 @@
#include <stdarg.h>
#include <assert.h>
+static int debug_quiet = 0;
+
+/* -----------------------------------------------------------------------------
+ * Swig_print_quiet()
+ *
+ * Set quiet mode when printing a parse tree node
+ * ----------------------------------------------------------------------------- */
+
+int Swig_print_quiet(int quiet) {
+ int previous_quiet = debug_quiet;
+ debug_quiet = quiet;
+ return previous_quiet;
+}
+
/* -----------------------------------------------------------------------------
* Swig_print_tags()
*
@@ -66,33 +80,42 @@ static void print_indent(int l) {
void Swig_print_node(Node *obj) {
Iterator ki;
Node *cobj;
+ List *keys = Keys(obj);
print_indent(0);
- Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj);
- ki = First(obj);
- while (ki.key) {
- String *k = ki.key;
- if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) ||
- (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) {
+ if (debug_quiet)
+ Printf(stdout, "+++ %s ----------------------------------------\n", nodeType(obj));
+ else
+ Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj);
+
+ SortList(keys, 0);
+ ki = First(keys);
+ while (ki.item) {
+ String *k = ki.item;
+ DOH *value = Getattr(obj, k);
+ if (Equal(k, "nodeType") || (*(Char(k)) == '$')) {
+ /* Do nothing */
+ } else if (debug_quiet && (Equal(k, "firstChild") || Equal(k, "lastChild") || Equal(k, "parentNode") || Equal(k, "nextSibling") ||
+ Equal(k, "previousSibling") || Equal(k, "symtab") || Equal(k, "csymtab") || Equal(k, "sym:symtab") || Equal(k, "sym:nextSibling") ||
+ Equal(k, "sym:previousSibling") || Equal(k, "csym:nextSibling") || Equal(k, "csym:previousSibling"))) {
/* Do nothing */
- } else if (Cmp(k, "kwargs") == 0 || Cmp(k, "parms") == 0 || Cmp(k, "wrap:parms") == 0 ||
- Cmp(k, "pattern") == 0 || Cmp(k, "templateparms") == 0 || Cmp(k, "throws") == 0) {
+ } else if (Equal(k, "kwargs") || Equal(k, "parms") || Equal(k, "wrap:parms") || Equal(k, "pattern") || Equal(k, "templateparms") || Equal(k, "throws")) {
print_indent(2);
/* Differentiate parameter lists by displaying within single quotes */
- Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(Getattr(obj, k)));
+ Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(value));
} else {
DOH *o;
const char *trunc = "";
print_indent(2);
- if (DohIsString(Getattr(obj, k))) {
- o = Str(Getattr(obj, k));
+ if (DohIsString(value)) {
+ o = Str(value);
if (Len(o) > 80) {
trunc = "...";
}
Printf(stdout, "%-12s - \"%(escape)-0.80s%s\"\n", k, o, trunc);
Delete(o);
} else {
- Printf(stdout, "%-12s - %p\n", k, Getattr(obj, k));
+ Printf(stdout, "%-12s - %p\n", k, value);
}
}
ki = Next(ki);
@@ -107,6 +130,7 @@ void Swig_print_node(Node *obj) {
print_indent(1);
Printf(stdout, "\n");
}
+ Delete(keys);
}
/* -----------------------------------------------------------------------------
@@ -225,7 +249,7 @@ void removeNode(Node *n) {
/* Delete attributes */
Delattr(n,"parentNode");
Delattr(n,"nextSibling");
- Delattr(n,"prevSibling");
+ Delattr(n,"previousSibling");
}
/* -----------------------------------------------------------------------------
@@ -261,12 +285,16 @@ int checkAttribute(Node *n, const_String_or_char_ptr name, const_String_or_char_
* ns - namespace for the view name for saving any attributes under
* n - node
* ... - list of attribute names of type char*
- * This method checks that the attribute names exist in the node n and asserts if
- * not. Assert will only occur unless the attribute is optional. An attribute is
- * optional if it is prefixed by ?, eg "?value". If the attribute name is prefixed
- * by * or ?, eg "*value" then a copy of the attribute is saved. The saved
- * attributes will be restored on a subsequent call to Swig_restore(). All the
- * saved attributes are saved in the view namespace (prefixed by ns).
+ *
+ * An attribute is optional if it is prefixed by ?, eg "?value". All
+ * non-optional attributes are checked for on node n and if any do not exist
+ * SWIG exits with a fatal error.
+ *
+ * If the attribute name is prefixed by * or ?, eg "*value" then a copy of the
+ * attribute is saved. The saved attributes will be restored on a subsequent
+ * call to Swig_restore(). All the saved attributes are saved in the view
+ * namespace (prefixed by ns).
+ *
* This function can be called more than once with different namespaces.
* ----------------------------------------------------------------------------- */
@@ -291,7 +319,7 @@ void Swig_require(const char *ns, Node *n, ...) {
obj = Getattr(n, name);
if (!opt && !obj) {
Swig_error(Getfile(n), Getline(n), "Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", name, nodeType(n));
- assert(obj);
+ Exit(EXIT_FAILURE);
}
if (!obj)
obj = DohNone;
diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
index c0f5397c1..f0dee59d9 100644
--- a/Source/Swig/typemap.c
+++ b/Source/Swig/typemap.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* typemap.c
*
@@ -151,7 +151,7 @@ static void set_typemap(const SwigType *type, Hash **tmhash) {
* Initialize the typemap system
* ----------------------------------------------------------------------------- */
-void Swig_typemap_init() {
+void Swig_typemap_init(void) {
typemaps = NewHash();
}
@@ -511,7 +511,12 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) {
if (sm) {
/* Got a typemap. Need to only merge attributes for methods that match our signature */
Iterator ki;
+ Hash *deferred_add;
match = 1;
+
+ /* Since typemap_register can modify the `sm` hash, we *cannot* call typemap_register while iterating over sm.
+ * Create a temporary hash of typemaps to add immediately after. */
+ deferred_add = NewHash();
for (ki = First(sm); ki.key; ki = Next(ki)) {
/* Check for a signature match with the source signature */
if ((count_args(ki.key) == narg) && (Strstr(ki.key, ssig))) {
@@ -521,34 +526,36 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) {
Replace(nkey, ssig, dsig, DOH_REPLACE_ANY);
/* Make sure the typemap doesn't already exist in the target map */
-
oldm = Getattr(tm, nkey);
if (!oldm || (!Getattr(tm, "code"))) {
String *code;
- ParmList *locals;
- ParmList *kwargs;
Hash *sm1 = ki.item;
code = Getattr(sm1, "code");
- locals = Getattr(sm1, "locals");
- kwargs = Getattr(sm1, "kwargs");
if (code) {
- String *src_str = ParmList_str_multibrackets(src);
- String *dest_str = ParmList_str_multibrackets(dest);
- String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str);
-
Replace(nkey, dsig, "", DOH_REPLACE_ANY);
Replace(nkey, "tmap:", "", DOH_REPLACE_ANY);
- typemap_register(nkey, dest, code, locals, kwargs, source_directive);
-
- Delete(source_directive);
- Delete(dest_str);
- Delete(src_str);
+ Setattr(deferred_add, nkey, sm1);
}
}
Delete(nkey);
}
}
+
+ /* After assembling the key/item pairs, add the resulting typemaps */
+ for (ki = First(deferred_add); ki.key; ki = Next(ki)) {
+ Hash *sm1 = ki.item;
+ String *src_str = ParmList_str_multibrackets(src);
+ String *dest_str = ParmList_str_multibrackets(dest);
+ String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str);
+
+ typemap_register(ki.key, dest, Getattr(sm1, "code"), Getattr(sm1, "locals"), Getattr(sm1, "kwargs"), source_directive);
+
+ Delete(source_directive);
+ Delete(dest_str);
+ Delete(src_str);
+ }
+ Delete(deferred_add);
}
Delete(ssig);
Delete(dsig);
@@ -1257,6 +1264,59 @@ static String *typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) {
}
/* -----------------------------------------------------------------------------
+ * typemap_merge_fragment_kwargs()
+ *
+ * If multiple 'fragment' attributes are provided to a typemap, combine them by
+ * concatenating with commas.
+ * ----------------------------------------------------------------------------- */
+
+static void typemap_merge_fragment_kwargs(Parm *kw) {
+ Parm *reattach_kw = NULL;
+ Parm *prev_kw = NULL;
+ Parm *next_kw = NULL;
+ String *fragment = NULL;
+ while (kw) {
+ next_kw = nextSibling(kw);
+ if (Strcmp(Getattr(kw, "name"), "fragment") == 0) {
+ String *thisfragment = Getattr(kw, "value");
+ String *kwtype = Getattr(kw, "type");
+ if (!fragment) {
+ /* First fragment found; it should remain in the list */
+ fragment = thisfragment;
+ prev_kw = kw;
+ } else {
+ /* Concatenate to previously found fragment */
+ Printv(fragment, ",", thisfragment, NULL);
+ reattach_kw = prev_kw;
+ }
+ if (kwtype) {
+ String *mangle = Swig_string_mangle(kwtype);
+ Append(fragment, mangle);
+ Delete(mangle);
+ /* Remove 'type' from kwargs so it's not duplicated later */
+ Setattr(kw, "type", NULL);
+ }
+ } else {
+ /* Not a fragment */
+ if (reattach_kw) {
+ /* Update linked list to remove duplicate fragment */
+ DohIncref(kw);
+ set_nextSibling(reattach_kw, kw);
+ set_previousSibling(kw, reattach_kw);
+ Delete(reattach_kw);
+ reattach_kw = NULL;
+ }
+ prev_kw = kw;
+ }
+ kw = next_kw;
+ }
+ if (reattach_kw) {
+ /* Update linked list to remove duplicate fragment */
+ set_nextSibling(reattach_kw, kw);
+ }
+}
+
+/* -----------------------------------------------------------------------------
* Swig_typemap_lookup()
*
* Attach one or more typemaps to a node and optionally generate the typemap contents
@@ -1390,7 +1450,6 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No
* ie, not use the typemap code, otherwise both f and actioncode must be non null. */
if (actioncode) {
const String *result_equals = NewStringf("%s = ", Swig_cresult_name());
- clname = Copy(actioncode);
/* check that the code in the typemap can be used in this optimal way.
* The code should be in the form "result = ...;\n". We need to extract
* the "..." part. This may not be possible for various reasons, eg
@@ -1398,22 +1457,17 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No
* hack and circumvents the normal requirement for a temporary variable
* to hold the result returned from a wrapped function call.
*/
- if (Strncmp(clname, result_equals, 9) == 0) {
- int numreplacements = Replace(clname, result_equals, "", DOH_REPLACE_ID_BEGIN);
- if (numreplacements == 1) {
- numreplacements = Replace(clname, ";\n", "", DOH_REPLACE_ID_END);
- if (numreplacements == 1) {
- if (Strchr(clname, ';') == 0) {
- lname = clname;
- actioncode = 0;
- optimal_substitution = 1;
- }
- }
- }
- }
- if (!optimal_substitution) {
+ if (Strncmp(actioncode, result_equals, Len(result_equals)) == 0 &&
+ Strchr(actioncode, ';') == Char(actioncode) + Len(actioncode) - 2 &&
+ Char(actioncode)[Len(actioncode) - 1] == '\n') {
+ clname = NewStringWithSize(Char(actioncode) + Len(result_equals),
+ Len(actioncode) - Len(result_equals) - 2);
+ lname = clname;
+ actioncode = 0;
+ optimal_substitution = 1;
+ } else {
Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute ignored\n", Swig_name_decl(node));
- Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", clname);
+ Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", actioncode);
delete_optimal_attribute = 1;
}
} else {
@@ -1463,6 +1517,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No
/* Attach kwargs - ie the typemap attributes */
kw = Getattr(tm, "kwargs");
+ typemap_merge_fragment_kwargs(kw);
while (kw) {
String *value = Copy(Getattr(kw, "value"));
String *kwtype = Getattr(kw, "type");
@@ -1577,6 +1632,7 @@ String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *node, co
static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *firstp, int nmatch) {
String *temp = NewStringEmpty();
Parm *kw = Getattr(tm, "kwargs");
+ typemap_merge_fragment_kwargs(kw);
while (kw) {
String *value = Copy(Getattr(kw, "value"));
String *type = Getattr(kw, "type");
@@ -2035,6 +2091,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper
Printf(stdout, "Swig_typemap_attach_parms: embedded\n");
#endif
if (already_substituting < 10) {
+ char* found_colon;
already_substituting++;
if ((in_typemap_search_multi == 0) && typemap_search_debug) {
String *dtypemap = NewString(dollar_typemap);
@@ -2042,7 +2099,15 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper
Printf(stdout, " Containing: %s\n", dtypemap);
Delete(dtypemap);
}
- Swig_typemap_attach_parms(tmap_method, to_match_parms, f);
+ found_colon = Strchr(tmap_method, ':');
+ if (found_colon) {
+ /* Substitute from a keyword argument to a typemap. Avoid emitting local variables from the attached typemap by passing NULL for the file. */
+ String *temp_tmap_method = NewStringWithSize(Char(tmap_method), (int)(found_colon - Char(tmap_method)));
+ Swig_typemap_attach_parms(temp_tmap_method, to_match_parms, NULL);
+ Delete(temp_tmap_method);
+ } else {
+ Swig_typemap_attach_parms(tmap_method, to_match_parms, f);
+ }
already_substituting--;
/* Look for the typemap code */
@@ -2105,7 +2170,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper
* Display all typemaps
* ----------------------------------------------------------------------------- */
-void Swig_typemap_debug() {
+void Swig_typemap_debug(void) {
int nesting_level = 2;
Printf(stdout, "---[ typemaps ]--------------------------------------------------------------\n");
Swig_print(typemaps, nesting_level);
diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c
index 9944a9eeb..8cd2e28e9 100644
--- a/Source/Swig/typeobj.c
+++ b/Source/Swig/typeobj.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* typeobj.c
*
@@ -209,6 +209,47 @@ SwigType *SwigType_pop(SwigType *t) {
}
/* -----------------------------------------------------------------------------
+ * SwigType_last()
+ *
+ * Return the last element of the given (partial) type.
+ * For example:
+ * t: q(const).p.
+ * result: p.
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_last(SwigType *t) {
+ SwigType *result;
+ char *c;
+ char *last;
+ int sz = 0;
+
+ if (!t)
+ return 0;
+
+ /* Find the last element */
+ c = Char(t);
+ last = 0;
+ while (*c) {
+ last = c;
+ sz = element_size(c);
+ c = c + sz;
+ if (*c == '.') {
+ c++;
+ sz++;
+ }
+ }
+
+ /* Extract the last element */
+ if (last) {
+ result = NewStringWithSize(last, sz);
+ } else {
+ result = 0;
+ }
+
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
* SwigType_parm()
*
* Returns the parameter of an operator as a string
@@ -359,8 +400,8 @@ SwigType *SwigType_del_pointer(SwigType *t) {
c++;
}
if (strncmp(c, "p.", 2)) {
- printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n");
- abort();
+ printf("Fatal error: SwigType_del_pointer applied to non-pointer.\n");
+ Exit(EXIT_FAILURE);
}
Delslice(t, 0, (int)((c - s) + 2));
return t;
@@ -402,9 +443,10 @@ SwigType *SwigType_add_reference(SwigType *t) {
SwigType *SwigType_del_reference(SwigType *t) {
char *c = Char(t);
- int check = strncmp(c, "r.", 2);
- assert(check == 0);
- (void)check;
+ if (strncmp(c, "r.", 2)) {
+ printf("Fatal error: SwigType_del_reference applied to non-reference.\n");
+ Exit(EXIT_FAILURE);
+ }
Delslice(t, 0, 2);
return t;
}
@@ -438,9 +480,10 @@ SwigType *SwigType_add_rvalue_reference(SwigType *t) {
SwigType *SwigType_del_rvalue_reference(SwigType *t) {
char *c = Char(t);
- int check = strncmp(c, "z.", 2);
- assert(check == 0);
- (void)check;
+ if (strncmp(c, "z.", 2)) {
+ fprintf(stderr, "Fatal error: SwigType_del_rvalue_reference() applied to non-rvalue-reference.\n");
+ Exit(EXIT_FAILURE);
+ }
Delslice(t, 0, 2);
return t;
}
@@ -643,9 +686,10 @@ SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size) {
SwigType *SwigType_del_array(SwigType *t) {
char *c = Char(t);
- int check = strncmp(c, "a(", 2);
- assert(check == 0);
- (void)check;
+ if (strncmp(c, "a(", 2)) {
+ fprintf(stderr, "Fatal error: SwigType_del_array() applied to non-array.\n");
+ Exit(EXIT_FAILURE);
+ }
Delslice(t, 0, element_size(c));
return t;
}
@@ -738,8 +782,10 @@ void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep) {
char *c = Char(t);
start = c;
- if (strncmp(c, "a(", 2))
- abort();
+ if (strncmp(c, "a(", 2)) {
+ fprintf(stderr, "Fatal error: SwigType_array_type applied to non-array.\n");
+ Exit(EXIT_FAILURE);
+ }
while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) {
c = strchr(c, '.');
@@ -831,8 +877,8 @@ SwigType *SwigType_pop_function(SwigType *t) {
c = Char(t);
}
if (strncmp(c, "f(", 2)) {
- printf("Fatal error. SwigType_pop_function applied to non-function.\n");
- abort();
+ fprintf(stderr, "Fatal error. SwigType_pop_function applied to non-function.\n");
+ Exit(EXIT_FAILURE);
}
g = SwigType_pop(t);
if (f)
diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c
index d6d6bcc88..74384f860 100644
--- a/Source/Swig/typesys.c
+++ b/Source/Swig/typesys.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* typesys.c
*
@@ -180,7 +180,7 @@ int Swig_value_wrapper_mode(int mode) {
}
-static void flush_cache() {
+static void flush_cache(void) {
typedef_resolve_cache = 0;
typedef_all_cache = 0;
typedef_qualified_cache = 0;
@@ -188,7 +188,7 @@ static void flush_cache() {
/* Initialize the scoping system */
-void SwigType_typesystem_init() {
+void SwigType_typesystem_init(void) {
if (global_scope)
Delete(global_scope);
if (scopes)
@@ -407,7 +407,7 @@ void SwigType_using_scope(Typetab *scope) {
* table for the scope that was popped off.
* ----------------------------------------------------------------------------- */
-Typetab *SwigType_pop_scope() {
+Typetab *SwigType_pop_scope(void) {
Typetab *t, *old = current_scope;
t = Getattr(current_scope, "parent");
if (!t)
@@ -1702,7 +1702,9 @@ void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr cl
if (t) {
char *ct = Char(t);
- if (strchr(ct, '<') && !(strstr(ct, "<("))) {
+ const char *lt = strchr(ct, '<');
+ /* Allow for `<<` operator in constant expression for array size. */
+ if (lt && lt[1] != '(' && lt[1] != '<') {
Printf(stdout, "Bad template type passed to SwigType_remember: %s\n", t);
assert(0);
}
@@ -1974,6 +1976,7 @@ void SwigType_inherit_equiv(File *out) {
Hash *sub;
Hash *rh;
List *rlist;
+ List *r_resolved_sorted_keys;
Iterator rk, bk, ck;
if (!conversions)
@@ -1981,10 +1984,12 @@ void SwigType_inherit_equiv(File *out) {
if (!subclass)
subclass = NewHash();
- rk = First(r_resolved);
- while (rk.key) {
+ r_resolved_sorted_keys = SortedKeys(r_resolved, Strcmp);
+ rk = First(r_resolved_sorted_keys);
+ while (rk.item) {
+ List *sub_sorted_keys;
/* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */
- base = SwigType_base(rk.key);
+ base = SwigType_base(rk.item);
/* Check to see whether the base is recorded in the subclass table */
sub = Getattr(subclass, base);
Delete(base);
@@ -1995,28 +2000,29 @@ void SwigType_inherit_equiv(File *out) {
/* This type has subclasses. We now need to walk through these subtypes and generate pointer conversion functions */
- rh = Getattr(r_resolved, rk.key);
+ rh = Getattr(r_resolved, rk.item);
rlist = NewList();
for (ck = First(rh); ck.key; ck = Next(ck)) {
Append(rlist, ck.key);
}
- /* Printf(stdout,"rk.key = '%s'\n", rk.key);
+ /* Printf(stdout,"rk.item = '%s'\n", rk.item);
Printf(stdout,"rh = %p '%s'\n", rh,rh); */
- bk = First(sub);
- while (bk.key) {
- prefix = SwigType_prefix(rk.key);
- Append(prefix, bk.key);
+ sub_sorted_keys = SortedKeys(sub, Strcmp);
+ bk = First(sub_sorted_keys);
+ while (bk.item) {
+ prefix = SwigType_prefix(rk.item);
+ Append(prefix, bk.item);
/* Printf(stdout,"set %p = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */
mprefix = SwigType_manglestr(prefix);
Setattr(rh, mprefix, prefix);
- mkey = SwigType_manglestr(rk.key);
+ mkey = SwigType_manglestr(rk.item);
ckey = NewStringf("%s+%s", mprefix, mkey);
if (!Getattr(conversions, ckey)) {
String *convname = NewStringf("%sTo%s", mprefix, mkey);
- String *lkey = SwigType_lstr(rk.key, 0);
+ String *lkey = SwigType_lstr(rk.item, 0);
String *lprefix = SwigType_lstr(prefix, 0);
- Hash *subhash = Getattr(sub, bk.key);
+ Hash *subhash = Getattr(sub, bk.item);
String *convcode = Getattr(subhash, "convcode");
if (convcode) {
char *newmemoryused = Strstr(convcode, "newmemory"); /* see if newmemory parameter is used in order to avoid unused parameter warnings */
@@ -2077,29 +2083,13 @@ void SwigType_inherit_equiv(File *out) {
Delete(mkey);
bk = Next(bk);
}
+ Delete(sub_sorted_keys);
rk = Next(rk);
Delete(rlist);
}
+ Delete(r_resolved_sorted_keys);
}
-/* Helper function to sort the mangled list */
-static int SwigType_compare_mangled(const DOH *a, const DOH *b) {
- return strcmp((char *) Data(a), (char *) Data(b));
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_get_sorted_mangled_list()
- *
- * Returns the sorted list of mangled type names that should be exported into the
- * wrapper file.
- * ----------------------------------------------------------------------------- */
-List *SwigType_get_sorted_mangled_list() {
- List *l = Keys(r_mangled);
- SortList(l, SwigType_compare_mangled);
- return l;
-}
-
-
/* -----------------------------------------------------------------------------
* SwigType_type_table()
*
@@ -2126,22 +2116,22 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
/*#define DEBUG 1*/
#ifdef DEBUG
Printf(stdout, "---r_mangled---\n");
- Printf(stdout, "%s\n", r_mangled);
+ Swig_print(r_mangled, 2);
Printf(stdout, "---r_resolved---\n");
- Printf(stdout, "%s\n", r_resolved);
+ Swig_print(r_resolved, 2);
Printf(stdout, "---r_ltype---\n");
- Printf(stdout, "%s\n", r_ltype);
+ Swig_print(r_ltype, 2);
Printf(stdout, "---subclass---\n");
- Printf(stdout, "%s\n", subclass);
+ Swig_print(subclass, 2);
Printf(stdout, "---conversions---\n");
- Printf(stdout, "%s\n", conversions);
+ Swig_print(conversions, 2);
Printf(stdout, "---r_clientdata---\n");
- Printf(stdout, "%s\n", r_clientdata);
+ Swig_print(r_clientdata, 2);
#endif
table = NewStringEmpty();
@@ -2155,12 +2145,10 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
Printf(f_forward, "\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n");
- mangled_list = SwigType_get_sorted_mangled_list();
+ mangled_list = SortedKeys(r_mangled, Strcmp);
for (ki = First(mangled_list); ki.item; ki = Next(ki)) {
List *el;
Iterator ei;
- SwigType *lt;
- SwigType *rt = 0;
String *nt;
String *ln;
String *rn;
@@ -2168,8 +2156,12 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
Hash *lthash;
Iterator ltiter;
Hash *nthash;
+ String *cast_temp_conv;
+ String *resolved_lstr = 0;
+ List *ntlist;
cast_temp = NewStringEmpty();
+ cast_temp_conv = NewStringEmpty();
Printv(types, "static swig_type_info _swigt_", ki.item, " = {", NIL);
Append(table_list, ki.item);
@@ -2185,8 +2177,8 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
nthash = NewHash();
ltiter = First(lthash);
while (ltiter.key) {
- lt = ltiter.key;
- rt = SwigType_typedef_resolve_all(lt);
+ SwigType *lt = ltiter.key;
+ SwigType *rt = SwigType_typedef_resolve_all(lt);
/* we save the original type and the fully resolved version */
ln = SwigType_lstr(lt, 0);
rn = SwigType_lstr(rt, 0);
@@ -2196,6 +2188,12 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
Setattr(nthash, rn, "1");
Setattr(nthash, ln, "1");
}
+ if (!resolved_lstr) {
+ resolved_lstr = Copy(rn);
+ } else if (Len(rn) < Len(resolved_lstr)) {
+ Delete(resolved_lstr);
+ resolved_lstr = Copy(rn);
+ }
if (SwigType_istemplate(rt)) {
String *dt = Swig_symbol_template_deftype(rt, 0);
String *dn = SwigType_lstr(dt, 0);
@@ -2205,33 +2203,50 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
Delete(dt);
Delete(dn);
}
+ Delete(rt);
+ Delete(rn);
+ Delete(ln);
ltiter = Next(ltiter);
}
/* now build nt */
- ltiter = First(nthash);
+ ntlist = SortedKeys(nthash, Strcmp);
+ ltiter = First(ntlist);
nt = 0;
- while (ltiter.key) {
- if (nt) {
- Printf(nt, "|%s", ltiter.key);
- } else {
- nt = NewString(ltiter.key);
+ while (ltiter.item) {
+ if (!Equal(resolved_lstr, ltiter.item)) {
+ if (nt) {
+ Printf(nt, "|%s", ltiter.item);
+ } else {
+ nt = NewString(ltiter.item);
+ }
}
ltiter = Next(ltiter);
}
+ /* Last in list is a resolved type used by SWIG_TypePrettyName.
+ * There can be more than one resolved type and the chosen one is simply the
+ * shortest in length, arguably the most user friendly/readable. */
+ if (nt) {
+ Printf(nt, "|%s", resolved_lstr);
+ } else {
+ nt = NewString(resolved_lstr);
+ }
+ Delete(ntlist);
Delete(nthash);
+ Delete(resolved_lstr);
Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd);
el = SwigType_equivalent_mangle(ki.item, 0, 0);
+ SortList(el, Strcmp);
for (ei = First(el); ei.item; ei = Next(ei)) {
String *ckey;
String *conv;
ckey = NewStringf("%s+%s", ei.item, ki.item);
conv = Getattr(conversions, ckey);
if (conv) {
- Printf(cast_temp, " {&_swigt_%s, %s, 0, 0},", ei.item, conv);
+ Printf(cast_temp_conv, " {&_swigt_%s, %s, 0, 0},", ei.item, conv);
} else {
Printf(cast_temp, " {&_swigt_%s, 0, 0, 0},", ei.item);
}
@@ -2248,13 +2263,13 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
}
}
Delete(el);
- Printf(cast, "%s{0, 0, 0, 0}};\n", cast_temp);
+ Printf(cast, "%s%s{0, 0, 0, 0}};\n", cast_temp, cast_temp_conv);
+ Delete(cast_temp_conv);
Delete(cast_temp);
Delete(nt);
- Delete(rt);
}
/* print the tables in the proper order */
- SortList(table_list, SwigType_compare_mangled);
+ SortList(table_list, Strcmp);
i = 0;
for (ki = First(table_list); ki.item; ki = Next(ki)) {
Printf(f_forward, "#define SWIGTYPE%s swig_types[%d]\n", ki.item, i++);
diff --git a/Source/Swig/wrapfunc.c b/Source/Swig/wrapfunc.c
index 29a59cc49..6d8237245 100644
--- a/Source/Swig/wrapfunc.c
+++ b/Source/Swig/wrapfunc.c
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* wrapfunc.c
*
@@ -27,7 +27,7 @@ static int Max_line_size = 128;
Wrapper *NewWrapper(void) {
Wrapper *w;
- w = (Wrapper *) malloc(sizeof(Wrapper));
+ w = (Wrapper *) Malloc(sizeof(Wrapper));
w->localh = NewHash();
w->locals = NewStringEmpty();
w->code = NewStringEmpty();
@@ -46,7 +46,7 @@ void DelWrapper(Wrapper *w) {
Delete(w->locals);
Delete(w->code);
Delete(w->def);
- free(w);
+ Free(w);
}
/* -----------------------------------------------------------------------------
diff --git a/TODO b/TODO
index 38ab4605d..2182ef86a 100644
--- a/TODO
+++ b/TODO
@@ -26,80 +26,6 @@ defer ready to go. The primary obstacle lies in the target language
This is one of the last remaining "hard" problems in the SWIG
core, but it is important that we solve it.
-*** "Nested" typemaps. The basic idea is similar to allowing one to
- use $descriptor(T) for any T, rather than just $descriptor
- for the type currently being typemapped.
-
- In short (ha!), given a previously defined typemap:
-
- %typemap(in) Foo {
- // whatever it takes to initialize $1 from $input
- }
-
- it would be possible to inline its code inside another typemap.
- While the syntax is still to be defined, the use would be
- along the lines of:
-
- template <class T> class vector {
- %typemap(in) vector<T> {
- ...
- for (int i=0; i<N; i++) {
- PyObject* x = ... // i-th element
- $typemap(in, T, x, $1[i]);
- }
- ...
- }
- ...
- }
-
- i.e., when $typemap(in,Foo,x,y) is encountered, it will
- be replaced by the code for %typemap(in) Foo; in the latter,
- x will be replaced for $input and y will be replaced for $1.
- As in the case above, x and y themselves might need to be
- expanded before or after being substituted in the typemap code.
- Also, $typemap(what,Foo,x,y,z,...) will be used in case of
- multi-arguments typemaps. The same will hold for "out" typemaps
- and all the others.
-
- Comment by mkoeppe:
-
- I think we need to be careful to keep the syntax readable.
- I would like to get a syntax that is close to that of
- typemap definitions. So consider this typemap:
-
- %typemap(in) int { ... }
-
- I would like to refer to this typemap like this:
-
- $typemap(in, input=x) int = foo;
-
- Here $input would be replaced by the given keyword argument
- x, and $1 would be replaced by foo.
-
- This syntax would extend easily to multi-typemaps:
-
- %typemap(in) ( int FIRST, double SECOND ) { ... }
-
- -> $typemap(in, input=x)
- ( int FIRST = foo, double SECOND = bar );
-
- The advantage of this syntax would be that the formal
- arguments (int FIRST, double SECOND) are close to the
- actual arguments (foo, bar).
-
- Comment by beazley
-
- $typemap(in, input=x) int = foo;
-
- is a little bit hard to parse in terms of variable substitution.
- I'm considering something like this:
-
- $typemap(in,1=int foo, input=x)
-
- Note: This is partially implemented in the new Unified Typemap
- Library(python,tcl,ruby and perl) via %fragments and the
- SWIG_From/SWIG_AsVal methdos.
-
*** Implement $fail special variable substitution in wrappers. Used
to properly transfer control out of a wrapper function while
reclaiming resources.
@@ -201,12 +127,7 @@ PHP
** When returning wrapped objects via alternate constructors if that
pointer value already exists "out there" as a resource we should
use the same resource, we can't have multiple ref-counted resources
- mapping to the same object in case it gets twice destroyed. And check
- if ref count destroying is even working, see smart_pointer_rename
-
-* Work out how classes without even inherited constructors should
- interact with the php "new <class>" notation.
- See: abstract_inherit_wrap.cpptest
+ mapping to the same object in case it gets twice destroyed.
** Look at pass by point and passby ref,
Make sometype** to be auto allocated
diff --git a/Tools/CI-linux-environment.sh b/Tools/CI-linux-environment.sh
index 0e9526dcf..e854c5b0e 100644
--- a/Tools/CI-linux-environment.sh
+++ b/Tools/CI-linux-environment.sh
@@ -29,11 +29,5 @@ case "$SWIGLANG" in
set -x
fi
;;
- "scilab")
- # Travis has the wrong version of Java pre-installed resulting in error using scilab:
- # /usr/bin/scilab-bin: error while loading shared libraries: libjava.so: cannot open shared object file: No such file or directory
- echo "JAVA_HOME was set to $JAVA_HOME"
- unset JAVA_HOME
- ;;
*) ;;
esac
diff --git a/Tools/CI-linux-install.sh b/Tools/CI-linux-install.sh
index 7bd141080..456f5bc42 100644
--- a/Tools/CI-linux-install.sh
+++ b/Tools/CI-linux-install.sh
@@ -12,8 +12,7 @@ else
fi
$RETRY sudo apt-get -qq install libboost-dev libpcre3-dev
-# testflags.py needs python
-$RETRY sudo apt-get install -qq python
+# Note: testflags.py needs python, but python is pre-installed
WITHLANG=$SWIGLANG
@@ -55,7 +54,7 @@ case "$SWIGLANG" in
fi
;;
"jsc")
- $RETRY sudo apt-get install -qq libjavascriptcoregtk-4.0-dev
+ $RETRY sudo apt-get install -qq libjavascriptcoregtk-${VER}-dev
;;
"v8")
$RETRY sudo apt-get install -qq libv8-dev
@@ -63,7 +62,7 @@ case "$SWIGLANG" in
esac
;;
"guile")
- $RETRY sudo apt-get -qq install guile-2.0-dev
+ $RETRY sudo apt-get -qq install guile-${VER:-2.0}-dev
;;
"lua")
if [[ -z "$VER" ]]; then
@@ -79,8 +78,14 @@ case "$SWIGLANG" in
$RETRY sudo apt-get -qq install ocaml camlp4
;;
"octave")
- $RETRY sudo apt-get -qq update
- $RETRY sudo apt-get -qq install liboctave-dev
+ if [[ "$VER" ]]; then
+ $RETRY sudo add-apt-repository -y ppa:devacom/science
+ $RETRY sudo apt-get -qq update
+ $RETRY sudo apt-get -qq install "liboctave-dev=$VER.*"
+ else
+ $RETRY sudo apt-get -qq update
+ $RETRY sudo apt-get -qq install liboctave-dev
+ fi
;;
"php")
if [[ "$VER" ]]; then
@@ -92,14 +97,20 @@ case "$SWIGLANG" in
;;
"python")
pip install --user pycodestyle
+ if [[ "$PY2" ]]; then
+ WITHLANG=$SWIGLANG
+ else
+ WITHLANG=${SWIGLANG}3
+ fi
if [[ "$VER" ]]; then
$RETRY sudo add-apt-repository -y ppa:deadsnakes/ppa
$RETRY sudo apt-get -qq update
$RETRY sudo apt-get -qq install python${VER}-dev
- WITHLANG=$SWIGLANG$PY3=$SWIGLANG$VER
- else
- $RETRY sudo apt-get install -qq python${PY3}-dev
- WITHLANG=$SWIGLANG$PY3
+ WITHLANG=$WITHLANG=$SWIGLANG$VER
+ elif [[ "$PY2" ]]; then
+ $RETRY sudo apt-get install -qq python-dev
+ else
+ $RETRY sudo apt-get install -qq python3-dev
fi
;;
"r")
@@ -120,22 +131,29 @@ case "$SWIGLANG" in
source $HOME/.rvm/scripts/rvm
set -x
fi
- if [[ "$VER" == "2.7" || "$VER" == "3.0" ]]; then
- # Ruby 2.7+ support is currently only rvm master (30 Dec 2019)
- $RETRY rvm get master
- rvm reload
- rvm list known
- fi
+ case "$VER" in
+ 2.7 | 3.0 | 3.1 )
+ # Ruby 2.7+ support is currently only rvm master (30 Dec 2019)
+ set +x
+ $RETRY rvm get master
+ rvm reload
+ rvm list known
+ set -x
+ ;;
+ esac
if [[ "$VER" ]]; then
$RETRY rvm install $VER
fi
;;
"scilab")
- # Travis has the wrong version of Java pre-installed resulting in error using scilab:
- # /usr/bin/scilab-bin: error while loading shared libraries: libjava.so: cannot open shared object file: No such file or directory
- echo "JAVA_HOME was set to $JAVA_HOME"
- unset JAVA_HOME
- $RETRY sudo apt-get -qq install scilab
+ if [[ -z "$VER" ]]; then
+ $RETRY sudo apt-get -qq install scilab
+ else
+ $RETRY wget --progress=dot:giga "https://www.scilab.org/download/$VER/scilab-$VER.bin.linux-x86_64.tar.gz"
+ # $HOME/.local/bin is in PATH and writeable
+ mkdir -p "$HOME/.local"
+ tar -xzf "scilab-$VER.bin.linux-x86_64.tar.gz" --strip-components=1 -C "$HOME/.local"
+ fi
;;
"tcl")
$RETRY sudo apt-get -qq install tcl-dev
diff --git a/Tools/brew-install b/Tools/brew-install
deleted file mode 100755
index 39fe22bc2..000000000
--- a/Tools/brew-install
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# Wrapper around 'brew install' emitting a message every minute if the command is still running.
-# This is used on Travis to ensure the install isn't killed when there is no output over a long period (10 minutes).
-# Usage: brew-install package, where package is the name of the package for brew to install.
-
-seconds=0
-minutes=0
-brew install "$@" &
-while true; do
- ps -p$! 2>& 1>/dev/null
- if [ $? = 0 ]; then
- if [ $seconds = 60 ]; then
- let seconds=0
- let minutes=minutes+1
- echo "brew install $1 still running ($minutes min)"
- fi
- sleep 1
- let seconds=seconds+1
- else
- break
- fi
-done
-wait $!
-exit $?
diff --git a/Tools/cmake/FindPCRE.cmake b/Tools/cmake/FindPCRE.cmake
deleted file mode 100644
index dbbd60ada..000000000
--- a/Tools/cmake/FindPCRE.cmake
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2007-2009 LuaDist.
-# Created by Peter Kapec <kapecp@gmail.com>
-# Redistribution and use of this file is allowed according to the terms of the MIT license.
-# For details see the COPYRIGHT file distributed with LuaDist.
-# Note:
-# Searching headers and libraries is very simple and is NOT as powerful as scripts
-# distributed with CMake, because LuaDist defines directories to search for.
-# Everyone is encouraged to contact the author with improvements. Maybe this file
-# becomes part of CMake distribution sometimes.
-
-# - Find pcre
-# Find the native PCRE headers and libraries.
-#
-# PCRE_INCLUDE_DIRS - where to find pcre.h, etc.
-# PCRE_LIBRARIES - List of libraries when using pcre.
-# PCRE_FOUND - True if pcre found.
-
-# Look for the header file.
-FIND_PATH(PCRE_INCLUDE_DIR NAMES pcre.h)
-
-# Look for the library.
-FIND_LIBRARY(PCRE_LIBRARY NAMES pcre)
-
-# Handle the QUIETLY and REQUIRED arguments and set PCRE_FOUND to TRUE if all listed variables are TRUE.
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_INCLUDE_DIR)
-
-# Copy the results to the output variables.
-IF(PCRE_FOUND)
- SET(PCRE_LIBRARIES ${PCRE_LIBRARY})
- SET(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR})
-ELSE(PCRE_FOUND)
- SET(PCRE_LIBRARIES)
- SET(PCRE_INCLUDE_DIRS)
-ENDIF(PCRE_FOUND)
-
-MARK_AS_ADVANCED(PCRE_INCLUDE_DIRS PCRE_LIBRARIES)
diff --git a/Tools/cmake/FindPCRE2.cmake b/Tools/cmake/FindPCRE2.cmake
new file mode 100644
index 000000000..08c216347
--- /dev/null
+++ b/Tools/cmake/FindPCRE2.cmake
@@ -0,0 +1,21 @@
+# - Find PCRE2
+# Perl Compatible Regular Expressions
+# https://www.pcre.org/
+
+# The following variables are set:
+# PCRE2_FOUND - System has the PCRE library
+# PCRE2_LIBRARIES - The PCRE library file
+# PCRE2_INCLUDE_DIRS - The folder with the PCRE headers
+
+find_library(PCRE2_LIBRARY NAMES pcre2 pcre2-8)
+find_path(PCRE2_INCLUDE_DIR pcre2.h)
+
+set (PCRE2_LIBRARIES ${PCRE2_LIBRARY})
+set (PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(PCRE2 DEFAULT_MSG PCRE2_LIBRARIES PCRE2_INCLUDE_DIRS)
+
+mark_as_advanced (
+ PCRE2_LIBRARY
+ PCRE2_INCLUDE_DIR)
diff --git a/Tools/cmake/swigconfig.h.in b/Tools/cmake/swigconfig.h.in
index 94cee1646..1cf58e511 100644
--- a/Tools/cmake/swigconfig.h.in
+++ b/Tools/cmake/swigconfig.h.in
@@ -46,7 +46,7 @@
#define PACKAGE "swig"
/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "http://www.swig.org"
+#define PACKAGE_BUGREPORT "https://www.swig.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "swig"
diff --git a/Tools/config/m4_ax_cxx_compile_stdcxx.m4 b/Tools/config/m4_ax_cxx_compile_stdcxx.m4
index 9413da624..51a35054d 100644
--- a/Tools/config/m4_ax_cxx_compile_stdcxx.m4
+++ b/Tools/config/m4_ax_cxx_compile_stdcxx.m4
@@ -10,8 +10,8 @@
#
# Check for baseline language coverage in the compiler for the specified
# version of the C++ standard. If necessary, add switches to CXX and
-# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
-# or '14' (for the C++14 standard).
+# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for
+# the respective C++ standard version.
#
# The second argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
@@ -36,13 +36,14 @@
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
# Copyright (c) 2020 Jason Merrill <jason@redhat.com>
+# Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 12
+#serial 14
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
dnl (serial version number 13).
@@ -51,6 +52,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
+ [$1], [20], [ax_cxx_compile_alternatives="20"],
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$2], [], [],
[$2], [ext], [],
@@ -151,7 +153,6 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
)
-
dnl Test body for checking C++14 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
@@ -159,12 +160,24 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
)
+dnl Test body for checking C++17 support
+
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
)
+dnl Test body for checking C++20 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20],
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_20
+)
+
+
dnl Tests for new features in C++11
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
@@ -960,3 +973,33 @@ namespace cxx17
#endif // __cplusplus < 201703L
]])
+
+
+dnl Tests for new features in C++20
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 202002L
+
+#error "This is not a C++20 compiler"
+
+#else
+
+#include <version>
+
+namespace cxx20
+{
+
+// As C++20 supports feature test macros in the standard, there is no
+// immediate need to actually test for feature availability on the
+// Autoconf side.
+
+} // namespace cxx20
+
+#endif // __cplusplus < 202002L
+
+]])
diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in
index 5eeec0785..6335d0a65 100644
--- a/Tools/javascript/Makefile.in
+++ b/Tools/javascript/Makefile.in
@@ -32,12 +32,6 @@ JSCENABLED = @JSCENABLED@
srcdir = @srcdir@
-ifneq (, $(V8_VERSION))
- JSV8_VERSION=$(V8_VERSION)
-else
- JSV8_VERSION=0x031110
-endif
-
# Regenerate Makefile if Makefile.in or config.status have changed.
Makefile: $(srcdir)/Makefile.in ../../config.status
cd ../.. && $(SHELL) ./config.status Tools/javascript/Makefile
@@ -45,7 +39,7 @@ Makefile: $(srcdir)/Makefile.in ../../config.status
# These settings are provided by 'configure' (see '/configure.in')
ifeq (1, $(JSV8ENABLED))
JS_INTERPRETER_SRC_V8 = v8_shell.cxx
-JS_INTERPRETER_ENABLE_V8 = -DENABLE_V8 -DSWIG_V8_VERSION=$(JSV8_VERSION) -DV8_DEPRECATION_WARNINGS
+JS_INTERPRETER_ENABLE_V8 = -DENABLE_V8 -DV8_DEPRECATION_WARNINGS
endif
ifeq (1, $(JSCENABLED))
diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx
index c173c147f..f17744ad6 100644
--- a/Tools/javascript/jsc_shell.cxx
+++ b/Tools/javascript/jsc_shell.cxx
@@ -18,7 +18,7 @@ typedef int (*JSCIntializer)(JSGlobalContextRef context, JSObjectRef *module);
public:
- JSCShell() { context = 0; };
+ JSCShell() { context = 0; }
virtual ~JSCShell();
diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx
index 5001bc25a..336edb2a6 100644
--- a/Tools/javascript/v8_shell.cxx
+++ b/Tools/javascript/v8_shell.cxx
@@ -13,57 +13,24 @@ typedef int (*V8ExtensionInitializer) (v8::Handle<v8::Object> module);
// Note: these typedefs and defines are used to deal with v8 API changes since version 3.19.00
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-typedef v8::Handle<v8::Value> SwigV8ReturnValue;
-typedef v8::Arguments SwigV8Arguments;
-typedef v8::AccessorInfo SwigV8PropertyCallbackInfo;
-#define SWIGV8_RETURN(val) return scope.Close(val)
-#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val)
-#else
typedef void SwigV8ReturnValue;
typedef v8::FunctionCallbackInfo<v8::Value> SwigV8Arguments;
typedef v8::PropertyCallbackInfo<v8::Value> SwigV8PropertyCallbackInfo;
#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return
#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return
-#endif
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032117)
-#define SWIGV8_HANDLESCOPE() v8::HandleScope scope
-#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope
-#define SWIGV8_ESCAPE(val) return scope.Close(val)
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318)
-#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent());
-#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope(v8::Isolate::GetCurrent());
-#define SWIGV8_ESCAPE(val) return scope.Close(val)
-#else
#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent());
#define SWIGV8_HANDLESCOPE_ESC() v8::EscapableHandleScope scope(v8::Isolate::GetCurrent());
#define SWIGV8_ESCAPE(val) return scope.Escape(val)
-#endif
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318)
-#define SWIGV8_CURRENT_CONTEXT() v8::Context::GetCurrent()
-#define SWIGV8_STRING_NEW(str) v8::String::New(str)
-#define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(func)
-#define SWIGV8_OBJECT_NEW() v8::Object::New()
-#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(val)
-#define SWIGV8_UNDEFINED() v8::Undefined()
-#else
#define SWIGV8_CURRENT_CONTEXT() v8::Isolate::GetCurrent()->GetCurrentContext()
#define SWIGV8_STRING_NEW(str) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str)
#define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(v8::Isolate::GetCurrent(), func)
#define SWIGV8_OBJECT_NEW() v8::Object::New(v8::Isolate::GetCurrent())
#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(v8::Isolate::GetCurrent(), val)
#define SWIGV8_UNDEFINED() v8::Undefined(v8::Isolate::GetCurrent())
-#endif
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-typedef v8::Persistent<v8::Context> SwigV8Context;
-#else
typedef v8::Local<v8::Context> SwigV8Context;
-#endif
class V8Shell: public JSShell {
@@ -149,13 +116,7 @@ bool V8Shell::RunScript(const std::string &scriptPath) {
context->Exit();
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- context.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
- context.Dispose(v8::Isolate::GetCurrent());
-#else
// context.Dispose();
-#endif
// v8::V8::Dispose();
@@ -193,13 +154,7 @@ bool V8Shell::RunShell() {
context->Exit();
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
- context.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
- context.Dispose(v8::Isolate::GetCurrent());
-#else
// context.Dispose();
-#endif
// v8::V8::Dispose();
@@ -249,13 +204,8 @@ SwigV8Context V8Shell::CreateShellContext() {
global->Set(SWIGV8_STRING_NEW("require"), SWIGV8_FUNCTEMPLATE_NEW(V8Shell::Require));
global->Set(SWIGV8_STRING_NEW("version"), SWIGV8_FUNCTEMPLATE_NEW(V8Shell::Version));
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
- SwigV8Context context = v8::Context::New(NULL, global);
- return context;
-#else
SwigV8Context context = v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
return context;
-#endif
}
v8::Handle<v8::Value> V8Shell::Import(const std::string &module_path)
@@ -307,7 +257,7 @@ SwigV8ReturnValue V8Shell::Require(const SwigV8Arguments &args) {
if (args.Length() != 1) {
printf("Illegal arguments for `require`");
- };
+ }
v8::String::Utf8Value str(args[0]);
const char *cstr = V8Shell::ToCString(str);
diff --git a/Tools/mkdist.py b/Tools/mkdist.py
index 4fba4701d..3d631607a 100755
--- a/Tools/mkdist.py
+++ b/Tools/mkdist.py
@@ -42,18 +42,18 @@ if dirname.lower() != dirname:
sys.exit(3)
# If directory and tarball exist, remove it
-print("Removing " + dirname)
if check_dir_exists(dirpath):
+ print("Removing " + dirpath)
run_command("rm", "-rf", dirpath)
-print("Removing " + dirname + ".tar if exists")
filename = dirpath + ".tar"
if check_file_exists(filename):
+ print("Removing " + filename)
run_command("rm", "-rf", filename)
-print("Removing " + dirname + ".tar.gz if exists")
filename += ".gz"
if check_file_exists(filename):
+ print("Removing " + filename)
run_command("rm", "-rf", filename)
# Grab the code from git
@@ -89,10 +89,10 @@ if not skip_checks:
print("Tagging release")
tag = "v" + version
-force = "-f " if force_tag else ""
+force = "-f" if force_tag else ""
command = ["git", "tag", "-a", "-m", "'Release version " + version + "'"]
-force and command.extend(force, tag)
-not force and command.append(tag)
+force and command.append(force)
+command.append(tag)
run_command(*command) == 0 or failed()
outdir = dirname + "/"
diff --git a/Tools/mkwindows.sh b/Tools/mkwindows.sh
index e6ae84350..ed78a2e8e 100755
--- a/Tools/mkwindows.sh
+++ b/Tools/mkwindows.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-# Build Windows distribution (swigwin-2.0.x.zip) from source tarball (swig-2.0.x.tar.gz)
+# Build Windows distribution (swigwin-x.y.z.zip) from source tarball (swig-x.y.x.tar.gz)
# Requires running in either:
# - MinGW environment
# - Linux using MinGW cross compiler
@@ -23,8 +23,8 @@ if test x$1 != x; then
fi
else
echo "Usage: mkwindows.sh version [zip]"
- echo " Build SWIG Windows distribution from source tarball. Works on Cygwin, MinGW or Linux"
- echo " version should be 2.0.x"
+ echo " Build SWIG Windows distribution from source tarball. Works on Cygwin, MinGW or Linux."
+ echo " version should be in format x.y.z, for example 4.1.0"
echo " zip is full path to zip program - default is /c/cygwin/bin/zip on MinGW, zip on Linux and Cygwin"
exit 1
fi
@@ -84,10 +84,10 @@ export CXXFLAGS="$compileflags"
swigbasename=swig-$version
swigwinbasename=swigwin-$version
tarball=$swigbasename.tar.gz
-pcre_tarball=`ls pcre-*.tar.*`
+pcre_tarball=`ls pcre2-*.tar.*`
if ! test -f "$pcre_tarball"; then
- echo "Could not find PCRE tarball. Please download a PCRE source tarball from http://www.pcre.org"
+ echo "Could not find PCRE2 tarball. Please download a PCRE2 source tarball from http://www.pcre.org"
echo "and place in the same directory as the SWIG tarball."
exit 1
fi
@@ -115,8 +115,9 @@ if test -f "$tarball"; then
./configure $extraconfigureoptions --without-alllang
echo "Compiling (quietly)..."
make > build.log
- echo "Simple check to see if swig.exe runs..."
+ echo "Simple check to see if swig.exe runs and show versions..."
env LD_LIBRARY_PATH= PATH= $wine ./swig.exe -version || exit 1
+ env LD_LIBRARY_PATH= PATH= $wine ./swig.exe -pcreversion || exit 1
echo "Simple check to see if ccache-swig.exe runs..."
env LD_LIBRARY_PATH= PATH= $wine ./CCache/ccache-swig.exe -V || exit 1
echo "Creating $swigwinbasename.zip..."
diff --git a/Tools/nuget-install.cmd b/Tools/nuget-install.cmd
deleted file mode 100644
index eec7f8787..000000000
--- a/Tools/nuget-install.cmd
+++ /dev/null
@@ -1,28 +0,0 @@
-rem Workaround 'nuget install' not being reliable by retrying a few times
-@echo off
-rem initiate the retry number
-set errorCode=1
-set retryNumber=0
-set maxRetries=5
-
-:RESTORE
-nuget install %*
-
-rem problem?
-IF ERRORLEVEL %errorCode% GOTO :RETRY
-
-rem everything is fine!
-@echo Installed nuget, retries: %reTryNumber%
-GOTO :EXIT
-
-:RETRY
-@echo Oops, nuget restore exited with code %errorCode% - let us try again!
-set /a retryNumber=%retryNumber%+1
-IF %reTryNumber% LSS %maxRetries% (GOTO :RESTORE)
-IF %retryNumber% EQU %maxRetries% (GOTO :ERR)
-
-:ERR
-@echo Sorry, we tried restoring nuget packages for %maxRetries% times and all attempts were unsuccessful!
-EXIT /B 1
-
-:EXIT
diff --git a/Tools/pcre-build.sh b/Tools/pcre-build.sh
index 92f645da2..e986d682f 100755
--- a/Tools/pcre-build.sh
+++ b/Tools/pcre-build.sh
@@ -4,17 +4,17 @@ pcre_subdir=pcre/pcre-swig-install
pcre_install_dir=`pwd`/$pcre_subdir
usage() {
- echo "Helper script to build PCRE as a static library from a tarball just for use during the"
- echo "SWIG build. It does not install PCRE for global use on your system."
+ echo "Helper script to build PCRE2 as a static library from a tarball just for use during the"
+ echo "SWIG build. It does not install PCRE2 for global use on your system."
echo "Usage: pcre-build.sh [--help] [args]"
- echo " args - optional additional arguments passed on to the PCRE configure script (leave out"
+ echo " args - optional additional arguments passed on to the PCRE2 configure script (leave out"
echo " unless you are an expert at configure)"
echo " --help - Display this help information."
echo "Instructions:"
- echo " - Download the latest PCRE source tarball from http://www.pcre.org and place in the"
+ echo " - Download the latest PCRE2 source tarball from http://www.pcre.org and place in the"
echo " directory that you will configure and build SWIG."
echo " - Run this script in the same directory that you intend to configure and build SWIG in."
- echo " This will configure and build PCRE as a static library."
+ echo " This will configure and build PCRE2 as a static library."
echo " - Afterwards run the SWIG configure script which will then find and use the PCRE static"
echo " libraries in the $pcre_subdir subdirectory."
exit 0
@@ -35,21 +35,21 @@ if test -f "pcre-build.sh" ; then
usage
fi
-echo "Looking for PCRE tarball..."
+echo "Looking for PCRE2 tarball..."
rm -rf pcre
-pcre_tarball=`ls pcre-*.tar*`
-test -n "$pcre_tarball" || bail "Could not find tarball matching pattern: pcre-*.tar*"
-test -f "$pcre_tarball" || bail "Could not find a single PCRE tarball. Found: $pcre_tarball"
+pcre_tarball=`ls pcre2-*.tar*`
+test -n "$pcre_tarball" || bail "Could not find tarball matching pattern: pcre2-*.tar*"
+test -f "$pcre_tarball" || bail "Could not find a single PCRE2 tarball. Found: $pcre_tarball"
echo "Extracting tarball: $pcre_tarball"
tar -xf $pcre_tarball || bail "Could not untar $pcre_tarball"
pcre_dir=`echo $pcre_tarball | sed -e "s/\.tar.*//"`
echo "Configuring PCRE in directory: pcre"
mv $pcre_dir pcre || bail "Could not create pcre directory"
-cd pcre && ./configure --prefix=$pcre_install_dir --disable-shared $* || bail "PCRE configure failed"
-echo "Building PCRE..."
-${MAKE:-make} -s || bail "Could not build PCRE"
-echo "Installing PCRE locally to $pcre_install_dir..."
-${MAKE:-make} -s install || bail "Could not install PCRE"
+cd pcre && ./configure --prefix=$pcre_install_dir --disable-shared $* || bail "PCRE2 configure failed"
+echo "Building PCRE2..."
+${MAKE:-make} -s || bail "Could not build PCRE2"
+echo "Installing PCRE2 locally to $pcre_install_dir..."
+${MAKE:-make} -s install || bail "Could not install PCRE2"
echo ""
-echo "The SWIG configure script can now be run, whereupon PCRE will automatically be detected and used from $pcre_install_dir/bin/pcre-config."
+echo "The SWIG configure script can now be run, whereupon PCRE2 will automatically be detected and used from $pcre_install_dir/bin/pcre-config."
diff --git a/Tools/travis-linux-install.sh b/Tools/travis-linux-install.sh
deleted file mode 100755
index cb64d57d2..000000000
--- a/Tools/travis-linux-install.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-# Install Linux packages where the version has been overridden in .travis.yml
-
-lsb_release -a
-# find location of current script (only works in bash)
-script_dir="$( dirname "${BASH_SOURCE[0]}")"
-
-# run generic script
-RETRY=travis-retry
-source "$script_dir"/CI-linux-install.sh
diff --git a/Tools/travis-osx-install.sh b/Tools/travis-osx-install.sh
deleted file mode 100755
index fc69c6654..000000000
--- a/Tools/travis-osx-install.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-# Install MacOS packages where the version has been overridden in .travis.yml
-
-set -e # exit on failure (same as -o errexit)
-
-# Disable 'brew cleanup', just wastes Travis job run time
-export HOMEBREW_NO_INSTALL_CLEANUP=1
-
-sw_vers
-travis_retry brew update
-echo "Installed packages..."
-travis_retry brew list --versions
-# travis_retry brew install pcre # Travis Xcode-7.3 has pcre
-# travis_retry brew install boost
-
-WITHLANG=$SWIGLANG
-
-case "$SWIGLANG" in
- "csharp")
- travis_retry brew install mono
- ;;
- "lua")
- travis_retry brew install lua
- ;;
- "octave")
- travis_retry Tools/brew-install octave
- ;;
- "perl5")
- travis_retry Tools/brew-install perl
- ;;
- "python")
- WITHLANG=$SWIGLANG$PY3
- ;;
- "tcl")
- travis_retry Tools/brew-install --cask tcl
- ;;
-esac
-
-# Workaround for https://github.com/travis-ci/travis-ci/issues/6522
-set +e # turn off exit on failure (same as +o errexit)
diff --git a/appveyor.yml b/appveyor.yml
index 07c4fac28..152336be4 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,5 +1,4 @@
platform:
-- x86
- x64
skip_commits:
@@ -18,39 +17,58 @@ environment:
VSVER: 12
- SWIGLANG: csharp
VSVER: 14
- - SWIGLANG: java
- VSVER: 14
- SWIGLANG: python
VSVER: 14
VER: 27
+ PY2: 2
+ - BUILDSYSTEM: cmake
+ VSVER: 14
- SWIGLANG: python
VSVER: 15
VER: 38
- PY3: 3
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- SWIGLANG: python
VSVER: 16
VER: 39
- PY3: 3
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ - SWIGLANG: csharp
+ VSVER: 17
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+ - SWIGLANG: csharp
+ VSVER: 17
+ Platform: x86
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+ - SWIGLANG: java
+ VSVER: 17
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+ - SWIGLANG: java
+ VSVER: 17
+ Platform: x86
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+ - SWIGLANG: python
+ VSVER: 17
+ VER: 310
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+ - SWIGLANG: python
+ VSVER: 17
+ VER: 310
+ Platform: x86
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- SWIGLANG: python
OSVARIANT: cygwin
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- SWIGLANG: java
OSVARIANT: mingw
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- SWIGLANG: python
OSVARIANT: mingw
WITHLANG: python
- VER: 37
- PY3: 3
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- - BUILDSYSTEM: cmake
- VSVER: 14
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
-matrix:
- allow_failures:
- - SWIGLANG: python
- OSVARIANT: cygwin
+#matrix:
+# allow_failures:
+# - SWIGLANG: python
+# OSVARIANT: cygwin
# Skip stale commits (pull requests only), see https://github.com/appveyor/ci/issues/38#issuecomment-70628826
init:
@@ -77,7 +95,7 @@ install:
$env:VSARCH=""
} else {
$env:PCRE_PLATFORM="x64"
- $env:JAVA_HOME="C:/Program Files/Java/jdk15"
+ $env:JAVA_HOME="C:/Program Files/Java/jdk17"
$env:VCVARS_PLATFORM="amd64"
$env:LANG_PLATFORM="-x64"
$env:CYGWINBIN="C:\cygwin64\bin"
@@ -94,7 +112,10 @@ install:
$env:CYGWIN="nodosfilewarning"
$env:CC="cccl"
$env:CXX="cccl"
- if ($env:VSVER -ge 16) {
+ if ($env:VSVER -ge 17) {
+ $env:VCVARSBAT="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars$env:MBITS.bat"
+ $env:BOOSTROOT="C:/Libraries/boost_1_77_0"
+ } elseif ($env:VSVER -eq 16) {
$env:VCVARSBAT="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars$env:MBITS.bat"
$env:BOOSTROOT="C:/Libraries/boost_1_73_0"
} elseif ($env:VSVER -eq 15) {
@@ -117,23 +138,23 @@ install:
$env:MSYSTEM="MINGW$env:MBITS" # This is important for msys2
$env:CC="gcc"
$env:CXX="g++"
- if ($env:MBITS -eq "64" -and $env:SWIGLANG -eq "python") {
- $env:CHECK_OPTIONS2="CFLAGS+=-DMS_WIN64 CXXFLAGS+=-DMS_WIN64"
- }
}
- if "%OSVARIANT%"=="" bash -c "cd /usr/bin && curl --retry 15 -s -L https://github.com/swig/cccl/archive/cccl-1.2.tar.gz | tar -xz --strip 1 cccl-cccl-1.2/cccl"
- if "%OSVARIANT%"=="" call "%VCVARSBAT%" %VCVARSARG%
-- if "%OSVARIANT%"=="" Tools\nuget-install.cmd pcre -Verbosity quiet -Version 8.33.0.1 -OutputDirectory C:\pcre
-- if "%OSVARIANT%"=="" set PCRE_ROOT=C:/pcre/pcre.8.33.0.1/build/native
-- if not "%OSVARIANT%"=="cygwin" set PATH=C:\Python%VER%%LANG_PLATFORM%;%PATH%
+- if "%OSVARIANT%"=="" appveyor-retry appveyor DownloadFile https://github.com/PhilipHazel/pcre2/archive/refs/tags/pcre2-10.39.zip
+- if "%OSVARIANT%"=="" 7z x pcre2-10.39.zip
+- if "%OSVARIANT%"=="" set PCRE_ROOT=C:/pcre
+- if "%OSVARIANT%"=="" set PATH=C:\Python%VER%%LANG_PLATFORM%;%PATH%
- if "%OSVARIANT%"=="" bash -c "which cl.exe"
- if "%OSVARIANT%"=="" bash -c "cl.exe /? 2>&1 | head -n 1"
- if "%OSVARIANT%"=="" bash -c "which csc.exe"
- if "%OSVARIANT%"=="" bash -c "csc.exe /? | head -n 1"
-- if "%OSVARIANT%"=="cygwin" %CYGWINSETUP% --quiet-mode --packages python2-devel,libpcre-devel,libboost-devel > cygwin-install.txt || bash -c "cat cygwin-install.txt"
-- if "%OSVARIANT%"=="mingw" bash -c "pacman --noconfirm --sync mingw%MBITS%/mingw-w64-%MARCH%-pcre mingw%MBITS%/mingw-w64-%MARCH%-boost"
+- if "%OSVARIANT%"=="cygwin" %CYGWINSETUP% --quiet-mode --packages python3-devel,libpcre2-devel,libboost-devel > cygwin-install.txt || bash -c "cat cygwin-install.txt"
+- if "%OSVARIANT%"=="mingw" bash -c "pacman --noconfirm --sync mingw%MBITS%/mingw-w64-%MARCH%-autotools mingw%MBITS%/mingw-w64-%MARCH%-pcre2 mingw%MBITS%/mingw-w64-%MARCH%-boost mingw%MBITS%/mingw-w64-%MARCH%-python"
- if not "%WITHLANG%"=="" set SWIGWITHLANG==%WITHLANG%
- if not "%WITHLANG%"=="" where %WITHLANG%
+- if "%SWIGLANG%"=="python" set PY3=3
+- if "%PY2%"=="2" set PY3=
- bash -c "which $CC"
- bash -c "which $CXX"
- bash -c "$CC --version | head -n 1"
@@ -148,15 +169,18 @@ install:
build_script:
- set CCCL_OPTIONS=--cccl-muffle /W3 /EHsc
- set CHECK_OPTIONS=CSHARPOPTIONS=-platform:%Platform%
-- if "%BUILDSYSTEM%"=="cmake" cmake --version && cmake -G "Visual Studio 14 2015%VSARCH%" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install2" -DCMAKE_C_FLAGS="/WX /DPCRE_STATIC" -DCMAKE_CXX_FLAGS="/WX /DPCRE_STATIC" -DPCRE_INCLUDE_DIR=%PCRE_ROOT%/include -DPCRE_LIBRARY=%PCRE_ROOT%/lib/v110/%PCRE_PLATFORM%/Release/static/utf8/pcre8.lib -DBISON_EXECUTABLE=C:/cygwin/bin/bison.exe . && cmake --build . --config Release --target install && ctest --output-on-failure -V -C Release && appveyor exit
+- if "%BUILDSYSTEM%"=="cmake" cd pcre2-pcre2-10.39 && cmake -G "Visual Studio 14 2015%VSARCH%" -DCMAKE_INSTALL_PREFIX="%PCRE_ROOT:\=/%" . && cmake --build . --config Release --target install && cd ..
+- if "%BUILDSYSTEM%"=="cmake" cmake --version && cmake -G "Visual Studio 14 2015%VSARCH%" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install2" -DCMAKE_C_FLAGS="/WX /DPCRE2_STATIC" -DCMAKE_CXX_FLAGS="/WX /DPCRE2_STATIC" -DPCRE2_INCLUDE_DIR=%PCRE_ROOT%/include -DPCRE2_LIBRARY=%PCRE_ROOT%/lib/pcre2-8-static.lib -DBISON_EXECUTABLE=C:/cygwin/bin/bison.exe . && cmake --build . --config Release --target install && ctest --output-on-failure -V -C Release && appveyor exit
+- if "%OSVARIANT%"=="" bash -c "exec 0</dev/null && cd pcre2-pcre2-10.39 && ./autogen.sh && ./configure CC=$CC CXX=$CXX CFLAGS='-O2' LDFLAGS='--cccl-link /LTCG' --prefix=%PCRE_ROOT% --disable-shared && time make -s -j%MAKEJOBS% LN_S=cp && make install && cd .. && cp -v %PCRE_ROOT%/lib/libpcre2-8.lib %PCRE_ROOT%/lib/pcre2-8.lib"
# Open dummy file descriptor to fix error on cygwin: ./configure: line 560: 0: Bad file descriptor
-- if "%OSVARIANT%"=="" bash -c "exec 0</dev/null && ./autogen.sh && time ./configure --disable-dependency-tracking --disable-ccache --enable-cpp11-testing CC=$CC CXX=$CXX CFLAGS='-O2' CXXFLAGS='-O2' LDFLAGS='--cccl-link /LTCG' PCRE_CFLAGS='-I%PCRE_ROOT%/include -DPCRE_STATIC' PCRE_LIBS='-L%PCRE_ROOT%/lib/v110/%PCRE_PLATFORM%/Release/static/utf8 -lpcre8' --without-perl5 --without-go --with-boost=%BOOSTROOT% || cat config.log"
-- if not "%OSVARIANT%"=="" bash -c "exec 0</dev/null && ./autogen.sh && time ./configure CC=%CC% CXX=%CXX% --without-alllang --with-$SWIGLANG$PY3$SWIGWITHLANG --enable-cpp11-testing || cat config.log"
+- if "%OSVARIANT%"=="" bash -c "exec 0</dev/null && ./autogen.sh && time ./configure --disable-dependency-tracking --disable-ccache CC=$CC CXX=$CXX CFLAGS='-O2' CXXFLAGS='-O2' LDFLAGS='--cccl-link /LTCG' PCRE2_CFLAGS='-I%PCRE_ROOT%/include -DPCRE2_STATIC' PCRE2_LIBS='-L%PCRE_ROOT%/lib/ -lpcre2-8' --without-perl5 --without-go --with-boost=%BOOSTROOT% || cat config.log"
+- if not "%OSVARIANT%"=="" bash -c "exec 0</dev/null && ./autogen.sh && time ./configure CC=%CC% CXX=%CXX% --without-alllang --with-$SWIGLANG$PY3$SWIGWITHLANG || cat config.log"
- bash -c "time make -s -j%MAKEJOBS%"
test_script:
- set CCCL_OPTIONS=--cccl-muffle /W3 /EHsc
- .\swig.exe -version
+- .\swig.exe -pcreversion
- if not "%OSVARIANT%"=="" CCache\ccache-swig -V
- bash -c "file ./swig.exe"
- bash -c "make check-%SWIGLANG%-version"
diff --git a/configure.ac b/configure.ac
index 9bf45c765..f88004ab9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
dnl The macros which aren't shipped with the autotools are stored in the
dnl Tools/config directory in .m4 files.
-AC_INIT([swig],[4.1.0],[http://www.swig.org])
+AC_INIT([swig],[4.1.0],[https://www.swig.org])
AC_PREREQ([2.60])
AC_CONFIG_SRCDIR([Source/Swig/swig.h])
@@ -48,46 +48,47 @@ fi
dnl PCRE
AC_ARG_WITH([pcre],
[AS_HELP_STRING([--without-pcre],
- [Disable support for regular expressions using PCRE])],
+ [Disable support for regular expressions using PCRE2])],
[],
[with_pcre=yes])
-AC_MSG_CHECKING([whether to enable PCRE support])
+AC_MSG_CHECKING([whether to enable PCRE2 support])
AC_MSG_RESULT([$with_pcre])
dnl To make configuring easier, check for a locally built PCRE using the Tools/pcre-build.sh script
if test x"${with_pcre}" = xyes ; then
- AC_MSG_CHECKING([whether to use local PCRE])
+ AC_MSG_CHECKING([whether to use local PCRE2])
local_pcre_config=no
- if test -z $PCRE_CONFIG; then
- if test -f `pwd`/pcre/pcre-swig-install/bin/pcre-config; then
- PCRE_CONFIG=`pwd`/pcre/pcre-swig-install/bin/pcre-config
- local_pcre_config=$PCRE_CONFIG
+ if test -z "$PCRE2_CONFIG"; then
+ if test -f `pwd`/pcre/pcre-swig-install/bin/pcre2-config; then
+ PCRE2_CONFIG=`pwd`/pcre/pcre-swig-install/bin/pcre2-config
+ local_pcre_config=$PCRE2_CONFIG
fi
fi
AC_MSG_RESULT([$local_pcre_config])
fi
AS_IF([test "x$with_pcre" != xno],
- [AX_PATH_GENERIC([pcre],
+ [AX_PATH_GENERIC([pcre2],
[], dnl Minimal version of PCRE we need -- accept any
[], dnl custom sed script for version parsing is not needed
- [AC_DEFINE([HAVE_PCRE], [1], [Define if you have PCRE library])
- LIBS="$LIBS $PCRE_LIBS"
- CPPFLAGS="$CPPFLAGS $PCRE_CFLAGS"
+ [AC_DEFINE([HAVE_PCRE], [1], [Define if you have PCRE2 library])
+ LIBS="$LIBS $PCRE2_LIBS"
+ CPPFLAGS="$CPPFLAGS $PCRE2_CFLAGS"
],
[AC_MSG_FAILURE([
- Cannot find pcre-config script from PCRE (Perl Compatible Regular Expressions)
+ Cannot find pcre2-config script from PCRE2 (Perl Compatible Regular Expressions)
library package. This dependency is needed for configure to complete,
Either:
- - Install the PCRE developer package on your system (preferred approach).
- - Download the PCRE source tarball, build and install on your system
+ - Install the PCRE2 developer package on your system (preferred approach).
+ - Download the PCRE2 source tarball, build and install on your system
as you would for any package built from source distribution.
- - Use the Tools/pcre-build.sh script to build PCRE just for SWIG to statically
+ - Use the Tools/pcre-build.sh script to build PCRE2 just for SWIG to statically
link against. Run 'Tools/pcre-build.sh --help' for instructions.
- (quite easy and does not require privileges to install PCRE on your system)
+ (quite easy and does not require privileges to install PCRE2 on your system)
- Use configure --without-pcre to disable regular expressions support in SWIG
(not recommended).])
- ])
+ ],
+ [],[],[--libs8])
])
@@ -143,7 +144,7 @@ AC_MSG_CHECKING(LDSHARED)
if test -z "$LDSHARED"
then
case $host in
- *-*-aix*) LDSHARED="\$(srcdir)/ld_so_aix \$(CC)";;
+ *-*-aix*) LDSHARED="$CC -shared";;
*-*-cygwin* | *-*-mingw*)
if test "$GCC" = yes; then
LDSHARED="\$(CC) -shared"
@@ -281,20 +282,21 @@ fi
AC_MSG_RESULT($LINKFORSHARED)
# Optional CFLAGS used to silence/enhance compiler warnings on some platforms.
-AC_MSG_CHECKING(PLATCFLAGS)
+AC_MSG_CHECKING(CFLAGS to use for testing (PLATCFLAGS))
case $host in
*-*-solaris*) if test "$GCC" = yes
then PLATCFLAGS=
else PLATCFLAGS=
# else PLATCFLAGS="-errtags=yes" # Need more work as C examples use ld for linking
fi;;
+ *-*-aix*) PLATCFLAGS="$CFLAGS";;
*) PLATCFLAGS=
esac
AC_MSG_RESULT($PLATCFLAGS)
# Add switch if necessary to enable C++11 support - just for tests
-AC_ARG_ENABLE([cpp11-testing], AS_HELP_STRING([--enable-cpp11-testing], [enable C++11 testing if supported by compiler (default disabled)]), [enable_cpp11_testing=$enableval], [enable_cpp11_testing=no])
-AC_MSG_CHECKING([whether to attempt to enable C++11 testing])
+AC_ARG_ENABLE([cpp11-testing], AS_HELP_STRING([--disable-cpp11-testing], [disable C++11 and later C++ standards testing even if supported by compiler (default enabled)]), [enable_cpp11_testing=$enableval], [enable_cpp11_testing=yes])
+AC_MSG_CHECKING([whether to attempt to enable C++11 and later C++ standards testing])
AC_MSG_RESULT([$enable_cpp11_testing])
PLATCXXFLAGS="$PLATCFLAGS"
@@ -302,50 +304,65 @@ if test x"$enable_cpp11_testing" = xyes; then
CXX_SAVED=$CXX
CXXCPP_SAVED=$CXXCPP
- # Test for c++17
+ # Test for c++20
CXXCPP=" "
- AX_CXX_COMPILE_STDCXX(17, [noext], [optional])
- AC_MSG_CHECKING([whether C++17 and earlier testing is enabled])
- if test "$HAVE_CXX17" = "1"; then
+ AX_CXX_COMPILE_STDCXX(20, [noext], [optional])
+ AC_MSG_CHECKING([whether C++11 to C++20 testing is enabled])
+ if test "$HAVE_CXX20" = "1"; then
AC_MSG_RESULT([yes])
PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+ HAVE_CXX17="1"
HAVE_CXX14="1"
HAVE_CXX11="1"
else
AC_MSG_RESULT([no])
- # Test for c++14
+ # Test for c++17
CXXCPP=" "
- CXX=$CXX_SAVED
- AX_CXX_COMPILE_STDCXX(14, [noext], [optional])
- AC_MSG_CHECKING([whether C++14 and earlier testing is enabled])
- if test "$HAVE_CXX14" = "1"; then
+ AX_CXX_COMPILE_STDCXX(17, [noext], [optional])
+ AC_MSG_CHECKING([whether C++11 to C++17 testing is enabled])
+ if test "$HAVE_CXX17" = "1"; then
AC_MSG_RESULT([yes])
PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+ HAVE_CXX14="1"
HAVE_CXX11="1"
else
AC_MSG_RESULT([no])
- # Test for c++11
+ # Test for c++14
CXXCPP=" "
CXX=$CXX_SAVED
- AX_CXX_COMPILE_STDCXX(11, [noext], [optional])
- AC_MSG_CHECKING([whether C++11 and earlier testing is enabled])
- if test "$HAVE_CXX11" = "1"; then
+ AX_CXX_COMPILE_STDCXX(14, [noext], [optional])
+ AC_MSG_CHECKING([whether C++11 to C++14 testing is enabled])
+ if test "$HAVE_CXX14" = "1"; then
AC_MSG_RESULT([yes])
PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+ HAVE_CXX11="1"
else
AC_MSG_RESULT([no])
- fi
+ # Test for c++11
+ CXXCPP=" "
+ CXX=$CXX_SAVED
+ AX_CXX_COMPILE_STDCXX(11, [noext], [optional])
+ AC_MSG_CHECKING([whether C++11 testing is enabled])
+ if test "$HAVE_CXX11" = "1"; then
+ AC_MSG_RESULT([yes])
+ PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
fi
-
fi
CXX=$CXX_SAVED
CXXCPP=$CXXCPP_SAVED
fi
AC_SUBST(HAVE_CXX11)
+AC_SUBST(HAVE_CXX14)
+AC_SUBST(HAVE_CXX17)
+AC_SUBST(HAVE_CXX20)
# On darwin 10.7,10.8,10.9 using clang++, need to ensure using
# libc++ for tests and examples to run under mono. May affect
@@ -360,6 +377,10 @@ case $host in
*) ;;
esac
+AC_MSG_CHECKING(CXXFLAGS to use for testing (PLATCXXFLAGS))
+PLATCXXFLAGS=$(echo $PLATCXXFLAGS | xargs) # Trim whitespace
+AC_MSG_RESULT([$PLATCXXFLAGS])
+
# Check for compiler pre-compiled header support
AC_MSG_CHECKING([if compiler supports pre-compiled headers])
PCHSUPPORT=no
@@ -458,10 +479,6 @@ AC_SEARCH_LIBS(t_open, nsl) # SVR4
AC_SEARCH_LIBS(gethostbyname, inet) # Sequent
AC_SEARCH_LIBS(socket, socket) # SVR4 sockets
-AC_CHECK_LIB(swill, swill_init, [SWIGLIBS="-lswill $LIBS" SWILL="-DSWIG_SWILL"])
-AC_SUBST(SWIGLIBS)
-AC_SUBST(SWILL)
-
# check for --with-libm=...
AC_SUBST(LIBM)
LIBM=-lm
@@ -496,799 +513,415 @@ fi
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
-#--------------------------------------------------------------------
-# Look for Tcl
-#--------------------------------------------------------------------
-
-TCLINCLUDE=
-TCLLIB=
-TCLPACKAGE=
-TCLLINK=
+#----------------------------------------------------------------
+# Look for Android
+#----------------------------------------------------------------
-AC_ARG_WITH(tclconfig, AS_HELP_STRING([--without-tcl], [Disable Tcl])
-AS_HELP_STRING([--with-tclconfig=path], [Set location of tclConfig.sh]), [with_tclconfig="$withval"], [with_tclconfig=])
-AC_ARG_WITH(tcl,
- [ --with-tcl=path Set location of Tcl package],[
- TCLPACKAGE="$withval"], [TCLPACKAGE="$alllang_default"])
-AC_ARG_WITH(tclincl,[ --with-tclincl=path Set location of Tcl include directory],[
- TCLINCLUDE="-I$withval"], [TCLINCLUDE=])
-AC_ARG_WITH(tcllib,[ --with-tcllib=path Set location of Tcl library directory],[
- TCLLIB="-L$withval"], [TCLLIB=])
+AC_ARG_WITH(android, AS_HELP_STRING([--without-android], [Disable Android])
+AS_HELP_STRING([--with-android=path], [Set location of android executable]),[ANDROIDBIN="$withval"], [ANDROIDBIN="$alllang_default"])
+AC_ARG_WITH(adb, [ --with-adb=path Set location of adb executable - Android Debug Bridge],[ADBBIN="$withval"], [ADBBIN=])
+AC_ARG_WITH(ant, [ --with-ant=path Set location of ant executable for Android],[ANTBIN="$withval"], [ANTBIN=])
+AC_ARG_WITH(ndk-build, [ --with-ndk-build=path Set location of Android ndk-build executable],[NDKBUILDBIN="$withval"], [NDKBUILDBIN=])
-# First, check for "--without-tcl" or "--with-tcl=no".
-if test x"${TCLPACKAGE}" = xno; then
-AC_MSG_NOTICE([Disabling Tcl])
-else
-AC_MSG_CHECKING([for Tcl configuration])
-# First check to see if --with-tclconfig was specified.
-if test x"${with_tclconfig}" != x ; then
- if test -f "${with_tclconfig}/tclConfig.sh" ; then
- TCLCONFIG=`(cd ${with_tclconfig}; pwd)`
- else
- AC_MSG_ERROR([${with_tcl} directory does not contain tclConfig.sh])
- fi
-fi
-# check in a few common install locations
-dirs="/usr/lib*/ /usr/lib*/tcl*/ /usr/local/lib*/ /usr/local/lib*/tcl*/"
-case $host in
-*-*-darwin*)
- tcl_framework="/System/Library/Frameworks/Tcl.framework/"
- macos_sysroot="$(xcodebuild -version -sdk macosx Path 2>/dev/null)" # For MacOSX10.14 and later
- dirs="$macos_sysroot$tcl_framework $tcl_framework $dirs"
- ;;
-*)
- ;;
-esac
-if test x"${TCLCONFIG}" = x ; then
- for d in $dirs ; do
- for i in `ls -d -r $d 2>/dev/null` ; do
- if test -f $i"tclConfig.sh" ; then
- TCLCONFIG=`(cd $i; pwd)`
- break
- fi
- done
- done
-fi
-if test x"${TCLCONFIG}" = x ; then
- AC_MSG_RESULT(no)
+# First, check for "--without-android" or "--with-android=no".
+if test x"${ANDROIDBIN}" = xno; then
+ AC_MSG_NOTICE([Disabling Android])
+ ANDROID=
else
- AC_MSG_RESULT(found $TCLCONFIG/tclConfig.sh)
- . $TCLCONFIG/tclConfig.sh
- if test -z "$TCLINCLUDE"; then
- TCLINCLUDE=`echo $TCL_INCLUDE_SPEC`
- fi
- if test -z "$TCLLIB"; then
- TCLLIB=$TCL_LIB_SPEC
- fi
-fi
+ if test "x$ANDROIDBIN" = xyes; then
+ AC_CHECK_PROGS(ANDROID, android)
+ else
+ ANDROID="$ANDROIDBIN"
+ fi
-if test -z "$TCLINCLUDE"; then
- if test "x$TCLPACKAGE" != xyes; then
- TCLINCLUDE="-I$TCLPACKAGE/include"
- fi
-fi
+ if test -z "$ADBBIN"; then
+ AC_CHECK_PROGS(ADB, adb)
+ else
+ ADB="$ADBBIN"
+ fi
-if test -z "$TCLLIB"; then
- if test "x$TCLPACKAGE" != xyes; then
- TCLLIB="-L$TCLPACKAGE/lib -ltcl"
- fi
-fi
+ if test -z "$ANTBIN"; then
+ AC_CHECK_PROGS(ANT, ant)
+ else
+ ANT="$ANTBIN"
+ fi
-AC_MSG_CHECKING(for Tcl header files)
-if test -z "$TCLINCLUDE"; then
-AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <tcl.h>]])],[],[TCLINCLUDE=""])
-if test -z "$TCLINCLUDE"; then
- dirs="/usr/local/include /usr/include /opt/local/include"
- for i in $dirs ; do
- if test -r $i/tcl.h; then
- AC_MSG_RESULT($i)
- TCLINCLUDE="-I$i"
- break
- fi
- done
-fi
-if test -z "$TCLINCLUDE"; then
- AC_MSG_RESULT(not found)
+ if test -z "$NDKBUILDBIN"; then
+ AC_CHECK_PROGS(NDKBUILD, ndk-build)
+ else
+ NDKBUILD="$NDKBUILDBIN"
+ fi
fi
+
+AC_SUBST(ANDROID)
+AC_SUBST(ADB)
+AC_SUBST(ANT)
+AC_SUBST(NDKBUILD)
+
+#----------------------------------------------------------------
+# Look for C#
+#----------------------------------------------------------------
+
+AC_ARG_WITH(csharp, AS_HELP_STRING([--without-csharp], [Disable CSharp]), [with_csharp="$withval"], [with_csharp="$alllang_default"])
+AC_ARG_WITH(cil-interpreter, [ --with-cil-interpreter=path Set location of CIL interpreter for CSharp],[CSHARPBIN="$withval"], [CSHARPBIN=])
+AC_ARG_WITH(csharp-compiler, [ --with-csharp-compiler=path Set location of CSharp compiler],[CSHARPCOMPILERBIN="$withval"], [CSHARPCOMPILERBIN=])
+
+# First, check for "--without-csharp" or "--with-csharp=no".
+if test x"${with_csharp}" = xno; then
+AC_MSG_NOTICE([Disabling CSharp])
+CSHARPCOMPILER=
else
- AC_MSG_RESULT($TCLINCLUDE)
-fi
-AC_MSG_CHECKING(for Tcl library)
-if test -z "$TCLLIB"; then
-dirs="/usr/local/lib /usr/lib /opt/local/lib /opt/freeware/lib"
-for i in $dirs ; do
- if test -r $i/libtcl.a; then
- AC_MSG_RESULT($i)
- TCLLIB="-L$i -ltcl"
- break
- fi
-done
-if test -z "$TCLLIB"; then
- AC_MSG_RESULT(not found)
+if test -z "$CSHARPCOMPILERBIN" ; then
+ case $host in
+ *-*-cygwin* | *-*-mingw*)
+ # prefer unified Mono mcs compiler (not to be confused with the ancient .NET 1 mcs) over older/alternative names.
+ AC_CHECK_PROGS(CSHARPCOMPILER, csc mcs mono-csc gmcs cscc)
+ if test -n "$CSHARPCOMPILER" && test "$CSHARPCOMPILER" = "csc" ; then
+ AC_MSG_CHECKING(whether csc is the Microsoft CSharp compiler)
+ csc 2>/dev/null | grep "C#" > /dev/null || CSHARPCOMPILER=""
+ if test -z "$CSHARPCOMPILER" ; then
+ AC_MSG_RESULT(no)
+ AC_CHECK_PROGS(CSHARPCOMPILER, mcs mono-csc gmcs cscc)
+ else
+ AC_MSG_RESULT(yes)
+ fi
+ fi
+ ;;
+ *)AC_CHECK_PROGS(CSHARPCOMPILER, mono-csc gmcs mcs cscc);;
+ esac
+else
+ CSHARPCOMPILER="$CSHARPCOMPILERBIN"
fi
+
+CSHARPCONVERTPATH="Tools/convertpath -u"
+if test -z "$CSHARPBIN" ; then
+ CSHARPCILINTERPRETER=""
+ CSHARPCILINTERPRETER_FLAGS=""
+ if test "cscc" = "$CSHARPCOMPILER" ; then
+ AC_CHECK_PROGS(CSHARPCILINTERPRETER, ilrun)
+ else
+ if test "mcs" = "$CSHARPCOMPILER"; then
+ # Check that mcs is the C# compiler and not the Unix mcs utility by examining the output of 'mcs --version'
+ # The Mono compiler should emit: Mono C# compiler version a.b.c.d
+ csharp_version_raw=`(mcs --version) 2>/dev/null`
+ csharp_version_searched=`(mcs --version | sed -e "/C#/b" -e "/Mono/b" -e d) 2>/dev/null` # return string if contains 'Mono' or 'C#'
+ CSHARPCOMPILER=""
+ if test -n "$csharp_version_raw" ; then
+ if test "$csharp_version_raw" = "$csharp_version_searched" ; then
+ CSHARPCOMPILER="mcs"
+ fi
+ fi
+ if test "mcs" != "$CSHARPCOMPILER" ; then
+ echo "mcs is not a working Mono C# compiler"
+ fi
+ fi
+ if test "mcs" = "$CSHARPCOMPILER" || test "gmcs" = "$CSHARPCOMPILER" || test "mono-csc" = "$CSHARPCOMPILER"; then
+ AC_CHECK_PROGS(CSHARPCILINTERPRETER, mono) # Mono JIT
+ CSHARPCILINTERPRETER_FLAGS="--debug"
+ else
+ if test "csc" = "$CSHARPCOMPILER"; then
+ CSHARPCONVERTPATH="Tools/convertpath -w"
+ fi
+ fi
+ fi
else
-AC_MSG_RESULT($TCLLIB)
+ CSHARPCILINTERPRETER="$CSHARPBIN"
fi
-# Cygwin (Windows) needs the library for dynamic linking
+# Cygwin requires the Windows standard (Pascal) calling convention as it is a Windows executable and not a Cygwin built executable
case $host in
-*-*-cygwin* | *-*-mingw*) TCLDYNAMICLINKING="$TCLLIB";;
-*-*-aix*) TCLDYNAMICLINKING="$TCLLIB";;
-*)TCLDYNAMICLINKING="";;
+*-*-cygwin* | *-*-mingw*)
+ if test "$GCC" = yes; then
+ CSHARPDYNAMICLINKING="$GCC_MNO_CYGWIN -mthreads -Wl,--add-stdcall-alias"
+ CSHARPCFLAGS="$GCC_MNO_CYGWIN -mthreads"
+ else
+ CSHARPDYNAMICLINKING=""
+ CSHARPCFLAGS=""
+ fi ;;
+*)
+ CSHARPDYNAMICLINKING=""
+ CSHARPCFLAGS=""
+ ;;
esac
-# AIX needs -ltcl for linking at test time
+# CSharp on Windows platforms including Cygwin doesn't use libname.dll, rather name.dll when loading dlls
case $host in
-*-*-aix*) TCLLINK="-ltcl";;
-*)TCLLINK="";;
+*-*-cygwin* | *-*-mingw*) CSHARPLIBRARYPREFIX="";;
+*)CSHARPLIBRARYPREFIX="lib";;
esac
+# C#/Mono on Mac OS X tweaks
case $host in
*-*-darwin*)
- TCLLDSHARED='$(CC) -dynamiclib -undefined suppress -flat_namespace'
- TCLCXXSHARED='$(CXX) -dynamiclib -undefined suppress -flat_namespace'
+ CSHARPSO=".so"
;;
*)
- TCLLDSHARED='$(LDSHARED)'
- TCLCXXSHARED='$(CXXSHARED)'
+ CSHARPSO=$SO
;;
esac
-
fi
-AC_SUBST(TCLINCLUDE)
-AC_SUBST(TCLLIB)
-AC_SUBST(TCLDYNAMICLINKING)
-AC_SUBST(TCLLDSHARED)
-AC_SUBST(TCLCXXSHARED)
-AC_SUBST(TCLLINK)
+AC_SUBST(CSHARPCILINTERPRETER_FLAGS)
+AC_SUBST(CSHARPCILINTERPRETER)
+AC_SUBST(CSHARPCONVERTPATH)
+AC_SUBST(CSHARPCOMPILER)
+AC_SUBST(CSHARPDYNAMICLINKING)
+AC_SUBST(CSHARPLIBRARYPREFIX)
+AC_SUBST(CSHARPCFLAGS)
+AC_SUBST(CSHARPSO)
#----------------------------------------------------------------
-# Look for Python
+# Look for D
#----------------------------------------------------------------
-PYINCLUDE=
-PYLIB=
-PYLINK=
-PYPACKAGE=
+AC_ARG_WITH(d, AS_HELP_STRING([--without-d], [Disable D]), [with_d="$withval"], [with_d="$alllang_default"])
+AC_ARG_WITH(d1-compiler, [ --with-d1-compiler=path Set location of D1/Tango compiler (DMD compatible)],[D1COMPILERBIN="$withval"], [D1COMPILERBIN=])
+AC_ARG_WITH(d2-compiler, [ --with-d2-compiler=path Set location of D2 compiler (DMD compatible)],[D2COMPILERBIN="$withval"], [D2COMPILERBIN=])
-AC_ARG_WITH(python, AS_HELP_STRING([--without-python], [Disable Python])
-AS_HELP_STRING([--with-python=path], [Set location of Python executable]),[ PYBIN="$withval"], [PYBIN="$alllang_default"])
-# First, check for "--without-python" or "--with-python=no".
-if test x"${PYBIN}" = xno; then
- AC_MSG_NOTICE([Disabling Python])
+# First, check for "--without-d" or "--with-d=no".
+if test x"${with_d}" = xno; then
+ AC_MSG_NOTICE([Disabling D])
+ D1COMPILER=
+ D2COMPILER=
else
- # First figure out the name of the Python executable
- if test "x$PYBIN" = xyes; then
- AC_CHECK_PROGS(PYTHON, [python python2.7])
- else
- PYTHON="$PYBIN"
- fi
+ old_ac_ext=$ac_ext
+ ac_ext=d
- PYVER=0
- if test -n "$PYTHON"; then
- AC_MSG_CHECKING([for $PYTHON major version number])
- PYVER=`($PYTHON -c "import sys; sys.stdout.write(sys.version[[0]])") 2>/dev/null`
- AC_MSG_RESULT($PYVER)
- if test -z "$PYVER"; then
- PYVER=0
- else
- AC_MSG_CHECKING(for Python os.name)
- PYOSNAME=`($PYTHON -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
- AC_MSG_RESULT($PYOSNAME)
- AC_MSG_CHECKING(for Python path separator)
- PYSEPARATOR=`($PYTHON -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
- AC_MSG_RESULT($PYSEPARATOR)
+ if test -z "$D1COMPILERBIN" ; then
+ AC_CHECK_PROGS(D1COMPILER, dmd ldmd gdmd)
+
+ if test -n "$D1COMPILER" ; then
+ AC_MSG_CHECKING(whether the D1/Tango compiler works)
+ cat > conftest.$ac_ext <<_ACEOF
+import tango.io.Stdout;
+void main() {
+}
+_ACEOF
+ rm -f conftest.$ac_objext
+ AS_IF(
+ [$D1COMPILER conftest.$ac_ext 2>&AS_MESSAGE_LOG_FD && test ! -s conftest.err && test -s conftest.$ac_objext],
+ [AC_MSG_RESULT([yes])],
+ [_AC_MSG_LOG_CONFTEST AC_MSG_RESULT([no])
+ D1COMPILER=]
+ )
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
+ else
+ D1COMPILER="$D1COMPILERBIN"
fi
- if test $PYVER -eq 1 -o $PYVER -eq 2; then
- AC_MSG_CHECKING(for Python prefix)
- PYPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
- AC_MSG_RESULT($PYPREFIX)
- AC_MSG_CHECKING(for Python exec-prefix)
- PYEPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)") 2>/dev/null`
- AC_MSG_RESULT($PYEPREFIX)
-
- if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
- # Windows installations are quite different to posix installations (MinGW path separator is a forward slash)
- PYPREFIX=`echo "$PYPREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
- PYTHON_SO=.pyd
-
- AC_MSG_CHECKING(for Python header files)
- if test -r $PYPREFIX/include/Python.h; then
- PYINCLUDE="-I$PYPREFIX/include"
- fi
- AC_MSG_RESULT($PYINCLUDE)
-
- AC_MSG_CHECKING(for Python library directory)
- if test -d $PYPREFIX/libs; then
- PYLIB=$PYPREFIX/libs
- PYLINKFILE=`ls $PYLIB/python*.lib | grep "python[[0-9]][[0-9]]\.lib"`
- if test -r "$PYLINKFILE"; then
- PYLINK=-l`basename $PYLINKFILE | sed -e 's/\.lib$//'`
- else
- PYLIB=
- fi
- fi
- else
- # Note: I could not think of a standard way to get the version string from different versions.
- # This trick pulls it out of the file location for a standard library file.
-
- AC_MSG_CHECKING(for Python version)
-
- # Need to do this hack since autoconf replaces __file__ with the name of the configure file
- filehack="file__"
- PYVERSION=`($PYTHON -c "import sys,string,operator,os.path; sys.stdout.write(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
- AC_MSG_RESULT($PYVERSION)
-
- # Find the directory for libraries this is necessary to deal with
- # platforms that can have apps built for multiple archs: e.g. x86_64
- AC_MSG_CHECKING(for Python lib dir)
- PYLIBDIR=`($PYTHON -c "import sys; sys.stdout.write(sys.lib)") 2>/dev/null`
- if test -z "$PYLIBDIR"; then
- # Fedora patch Python to add sys.lib, for other distros we assume "lib".
- PYLIBDIR="lib"
- fi
- AC_MSG_RESULT($PYLIBDIR)
-
- # Set the include directory
-
- AC_MSG_CHECKING(for Python header files)
- if test -r $PYPREFIX/include/$PYVERSION/Python.h; then
- PYINCLUDE="-I$PYPREFIX/include/$PYVERSION -I$PYEPREFIX/$PYLIBDIR/$PYVERSION/config"
- fi
- if test -z "$PYINCLUDE"; then
- if test -r $PYPREFIX/include/Py/Python.h; then
- PYINCLUDE="-I$PYPREFIX/include/Py -I$PYEPREFIX/$PYLIBDIR/python/lib"
- fi
- fi
- AC_MSG_RESULT($PYINCLUDE)
-
- # Set the library directory blindly. This probably won't work with older versions
- AC_MSG_CHECKING(for Python library directory)
- dirs="$PYVERSION/config $PYVERSION/$PYLIBDIR python/$PYLIBDIR"
- for i in $dirs; do
- if test -d $PYEPREFIX/$PYLIBDIR/$i; then
- PYLIB="$PYEPREFIX/$PYLIBDIR/$i"
- break
- fi
- done
-
- PYLINK="-l$PYVERSION"
- fi
+ if test -z "$D2COMPILERBIN" ; then
+ AC_CHECK_PROGS(D2COMPILER, dmd gdmd ldmd2 ldc2)
- if test -z "$PYLIB"; then
- AC_MSG_RESULT(Not found)
- else
- AC_MSG_RESULT($PYLIB)
- fi
- AC_MSG_CHECKING(for Python library)
- if test -z "$PYLINK"; then
- AC_MSG_RESULT(Not found)
- else
- AC_MSG_RESULT($PYLINK)
+ if test -n "$D2COMPILER" ; then
+ AC_MSG_CHECKING(whether the D2 compiler works)
+ cat > conftest.$ac_ext <<_ACEOF
+import std.algorithm;
+void main() {
+}
+_ACEOF
+ rm -f conftest.$ac_objext
+ AS_IF(
+ [$D2COMPILER conftest.$ac_ext 2>&AS_MESSAGE_LOG_FD && test ! -s conftest.err && test -s conftest.$ac_objext],
+ [AC_MSG_RESULT([yes])],
+ [_AC_MSG_LOG_CONFTEST AC_MSG_RESULT([no])
+ D2COMPILER=]
+ )
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
+ else
+ D2COMPILER="$D2COMPILERBIN"
fi
- # Cygwin (Windows) needs the library for dynamic linking
- case $host in
- *-*-cygwin* | *-*-mingw*)
- PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK"
- DEFS="-DUSE_DL_IMPORT $DEFS"
- ;;
- *)PYTHONDYNAMICLINKING="";;
- esac
+ ac_ext=$old_ac_ext
fi
-AC_SUBST(PYINCLUDE)
-AC_SUBST(PYLIB)
-AC_SUBST(PYLINK)
-AC_SUBST(PYTHONDYNAMICLINKING)
+if test -n "$D1COMPILER"; then
+ DDEFAULTVERSION=1
+elif test -n "$D2COMPILER"; then
+ DDEFAULTVERSION=2
+fi
+# Do not prefix library file names with "lib" on Windows.
+case $host in
+*-*-cygwin* | *-*-mingw*) DLIBPREFIX="";;
+*)DLIBPREFIX="lib";;
+esac
+
+AC_SUBST(D1COMPILER)
+AC_SUBST(D2COMPILER)
+AC_SUBST(DDEFAULTVERSION)
+AC_SUBST(DLIBPREFIX)
#----------------------------------------------------------------
-# Look for Python 3.x
+# Look for Go compilers
#----------------------------------------------------------------
-PY3INCLUDE=
-PY3LIB=
-PY3LINK=
-PY3PACKAGE=
-
-AC_ARG_WITH(python3, AS_HELP_STRING([--without-python3], [Disable Python 3.x support])
-AS_HELP_STRING([--with-python3=path], [Set location of Python 3.x executable]),[ PY3BIN="$withval"], [PY3BIN="$alllang_default"])
+AC_ARG_WITH(go, AS_HELP_STRING([--without-go], [Disable Go])
+AS_HELP_STRING([--with-go=path], [Set location of Go compiler]),[GOBIN="$withval"], [GOBIN="$alllang_default"])
-# First, check for "--without-python3" or "--with-python3=no".
-if test x"${PY3BIN}" = xno; then
- AC_MSG_NOTICE([Disabling Python 3.x support])
+if test x"${GOBIN}" = xno; then
+ AC_MSG_NOTICE([Disabling Go])
+ GO=
+ GOGCC=false
+ GCCGO=
+ GOOPT=
+ GCCGOOPT=
+ GOVERSIONOPTION=
else
- if test -z "$PYVER"; then
- PYVER=0
- fi
- if test "x$PY3BIN" = xyes; then
- if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\" -a $PYVER -ge 3; then
- PYTHON3="$PYTHON"
- else
- for py_ver in 3 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 ""; do
- AC_CHECK_PROGS(PYTHON3, [python$py_ver])
- if test -n "$PYTHON3"; then
- AC_CHECK_PROGS(PY3CONFIG, [$PYTHON3-config])
- if test -n "$PY3CONFIG"; then
- break
- fi
- fi
- done
- fi
- else
- PYTHON3="$PY3BIN"
- AC_CHECK_PROGS(PY3CONFIG, [$PYTHON3-config])
- fi
- if test -n "$PYTHON3"; then
- AC_MSG_CHECKING([for $PYTHON3 major version number])
- PYVER=`($PYTHON3 -c "import sys; sys.stdout.write(sys.version[[0]])") 2>/dev/null`
- AC_MSG_RESULT($PYVER)
- if test -z "$PYVER"; then
- PYVER=0
- fi
+ if test "x$GOBIN" = xyes; then
+ AC_CHECK_PROGS(GO, go)
+ else
+ GO="$GOBIN"
fi
- if test $PYVER -ge 3; then
- AC_MSG_CHECKING(for Python 3.x os.name)
- PY3OSNAME=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
- AC_MSG_RESULT($PY3OSNAME)
- AC_MSG_CHECKING(for Python 3.x path separator)
- PYSEPARATOR=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
- AC_MSG_RESULT($PYSEPARATOR)
+ GOGCC=false
+ GCCGO=
+ GOOPT=
+ GCCGOOPT=
+ GOVERSIONOPTION=
- if test x"$PY3OSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
- # Windows installations are quite different to posix installations
- # There is no python-config to use
- AC_MSG_CHECKING(for Python 3.x prefix)
- PY3PREFIX=`($PYTHON3 -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
- AC_MSG_RESULT($PY3PREFIX)
- PY3PREFIX=`echo "$PY3PREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
- PYTHON_SO=.pyd
+ if test -n "$GO" ; then
+ GOVERSIONOPTION=version
+ go_version=$($GO $GOVERSIONOPTION | sed -e 's/go version //')
+ AC_MSG_CHECKING([whether go version is too old])
+ case $go_version in
+ go1.[012]*)
+ AC_MSG_RESULT([yes - minimum version is 1.3])
+ GO=
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+ fi
- AC_MSG_CHECKING(for Python 3.x header files)
- if test -r $PY3PREFIX/include/Python.h; then
- PY3INCLUDE="-I$PY3PREFIX/include"
- fi
- AC_MSG_RESULT($PY3INCLUDE)
+ AC_CHECK_PROGS(GCCGO, gccgo)
- AC_MSG_CHECKING(for Python 3.x library directory)
- if test -d $PY3PREFIX/libs; then
- PY3LIB=$PY3PREFIX/libs
- PY3LINKFILE=`ls $PY3LIB/python*.lib | grep "python[[0-9]][[0-9]]\.lib"`
- if test -r "$PY3LINKFILE"; then
- PY3LINK=-l`basename $PY3LINKFILE | sed -e 's/\.lib$//'`
- else
- PY3LIB=
- fi
- fi
- if test -z "$PY3LIB"; then
- AC_MSG_RESULT([Not found])
- else
- AC_MSG_RESULT($PY3LIB)
- fi
- AC_MSG_CHECKING([for Python 3.x library])
- if test -z "$PY3LINK"; then
- AC_MSG_RESULT(Not found)
+ if test -n "$GCCGO" ; then
+ if $GCCGO --help 2>/dev/null | grep gccgo >/dev/null 2>&1 ; then
+ AC_MSG_CHECKING([whether gccgo version is too old])
+ go_version=[`$GO $GOVERSIONOPTION | sed -n '1p' | sed -e 's/^.* \([0-9.]*\) *$/\1/' -e 's/[.]//g'`]
+ if test "x$go_version" = x; then
+ AC_MSG_RESULT([could not determine gccgo version])
+ GCCGO=
+ elif test "$go_version" -lt 470; then
+ AC_MSG_RESULT([yes - minimum version is 4.7.0])
+ GCCGO=
else
- AC_MSG_RESULT($PY3LINK)
- fi
- elif test -n "$PY3CONFIG"; then
- AC_MSG_CHECKING([for Python 3.x prefix])
- PY3PREFIX=`($PY3CONFIG --prefix) 2>/dev/null`
- AC_MSG_RESULT($PY3PREFIX)
- AC_MSG_CHECKING(for Python 3.x exec-prefix)
- # Piped through xargs to strip trailing whitespace (bug in msys2 + mingw Python)
- PY3EPREFIX=`($PY3CONFIG --exec-prefix | xargs) 2>/dev/null`
- AC_MSG_RESULT($PY3EPREFIX)
-
- # Note: I could not think of a standard way to get the version string from different versions.
- # This trick pulls it out of the file location for a standard library file.
-
- AC_MSG_CHECKING([for Python 3.x version])
-
- # Need to do this hack since autoconf replaces __file__ with the name of the configure file
- filehack="file__"
- PY3VERSION=`($PYTHON3 -c "import string,operator,os.path; print(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
- AC_MSG_RESULT($PY3VERSION)
-
- # Find the directory for libraries this is necessary to deal with
- # platforms that can have apps built for multiple archs: e.g. x86_64
- AC_MSG_CHECKING([for Python 3.x lib dir])
- PY3LIBDIR=`($PYTHON3 -c "import sys; print(sys.lib)") 2>/dev/null`
- if test -z "$PY3LIBDIR"; then
- # some dists don't have sys.lib so the best we can do is assume lib
- PY3LIBDIR="lib"
- fi
- AC_MSG_RESULT($PY3LIBDIR)
-
- # Set the include directory
-
- AC_MSG_CHECKING([for Python 3.x header files])
- PY3INCLUDE=`($PY3CONFIG --includes) 2>/dev/null`
- AC_MSG_RESULT($PY3INCLUDE)
-
- # Set the library directory blindly. This probably won't work with older versions
- AC_MSG_CHECKING([for Python 3.x library directory])
- dirs="$PY3VERSION/config $PY3VERSION/$PY3LIBDIR python/$PY3LIBDIR"
- for i in $dirs; do
- if test -d $PY3EPREFIX/$PY3LIBDIR/$i; then
- PY3LIB="$PY3EPREFIX/$PY3LIBDIR/$i"
- break
+ AC_MSG_RESULT([no])
+ if test "$go_version" -lt 480; then
+ GCCGOOPT="-intgosize 32"
fi
- done
- if test -z "$PY3LIB"; then
- AC_MSG_RESULT([Not found])
- else
- AC_MSG_RESULT($PY3LIB)
- fi
-
- PY3LINK="-l$PY3VERSION"
-
- AC_MSG_CHECKING([for Python 3.x library])
- if test -z "$PY3LINK"; then
- AC_MSG_RESULT(Not found)
- else
- AC_MSG_RESULT($PY3LINK)
fi
fi
fi
-
- # Cygwin (Windows) needs the library for dynamic linking
- case $host in
- *-*-cygwin* | *-*-mingw*)
- PYTHON3DYNAMICLINKING="-L$PY3LIB $PY3LINK"
- DEFS="-DUSE_DL_IMPORT $DEFS"
- ;;
- *)PYTHON3DYNAMICLINKING="";;
- esac
-
- AC_SUBST(PY3INCLUDE)
- AC_SUBST(PY3LIB)
- AC_SUBST(PY3LINK)
- AC_SUBST(PYTHON3DYNAMICLINKING)
fi
-if test -n "$PYINCLUDE" || test -n "$PY3INCLUDE" ; then
- AC_CHECK_PROGS(PYCODESTYLE, pycodestyle)
- if test -n "$PYCODESTYLE"; then
- AC_MSG_CHECKING(pycodestyle version)
- pycodestyle_version=`$PYCODESTYLE --version 2>/dev/null`
- AC_MSG_RESULT($pycodestyle_version)
- fi
-fi
+AC_SUBST(GOGCC)
+AC_SUBST(GCCGO)
+AC_SUBST(GO)
+AC_SUBST(GOC)
+AC_SUBST(GO1)
+AC_SUBST(GO12)
+AC_SUBST(GO13)
+AC_SUBST(GO15)
+AC_SUBST(GOOPT)
+AC_SUBST(GCCGOOPT)
+AC_SUBST(GOVERSIONOPTION)
#----------------------------------------------------------------
-# Look for Perl5
+# Look for Guile
#----------------------------------------------------------------
-PERLBIN=
-
-AC_ARG_WITH(perl5, AS_HELP_STRING([--without-perl5], [Disable Perl5])
-AS_HELP_STRING([--with-perl5=path], [Set location of Perl5 executable]),[ PERLBIN="$withval"], [PERLBIN="$alllang_default"])
-
-# First, check for "--without-perl5" or "--with-perl5=no".
-if test x"${PERLBIN}" = xno; then
-AC_MSG_NOTICE([Disabling Perl5])
-PERL=
-else
+GUILE=
+GUILE_CFLAGS=
+GUILE_LIBS=
-# First figure out what the name of Perl5 is
+AC_ARG_WITH(guile-config, AS_HELP_STRING([--without-guile], [Disable Guile])
+AS_HELP_STRING([--with-guile-config=path], [Set location of guile-config]),[ GUILE_CONFIG="$withval"], [GUILE_CONFIG=])
+AC_ARG_WITH(guile,[ --with-guile=path Set location of Guile executable],[
+ GUILE="$withval"], [GUILE="$alllang_default"])
+AC_ARG_WITH(guile-cflags,[ --with-guile-cflags=cflags Set cflags required to compile against Guile],[
+ GUILE_CFLAGS="$withval"])
+AC_ARG_WITH(guile-libs,[ --with-guile-libs=ldflags Set ldflags needed to link with Guile],[
+ GUILE_LIBS="$withval"])
-if test "x$PERLBIN" = xyes; then
-AC_CHECK_PROGS(PERL, perl perl5.6.1 perl5.6.0 perl5.004 perl5.003 perl5.002 perl5.001 perl5 perl)
+# First, check for "--without-guile" or "--with-guile=no".
+if test x"${GUILE}" = xno; then
+ AC_MSG_NOTICE([Disabling Guile])
else
-PERL="$PERLBIN"
-fi
-
-
-# This could probably be simplified as for all platforms and all versions of Perl the following apparently should be run to get the compilation options:
-# perl -MExtUtils::Embed -e ccopts
-AC_MSG_CHECKING(for Perl5 header files)
-if test -n "$PERL"; then
- PERL5DIR=`($PERL -MConfig -le 'print $Config{archlibexp}') 2>/dev/null`
- if test -n "$PERL5DIR" ; then
- dirs="$PERL5DIR $PERL5DIR/CORE"
- PERL5EXT=none
- for i in $dirs; do
- if test -r $i/perl.h; then
- AC_MSG_RESULT($i)
- PERL5EXT="$i"
- break
- fi
- done
- if test "$PERL5EXT" = none; then
- PERL5EXT="$PERL5DIR/CORE"
- AC_MSG_RESULT(could not locate perl.h...using $PERL5EXT)
- fi
-
- AC_MSG_CHECKING(for Perl5 library)
- PERL5LIB=`($PERL -e 'use Config; $_=$Config{libperl}; s/^lib//; s/$Config{_a}$//; s/\.$Config{so}.*//; print $_, "\n"') 2>/dev/null`
- if test -z "$PERL5LIB" ; then
- AC_MSG_RESULT(not found)
- else
- AC_MSG_RESULT($PERL5LIB)
- fi
- AC_MSG_CHECKING(for Perl5 ccflags)
- PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//") 2>/dev/null`
- if test -z "$PERL5CCFLAGS" ; then
- AC_MSG_RESULT(not found)
- else
- AC_MSG_RESULT($PERL5CCFLAGS)
- fi
- AC_MSG_CHECKING(for Perl5 ccdlflags)
- PERL5CCDLFLAGS=`($PERL -e 'use Config; print $Config{ccdlflags}, "\n"') 2>/dev/null`
- if test -z "$PERL5CCDLFLAGS" ; then
- AC_MSG_RESULT(not found)
- else
- AC_MSG_RESULT($PERL5CCDLFLAGS)
- fi
- AC_MSG_CHECKING(for Perl5 cccdlflags)
- PERL5CCCDLFLAGS=`($PERL -e 'use Config; print $Config{cccdlflags}, "\n"') 2>/dev/null`
- if test -z "$PERL5CCCDLFLAGS" ; then
- AC_MSG_RESULT(not found)
- else
- AC_MSG_RESULT($PERL5CCCDLFLAGS)
- fi
- AC_MSG_CHECKING(for Perl5 ldflags)
- PERL5LDFLAGS=`($PERL -e 'use Config; print $Config{ldflags}, "\n"') 2>/dev/null`
- if test -z "$PERL5LDFLAGS" ; then
- AC_MSG_RESULT(not found)
- else
- AC_MSG_RESULT($PERL5LDFLAGS)
- fi
- AC_MSG_CHECKING(for Perl5 Test::More module) # For test-suite
- PERL5TESTMORE=`($PERL -e 'use Test::More; print "good";') 2>/dev/null`
- if test -z "$PERL5TESTMORE" ; then
- AC_MSG_RESULT(not found)
+ if test -z "$GUILE_CONFIG" ; then
+ AC_PATH_PROG(GUILE_CONFIG, guile-config)
+ fi
+ if test -n "$GUILE_CONFIG" ; then
+ if test x"$GUILE" = xyes; then
+ AC_MSG_CHECKING([for guile executable])
+ # Try extracting it via guile-config first. If it's defined there it's the most reliable result
+ GUILE="`$GUILE_CONFIG info guile 2>/dev/null`"
+ if test -n "$GUILE"; then
+ AC_MSG_RESULT([$GUILE])
else
- AC_MSG_RESULT(found)
+ AC_MSG_RESULT([not found via guile-config - constructing path])
+ AC_MSG_CHECKING([for guile bindir])
+ guile_bindir="`$GUILE_CONFIG info bindir`"
+ AC_MSG_RESULT([$guile_bindir])
+ GUILE="$guile_bindir/guile"
+ fi
+ if ! test -f "$GUILE" ; then
+ GUILE=
+ AC_PATH_PROG(GUILE, guile)
+ fi
+ if test -z "$GUILE" ; then
+ AC_MSG_WARN([no suitable guile executable found. Disabling Guile])
+ fi
fi
- else
- AC_MSG_RESULT(unable to determine perl5 configuration)
- PERL5EXT=$PERL5DIR
- fi
-else
- AC_MSG_RESULT(could not figure out how to run perl5)
-fi
-
-# Cygwin (Windows) needs the library for dynamic linking
-case $host in
-*-*-cygwin* | *-*-mingw*) PERL5DYNAMICLINKING="-L$PERL5EXT -l$PERL5LIB";;
-*)PERL5DYNAMICLINKING="";;
-esac
-fi
-
-AC_SUBST(PERL)
-AC_SUBST(PERL5EXT)
-AC_SUBST(PERL5DYNAMICLINKING)
-AC_SUBST(PERL5LIB)
-AC_SUBST(PERL5CCFLAGS)
-AC_SUBST(PERL5CCDLFLAGS)
-AC_SUBST(PERL5CCCDLFLAGS)
-AC_SUBST(PERL5LDFLAGS)
-
-#----------------------------------------------------------------
-# Look for Octave
-#----------------------------------------------------------------
-
-OCTAVEBIN=
-OCTAVE_SO=.oct
-
-AC_ARG_WITH(octave, AS_HELP_STRING([--without-octave], [Disable Octave])
-AS_HELP_STRING([--with-octave=path], [Set location of Octave executable]),[OCTAVEBIN="$withval"], [OCTAVEBIN="$alllang_default"])
-
-# Check for "--without-octave" or "--with-octave=no".
-if test x"${OCTAVEBIN}" = xno; then
- AC_MSG_NOTICE([Disabling Octave])
- OCTAVE=
-
-# Check for Octave; prefer command-line program "octave-cli" to (in newer versions) GUI program "octave"
-elif test "x$OCTAVEBIN" = xyes; then
- AC_PATH_PROG(OCTAVE, [octave-cli octave])
-
-else
- OCTAVE="$OCTAVEBIN"
-fi
-
-# Check if Octave works
-if test -n "$OCTAVE"; then
- AC_MSG_CHECKING([if ${OCTAVE} works])
- AS_IF([test "x`${OCTAVE} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/Octave, version/p'`" != x],[
- AC_MSG_RESULT([yes])
- ],[
- AC_MSG_RESULT([no])
- OCTAVE=
- ])
-fi
-
-# Check for required Octave helper program "mkoctfile"
-if test -n "$OCTAVE"; then
- AC_MSG_CHECKING([for mkoctfile])
- version_suffix=["`echo $OCTAVE | sed -e 's|.*\(-[0-9][0-9.]*\)$|\1|'`"]
- case $version_suffix in
- -*) ;;
- *) version_suffix="" ;;
- esac
- octave_directory=`dirname $OCTAVE`
- if test "$octave_directory" = "." ; then
- mkoctfile="mkoctfile${version_suffix}"
- else
- mkoctfile="${octave_directory}/mkoctfile${version_suffix}"
- fi
- AC_MSG_RESULT([${mkoctfile}])
- AC_MSG_CHECKING([if ${mkoctfile} works])
- mkoctfile="env - PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH ${mkoctfile}"
- AS_IF([test "x`${mkoctfile} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/mkoctfile, version/p'`" != x],[
- AC_MSG_RESULT([yes])
- ],[
- AC_MSG_RESULT([no])
- OCTAVE=
- ])
-fi
-
-# Check for Octave preprocessor/compiler/linker flags
-if test -n "$OCTAVE"; then
- AC_MSG_CHECKING([for Octave preprocessor flags])
- OCTAVE_CPPFLAGS=
- for var in CPPFLAGS INCFLAGS ALL_CXXFLAGS; do
- for flag in `${mkoctfile} -p ${var}`; do
- case ${flag} in
- -D*|-I*) OCTAVE_CPPFLAGS="${OCTAVE_CPPFLAGS} ${flag}";;
- *) ;;
- esac
- done
- done
- AC_MSG_RESULT([$OCTAVE_CPPFLAGS])
-
- AC_MSG_CHECKING([for Octave compiler flags])
- OCTAVE_CXXFLAGS=
- for var in CXX ALL_CXXFLAGS; do
- for flag in `${mkoctfile} -p ${var}`; do
- case ${flag} in
- -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
- *) ;;
- esac
- done
- done
- save_CXXFLAGS="${CXXFLAGS}"
- CXXFLAGS="-Werror -O0"
- AC_COMPILE_IFELSE([
- AC_LANG_PROGRAM([],[])
- ],[
- OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} -O0"
- ])
- CXXFLAGS="${save_CXXFLAGS}"
- AC_MSG_RESULT([$OCTAVE_CXXFLAGS])
-
- AC_MSG_CHECKING([for Octave linker flags])
- OCTAVE_LDFLAGS=
- for var in OCTLIBDIR; do
- OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`${mkoctfile} -p ${var}`
- done
- for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do
- OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`${mkoctfile} -p ${var}`
- done
- AC_MSG_RESULT([$OCTAVE_LDFLAGS])
-
-fi
-
-# Check for Octave options
-if test -n "$OCTAVE"; then
- for octave_opt in --no-window-system --silent --norc --no-history; do
- AC_MSG_CHECKING([if Octave option '${octave_opt}' is supported])
- octave_out=`${OCTAVE} ${octave_opt} /dev/null 2>&1 | sed -n '1p' | sed -n '/unrecognized/p'`
- AS_IF([test "x${octave_out}" = x],[
- AC_MSG_RESULT([yes])
- OCTAVE="${OCTAVE} ${octave_opt}"
- ],[
- AC_MSG_RESULT([no])
- ])
- done
-fi
-
-AC_SUBST(OCTAVE)
-AC_SUBST(OCTAVE_SO)
-AC_SUBST(OCTAVE_CPPFLAGS)
-AC_SUBST(OCTAVE_CXXFLAGS)
-AC_SUBST(OCTAVE_LDFLAGS)
-
-#----------------------------------------------------------------
-# Look for Scilab
-#----------------------------------------------------------------
-
-AC_ARG_WITH(scilab, AS_HELP_STRING([--without-scilab], [Disable Scilab])
-AS_HELP_STRING([--with-scilab=path], [Set location of Scilab executable]),[SCILABBIN="$withval"], [SCILABBIN="$alllang_default"])
-AC_ARG_WITH(scilab-inc, [ --with-scilab-inc=path Set location of Scilab include directory], [SCILABINCDIR="$withval"], [SCILABINCDIR=""])
-
-# First, check for "--without-scilab" or "--with-scilab=no".
-if test x"${SCILABBIN}" = xno; then
- AC_MSG_NOTICE([Disabling Scilab])
- SCILAB=
-else
- # Check for Scilab executable
- if test "x$SCILABBIN" = xyes; then
- AC_CHECK_PROGS(SCILAB, scilab)
- else
- AC_MSG_CHECKING(for scilab)
- if test -f "$SCILABBIN"; then
- AC_MSG_RESULT($SCILABBIN)
- SCILAB="$SCILABBIN"
- else
- AC_MSG_RESULT(not found)
+ if test -n "$GUILE" ; then
+ AC_MSG_CHECKING([for guile version])
+ guile_version=`$GUILE -c '(display (effective-version))'`
+ AC_MSG_RESULT([$guile_version])
+ AC_MSG_CHECKING([for guile version >= 1.8])
+ guile_good_version=`$GUILE -c '(if (>= (string->number (effective-version)) 1.8) (display "yes") (display "no"))'`
+ AC_MSG_RESULT([$guile_good_version])
+ if test x"$guile_good_version" != xyes ; then
+ AC_MSG_WARN([at least guile version 1.8 is required. Disabling Guile])
+ GUILE=
+ fi
fi
- fi
-
- if test -n "$SCILAB"; then
- # Check for Scilab version (needs api_scilab so needs version 5.3.3 or higher)
- SCILAB_FULL_VERSION=`$SCILAB -version | head -1 | sed -e 's|Scilab version \"\(.*\)\"|\1|g'`
-
- AC_MSG_CHECKING(Scilab version is 5.3.3 or higher)
- SCILAB_MAJOR_VERSION=`echo $SCILAB_FULL_VERSION | cut -d. -f1`
- SCILAB_MINOR_VERSION=`echo $SCILAB_FULL_VERSION | cut -d. -f2`
- SCILAB_MAINTENANCE_VERSION=`echo $SCILAB_FULL_VERSION | cut -d. -f3`
- SCILAB_VERSION="$SCILAB_MAJOR_VERSION$SCILAB_MINOR_VERSION$SCILAB_MAINTENANCE_VERSION"
- if test $SCILAB_VERSION -ge 533; then
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- SCILAB=
+ if test -n "$GUILE" ; then
+ # Test if guile-config and guile versions match. They should.
+ gc_version="`$GUILE_CONFIG --version 2>&1 | sed '1 s/.* //;q'`"
+ g_version="`$GUILE --version | sed '1 s/.* //;q'`"
+ if test "$gc_version" != "$g_version"; then
+ AC_MSG_WARN([different versions reported by $GUILE_CONFIG ($gc_version) and $GUILE ($g_version). Disabling Guile])
+ GUILE=
+ fi
fi
- if test -n "$SCILAB"; then
- # Set Scilab startup options depending on version
- AC_MSG_CHECKING(for Scilab startup options)
- SCILABOPT="-nwni -nb"
- if test $SCILAB_VERSION -ge 540; then
- SCILABOPT+=" -noatomsautoload"
- fi
- if test $SCILAB_VERSION -ge 600; then
- SCILABOPT+=" -quit"
+ if test -n "$GUILE" ; then
+ if test -z "$GUILE_CFLAGS" ; then
+ AC_MSG_CHECKING([for guile compile flags])
+ GUILE_CFLAGS="`$GUILE_CONFIG compile`" # Note that this can sometimes be empty
+ AC_MSG_RESULT([$GUILE_CFLAGS])
fi
- AC_MSG_RESULT($SCILABOPT)
- # Check for Scilab header files
- AC_MSG_CHECKING(for Scilab header files)
- if test "$SCILABINCDIR" != ""; then
- dirs="$SCILABINCDIR"
- elif test -n "$PKG_CONFIG "; then
- dirs=`$PKG_CONFIG scilab --cflags-only-I | sed -e 's/-I//g'`
- else
- dirs=""
- fi
- for i in $dirs; do
- if test -r $i/api_scilab.h; then
- AC_MSG_RESULT($i)
- SCILABINCLUDE="-I$i"
- break
- fi
- if test -r $i/scilab/api_scilab.h; then
- AC_MSG_RESULT($i/scilab)
- SCILABINCLUDE="-I$i/scilab"
- break
- fi
- done
- if test "$SCILABINCLUDE" = "" ; then
- AC_MSG_RESULT(not found)
- SCILAB=
+ if test -z "$GUILE_LIBS" ; then
+ AC_MSG_CHECKING([for guile link flags])
+ GUILE_LIBS="`$GUILE_CONFIG link`"
+ AC_MSG_RESULT([$GUILE_LIBS])
fi
fi
fi
fi
-AC_SUBST(SCILAB)
-AC_SUBST(SCILABINCLUDE)
-AC_SUBST(SCILABOPT)
-
+AC_SUBST(GUILE)
+AC_SUBST(GUILE_CFLAGS)
+AC_SUBST(GUILE_LIBS)
#----------------------------------------------------------------
# Look for java
@@ -1604,69 +1237,60 @@ else
fi
#----------------------------------------------------------------
- # Look for JavascriptCore (Webkit) settings (JSCOREINCDIR, JSCOREDYNAMICLINKING)
+ # Look for JavaScriptCore (Webkit) settings
#----------------------------------------------------------------
# check for include files
- AC_MSG_CHECKING(for JavaScriptCore/JavaScript.h)
- AC_ARG_WITH(jscoreinc, [ --with-jscoreinc=path Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=])
-
- JSCOREVERSION=
-
- if test -z "$JSCOREINCDIR"; then
- JSCOREINCDIR="/usr/include/ /usr/local/include/"
-
- # Add in default directory for JavaScriptCore headers for Linux and Mac OS X
- case $host in
- *-*-linux*)
- JSCOREINCDIR="/usr/include/webkit-1.0/ /usr/include/webkitgtk-1.0/ /usr/local/include/webkit-1.0/JavaScriptCore/ $JSCOREINCDIR"
- ;;
- *-*-darwin*)
- JSCOREINCDIR="/System/Library/Frameworks/JavaScriptCore.framework/Headers/ $JSCOREINCDIR"
- ;;
- *)
- ;;
- esac
- fi
-
- for d in $JSCOREINCDIR ; do
- if test -r "$d/JavaScriptCore/JavaScript.h" || test -r "$d/JavaScript.h" ; then
- AC_MSG_RESULT($d)
- JSCOREINCDIR=$d
- JSCOREINC=-I\"$d\"
- break
- fi
- done
-
- if test "$JSCOREINC" = "" ; then
- AC_MSG_RESULT(not found)
- fi
-
+ AC_ARG_WITH(jscoreinc, [ --with-jscoreinc=path Set location of JavaScriptCore/Webkit include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=])
# check for JavaScriptCore/Webkit libraries
AC_ARG_WITH(jscorelib,[ --with-jscorelib=path Set location of the JavaScriptCore/Webkit library directory],[JSCORELIB="-L$withval"], [JSCORELIB=])
- if test -z "$JSCORELIB" -a -n "$PKG_CONFIG "; then
- AC_MSG_CHECKING(for JavaScriptCore/Webkit library)
- if $PKG_CONFIG javascriptcoregtk-4.0 2>/dev/null ; then
- JSCORELIB=`$PKG_CONFIG --libs javascriptcoregtk-4.0`
- JSCOREINC=`$PKG_CONFIG --cflags-only-I javascriptcoregtk-4.0`
- JSCOREVERSION=`$PKG_CONFIG --modversion javascriptcoregtk-4.0`
- elif $PKG_CONFIG javascriptcoregtk-3.0 2>/dev/null ; then
- JSCORELIB=`$PKG_CONFIG --libs javascriptcoregtk-3.0`
- JSCOREINC=`$PKG_CONFIG --cflags-only-I javascriptcoregtk-3.0`
- JSCOREVERSION=`$PKG_CONFIG --modversion javascriptcoregtk-3.0`
- elif $PKG_CONFIG javascriptcoregtk-1.0 2>/dev/null ; then
- JSCORELIB=`$PKG_CONFIG --libs javascriptcoregtk-1.0`
- JSCOREVERSION=`$PKG_CONFIG --modversion javascriptcoregtk-1.0`
- fi
- if test -z "$JSCORELIB"; then
- AC_MSG_RESULT(not found)
- JSCENABLED=
- else
- AC_MSG_RESULT([$JSCORELIB])
- JSCOREDYNAMICLINKING="$JSCORELIB"
- JSCENABLED=1
+ JSCOREVERSION=
+
+ if test -z "$JSCOREINCDIR" -a -n "$JSCORELIB"; then
+ AC_MSG_ERROR([Either both or none of --with-jcoreinc --with-jscorelib should be specified])
+ elif test -n "$JSCOREINCDIR" -a -z "$JSCORELIB"; then
+ AC_MSG_ERROR([Either both or none of --with-jcoreinc --with-jscorelib should be specified])
+ elif test -z "$JSCOREINCDIR" -a -z "$JSCORELIB"; then
+ if test -z "$JSCORELIB" -a -n "$PKG_CONFIG "; then
+ AC_MSG_CHECKING(for JavaScriptCore/Webkit)
+ if $PKG_CONFIG javascriptcoregtk-4.1 2>/dev/null ; then
+ JSCORELIB=`$PKG_CONFIG --libs javascriptcoregtk-4.1`
+ JSCOREINC=`$PKG_CONFIG --cflags-only-I javascriptcoregtk-4.1`
+ JSCOREVERSION=`$PKG_CONFIG --modversion javascriptcoregtk-4.1`
+ elif $PKG_CONFIG javascriptcoregtk-4.0 2>/dev/null ; then
+ JSCORELIB=`$PKG_CONFIG --libs javascriptcoregtk-4.0`
+ JSCOREINC=`$PKG_CONFIG --cflags-only-I javascriptcoregtk-4.0`
+ JSCOREVERSION=`$PKG_CONFIG --modversion javascriptcoregtk-4.0`
+ elif $PKG_CONFIG javascriptcoregtk-3.0 2>/dev/null ; then
+ JSCORELIB=`$PKG_CONFIG --libs javascriptcoregtk-3.0`
+ JSCOREINC=`$PKG_CONFIG --cflags-only-I javascriptcoregtk-3.0`
+ JSCOREVERSION=`$PKG_CONFIG --modversion javascriptcoregtk-3.0`
+ elif $PKG_CONFIG javascriptcoregtk-1.0 2>/dev/null ; then
+ JSCORELIB=`$PKG_CONFIG --libs javascriptcoregtk-1.0`
+ JSCOREVERSION=`$PKG_CONFIG --modversion javascriptcoregtk-1.0`
+ fi
+ if test -z "$JSCORELIB"; then
+ AC_MSG_RESULT(not found)
+ JSCENABLED=
+ else
+ AC_MSG_RESULT([version $JSCOREVERSION])
+ AC_MSG_CHECKING(for JavaScriptCore/Webkit include flags)
+ AC_MSG_RESULT([$JSCOREINC])
+ AC_MSG_CHECKING(for JavaScriptCore/Webkit link flags)
+ AC_MSG_RESULT([$JSCORELIB])
+ JSCOREDYNAMICLINKING="$JSCORELIB"
+ JSCENABLED=1
+ fi
fi
+ else
+ AC_MSG_CHECKING(for JavaScriptCore/Webkit include flags)
+ JSCOREINC=-I\"$JSCOREINCDIR\"
+ AC_MSG_RESULT([$JSCOREINC])
+ AC_MSG_CHECKING(for JavaScriptCore/Webkit link flags)
+ AC_MSG_RESULT([$JSCORELIB])
+ JSCOREDYNAMICLINKING="$JSCORELIB"
+ JSCENABLED=1
fi
#----------------------------------------------------------------
@@ -1759,139 +1383,140 @@ AC_SUBST(NODEJS)
AC_SUBST(NODEGYP)
#----------------------------------------------------------------
-# Look for Android
+# Look for Lua
#----------------------------------------------------------------
-AC_ARG_WITH(android, AS_HELP_STRING([--without-android], [Disable Android])
-AS_HELP_STRING([--with-android=path], [Set location of android executable]),[ANDROIDBIN="$withval"], [ANDROIDBIN="$alllang_default"])
-AC_ARG_WITH(adb, [ --with-adb=path Set location of adb executable - Android Debug Bridge],[ADBBIN="$withval"], [ADBBIN=])
-AC_ARG_WITH(ant, [ --with-ant=path Set location of ant executable for Android],[ANTBIN="$withval"], [ANTBIN=])
-AC_ARG_WITH(ndk-build, [ --with-ndk-build=path Set location of Android ndk-build executable],[NDKBUILDBIN="$withval"], [NDKBUILDBIN=])
+LUABIN=
+LUAINCLUDE=
+LUALIB=
+LUADYNAMICLOADLIB=
+LUAFLAGS=
+LUALINK=
+# note: if LUABIN is empty then lua tests will not be done
+# LUABIN will be cleared if certain dependencies cannot be found
-# First, check for "--without-android" or "--with-android=no".
-if test x"${ANDROIDBIN}" = xno; then
- AC_MSG_NOTICE([Disabling Android])
- ANDROID=
+AC_ARG_WITH(lua, AS_HELP_STRING([--without-lua], [Disable Lua])
+AS_HELP_STRING([--with-lua=path], [Set location of Lua executable]),[ LUABIN="$withval"], [LUABIN="$alllang_default"])
+AC_ARG_WITH(luaincl,[ --with-luaincl=path Set location of Lua include directory],[
+ LUAINCLUDE="$withval"], [LUAINCLUDE=])
+AC_ARG_WITH(lualib,[ --with-lualib=path Set location of Lua library directory],[
+ LUALIB="$withval"], [LUALIB=])
+
+# First, check for "--without-lua" or "--with-lua=no".
+if test x"${LUABIN}" = xno; then
+AC_MSG_NOTICE([Disabling Lua])
else
- if test "x$ANDROIDBIN" = xyes; then
- AC_CHECK_PROGS(ANDROID, android)
- else
- ANDROID="$ANDROIDBIN"
- fi
- if test -z "$ADBBIN"; then
- AC_CHECK_PROGS(ADB, adb)
- else
- ADB="$ADBBIN"
- fi
+# can we find lua?
+if test "x$LUABIN" = xyes; then
+ # We look for a versioned Lua binary first, as there can be
+ # multiple versions of Lua installed on some systems (like Debian).
+ AC_PATH_PROGS(LUABIN, [lua5.4 lua5.3 lua5.2 lua5.1 lua])
+fi
- if test -z "$ANTBIN"; then
- AC_CHECK_PROGS(ANT, ant)
+# check version: we need Lua 5.x
+if test "$LUABIN"; then
+ AC_MSG_CHECKING(Lua version)
+ [LUA_VERSION=`$LUABIN -e 'print(string.match(_VERSION, "%d+[.]%d+"))'`]
+ # For 5.0 and 5.1 header and libraries may be named using 50 or 51.
+ LUA_VERSION_NO_DOTS=
+ if test -n "$LUA_VERSION" ; then
+ AC_MSG_RESULT([Lua $LUA_VERSION.x])
else
- ANT="$ANTBIN"
+ AC_MSG_RESULT([failed])
fi
+ case $LUA_VERSION in
+ 5.0) LUA_VERSION_NO_DOTS=50 ;;
+ 5.1) LUA_VERSION_NO_DOTS=51 ;;
+ 5.*) ;;
+ *)
+ AC_MSG_WARN([Not Lua 5.x, SWIG does not support this version of Lua])
+ LUABIN=""
+ ;;
+ esac
+fi
- if test -z "$NDKBUILDBIN"; then
- AC_CHECK_PROGS(NDKBUILD, ndk-build)
+if test "$LUABIN"; then
+ AC_MSG_CHECKING(whether Lua dynamic loading is enabled)
+ # using Lua to check Lua
+ # lua 5.0 & 5.1 have different fn names
+ if test "$LUA_VERSION" = "5.0"; then
+ LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=loadlib("no_such_lib","") if c~="absent" then print "1" end'`
else
- NDKBUILD="$NDKBUILDBIN"
+ LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=package.loadlib("no_such_lib","") if c~="absent" then print "1" end'`
fi
-fi
-
-AC_SUBST(ANDROID)
-AC_SUBST(ADB)
-AC_SUBST(ANT)
-AC_SUBST(NDKBUILD)
-
-#----------------------------------------------------------------
-# Look for Guile
-#----------------------------------------------------------------
-
-GUILE=
-GUILE_CFLAGS=
-GUILE_LIBS=
-AC_ARG_WITH(guile-config, AS_HELP_STRING([--without-guile], [Disable Guile])
-AS_HELP_STRING([--with-guile-config=path], [Set location of guile-config]),[ GUILE_CONFIG="$withval"], [GUILE_CONFIG=])
-AC_ARG_WITH(guile,[ --with-guile=path Set location of Guile executable],[
- GUILE="$withval"], [GUILE="$alllang_default"])
-AC_ARG_WITH(guile-cflags,[ --with-guile-cflags=cflags Set cflags required to compile against Guile],[
- GUILE_CFLAGS="$withval"])
-AC_ARG_WITH(guile-libs,[ --with-guile-libs=ldflags Set ldflags needed to link with Guile],[
- GUILE_LIBS="$withval"])
-
-# First, check for "--without-guile" or "--with-guile=no".
-if test x"${GUILE}" = xno; then
- AC_MSG_NOTICE([Disabling Guile])
-else
- if test -z "$GUILE_CONFIG" ; then
- AC_PATH_PROG(GUILE_CONFIG, guile-config)
+ if test -z "$LUADYNAMICLOADLIB"; then
+ AC_MSG_RESULT(no)
+ else
+ AC_MSG_RESULT(yes)
fi
- if test -n "$GUILE_CONFIG" ; then
- if test x"$GUILE" = xyes; then
- AC_MSG_CHECKING([for guile executable])
- # Try extracting it via guile-config first. If it's defined there it's the most reliable result
- GUILE="`$GUILE_CONFIG info guile 2>/dev/null`"
- if test -n "$GUILE"; then
- AC_MSG_RESULT([$GUILE])
- else
- AC_MSG_RESULT([not found via guile-config - constructing path])
- AC_MSG_CHECKING([for guile bindir])
- guile_bindir="`$GUILE_CONFIG info bindir`"
- AC_MSG_RESULT([$guile_bindir])
- GUILE="$guile_bindir/guile"
- fi
- if ! test -f "$GUILE" ; then
- GUILE=
- AC_PATH_PROG(GUILE, guile)
- fi
- if test -z "$GUILE" ; then
- AC_MSG_WARN([no suitable guile executable found. Disabling Guile])
- fi
- fi
- if test -n "$GUILE" ; then
- AC_MSG_CHECKING([for guile version])
- guile_version=`$GUILE -c '(display (effective-version))'`
- AC_MSG_RESULT([$guile_version])
- AC_MSG_CHECKING([for guile version >= 1.8])
- guile_good_version=`$GUILE -c '(if (>= (string->number (effective-version)) 1.8) (display "yes") (display "no"))'`
- AC_MSG_RESULT([$guile_good_version])
- if test x"$guile_good_version" != xyes ; then
- AC_MSG_WARN([at least guile version 1.8 is required. Disabling Guile])
- GUILE=
+ # look for the header files & set LUAFLAGS accordingly
+ # will clear LUABIN if not present
+ if test -n "$LUAINCLUDE"; then
+ AC_CHECK_FILE($LUAINCLUDE/lua.h,[LUAFLAGS="-I$LUAINCLUDE"],[LUABIN=])
+ else
+ LUA_OK="1"
+ CFLAGS_SAVED=$CFLAGS
+ CFLAGS= # Use empty CFLAGS to avoid failure: "present but cannot be compiled"
+ AC_CHECK_HEADER([lua.h],[LUAFLAGS=""],[LUA_OK=""])
+ CFLAGS=$CFLAGS_SAVED
+ # if we didn't get it, going to have to look elsewhere (the hard way)
+ if test -z "$LUA_OK"; then
+ AC_MSG_CHECKING(for lua.h in other locations)
+ # note: Debian/Ubuntu seem to like /usr/include/lua5.1/lua.h
+ # The ordering of the include directories to search should match
+ # the ordering of libraries to search in the library test below.
+ inc=/usr/include
+ incloc=/usr/local/include
+ dirs="$inc/lua$LUA_VERSION"
+ test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $inc/lua$LUA_VERSION_NO_DOTS"
+ dirs="$dirs $incloc/lua$LUA_VERSION"
+ test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $incloc/lua$LUA_VERSION_NO_DOTS"
+ dirs="$dirs $incloc"
+ for i in $dirs; do
+ #echo "$i"
+ if test -r $i/lua.h; then
+ AC_MSG_RESULT($i/lua.h)
+ LUAFLAGS="-I$i"
+ break
+ fi
+ done
+ if test -z "$LUAFLAGS"; then
+ AC_MSG_RESULT(not found)
+ LUABIN="" # clear the bin
fi
fi
+ fi
- if test -n "$GUILE" ; then
- # Test if guile-config and guile versions match. They should.
- gc_version="`$GUILE_CONFIG --version 2>&1 | sed '1 s/.* //;q'`"
- g_version="`$GUILE --version | sed '1 s/.* //;q'`"
- if test "$gc_version" != "$g_version"; then
- AC_MSG_WARN([different versions reported by $GUILE_CONFIG ($gc_version) and $GUILE ($g_version). Disabling Guile])
- GUILE=
- fi
- fi
+ # look for the library files & set LUALINK accordingly
+ # will clear LUABIN if not present
+ lua_save_LIBS=$LIBS # the code seems to disrupt LIBS, so saving
- if test -n "$GUILE" ; then
- if test -z "$GUILE_CFLAGS" ; then
- AC_MSG_CHECKING([for guile compile flags])
- GUILE_CFLAGS="`$GUILE_CONFIG compile`" # Note that this can sometimes be empty
- AC_MSG_RESULT([$GUILE_CFLAGS])
- fi
+ if test -n "$LUALIB"; then
+ AC_CHECK_FILE($LUALIB/liblua.a,[LUALINK="-L$LUALIB -llua"],[LUABIN=])
+ else
+ libs="lua lua$LUA_VERSION"
+ test -z "$LUA_VERSION_NO_DOTS" || libs="$libs lua$LUA_VERSION_NO_DOTS"
+ AC_SEARCH_LIBS(lua_close, [$libs], [LUALINK="-l$ac_lib"],[LUABIN=])
+ fi
- if test -z "$GUILE_LIBS" ; then
- AC_MSG_CHECKING([for guile link flags])
- GUILE_LIBS="`$GUILE_CONFIG link`"
- AC_MSG_RESULT([$GUILE_LIBS])
- fi
- fi
+ # adding lualib for lua 5.0
+ if test "$LUA_VERSION" = "5.0"; then
+ LUALINK="$LUALINK -llualib"
fi
+ LUALINK="$LUALINK -pthread"
+
+ LIBS=$lua_save_LIBS # restore LIBS
fi
-AC_SUBST(GUILE)
-AC_SUBST(GUILE_CFLAGS)
-AC_SUBST(GUILE_LIBS)
+fi # if not disabled
+
+AC_SUBST(LUADYNAMICLINKING)
+AC_SUBST(LUAFLAGS)
+AC_SUBST(LUALINK)
+AC_SUBST(LUABIN)
#----------------------------------------------------------------
# Look for MzScheme
@@ -1936,136 +1561,288 @@ fi
AC_SUBST(MZDYNOBJ)
#----------------------------------------------------------------
-# Look for Ruby
+# Look for OCaml
#----------------------------------------------------------------
-RUBYBIN=
+AC_ARG_WITH(ocaml, AS_HELP_STRING([--without-ocaml], [Disable OCaml]), [with_ocaml="$withval"], [with_ocaml="$alllang_default"])
+AC_ARG_WITH(ocamlc,[ --with-ocamlc=path Set location of ocamlc executable],[ OCAMLC="$withval"], [OCAMLC=])
+AC_ARG_WITH(ocamldlgen,[ --with-ocamldlgen=path Set location of ocamldlgen],[ OCAMLDLGEN="$withval" ], [OCAMLDLGEN=])
+AC_ARG_WITH(ocamlfind,[ --with-ocamlfind=path Set location of ocamlfind],[OCAMLFIND="$withval"],[OCAMLFIND=])
+AC_ARG_WITH(ocamlmktop,[ --with-ocamlmktop=path Set location of ocamlmktop executable],[ OCAMLMKTOP="$withval"], [OCAMLMKTOP=])
+AC_ARG_WITH(camlp4,[ --with-camlp4=path Set location of camlp4 executable],[ CAMLP4="$withval"], [CAMLP4=])
-AC_ARG_WITH(ruby, AS_HELP_STRING([--without-ruby], [Disable Ruby])
-AS_HELP_STRING([--with-ruby=path], [Set location of Ruby executable]),[ RUBYBIN="$withval"], [RUBYBIN="$alllang_default"])
+# First, check for "--without-ocaml" or "--with-ocaml=no".
+if test x"${with_ocaml}" = xno; then
+ AC_MSG_NOTICE([Disabling OCaml])
+ OCAMLC=
+else
+ # OCaml compiler
+ if test -z "$OCAMLC"; then
+ AC_CHECK_PROGS(OCAMLC, ocamlc)
+ fi
+
+ # OCaml Pre-Processor-Pretty-Printer
+ if test -z "$CAMLP4"; then
+ AC_CHECK_PROGS(CAMLP4, camlp4)
+ fi
+
+ # OCaml DL load generator
+ if test -z "$OCAMLDLGEN"; then
+ AC_CHECK_PROGS(OCAMLDLGEN, ocamldlgen)
+ fi
+
+ # OCaml package tool
+ if test -z "$OCAMLFIND"; then
+ AC_CHECK_PROGS(OCAMLFIND, ocamlfind)
+ fi
+
+ # OCaml toplevel creator
+ if test -z "$OCAMLMKTOP"; then
+ AC_CHECK_PROGS(OCAMLMKTOP, ocamlmktop)
+ fi
+fi
+
+AC_SUBST(OCAMLC)
+AC_SUBST(CAMLP4)
+AC_SUBST(OCAMLDLGEN)
+AC_SUBST(OCAMLFIND)
+AC_SUBST(OCAMLMKTOP)
+
+#----------------------------------------------------------------
+# Look for Octave
+#----------------------------------------------------------------
+
+OCTAVEBIN=
+OCTAVE_SO=.oct
+
+AC_ARG_WITH(octave, AS_HELP_STRING([--without-octave], [Disable Octave])
+AS_HELP_STRING([--with-octave=path], [Set location of Octave executable]),[OCTAVEBIN="$withval"], [OCTAVEBIN="$alllang_default"])
+
+# Check for "--without-octave" or "--with-octave=no".
+if test x"${OCTAVEBIN}" = xno; then
+ AC_MSG_NOTICE([Disabling Octave])
+ OCTAVE=
+
+# Check for Octave; prefer command-line program "octave-cli" to (in newer versions) GUI program "octave"
+elif test "x$OCTAVEBIN" = xyes; then
+ AC_PATH_PROG(OCTAVE, [octave-cli octave])
-# First, check for "--without-ruby" or "--with-ruby=no".
-RUBYSO=$SO
-if test x"${RUBYBIN}" = xno; then
-AC_MSG_NOTICE([Disabling Ruby])
-RUBY=
else
+ OCTAVE="$OCTAVEBIN"
+fi
-# First figure out what the name of Ruby is
+# Check if Octave works
+if test -n "$OCTAVE"; then
+ AC_MSG_CHECKING([if ${OCTAVE} works])
+ AS_IF([test "x`${OCTAVE} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/Octave, version/p'`" != x],[
+ AC_MSG_RESULT([yes])
+ ],[
+ AC_MSG_RESULT([no])
+ OCTAVE=
+ ])
+fi
-if test "x$RUBYBIN" = xyes; then
- AC_CHECK_PROGS(RUBY, ruby)
+# Check for required Octave helper program "mkoctfile"
+if test -n "$OCTAVE"; then
+ AC_MSG_CHECKING([for mkoctfile])
+ version_suffix=["`echo $OCTAVE | sed -e 's|.*\(-[0-9][0-9.]*\)$|\1|'`"]
+ case $version_suffix in
+ -*) ;;
+ *) version_suffix="" ;;
+ esac
+ octave_directory=`dirname $OCTAVE`
+ if test "$octave_directory" = "." ; then
+ mkoctfile="mkoctfile${version_suffix}"
+ else
+ mkoctfile="${octave_directory}/mkoctfile${version_suffix}"
+ fi
+ AC_MSG_RESULT([${mkoctfile}])
+ AC_MSG_CHECKING([if ${mkoctfile} works])
+ mkoctfile="env - PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH ${mkoctfile}"
+ AS_IF([test "x`${mkoctfile} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/mkoctfile, version/p'`" != x],[
+ AC_MSG_RESULT([yes])
+ ],[
+ AC_MSG_RESULT([no])
+ OCTAVE=
+ ])
+fi
+
+# Check for Octave preprocessor/compiler/linker flags
+if test -n "$OCTAVE"; then
+
+ AC_MSG_CHECKING([for Octave preprocessor flags])
+ OCTAVE_CPPFLAGS=
+ for var in CPPFLAGS INCFLAGS ALL_CXXFLAGS; do
+ for flag in `${mkoctfile} -p ${var}`; do
+ case ${flag} in
+ -D*|-I*) OCTAVE_CPPFLAGS="${OCTAVE_CPPFLAGS} ${flag}";;
+ *) ;;
+ esac
+ done
+ done
+ AC_MSG_RESULT([$OCTAVE_CPPFLAGS])
+
+ AC_MSG_CHECKING([for Octave compiler flags])
+ OCTAVE_CXXFLAGS=
+ for var in CXX ALL_CXXFLAGS; do
+ for flag in `${mkoctfile} -p ${var}`; do
+ case ${flag} in
+ -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
+ *) ;;
+ esac
+ done
+ done
+ save_CXXFLAGS="${CXXFLAGS}"
+ CXXFLAGS="-Werror -O0"
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([],[])
+ ],[
+ OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} -O0"
+ ])
+ CXXFLAGS="${save_CXXFLAGS}"
+ AC_MSG_RESULT([$OCTAVE_CXXFLAGS])
+
+ AC_MSG_CHECKING([for Octave linker flags])
+ OCTAVE_LDFLAGS=
+ for var in OCTLIBDIR; do
+ OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`${mkoctfile} -p ${var}`
+ done
+ for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do
+ OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`${mkoctfile} -p ${var}`
+ done
+ AC_MSG_RESULT([$OCTAVE_LDFLAGS])
+
+fi
+
+# Check for Octave options
+if test -n "$OCTAVE"; then
+ for octave_opt in --no-window-system --silent --norc --no-history; do
+ AC_MSG_CHECKING([if Octave option '${octave_opt}' is supported])
+ octave_out=`${OCTAVE} ${octave_opt} /dev/null 2>&1 | sed -n '1p' | sed -n '/unrecognized/p'`
+ AS_IF([test "x${octave_out}" = x],[
+ AC_MSG_RESULT([yes])
+ OCTAVE="${OCTAVE} ${octave_opt}"
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+ done
+fi
+
+AC_SUBST(OCTAVE)
+AC_SUBST(OCTAVE_SO)
+AC_SUBST(OCTAVE_CPPFLAGS)
+AC_SUBST(OCTAVE_CXXFLAGS)
+AC_SUBST(OCTAVE_LDFLAGS)
+
+#----------------------------------------------------------------
+# Look for Perl5
+#----------------------------------------------------------------
+
+PERLBIN=
+
+AC_ARG_WITH(perl5, AS_HELP_STRING([--without-perl5], [Disable Perl5])
+AS_HELP_STRING([--with-perl5=path], [Set location of Perl5 executable]),[ PERLBIN="$withval"], [PERLBIN="$alllang_default"])
+
+# First, check for "--without-perl5" or "--with-perl5=no".
+if test x"${PERLBIN}" = xno; then
+AC_MSG_NOTICE([Disabling Perl5])
+PERL=
else
- RUBY="$RUBYBIN"
+
+# First figure out what the name of Perl5 is
+
+if test "x$PERLBIN" = xyes; then
+AC_CHECK_PROGS(PERL, perl perl5)
+else
+PERL="$PERLBIN"
fi
-AC_MSG_CHECKING(for Ruby header files)
-if test -n "$RUBY"; then
- # Try Ruby1.9+ first
- RUBYDIR=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["rubyhdrdir"]] || $rubyhdrdir') 2>/dev/null`
- RUBYARCHHDRDIR=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["rubyarchhdrdir"]] || $rubyarchhdrdir') 2>/dev/null`
- if test x"$RUBYDIR" = x"" || test x"$RUBYDIR" = x"nil"; then
- RUBYDIR=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["archdir"]] || $archdir') 2>/dev/null`
- else
- RUBYARCH=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["arch"]] || $arch') 2>/dev/null`
- fi
- if test x"$RUBYDIR" != x""; then
- dirs="$RUBYDIR"
- RUBYINCLUDE=
+
+# This could probably be simplified as for all platforms and all versions of Perl the following apparently should be run to get the compilation options:
+# perl -MExtUtils::Embed -e ccopts
+AC_MSG_CHECKING(for Perl5 header files)
+if test -n "$PERL"; then
+ PERL5DIR=`($PERL -MConfig -le 'print $Config{archlibexp}') 2>/dev/null`
+ if test -n "$PERL5DIR" ; then
+ dirs="$PERL5DIR $PERL5DIR/CORE"
+ PERL5EXT=none
for i in $dirs; do
- if test -r $i/ruby.h; then
- if test x"$RUBYARCH" = x""; then
- RUBYINCLUDE="-I$i"
- elif test -n "$RUBYARCHHDRDIR"; then
- RUBYINCLUDE="-I$i -I$RUBYARCHHDRDIR"
- else
- RUBYINCLUDE="-I$i -I$i/$RUBYARCH"
- fi
- AC_MSG_RESULT($RUBYINCLUDE)
+ if test -r $i/perl.h; then
+ AC_MSG_RESULT($i)
+ PERL5EXT="$i"
break
fi
done
- if test x"$RUBYINCLUDE" = x""; then
- AC_MSG_RESULT(could not locate ruby.h)
+ if test "$PERL5EXT" = none; then
+ PERL5EXT="$PERL5DIR/CORE"
+ AC_MSG_RESULT(could not locate perl.h...using $PERL5EXT)
fi
- # Find library and path for linking.
- AC_MSG_CHECKING(for Ruby library)
- RUBYLIB=""
- rb_archlibdir=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["archlibdir"]]') 2>/dev/null`
- rb_libdir=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["libdir"]]') 2>/dev/null`
- rb_bindir=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["bindir"]]') 2>/dev/null`
- dirs="$dirs $rb_archlibdir $rb_libdir $rb_bindir"
-
- rb_libruby=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["LIBRUBY_A"]]') 2>/dev/null`
- RUBYLINK=`($RUBY -rrbconfig -e '
- c = RbConfig::CONFIG
- if c.has_key? "LIBRUBYARG_STATIC" # 1.8.x
- if c[["LIBRUBY"]] == c[["LIBRUBY_A"]]
- link = c[["LIBRUBYARG_STATIC"]]
- else
- link = c[["LIBRUBYARG_SHARED"]]
- end
- else # 1.6.x
- link = "-l" + c[["RUBY_INSTALL_NAME"]]
- end
-
- # Get the target Ruby was built for
- target = c[["target"]]
-
- if target == "i386-pc-mswin32"
- # Need to change msvcrt-ruby*.lib to -lmsvcrt-ruby*
- ext = File.extname(link)
- # Get index that counts backwards from end of string
- index = -1 - ext.size
- # Strip off the extension
- link = link.slice(0..index)
- puts "-l#{link}"
- else
- puts link
- end') 2>/dev/null`
-
- if test "$rb_libruby" != ""; then
- for i in $dirs; do
- if (test -r $i/$rb_libruby;) then
- RUBYLIB="$i"
- break
- fi
- done
+ AC_MSG_CHECKING(for Perl5 library)
+ PERL5LIB=`($PERL -e 'use Config; $_=$Config{libperl}; s/^lib//; s/$Config{_a}$//; s/\.$Config{so}.*//; print $_, "\n"') 2>/dev/null`
+ if test -z "$PERL5LIB" ; then
+ AC_MSG_RESULT(not found)
+ else
+ AC_MSG_RESULT($PERL5LIB)
fi
- if test "$RUBYLIB" = ""; then
- RUBYLIB="$RUBYDIR"
- AC_MSG_RESULT(not found... using $RUBYDIR)
+ AC_MSG_CHECKING(for Perl5 ccflags)
+ PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//") 2>/dev/null`
+ if test -z "$PERL5CCFLAGS" ; then
+ AC_MSG_RESULT(not found)
else
- AC_MSG_RESULT($RUBYLINK in $RUBYLIB)
+ AC_MSG_RESULT($PERL5CCFLAGS)
fi
+ AC_MSG_CHECKING(for Perl5 ccdlflags)
+ PERL5CCDLFLAGS=`($PERL -e 'use Config; print $Config{ccdlflags}, "\n"') 2>/dev/null`
+ if test -z "$PERL5CCDLFLAGS" ; then
+ AC_MSG_RESULT(not found)
+ else
+ AC_MSG_RESULT($PERL5CCDLFLAGS)
+ fi
+ AC_MSG_CHECKING(for Perl5 cccdlflags)
+ PERL5CCCDLFLAGS=`($PERL -e 'use Config; print $Config{cccdlflags}, "\n"') 2>/dev/null`
+ if test -z "$PERL5CCCDLFLAGS" ; then
+ AC_MSG_RESULT(not found)
+ else
+ AC_MSG_RESULT($PERL5CCCDLFLAGS)
+ fi
+ AC_MSG_CHECKING(for Perl5 ldflags)
+ PERL5LDFLAGS=`($PERL -e 'use Config; print $Config{ldflags}, "\n"') 2>/dev/null`
+ if test -z "$PERL5LDFLAGS" ; then
+ AC_MSG_RESULT(not found)
+ else
+ AC_MSG_RESULT($PERL5LDFLAGS)
+ fi
+ AC_MSG_CHECKING(for Perl5 Test::More module) # For test-suite
+ PERL5TESTMORE=`($PERL -e 'use Test::More; print "good";') 2>/dev/null`
+ if test -z "$PERL5TESTMORE" ; then
+ AC_MSG_RESULT(not found)
+ else
+ AC_MSG_RESULT(found)
+ fi
else
- AC_MSG_RESULT(unable to determine ruby configuration)
+ AC_MSG_RESULT(unable to determine perl5 configuration)
+ PERL5EXT=$PERL5DIR
fi
-
- case $host in
- *-*-mingw*) ;; # do nothing, the default windows libraries are already included
- *) RUBYLINK="$RUBYLINK `($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["LIBS"]]') 2>/dev/null`";;
- esac
-
- RUBYCCDLFLAGS=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["CCDLFLAGS"]]') 2>/dev/null`
- RUBYSO=.`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["DLEXT"]]') 2>/dev/null`
else
- AC_MSG_RESULT(could not figure out how to run ruby)
+ AC_MSG_RESULT(could not figure out how to run perl5)
fi
+# Cygwin (Windows) needs the library for dynamic linking
case $host in
-*-*-cygwin* | *-*-mingw*) RUBYDYNAMICLINKING="-L$RUBYLIB $RUBYLINK";;
-*) RUBYDYNAMICLINKING="";;
+*-*-cygwin* | *-*-mingw*) PERL5DYNAMICLINKING="-L$PERL5EXT -l$PERL5LIB";;
+*)PERL5DYNAMICLINKING="";;
esac
fi
-AC_SUBST(RUBYINCLUDE)
-AC_SUBST(RUBYLIB)
-AC_SUBST(RUBYLINK)
-AC_SUBST(RUBYCCDLFLAGS)
-AC_SUBST(RUBYSO)
-AC_SUBST(RUBYDYNAMICLINKING)
+AC_SUBST(PERL)
+AC_SUBST(PERL5EXT)
+AC_SUBST(PERL5DYNAMICLINKING)
+AC_SUBST(PERL5LIB)
+AC_SUBST(PERL5CCFLAGS)
+AC_SUBST(PERL5CCDLFLAGS)
+AC_SUBST(PERL5CCCDLFLAGS)
+AC_SUBST(PERL5LDFLAGS)
#-------------------------------------------------------------------------
# Look for PHP
@@ -2082,7 +1859,7 @@ if test x"${PHPBIN}" = xno; then
PHP=
else
if test "x$PHPBIN" = xyes; then
- AC_CHECK_PROGS(PHP, [php8.0 php7.4 php7.3 php7.2 php7.1 php7.0 php])
+ AC_CHECK_PROGS(PHP, [php8.1 php8.0 php7.4 php7.3 php7.2 php7.1 php7.0 php])
else
PHP=$PHPBIN
fi
@@ -2119,303 +1896,341 @@ AC_SUBST(PHP)
AC_SUBST(PHPINC)
#----------------------------------------------------------------
-# Look for OCaml
+# Look for Python
#----------------------------------------------------------------
-AC_ARG_WITH(ocaml, AS_HELP_STRING([--without-ocaml], [Disable OCaml]), [with_ocaml="$withval"], [with_ocaml="$alllang_default"])
-AC_ARG_WITH(ocamlc,[ --with-ocamlc=path Set location of ocamlc executable],[ OCAMLC="$withval"], [OCAMLC=])
-AC_ARG_WITH(ocamldlgen,[ --with-ocamldlgen=path Set location of ocamldlgen],[ OCAMLDLGEN="$withval" ], [OCAMLDLGEN=])
-AC_ARG_WITH(ocamlfind,[ --with-ocamlfind=path Set location of ocamlfind],[OCAMLFIND="$withval"],[OCAMLFIND=])
-AC_ARG_WITH(ocamlmktop,[ --with-ocamlmktop=path Set location of ocamlmktop executable],[ OCAMLMKTOP="$withval"], [OCAMLMKTOP=])
-AC_ARG_WITH(camlp4,[ --with-camlp4=path Set location of camlp4 executable],[ CAMLP4="$withval"], [CAMLP4=])
+PYINCLUDE=
+PYLIB=
+PYLINK=
+PYPACKAGE=
-# First, check for "--without-ocaml" or "--with-ocaml=no".
-if test x"${with_ocaml}" = xno; then
- AC_MSG_NOTICE([Disabling OCaml])
- OCAMLC=
-else
- # OCaml compiler
- if test -z "$OCAMLC"; then
- AC_CHECK_PROGS(OCAMLC, ocamlc)
- fi
+AC_ARG_WITH(python, AS_HELP_STRING([--without-python], [Don't probe for Python 2.x])
+AS_HELP_STRING([--with-python=path], [Set location of Python 2.x executable]), [PYBIN="$withval"], [PYBIN="$alllang_default"])
- # OCaml Pre-Processor-Pretty-Printer
- if test -z "$CAMLP4"; then
- AC_CHECK_PROGS(CAMLP4, camlp4)
- fi
+# First, check for "--without-python" or "--with-python=no".
+if test x"${PYBIN}" = xno; then
+ AC_MSG_NOTICE([Disabling Python 2.x probe])
+else
+ # First figure out the name of the Python 2.x executable
+ if test "x$PYBIN" = xyes; then
+ AC_CHECK_PROGS(PYTHON, [python python2.7])
+ else
+ PYTHON="$PYBIN"
+ fi
- # OCaml DL load generator
- if test -z "$OCAMLDLGEN"; then
- AC_CHECK_PROGS(OCAMLDLGEN, ocamldlgen)
+ PYVER=0
+ if test -n "$PYTHON"; then
+ AC_MSG_CHECKING([for $PYTHON major version number])
+ PYVER=`($PYTHON -c "import sys; sys.stdout.write(sys.version[[0]])") 2>/dev/null`
+ AC_MSG_RESULT($PYVER)
+ if test -z "$PYVER"; then
+ PYVER=0
+ else
+ AC_MSG_CHECKING(for Python 2.x os.name)
+ PYOSNAME=`($PYTHON -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
+ AC_MSG_RESULT($PYOSNAME)
+ AC_MSG_CHECKING(for Python 2.x path separator)
+ PYSEPARATOR=`($PYTHON -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
+ AC_MSG_RESULT($PYSEPARATOR)
fi
+ fi
- # OCaml package tool
- if test -z "$OCAMLFIND"; then
- AC_CHECK_PROGS(OCAMLFIND, ocamlfind)
- fi
+ if test $PYVER -eq 1 -o $PYVER -eq 2; then
+ AC_MSG_CHECKING(for Python 2.x prefix)
+ PYPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
+ AC_MSG_RESULT($PYPREFIX)
+ AC_MSG_CHECKING(for Python 2.x exec-prefix)
+ PYEPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)") 2>/dev/null`
+ AC_MSG_RESULT($PYEPREFIX)
- # OCaml toplevel creator
- if test -z "$OCAMLMKTOP"; then
- AC_CHECK_PROGS(OCAMLMKTOP, ocamlmktop)
- fi
-fi
+ if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
+ # Windows installations are quite different to posix installations (MinGW path separator is a forward slash)
+ PYPREFIX=`echo "$PYPREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
+ PYTHON_SO=.pyd
-AC_SUBST(OCAMLC)
-AC_SUBST(CAMLP4)
-AC_SUBST(OCAMLDLGEN)
-AC_SUBST(OCAMLFIND)
-AC_SUBST(OCAMLMKTOP)
+ AC_MSG_CHECKING(for Python 2.x header files)
+ if test -r $PYPREFIX/include/Python.h; then
+ PYINCLUDE="-I$PYPREFIX/include"
+ fi
+ AC_MSG_RESULT($PYINCLUDE)
-#----------------------------------------------------------------
-# Look for C#
-#----------------------------------------------------------------
+ AC_MSG_CHECKING(for Python 2.x library directory)
+ if test -d $PYPREFIX/libs; then
+ PYLIB=$PYPREFIX/libs
+ PYLINKFILE=`ls $PYLIB/python*.lib | grep "python[[0-9]][[0-9]]\+\.lib"`
+ if test -r "$PYLINKFILE"; then
+ PYLINK=-l`basename $PYLINKFILE | sed -e 's/\.lib$//'`
+ else
+ PYLIB=
+ fi
+ fi
+ else
+ # Note: I could not think of a standard way to get the version string from different versions.
+ # This trick pulls it out of the file location for a standard library file.
-AC_ARG_WITH(csharp, AS_HELP_STRING([--without-csharp], [Disable CSharp]), [with_csharp="$withval"], [with_csharp="$alllang_default"])
-AC_ARG_WITH(cil-interpreter, [ --with-cil-interpreter=path Set location of CIL interpreter for CSharp],[CSHARPBIN="$withval"], [CSHARPBIN=])
-AC_ARG_WITH(csharp-compiler, [ --with-csharp-compiler=path Set location of CSharp compiler],[CSHARPCOMPILERBIN="$withval"], [CSHARPCOMPILERBIN=])
+ AC_MSG_CHECKING(for Python 2.x version)
-# First, check for "--without-csharp" or "--with-csharp=no".
-if test x"${with_csharp}" = xno; then
-AC_MSG_NOTICE([Disabling CSharp])
-CSHARPCOMPILER=
-else
+ # Need to do this hack since autoconf replaces __file__ with the name of the configure file
+ filehack="file__"
+ PYVERSION=`($PYTHON -c "import sys,string,operator,os.path; sys.stdout.write(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
+ AC_MSG_RESULT($PYVERSION)
-if test -z "$CSHARPCOMPILERBIN" ; then
- case $host in
- *-*-cygwin* | *-*-mingw*)
- # prefer unified Mono mcs compiler (not to be confused with the ancient .NET 1 mcs) over older/alternative names.
- AC_CHECK_PROGS(CSHARPCOMPILER, csc mcs mono-csc gmcs cscc)
- if test -n "$CSHARPCOMPILER" && test "$CSHARPCOMPILER" = "csc" ; then
- AC_MSG_CHECKING(whether csc is the Microsoft CSharp compiler)
- csc 2>/dev/null | grep "C#" > /dev/null || CSHARPCOMPILER=""
- if test -z "$CSHARPCOMPILER" ; then
- AC_MSG_RESULT(no)
- AC_CHECK_PROGS(CSHARPCOMPILER, mcs mono-csc gmcs cscc)
- else
- AC_MSG_RESULT(yes)
+ # Find the directory for libraries this is necessary to deal with
+ # platforms that can have apps built for multiple archs: e.g. x86_64
+ AC_MSG_CHECKING(for Python 2.x lib dir)
+ PYLIBDIR=`($PYTHON -c "import sys; sys.stdout.write(sys.lib)") 2>/dev/null`
+ if test -z "$PYLIBDIR"; then
+ # Fedora patch Python to add sys.lib, for other distros we assume "lib".
+ PYLIBDIR="lib"
fi
- fi
- ;;
- *)AC_CHECK_PROGS(CSHARPCOMPILER, mono-csc gmcs mcs cscc);;
- esac
-else
- CSHARPCOMPILER="$CSHARPCOMPILERBIN"
-fi
+ AC_MSG_RESULT($PYLIBDIR)
-CSHARPCONVERTPATH="Tools/convertpath -u"
-if test -z "$CSHARPBIN" ; then
- CSHARPCILINTERPRETER=""
- CSHARPCILINTERPRETER_FLAGS=""
- if test "cscc" = "$CSHARPCOMPILER" ; then
- AC_CHECK_PROGS(CSHARPCILINTERPRETER, ilrun)
- else
- if test "mcs" = "$CSHARPCOMPILER"; then
- # Check that mcs is the C# compiler and not the Unix mcs utility by examining the output of 'mcs --version'
- # The Mono compiler should emit: Mono C# compiler version a.b.c.d
- csharp_version_raw=`(mcs --version) 2>/dev/null`
- csharp_version_searched=`(mcs --version | sed -e "/C#/b" -e "/Mono/b" -e d) 2>/dev/null` # return string if contains 'Mono' or 'C#'
- CSHARPCOMPILER=""
- if test -n "$csharp_version_raw" ; then
- if test "$csharp_version_raw" = "$csharp_version_searched" ; then
- CSHARPCOMPILER="mcs"
- fi
+ # Set the include directory
+
+ AC_MSG_CHECKING(for Python 2.x header files)
+ if test -r $PYPREFIX/include/$PYVERSION/Python.h; then
+ PYINCLUDE="-I$PYPREFIX/include/$PYVERSION -I$PYEPREFIX/$PYLIBDIR/$PYVERSION/config"
fi
- if test "mcs" != "$CSHARPCOMPILER" ; then
- echo "mcs is not a working Mono C# compiler"
+ if test -z "$PYINCLUDE"; then
+ if test -r $PYPREFIX/include/Py/Python.h; then
+ PYINCLUDE="-I$PYPREFIX/include/Py -I$PYEPREFIX/$PYLIBDIR/python/lib"
+ fi
fi
+ AC_MSG_RESULT($PYINCLUDE)
+
+ # Set the library directory blindly. This probably won't work with older versions
+ AC_MSG_CHECKING(for Python 2.x library directory)
+ dirs="$PYVERSION/config $PYVERSION/$PYLIBDIR python/$PYLIBDIR"
+ for i in $dirs; do
+ if test -d $PYEPREFIX/$PYLIBDIR/$i; then
+ PYLIB="$PYEPREFIX/$PYLIBDIR/$i"
+ break
+ fi
+ done
+
+ PYLINK="-l$PYVERSION"
fi
- if test "mcs" = "$CSHARPCOMPILER" || test "gmcs" = "$CSHARPCOMPILER" || test "mono-csc" = "$CSHARPCOMPILER"; then
- AC_CHECK_PROGS(CSHARPCILINTERPRETER, mono) # Mono JIT
- CSHARPCILINTERPRETER_FLAGS="--debug"
+
+ if test -z "$PYLIB"; then
+ AC_MSG_RESULT(Not found)
else
- if test "csc" = "$CSHARPCOMPILER"; then
- CSHARPCONVERTPATH="Tools/convertpath -w"
- fi
+ AC_MSG_RESULT($PYLIB)
fi
- fi
-else
- CSHARPCILINTERPRETER="$CSHARPBIN"
-fi
-
-# Cygwin requires the Windows standard (Pascal) calling convention as it is a Windows executable and not a Cygwin built executable
-case $host in
-*-*-cygwin* | *-*-mingw*)
- if test "$GCC" = yes; then
- CSHARPDYNAMICLINKING="$GCC_MNO_CYGWIN -mthreads -Wl,--add-stdcall-alias"
- CSHARPCFLAGS="$GCC_MNO_CYGWIN -mthreads"
+ AC_MSG_CHECKING(for Python 2.x library)
+ if test -z "$PYLINK"; then
+ AC_MSG_RESULT(Not found)
else
- CSHARPDYNAMICLINKING=""
- CSHARPCFLAGS=""
- fi ;;
-*)
- CSHARPDYNAMICLINKING=""
- CSHARPCFLAGS=""
- ;;
-esac
-
-# CSharp on Windows platforms including Cygwin doesn't use libname.dll, rather name.dll when loading dlls
-case $host in
-*-*-cygwin* | *-*-mingw*) CSHARPLIBRARYPREFIX="";;
-*)CSHARPLIBRARYPREFIX="lib";;
-esac
+ AC_MSG_RESULT($PYLINK)
+ fi
+ fi
-# C#/Mono on Mac OS X tweaks
-case $host in
-*-*-darwin*)
- CSHARPSO=".so"
+ # Cygwin (Windows) needs the library for dynamic linking
+ case $host in
+ *-*-cygwin* | *-*-mingw*)
+ PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK"
+ DEFS="-DUSE_DL_IMPORT $DEFS"
;;
-*)
- CSHARPSO=$SO
+ *-*-aix*)
+ PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK"
;;
-esac
+ *)PYTHONDYNAMICLINKING="";;
+ esac
fi
-AC_SUBST(CSHARPCILINTERPRETER_FLAGS)
-AC_SUBST(CSHARPCILINTERPRETER)
-AC_SUBST(CSHARPCONVERTPATH)
-AC_SUBST(CSHARPCOMPILER)
-AC_SUBST(CSHARPDYNAMICLINKING)
-AC_SUBST(CSHARPLIBRARYPREFIX)
-AC_SUBST(CSHARPCFLAGS)
-AC_SUBST(CSHARPSO)
+AC_SUBST(PYINCLUDE)
+AC_SUBST(PYLIB)
+AC_SUBST(PYLINK)
+AC_SUBST(PYTHONDYNAMICLINKING)
+
#----------------------------------------------------------------
-# Look for Lua
+# Look for Python 3.x
#----------------------------------------------------------------
-LUABIN=
-LUAINCLUDE=
-LUALIB=
-LUADYNAMICLOADLIB=
-LUAFLAGS=
-LUALINK=
-# note: if LUABIN is empty then lua tests will not be done
-# LUABIN will be cleared if certain dependencies cannot be found
+PY3INCLUDE=
+PY3LIB=
+PY3LINK=
+PY3PACKAGE=
-AC_ARG_WITH(lua, AS_HELP_STRING([--without-lua], [Disable Lua])
-AS_HELP_STRING([--with-lua=path], [Set location of Lua executable]),[ LUABIN="$withval"], [LUABIN="$alllang_default"])
-AC_ARG_WITH(luaincl,[ --with-luaincl=path Set location of Lua include directory],[
- LUAINCLUDE="$withval"], [LUAINCLUDE=])
-AC_ARG_WITH(lualib,[ --with-lualib=path Set location of Lua library directory],[
- LUALIB="$withval"], [LUALIB=])
+AC_ARG_WITH(python3, AS_HELP_STRING([--without-python3], [Don't probe for Python 3.x])
+AS_HELP_STRING([--with-python3=path], [Set location of Python 3.x executable]), [PY3BIN="$withval"], [PY3BIN="$alllang_default"])
-# First, check for "--without-lua" or "--with-lua=no".
-if test x"${LUABIN}" = xno; then
-AC_MSG_NOTICE([Disabling Lua])
+# First, check for "--without-python3" or "--with-python3=no".
+if test x"${PY3BIN}" = xno; then
+ AC_MSG_NOTICE([Disabling Python 3.x probe])
else
-
-# can we find lua?
-if test "x$LUABIN" = xyes; then
- # We look for a versioned Lua binary first, as there can be
- # multiple versions of Lua installed on some systems (like Debian).
- AC_PATH_PROGS(LUABIN, [lua5.4 lua5.3 lua5.2 lua5.1 lua])
-fi
-
-# check version: we need Lua 5.x
-if test "$LUABIN"; then
- AC_MSG_CHECKING(Lua version)
- [LUA_VERSION=`$LUABIN -e 'print(string.match(_VERSION, "%d+[.]%d+"))'`]
- # For 5.0 and 5.1 header and libraries may be named using 50 or 51.
- LUA_VERSION_NO_DOTS=
- if test -n "$LUA_VERSION" ; then
- AC_MSG_RESULT([Lua $LUA_VERSION.x])
- else
- AC_MSG_RESULT([failed])
+ if test -z "$PYVER"; then
+ PYVER=0
fi
- case $LUA_VERSION in
- 5.0) LUA_VERSION_NO_DOTS=50 ;;
- 5.1) LUA_VERSION_NO_DOTS=51 ;;
- 5.*) ;;
- *)
- AC_MSG_WARN([Not Lua 5.x, SWIG does not support this version of Lua])
- LUABIN=""
- ;;
- esac
-fi
-
-if test "$LUABIN"; then
- AC_MSG_CHECKING(whether Lua dynamic loading is enabled)
- # using Lua to check Lua
- # lua 5.0 & 5.1 have different fn names
- if test "$LUA_VERSION" = "5.0"; then
- LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=loadlib("no_such_lib","") if c~="absent" then print "1" end'`
+ if test "x$PY3BIN" = xyes; then
+ if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\" -a $PYVER -ge 3; then
+ PYTHON3="$PYTHON"
+ else
+ for py_ver in 3 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 ""; do
+ AC_CHECK_PROGS(PYTHON3, [python$py_ver])
+ if test -n "$PYTHON3"; then
+ AC_CHECK_PROGS(PY3CONFIG, [$PYTHON3-config])
+ if test -n "$PY3CONFIG"; then
+ break
+ fi
+ fi
+ done
+ fi
else
- LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=package.loadlib("no_such_lib","") if c~="absent" then print "1" end'`
+ PYTHON3="$PY3BIN"
+ AC_CHECK_PROGS(PY3CONFIG, [$PYTHON3-config])
fi
- if test -z "$LUADYNAMICLOADLIB"; then
- AC_MSG_RESULT(no)
- else
- AC_MSG_RESULT(yes)
+ if test -n "$PYTHON3"; then
+ AC_MSG_CHECKING([for $PYTHON3 major version number])
+ PYVER=`($PYTHON3 -c "import sys; sys.stdout.write(sys.version[[0]])") 2>/dev/null`
+ AC_MSG_RESULT($PYVER)
+ if test -z "$PYVER"; then
+ PYVER=0
+ fi
fi
- # look for the header files & set LUAFLAGS accordingly
- # will clear LUABIN if not present
- if test -n "$LUAINCLUDE"; then
- AC_CHECK_FILE($LUAINCLUDE/lua.h,[LUAFLAGS="-I$LUAINCLUDE"],[LUABIN=])
- else
- LUA_OK="1"
- CFLAGS_SAVED=$CFLAGS
- CFLAGS= # Use empty CFLAGS to avoid failure: "present but cannot be compiled"
- AC_CHECK_HEADER([lua.h],[LUAFLAGS=""],[LUA_OK=""])
- CFLAGS=$CFLAGS_SAVED
- # if we didn't get it, going to have to look elsewhere (the hard way)
- if test -z "$LUA_OK"; then
- AC_MSG_CHECKING(for lua.h in other locations)
- # note: Debian/Ubuntu seem to like /usr/include/lua5.1/lua.h
- # The ordering of the include directories to search should match
- # the ordering of libraries to search in the library test below.
- inc=/usr/include
- incloc=/usr/local/include
- dirs="$inc/lua$LUA_VERSION"
- test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $inc/lua$LUA_VERSION_NO_DOTS"
- dirs="$dirs $incloc/lua$LUA_VERSION"
- test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $incloc/lua$LUA_VERSION_NO_DOTS"
- dirs="$dirs $incloc"
+ if test $PYVER -ge 3; then
+ AC_MSG_CHECKING(for Python 3.x os.name)
+ PY3OSNAME=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
+ AC_MSG_RESULT($PY3OSNAME)
+ AC_MSG_CHECKING(for Python 3.x path separator)
+ PYSEPARATOR=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
+ AC_MSG_RESULT($PYSEPARATOR)
+
+ if test x"$PY3OSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
+ # Windows installations are quite different to posix installations
+ # There is no python-config to use
+ AC_MSG_CHECKING(for Python 3.x prefix)
+ PY3PREFIX=`($PYTHON3 -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
+ AC_MSG_RESULT($PY3PREFIX)
+ PY3PREFIX=`echo "$PY3PREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
+ PYTHON_SO=.pyd
+
+ AC_MSG_CHECKING(for Python 3.x header files)
+ if test -r $PY3PREFIX/include/Python.h; then
+ PY3INCLUDE="-I$PY3PREFIX/include"
+ fi
+ AC_MSG_RESULT($PY3INCLUDE)
+
+ AC_MSG_CHECKING(for Python 3.x library directory)
+ if test -d $PY3PREFIX/libs; then
+ PY3LIB=$PY3PREFIX/libs
+ PY3LINKFILE=`ls $PY3LIB/python*.lib | grep "python[[0-9]][[0-9]]\+\.lib"`
+ if test -r "$PY3LINKFILE"; then
+ PY3LINK=-l`basename $PY3LINKFILE | sed -e 's/\.lib$//'`
+ else
+ PY3LIB=
+ fi
+ fi
+ if test -z "$PY3LIB"; then
+ AC_MSG_RESULT([Not found])
+ else
+ AC_MSG_RESULT($PY3LIB)
+ fi
+ AC_MSG_CHECKING([for Python 3.x library])
+ if test -z "$PY3LINK"; then
+ AC_MSG_RESULT(Not found)
+ else
+ AC_MSG_RESULT($PY3LINK)
+ fi
+ elif test -n "$PY3CONFIG"; then
+ AC_MSG_CHECKING([for Python 3.x prefix])
+ PY3PREFIX=`($PY3CONFIG --prefix) 2>/dev/null`
+ AC_MSG_RESULT($PY3PREFIX)
+ AC_MSG_CHECKING(for Python 3.x exec-prefix)
+ # Piped through xargs to strip trailing whitespace (bug in msys2 + mingw Python)
+ PY3EPREFIX=`($PY3CONFIG --exec-prefix | xargs) 2>/dev/null`
+ AC_MSG_RESULT($PY3EPREFIX)
+
+ # Note: I could not think of a standard way to get the version string from different versions.
+ # This trick pulls it out of the file location for a standard library file.
+
+ AC_MSG_CHECKING([for Python 3.x version])
+
+ # Need to do this hack since autoconf replaces __file__ with the name of the configure file
+ filehack="file__"
+ PY3VERSION=`($PYTHON3 -c "import string,operator,os.path; print(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
+ AC_MSG_RESULT($PY3VERSION)
+
+ # Find the directory for libraries this is necessary to deal with
+ # platforms that can have apps built for multiple archs: e.g. x86_64
+ AC_MSG_CHECKING([for Python 3.x lib dir])
+ PY3LIBDIR=`($PYTHON3 -c "import sys; print(sys.lib)") 2>/dev/null`
+ if test -z "$PY3LIBDIR"; then
+ # some dists don't have sys.lib so the best we can do is assume lib
+ PY3LIBDIR="lib"
+ fi
+ AC_MSG_RESULT($PY3LIBDIR)
+
+ # Set the include directory
+
+ AC_MSG_CHECKING([for Python 3.x header files])
+ PY3INCLUDE=`($PY3CONFIG --includes) 2>/dev/null`
+ AC_MSG_RESULT($PY3INCLUDE)
+
+ # Set the library directory blindly. This probably won't work with older versions
+ AC_MSG_CHECKING([for Python 3.x library directory])
+ dirs="$PY3VERSION/config $PY3VERSION/$PY3LIBDIR python/$PY3LIBDIR"
for i in $dirs; do
- #echo "$i"
- if test -r $i/lua.h; then
- AC_MSG_RESULT($i/lua.h)
- LUAFLAGS="-I$i"
+ if test -d $PY3EPREFIX/$PY3LIBDIR/$i; then
+ PY3LIB="$PY3EPREFIX/$PY3LIBDIR/$i"
break
fi
done
- if test -z "$LUAFLAGS"; then
- AC_MSG_RESULT(not found)
- LUABIN="" # clear the bin
+ if test -z "$PY3LIB"; then
+ # Last resort
+ if test -d $PY3EPREFIX/$PY3LIBDIR; then
+ PY3LIB="$PY3EPREFIX/$PY3LIBDIR"
+ fi
+ fi
+ if test -z "$PY3LIB"; then
+ AC_MSG_RESULT([Not found])
+ else
+ AC_MSG_RESULT($PY3LIB)
fi
- fi
- fi
- # look for the library files & set LUALINK accordingly
- # will clear LUABIN if not present
- lua_save_LIBS=$LIBS # the code seems to disrupt LIBS, so saving
+ PY3LINK="-l$PY3VERSION"
- if test -n "$LUALIB"; then
- AC_CHECK_FILE($LUALIB/liblua.a,[LUALINK="-L$LUALIB -llua"],[LUABIN=])
- else
- libs="lua lua$LUA_VERSION"
- test -z "$LUA_VERSION_NO_DOTS" || libs="$libs lua$LUA_VERSION_NO_DOTS"
- AC_SEARCH_LIBS(lua_close, [$libs], [LUALINK="-l$ac_lib"],[LUABIN=])
+ AC_MSG_CHECKING([for Python 3.x library])
+ if test -z "$PY3LINK"; then
+ AC_MSG_RESULT(Not found)
+ else
+ AC_MSG_RESULT($PY3LINK)
+ fi
+ fi
fi
- # adding lualib for lua 5.0
- if test "$LUA_VERSION" = "5.0"; then
- LUALINK="$LUALINK -llualib"
- fi
+ # Cygwin (Windows) needs the library for dynamic linking
+ case $host in
+ *-*-cygwin* | *-*-mingw*)
+ # PYTHON3DYNAMICLINKING ought to be replaced by $PY3CONFIG --ldflags
+ PYTHON3DYNAMICLINKING="-L$PY3LIB $PY3LINK"
+ DEFS="-DUSE_DL_IMPORT $DEFS"
+ ;;
+ *-*-aix*)
+ PYTHON3DYNAMICLINKING="-L$PY3LIB $PY3LINK"
+ ;;
+ *)PYTHON3DYNAMICLINKING="";;
+ esac
- LIBS=$lua_save_LIBS # restore LIBS
+ AC_SUBST(PY3INCLUDE)
+ AC_SUBST(PY3LIB)
+ AC_SUBST(PY3LINK)
+ AC_SUBST(PYTHON3DYNAMICLINKING)
fi
-fi # if not disabled
-
-AC_SUBST(LUADYNAMICLINKING)
-AC_SUBST(LUAFLAGS)
-AC_SUBST(LUALINK)
-AC_SUBST(LUABIN)
+if test -n "$PYINCLUDE" || test -n "$PY3INCLUDE" ; then
+ AC_CHECK_PROGS(PYCODESTYLE, pycodestyle)
+ if test -n "$PYCODESTYLE"; then
+ AC_MSG_CHECKING(pycodestyle version)
+ pycodestyle_version=`$PYCODESTYLE --version 2>/dev/null`
+ AC_MSG_RESULT($pycodestyle_version)
+ fi
+fi
#----------------------------------------------------------------
-# Look for GNU R
+# Look for R
#----------------------------------------------------------------
RBIN=
@@ -2438,220 +2253,413 @@ fi
AC_SUBST(RBIN)
#----------------------------------------------------------------
-# Look for Go compilers
+# Look for Ruby
#----------------------------------------------------------------
-AC_ARG_WITH(go, AS_HELP_STRING([--without-go], [Disable Go])
-AS_HELP_STRING([--with-go=path], [Set location of Go compiler]),[GOBIN="$withval"], [GOBIN="$alllang_default"])
+RUBYBIN=
-if test x"${GOBIN}" = xno; then
- AC_MSG_NOTICE([Disabling Go])
- GO=
- GOGCC=false
- GCCGO=
- GOOPT=
- GCCGOOPT=
- GOVERSIONOPTION=
+AC_ARG_WITH(ruby, AS_HELP_STRING([--without-ruby], [Disable Ruby])
+AS_HELP_STRING([--with-ruby=path], [Set location of Ruby executable]),[ RUBYBIN="$withval"], [RUBYBIN="$alllang_default"])
+
+# First, check for "--without-ruby" or "--with-ruby=no".
+RUBYSO=$SO
+if test x"${RUBYBIN}" = xno; then
+AC_MSG_NOTICE([Disabling Ruby])
+RUBY=
else
- if test "x$GOBIN" = xyes; then
- AC_CHECK_PROGS(GO, go)
+# First figure out what the name of Ruby is
+
+if test "x$RUBYBIN" = xyes; then
+ AC_CHECK_PROGS(RUBY, ruby)
+else
+ RUBY="$RUBYBIN"
+fi
+
+AC_MSG_CHECKING(for Ruby header files)
+if test -n "$RUBY"; then
+ # Try Ruby1.9+ first
+ RUBYDIR=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["rubyhdrdir"]] || $rubyhdrdir') 2>/dev/null`
+ RUBYARCHHDRDIR=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["rubyarchhdrdir"]] || $rubyarchhdrdir') 2>/dev/null`
+ if test x"$RUBYDIR" = x"" || test x"$RUBYDIR" = x"nil"; then
+ RUBYDIR=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["archdir"]] || $archdir') 2>/dev/null`
+ else
+ RUBYARCH=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["arch"]] || $arch') 2>/dev/null`
+ fi
+ if test x"$RUBYDIR" != x""; then
+ dirs="$RUBYDIR"
+ RUBYINCLUDE=
+ for i in $dirs; do
+ if test -r $i/ruby.h; then
+ if test x"$RUBYARCH" = x""; then
+ RUBYINCLUDE="-I$i"
+ elif test -n "$RUBYARCHHDRDIR"; then
+ RUBYINCLUDE="-I$i -I$RUBYARCHHDRDIR"
+ else
+ RUBYINCLUDE="-I$i -I$i/$RUBYARCH"
+ fi
+ AC_MSG_RESULT($RUBYINCLUDE)
+ break
+ fi
+ done
+ if test x"$RUBYINCLUDE" = x""; then
+ AC_MSG_RESULT(could not locate ruby.h)
+ fi
+
+ # Find library and path for linking.
+ AC_MSG_CHECKING(for Ruby library)
+ RUBYLIB=""
+ rb_archlibdir=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["archlibdir"]]') 2>/dev/null`
+ rb_libdir=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["libdir"]]') 2>/dev/null`
+ rb_bindir=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["bindir"]]') 2>/dev/null`
+ dirs="$dirs $rb_archlibdir $rb_libdir $rb_bindir"
+
+ rb_libruby=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["LIBRUBY_A"]]') 2>/dev/null`
+ RUBYLINK=`($RUBY -rrbconfig -e '
+ c = RbConfig::CONFIG
+ if c.has_key? "LIBRUBYARG_STATIC" # 1.8.x
+ if c[["LIBRUBY"]] == c[["LIBRUBY_A"]]
+ link = c[["LIBRUBYARG_STATIC"]]
+ else
+ link = c[["LIBRUBYARG_SHARED"]]
+ end
+ else # 1.6.x
+ link = "-l" + c[["RUBY_INSTALL_NAME"]]
+ end
+
+ # Get the target Ruby was built for
+ target = c[["target"]]
+
+ if target == "i386-pc-mswin32"
+ # Need to change msvcrt-ruby*.lib to -lmsvcrt-ruby*
+ ext = File.extname(link)
+ # Get index that counts backwards from end of string
+ index = -1 - ext.size
+ # Strip off the extension
+ link = link.slice(0..index)
+ puts "-l#{link}"
+ else
+ puts link
+ end') 2>/dev/null`
+
+ if test "$rb_libruby" != ""; then
+ for i in $dirs; do
+ if (test -r $i/$rb_libruby;) then
+ RUBYLIB="$i"
+ break
+ fi
+ done
+ fi
+ if test "$RUBYLIB" = ""; then
+ RUBYLIB="$RUBYDIR"
+ AC_MSG_RESULT(not found... using $RUBYDIR)
+ else
+ AC_MSG_RESULT($RUBYLINK in $RUBYLIB)
+ fi
+ else
+ AC_MSG_RESULT(unable to determine ruby configuration)
+ fi
+
+ case $host in
+ *-*-mingw*) ;; # do nothing, the default windows libraries are already included
+ *) RUBYLINK="$RUBYLINK `($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["LIBS"]]') 2>/dev/null`";;
+ esac
+
+ RUBYCCDLFLAGS=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["CCDLFLAGS"]]') 2>/dev/null`
+ RUBYSO=.`($RUBY -rrbconfig -e 'print RbConfig::CONFIG[["DLEXT"]]') 2>/dev/null`
+else
+ AC_MSG_RESULT(could not figure out how to run ruby)
+fi
+
+case $host in
+*-*-cygwin* | *-*-mingw*) RUBYDYNAMICLINKING="-L$RUBYLIB $RUBYLINK";;
+*) RUBYDYNAMICLINKING="";;
+esac
+fi
+
+AC_SUBST(RUBYINCLUDE)
+AC_SUBST(RUBYLIB)
+AC_SUBST(RUBYLINK)
+AC_SUBST(RUBYCCDLFLAGS)
+AC_SUBST(RUBYSO)
+AC_SUBST(RUBYDYNAMICLINKING)
+
+#----------------------------------------------------------------
+# Look for Scilab
+#----------------------------------------------------------------
+
+AC_ARG_WITH(scilab, AS_HELP_STRING([--without-scilab], [Disable Scilab])
+AS_HELP_STRING([--with-scilab=path], [Set location of Scilab executable]),[SCILABBIN="$withval"], [SCILABBIN="$alllang_default"])
+AC_ARG_WITH(scilab-inc, [ --with-scilab-inc=path Set location of Scilab include directory], [SCILABINCDIR="$withval"], [SCILABINCDIR=""])
+
+# First, check for "--without-scilab" or "--with-scilab=no".
+if test x"${SCILABBIN}" = xno; then
+ AC_MSG_NOTICE([Disabling Scilab])
+ SCILAB=
+else
+ # Check for Scilab executable
+ if test "x$SCILABBIN" = xyes; then
+ AC_PATH_PROG(SCILAB, scilab)
else
- GO="$GOBIN"
+ AC_MSG_CHECKING(for scilab)
+ if test -f "$SCILABBIN"; then
+ AC_MSG_RESULT($SCILABBIN)
+ SCILAB="$SCILABBIN"
+ else
+ AC_MSG_RESULT(not found)
+ fi
fi
- GOGCC=false
- GCCGO=
- GOOPT=
- GCCGOOPT=
- GOVERSIONOPTION=
+ if test -n "$SCILAB"; then
+ # Check for Scilab version (needs api_scilab so needs version 5.3.3 or higher)
+ SCILAB_VERSION=`$SCILAB -nwni -version | head -1 | sed -e 's|Scilab version \"\(.*\)\"|\1|g'`
- if test -n "$GO" ; then
- GOVERSIONOPTION=version
- go_version=$($GO $GOVERSIONOPTION | sed -e 's/go version //')
- AC_MSG_CHECKING([whether go version is too old])
- case $go_version in
- go1.[012]*)
- AC_MSG_RESULT([yes - minimum version is 1.3])
- GO=
- GOOPT="-intgosize 32"
- ;;
- *)
- AC_MSG_RESULT([no])
- case "$(go env GOARCH)" in
- amd64 | arm64 | ppc64*)
- GOOPT="-intgosize 64"
- ;;
- *)
- GOOPT="-intgosize 32"
- ;;
- esac
- ;;
- esac
- fi
+ AC_MSG_CHECKING(Scilab version is 5.3.3 or higher)
+ SCILAB_MAJOR_VERSION=`echo $SCILAB_VERSION | cut -d. -f1`
+ SCILAB_MINOR_VERSION=`echo $SCILAB_VERSION | cut -d. -f2`
+ SCILAB_MAINTENANCE_VERSION=`echo $SCILAB_VERSION | cut -d. -f3`
+ SCILAB_VERSION_NO_DOTS="$SCILAB_MAJOR_VERSION$SCILAB_MINOR_VERSION$SCILAB_MAINTENANCE_VERSION"
- AC_CHECK_PROGS(GCCGO, gccgo)
+ if test -n "$SCILAB_VERSION_NO_DOTS" && test "$SCILAB_VERSION_NO_DOTS" -ge 533; then
+ AC_MSG_RESULT(yes - $SCILAB_VERSION)
+ else
+ AC_MSG_RESULT(no - $SCILAB_VERSION)
+ SCILAB=
+ fi
- if test -n "$GCCGO" ; then
- if $GCCGO --help 2>/dev/null | grep gccgo >/dev/null 2>&1 ; then
- AC_MSG_CHECKING([whether gccgo version is too old])
- go_version=[`$GO $GOVERSIONOPTION | sed -n '1p' | sed -e 's/^.* \([0-9.]*\) *$/\1/' -e 's/[.]//g'`]
- if test "x$go_version" = x; then
- AC_MSG_RESULT([could not determine gccgo version])
- GCCGO=
- elif test "$go_version" -lt 470; then
- AC_MSG_RESULT([yes - minimum version is 4.7.0])
- GCCGO=
+ if test -n "$SCILAB"; then
+ # Set Scilab startup options depending on version
+ AC_MSG_CHECKING(for Scilab startup options)
+ SCILABOPT="-nwni -nb"
+ if test $SCILAB_VERSION_NO_DOTS -ge 540; then
+ SCILABOPT+=" -noatomsautoload"
+ fi
+ if test $SCILAB_VERSION_NO_DOTS -ge 600; then
+ SCILABOPT+=" -quit"
+ fi
+ AC_MSG_RESULT($SCILABOPT)
+
+ # Check for Scilab header files
+ AC_MSG_CHECKING(for Scilab header files)
+ headers="`AS_DIRNAME(["$SCILAB"])`/../include"
+ if test "$SCILABINCDIR" != ""; then
+ dirs="$SCILABINCDIR"
+ elif test -d "$SCI"; then
+ dirs="$SCI/include $SCI/../../include"
+ elif test -d "$headers"; then
+ dirs="$headers"
+ elif test -n "$PKG_CONFIG "; then
+ dirs=`$PKG_CONFIG scilab --cflags-only-I | sed -e 's/-I//g'`
else
- AC_MSG_RESULT([no])
- if test "$go_version" -lt 480; then
- GCCGOOPT="-intgosize 32"
- else
- AC_CHECK_SIZEOF([void *], [4])
- if test "$ac_cv_sizeof_void_p" = "8"; then
- GCCGOOPT="-intgosize 64"
- else
- GCCGOOPT="-intgosize 32"
- fi
+ dirs="/usr/include"
+ fi
+ for i in $dirs; do
+ if test -r $i/api_scilab.h; then
+ AC_MSG_RESULT($i)
+ SCILABINCLUDE="-I$i"
+ break
+ fi
+ if test -r $i/scilab/api_scilab.h; then
+ AC_MSG_RESULT($i/scilab)
+ SCILABINCLUDE="-I$i/scilab"
+ break
fi
+ done
+ if test "$SCILABINCLUDE" = "" ; then
+ AC_MSG_RESULT(not found)
+ SCILAB=
fi
fi
fi
fi
-AC_SUBST(GOGCC)
-AC_SUBST(GCCGO)
-AC_SUBST(GO)
-AC_SUBST(GOC)
-AC_SUBST(GO1)
-AC_SUBST(GO12)
-AC_SUBST(GO13)
-AC_SUBST(GO15)
-AC_SUBST(GOOPT)
-AC_SUBST(GCCGOOPT)
-AC_SUBST(GOVERSIONOPTION)
+AC_SUBST(SCILAB)
+AC_SUBST(SCILABINCLUDE)
+AC_SUBST(SCILABOPT)
+AC_SUBST(SCILAB_VERSION)
-#----------------------------------------------------------------
-# Look for D
-#----------------------------------------------------------------
+#--------------------------------------------------------------------
+# Look for Tcl
+#--------------------------------------------------------------------
-AC_ARG_WITH(d, AS_HELP_STRING([--without-d], [Disable D]), [with_d="$withval"], [with_d="$alllang_default"])
-AC_ARG_WITH(d1-compiler, [ --with-d1-compiler=path Set location of D1/Tango compiler (DMD compatible)],[D1COMPILERBIN="$withval"], [D1COMPILERBIN=])
-AC_ARG_WITH(d2-compiler, [ --with-d2-compiler=path Set location of D2 compiler (DMD compatible)],[D2COMPILERBIN="$withval"], [D2COMPILERBIN=])
+TCLINCLUDE=
+TCLLIB=
+TCLPACKAGE=
+TCLLINK=
+AC_ARG_WITH(tclconfig, AS_HELP_STRING([--without-tcl], [Disable Tcl])
+AS_HELP_STRING([--with-tclconfig=path], [Set location of tclConfig.sh]), [with_tclconfig="$withval"], [with_tclconfig=])
+AC_ARG_WITH(tcl,
+ [ --with-tcl=path Set location of Tcl package],[
+ TCLPACKAGE="$withval"], [TCLPACKAGE="$alllang_default"])
+AC_ARG_WITH(tclincl,[ --with-tclincl=path Set location of Tcl include directory],[
+ TCLINCLUDE="-I$withval"], [TCLINCLUDE=])
+AC_ARG_WITH(tcllib,[ --with-tcllib=path Set location of Tcl library directory],[
+ TCLLIB="-L$withval"], [TCLLIB=])
-# First, check for "--without-d" or "--with-d=no".
-if test x"${with_d}" = xno; then
- AC_MSG_NOTICE([Disabling D])
- D1COMPILER=
- D2COMPILER=
+# First, check for "--without-tcl" or "--with-tcl=no".
+if test x"${TCLPACKAGE}" = xno; then
+AC_MSG_NOTICE([Disabling Tcl])
else
- old_ac_ext=$ac_ext
- ac_ext=d
-
- if test -z "$D1COMPILERBIN" ; then
- AC_CHECK_PROGS(D1COMPILER, dmd ldmd gdmd)
-
- if test -n "$D1COMPILER" ; then
- AC_MSG_CHECKING(whether the D1/Tango compiler works)
- cat > conftest.$ac_ext <<_ACEOF
-import tango.io.Stdout;
-void main() {
-}
-_ACEOF
- rm -f conftest.$ac_objext
- AS_IF(
- [$D1COMPILER conftest.$ac_ext 2>&AS_MESSAGE_LOG_FD && test ! -s conftest.err && test -s conftest.$ac_objext],
- [AC_MSG_RESULT([yes])],
- [_AC_MSG_LOG_CONFTEST AC_MSG_RESULT([no])
- D1COMPILER=]
- )
- rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+AC_MSG_CHECKING([for Tcl configuration])
+# First check to see if --with-tclconfig was specified.
+if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ TCLCONFIG=`(cd ${with_tclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tcl} directory does not contain tclConfig.sh])
+ fi
+fi
+# check in a few common install locations
+dirs="/usr/lib*/ /usr/lib*/tcl*/ /usr/local/lib*/ /usr/local/lib*/tcl*/"
+case $host in
+*-*-darwin*)
+ tcl_framework="/System/Library/Frameworks/Tcl.framework/"
+ macos_sysroot="$(xcodebuild -version -sdk macosx Path 2>/dev/null)" # For MacOSX10.14 and later
+ dirs="$macos_sysroot$tcl_framework $tcl_framework $dirs"
+ ;;
+*)
+ ;;
+esac
+if test x"${TCLCONFIG}" = x ; then
+ for d in $dirs ; do
+ for i in `ls -d -r $d 2>/dev/null` ; do
+ if test -f $i"tclConfig.sh" ; then
+ TCLCONFIG=`(cd $i; pwd)`
+ break
+ fi
+ done
+ done
+fi
+if test x"${TCLCONFIG}" = x ; then
+ AC_MSG_RESULT(no)
+else
+ AC_MSG_RESULT(found $TCLCONFIG/tclConfig.sh)
+ . $TCLCONFIG/tclConfig.sh
+ if test -z "$TCLINCLUDE"; then
+ TCLINCLUDE=`echo $TCL_INCLUDE_SPEC`
fi
- else
- D1COMPILER="$D1COMPILERBIN"
- fi
+ if test -z "$TCLLIB"; then
+ TCLLIB=$TCL_LIB_SPEC
+ fi
+fi
- if test -z "$D2COMPILERBIN" ; then
- AC_CHECK_PROGS(D2COMPILER, dmd gdmd)
+if test -z "$TCLINCLUDE"; then
+ if test "x$TCLPACKAGE" != xyes; then
+ TCLINCLUDE="-I$TCLPACKAGE/include"
+ fi
+fi
- if test -n "$D2COMPILER" ; then
- AC_MSG_CHECKING(whether the D2 compiler works)
- cat > conftest.$ac_ext <<_ACEOF
-import std.algorithm;
-void main() {
-}
-_ACEOF
- rm -f conftest.$ac_objext
- AS_IF(
- [$D2COMPILER conftest.$ac_ext 2>&AS_MESSAGE_LOG_FD && test ! -s conftest.err && test -s conftest.$ac_objext],
- [AC_MSG_RESULT([yes])],
- [_AC_MSG_LOG_CONFTEST AC_MSG_RESULT([no])
- D2COMPILER=]
- )
- rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- else
- D2COMPILER="$D2COMPILERBIN"
- fi
+if test -z "$TCLLIB"; then
+ if test "x$TCLPACKAGE" != xyes; then
+ TCLLIB="-L$TCLPACKAGE/lib -ltcl"
+ fi
+fi
- ac_ext=$old_ac_ext
+AC_MSG_CHECKING(for Tcl header files)
+if test -z "$TCLINCLUDE"; then
+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <tcl.h>]])],[],[TCLINCLUDE=""])
+if test -z "$TCLINCLUDE"; then
+ dirs="/usr/local/include /usr/include /opt/local/include"
+ for i in $dirs ; do
+ if test -r $i/tcl.h; then
+ AC_MSG_RESULT($i)
+ TCLINCLUDE="-I$i"
+ break
+ fi
+ done
+fi
+if test -z "$TCLINCLUDE"; then
+ AC_MSG_RESULT(not found)
+fi
+else
+ AC_MSG_RESULT($TCLINCLUDE)
fi
-if test -n "$D1COMPILER"; then
- DDEFAULTVERSION=1
-elif test -n "$D2COMPILER"; then
- DDEFAULTVERSION=2
+AC_MSG_CHECKING(for Tcl library)
+if test -z "$TCLLIB"; then
+dirs="/usr/local/lib /usr/lib /opt/local/lib /opt/freeware/lib"
+for i in $dirs ; do
+ if test -r $i/libtcl.a; then
+ AC_MSG_RESULT($i)
+ TCLLIB="-L$i -ltcl"
+ break
+ fi
+done
+if test -z "$TCLLIB"; then
+ AC_MSG_RESULT(not found)
+fi
+else
+AC_MSG_RESULT($TCLLIB)
fi
-# Do not prefix library file names with "lib" on Windows.
+# Cygwin (Windows) needs the library for dynamic linking
case $host in
-*-*-cygwin* | *-*-mingw*) DLIBPREFIX="";;
-*)DLIBPREFIX="lib";;
+*-*-cygwin* | *-*-mingw*) TCLDYNAMICLINKING="$TCLLIB";;
+*-*-aix*) TCLDYNAMICLINKING="$TCLLIB";;
+*)TCLDYNAMICLINKING="";;
esac
-AC_SUBST(D1COMPILER)
-AC_SUBST(D2COMPILER)
-AC_SUBST(DDEFAULTVERSION)
-AC_SUBST(DLIBPREFIX)
+# AIX needs -ltcl for linking at test time
+case $host in
+*-*-aix*) TCLLINK="-ltcl";;
+*)TCLLINK="";;
+esac
+
+case $host in
+*-*-darwin*)
+ TCLLDSHARED='$(CC) -dynamiclib -undefined suppress -flat_namespace'
+ TCLCXXSHARED='$(CXX) -dynamiclib -undefined suppress -flat_namespace'
+ ;;
+*)
+ TCLLDSHARED='$(LDSHARED)'
+ TCLCXXSHARED='$(CXXSHARED)'
+ ;;
+esac
+
+fi
+
+AC_SUBST(TCLINCLUDE)
+AC_SUBST(TCLLIB)
+AC_SUBST(TCLDYNAMICLINKING)
+AC_SUBST(TCLLDSHARED)
+AC_SUBST(TCLCXXSHARED)
+AC_SUBST(TCLLINK)
#----------------------------------------------------------------
# Determine which languages to use for examples/test-suite
#----------------------------------------------------------------
-SKIP_TCL=
-if test -z "$TCLINCLUDE" || test -z "$TCLLIB" ; then
- SKIP_TCL="1"
+SKIP_CSHARP=
+if test -z "$CSHARPCOMPILER" ; then
+ SKIP_CSHARP="1"
+else
+ if test "cscc" = "$CSHARPCOMPILER" && test -z "$CSHARPCILINTERPRETER" ; then
+ SKIP_CSHARP="1"
+ fi
fi
-AC_SUBST(SKIP_TCL)
+AC_SUBST(SKIP_CSHARP)
-SKIP_PERL5=
-if test -z "$PERL" || test -z "$PERL5EXT" || test -z "$PERL5TESTMORE"; then
- SKIP_PERL5="1"
+SKIP_D=
+if test -z "$DDEFAULTVERSION" ; then
+ SKIP_D="1"
fi
-AC_SUBST(SKIP_PERL5)
+AC_SUBST(SKIP_D)
-SKIP_OCTAVE=
-if test -z "$OCTAVE" ; then
- SKIP_OCTAVE="1"
+SKIP_GO=
+if test -z "$GO" ; then
+ SKIP_GO="1"
fi
-AC_SUBST(SKIP_OCTAVE)
+AC_SUBST(SKIP_GO)
-SKIP_PYTHON=
-if (test -z "$PYINCLUDE" || test -z "$PYLINK") &&
- (test -z "$PY3INCLUDE" || test -z "$PY3LINK") ; then
- SKIP_PYTHON="1"
-fi
-AC_SUBST(SKIP_PYTHON)
-
-SKIP_PYTHON3=
-if test -z "$PY3INCLUDE" || test -z "$PY3LINK" ; then
- SKIP_PYTHON3="1"
+SKIP_GUILE=
+if test -z "$GUILE" || test -z "$GUILE_LIBS" ; then
+ SKIP_GUILE="1"
fi
-AC_SUBST(SKIP_PYTHON3)
+AC_SUBST(SKIP_GUILE)
SKIP_JAVA=
if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then
@@ -2659,17 +2667,20 @@ if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then
fi
AC_SUBST(SKIP_JAVA)
+
SKIP_JAVASCRIPT=
if test -z "$JAVASCRIPT" || ( test -z "$NODEJS" && test -z "$JSCENABLED" && test -z "$JSV8ENABLED" ) ; then
SKIP_JAVASCRIPT="1"
fi
AC_SUBST(SKIP_JAVASCRIPT)
-SKIP_GUILE=
-if test -z "$GUILE" || test -z "$GUILE_LIBS" ; then
- SKIP_GUILE="1"
+
+SKIP_LUA=
+# we need LUABIN & dynamic loading
+if test -z "$LUABIN" || test -z "$LUADYNAMICLOADLIB"; then
+ SKIP_LUA="1"
fi
-AC_SUBST(SKIP_GUILE)
+AC_SUBST(SKIP_LUA)
SKIP_MZSCHEME=
@@ -2679,11 +2690,18 @@ fi
AC_SUBST(SKIP_MZSCHEME)
-SKIP_RUBY=
-if test -z "$RUBY" || test -z "$RUBYINCLUDE" || test -z "$RUBYLIB" ; then
- SKIP_RUBY="1"
+SKIP_OCAML=
+if test -z "$OCAMLC" || test -z "$CAMLP4" ; then
+ SKIP_OCAML="1"
fi
-AC_SUBST(SKIP_RUBY)
+AC_SUBST(SKIP_OCAML)
+
+
+SKIP_OCTAVE=
+if test -z "$OCTAVE" ; then
+ SKIP_OCTAVE="1"
+fi
+AC_SUBST(SKIP_OCTAVE)
SKIP_PHP=
@@ -2693,29 +2711,27 @@ fi
AC_SUBST(SKIP_PHP)
-SKIP_OCAML=
-if test -z "$OCAMLC" || test -z "$CAMLP4" ; then
- SKIP_OCAML="1"
+SKIP_PERL5=
+if test -z "$PERL" || test -z "$PERL5EXT" || test -z "$PERL5TESTMORE"; then
+ SKIP_PERL5="1"
fi
-AC_SUBST(SKIP_OCAML)
+AC_SUBST(SKIP_PERL5)
-SKIP_CSHARP=
-if test -z "$CSHARPCOMPILER" ; then
- SKIP_CSHARP="1"
-else
- if test "cscc" = "$CSHARPCOMPILER" && test -z "$CSHARPCILINTERPRETER" ; then
- SKIP_CSHARP="1"
- fi
+SKIP_PYTHON=
+if (test -z "$PYINCLUDE" || test -z "$PYLINK") &&
+ (test -z "$PY3INCLUDE" || test -z "$PY3LINK") ; then
+ SKIP_PYTHON="1"
fi
-AC_SUBST(SKIP_CSHARP)
+AC_SUBST(SKIP_PYTHON)
-SKIP_LUA=
-# we need LUABIN & dynamic loading
-if test -z "$LUABIN" || test -z "$LUADYNAMICLOADLIB"; then
- SKIP_LUA="1"
+
+SKIP_PYTHON3=
+if test -z "$PY3INCLUDE" || test -z "$PY3LINK" ; then
+ SKIP_PYTHON3="1"
fi
-AC_SUBST(SKIP_LUA)
+AC_SUBST(SKIP_PYTHON3)
+
SKIP_R=
if test -z "$RBIN" ; then
@@ -2723,23 +2739,27 @@ if test -z "$RBIN" ; then
fi
AC_SUBST(SKIP_R)
+
+SKIP_RUBY=
+if test -z "$RUBY" || test -z "$RUBYINCLUDE" || test -z "$RUBYLIB" ; then
+ SKIP_RUBY="1"
+fi
+AC_SUBST(SKIP_RUBY)
+
+
SKIP_SCILAB=
if test -z "$SCILAB"; then
SKIP_SCILAB="1"
fi
AC_SUBST(SKIP_SCILAB)
-SKIP_GO=
-if test -z "$GO" ; then
- SKIP_GO="1"
-fi
-AC_SUBST(SKIP_GO)
-SKIP_D=
-if test -z "$DDEFAULTVERSION" ; then
- SKIP_D="1"
+SKIP_TCL=
+if test -z "$TCLINCLUDE" || test -z "$TCLLIB" ; then
+ SKIP_TCL="1"
fi
-AC_SUBST(SKIP_D)
+AC_SUBST(SKIP_TCL)
+
#----------------------------------------------------------------
# Additional language dependencies
@@ -2825,28 +2845,27 @@ AC_SUBST(SWIG_LIB_SET)
AC_CONFIG_FILES([
Makefile
- swig.spec
Examples/Makefile
Examples/d/example.mk
Examples/xml/Makefile
Examples/test-suite/errors/Makefile
Examples/test-suite/csharp/Makefile
Examples/test-suite/d/Makefile
+ Examples/test-suite/go/Makefile
Examples/test-suite/guile/Makefile
Examples/test-suite/java/Makefile
Examples/test-suite/javascript/Makefile
+ Examples/test-suite/lua/Makefile
Examples/test-suite/mzscheme/Makefile
Examples/test-suite/ocaml/Makefile
Examples/test-suite/octave/Makefile
Examples/test-suite/perl5/Makefile
Examples/test-suite/php/Makefile
Examples/test-suite/python/Makefile
+ Examples/test-suite/r/Makefile
Examples/test-suite/ruby/Makefile
Examples/test-suite/scilab/Makefile
Examples/test-suite/tcl/Makefile
- Examples/test-suite/lua/Makefile
- Examples/test-suite/r/Makefile
- Examples/test-suite/go/Makefile
Source/Makefile
Tools/javascript/Makefile
])
diff --git a/swig.spec.in b/swig.spec.in
deleted file mode 100644
index 140b96206..000000000
--- a/swig.spec.in
+++ /dev/null
@@ -1,70 +0,0 @@
-# You can build the package from Git using something like:
-# tar -czf swig-@PACKAGE_VERSION@.tar.gz swig-@PACKAGE_VERSION@ && rpmbuild -tb swig-@PACKAGE_VERSION@.tar.gz
-# @configure_input@
-
-%define ver @PACKAGE_VERSION@
-%define rel 1
-%define prefix /usr
-%define home_page http://www.swig.org
-%define docprefix %{prefix}/share
-
-######################################################################
-# Usually, nothing needs to be changed below here between releases
-######################################################################
-Summary: Simplified Wrapper and Interface Generator
-Name: swig
-Version: %{ver}
-Release: %{rel}
-URL: %{home_page}
-Source0: %{name}-%{version}.tar.gz
-License: BSD
-Group: Development/Tools
-BuildRoot: %{_tmppath}/%{name}-root
-
-%description
-SWIG is a software development tool that connects programs written in C and C++
-with a variety of high-level programming languages. SWIG is primarily used with
-common scripting languages such as Perl, Python, Tcl/Tk, and Ruby, however the
-list of supported languages also includes non-scripting languages such as Java,
-OCAML and C#. Also several interpreted and compiled Scheme implementations
-(Guile, MzScheme) are supported. SWIG is most commonly used to create
-high-level interpreted or compiled programming environments, user interfaces,
-and as a tool for testing and prototyping C/C++ software. SWIG can also export
-its parse tree in the form of XML.
-
-%prep
-%setup -q -n %{name}-%{version}
-
-%build
-# so we can build package from Git source too
-[ ! -r configure ] && ./autogen.sh
-%configure
-make
-
-%install
-rm -rf ${RPM_BUILD_ROOT}
-make DESTDIR=$RPM_BUILD_ROOT install
-
-%clean
-rm -rf ${RPM_BUILD_ROOT}
-
-%files
-%defattr(-,root,root)
-%doc ANNOUNCE CHANGES INSTALL LICENSE LICENSE-GPL LICENSE-UNIVERSITIES README RELEASENOTES
-%doc Doc/*
-%{_bindir}/*
-%{prefix}/share/*
-
-%changelog
-* Thu Sep 16 2004 Marcelo Matus <mmatus@acms.arizona.edu>
-- Small fixes needed after removing the runtime package
-* Tue Jul 20 2004 William Fulton <wsf@fultondesigns.co.uk>
-- Update for SWIG-1.3.22 - Removed runtime package
-* Wed Mar 03 2004 Robert H De Vries
-- Update to work with Fedora Core 1 rpm 4.2.1
-* Wed Jul 24 2002 Sam Liddicott <sam@liddicott.com>
-- Added runtime package of runtime libs
-* Mon Sep 10 2001 Tony Seward <anthony.seward@ieee.org>
-- Merge Red Hat's and Dustin Mitchell's .spec files.
-- Install all of the examples in the documentation directory.
-- Auto create the list of installed files.