diff --git a/.gitignore b/.gitignore index 1f1561475..5df510547 100644 --- a/.gitignore +++ b/.gitignore @@ -173,6 +173,8 @@ Examples/ocaml/**/swigp4.ml # Octave swigexample*.oct Examples/test-suite/octave/*.oct +Examples/test-suite/octave/octheaders.hpp +Examples/test-suite/octave/octheaders.hpp.gch # Perl5 Examples/test-suite/perl5/*.pm diff --git a/.travis.yml b/.travis.yml index cedce513d..385e7be42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -146,7 +146,12 @@ matrix: os: linux env: SWIGLANG=octave SWIGJOBS=-j2 sudo: required - dist: xenial + dist: xenial # Octave v4.0.0 + - compiler: gcc + os: linux + env: SWIGLANG=octave SWIGJOBS=-j2 CPP11=1 + sudo: required + dist: bionic # Octave v4.2.2 - compiler: gcc os: linux env: SWIGLANG=perl5 @@ -437,7 +442,7 @@ matrix: env: SWIGLANG=lua - compiler: clang os: osx - env: SWIGLANG=octave SWIGJOBS=-j2 + env: SWIGLANG=octave SWIGJOBS=-j2 CPP11=1 - compiler: clang os: osx env: SWIGLANG=perl5 @@ -475,10 +480,6 @@ matrix: env: SWIGLANG=php VER=7.2 sudo: required dist: xenial - # Sometimes hits the Travis 50 minute time limit - - compiler: clang - os: osx - env: SWIGLANG=octave SWIGJOBS=-j2 # Experimental languages - compiler: gcc os: linux diff --git a/CHANGES.current b/CHANGES.current index b45fee280..3bded39e3 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -16,6 +16,22 @@ Version 4.0.2 (in progress) 2020-05-24: vapier [JS] #1796 Fix pkg-config invocation in configure. +2020-04-30: kwwette + [Octave] Fix exception raising for newer Octave versions + Since (at least) Octave 5.1.0, the Octave error() function now raises a C++ exception, + which if uncaught immediately exits a SWIG wrapper function, bypassing any cleanup code + that may appear after a "fail:" label. This patch adds a "try { ... } catch(...) { }" + block around the contents of SWIG wrapper functions to first execute the cleanup code + before rethrowing any exception raised. It is backward compatible with earlier versions + of Octave where error() does not raise an exception, which will still branch to the + "fail:" block to execute cleanup code if an error is encountered. + + Note that the new "try { ... } catch(...) { }" block will localise any local variables + used in typemaps that were NOT declared through SWIG's %typemap(...) syntax, so it's + possible this could break existing SWIG wrappers which were implicitly sharing local + variables between typemaps. This can be fixed, however, by declaring local variables + which need to be shared between typemaps through SWIG's %typemap(...) syntax. + 2020-02-18: ryannevell [Lua] #1728 Add support for LUA lightuserdata to SWIG_Lua_ConvertPtr. diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 6fbca29db..87386f7eb 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -58,6 +58,7 @@ INTERFACE = INTERFACEDIR = INTERFACEPATH = $(SRCDIR)$(INTERFACEDIR)$(INTERFACE) SWIGOPT = +PCHSUPPORT = @PCHSUPPORT@ # SWIG_LIB_DIR and SWIGEXE must be explicitly set by Makefiles using this Makefile SWIG_LIB_DIR = ./Lib @@ -438,14 +439,37 @@ 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 # ---------------------------------------------------------------- octave: $(SRCDIR_SRCS) - $(SWIG) -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) - $(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX) + $(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) @@ -454,8 +478,8 @@ octave: $(SRCDIR_SRCS) # ----------------------------------------------------------------- octave_cpp: $(SRCDIR_SRCS) - $(SWIG) -c++ -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) - $(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX) + $(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) # ----------------------------------------------------------------- @@ -481,6 +505,7 @@ octave_clean: rm -f *_wrap* *~ .~* myoctave@EXEEXT@ *.pyc rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@SO@ *$(OCTAVE_SO) + rm -f $(OCTHEADERS) $(OCTHEADERSGCH) ################################################################## ##### GUILE ###### diff --git a/Examples/octave/example.mk b/Examples/octave/example.mk index 1ab96f038..88608a12b 100644 --- a/Examples/octave/example.mk +++ b/Examples/octave/example.mk @@ -8,25 +8,25 @@ TARGET = swigexample INTERFACE = example.i check: build - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_run + $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_run build: ifneq (,$(SRCS)) - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \ + $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave else - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \ + $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave_cpp endif ifneq (,$(TARGET2)$(SWIGOPT2)) ifneq (,$(SRCS)) - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \ + $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave else - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \ + $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave_cpp endif @@ -34,4 +34,4 @@ endif clean: - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_clean + $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_clean diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in index 3c8f3b165..1d54a47bb 100644 --- a/Examples/test-suite/octave/Makefile.in +++ b/Examples/test-suite/octave/Makefile.in @@ -5,6 +5,7 @@ LANGUAGE = octave OCTAVE = @OCTAVE@ SCRIPTSUFFIX = _runme.m +PCHSUPPORT = @PCHSUPPORT@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -61,6 +62,23 @@ CSRCS = octave_empty.c +$(swig_and_compile_multi_cpp) $(run_testcase) +# Pre-compile Octave headers, if supported + +ifeq (yes,$(PCHSUPPORT)) + +export OCTHEADERSSRC = @top_srcdir@/Lib/octave/octheaders.hpp +export OCTHEADERS = @top_builddir@/Examples/test-suite/octave/octheaders.hpp +export OCTHEADERSGCH = $(OCTHEADERS).gch +export SWIGOCTHDROPT = -DSWIG_OCTAVE_EXTERNAL_OCTHEADERS +export IOCTHEADERS = -I@top_builddir@/Examples/test-suite/octave @PCHINCLUDEARG@ $(OCTHEADERS)@PCHINCLUDEEXT@ + +$(OCTHEADERSGCH): $(OCTHEADERSSRC) + $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile octave_precompile_headers + +$(NOT_BROKEN_TEST_CASES) $(BROKEN_TEST_CASES): $(OCTHEADERSGCH) + +endif + # Runs the testcase. A testcase is only run if # a file is found which has _runme.m appended after the testcase name. run_testcase = \ diff --git a/Lib/octave/director.swg b/Lib/octave/director.swg index bf71d18e8..5b9cd86e0 100644 --- a/Lib/octave/director.swg +++ b/Lib/octave/director.swg @@ -7,8 +7,6 @@ # define SWIG_DIRECTOR_CAST(ARG) dynamic_cast(ARG) -#include - namespace Swig { class Director { diff --git a/Lib/octave/extra-install.list b/Lib/octave/extra-install.list new file mode 100644 index 000000000..41ef94778 --- /dev/null +++ b/Lib/octave/extra-install.list @@ -0,0 +1,2 @@ +# see top-level Makefile.in +octheaders.hpp diff --git a/Lib/octave/octcontainer.swg b/Lib/octave/octcontainer.swg index 310a849d9..80d593f4f 100644 --- a/Lib/octave/octcontainer.swg +++ b/Lib/octave/octcontainer.swg @@ -11,12 +11,6 @@ * be the case. * ----------------------------------------------------------------------------- */ -%{ -#include -#include -%} - - #if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS) # if !defined(SWIG_EXPORT_ITERATOR_METHODS) # define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS @@ -64,7 +58,6 @@ namespace swig { %fragment("OctSequence_Base","header",fragment="") { -%#include namespace std { template <> diff --git a/Lib/octave/octheaders.hpp b/Lib/octave/octheaders.hpp new file mode 100644 index 000000000..abf6428e7 --- /dev/null +++ b/Lib/octave/octheaders.hpp @@ -0,0 +1,130 @@ +// +// This header includes all C++ headers required for generated Octave wrapper code. +// Using a single header file allows pre-compilation of Octave headers, as follows: +// * Check out this header file: +// swig -octave -co octheaders.hpp +// * Pre-compile header file into octheaders.hpp.gch: +// g++ -c ... octheaders.hpp +// * Use pre-compiled header file: +// g++ -c -include octheaders.hpp ... +// + +#if !defined(_SWIG_OCTAVE_OCTHEADERS_HPP) +#define _SWIG_OCTAVE_OCTHEADERS_HPP + +// Required C++ headers +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Minimal headers to define Octave version +#include +#include + +// Macro for enabling features which require Octave version >= major.minor.patch +// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '' (released) and '+' (in development) patch numbers +#define SWIG_OCTAVE_PREREQ(major, minor, patch) \ + ( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + (OCTAVE_PATCH_VERSION + 0) >= ((major)<<16) + ((minor)<<8) + (patch) ) + +// Reconstruct Octave major, minor, and patch versions for releases prior to 3.8.1 +#if !defined(OCTAVE_MAJOR_VERSION) + +# if !defined(OCTAVE_API_VERSION_NUMBER) + +// Hack to distinguish between Octave 3.8.0, which removed OCTAVE_API_VERSION_NUMBER but did not yet +// introduce OCTAVE_MAJOR_VERSION, and Octave <= 3.2, which did not define OCTAVE_API_VERSION_NUMBER +# include +# if defined(octave_ov_h) +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 8 +# define OCTAVE_PATCH_VERSION 0 +# else + +// Hack to distinguish between Octave 3.2 and earlier versions, before OCTAVE_API_VERSION_NUMBER existed +# define ComplexLU __ignore +# include +# undef ComplexLU +# if defined(octave_Complex_LU_h) + +// We know only that this version is prior to Octave 3.2, i.e. OCTAVE_API_VERSION_NUMBER < 37 +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 1 +# define OCTAVE_PATCH_VERSION 99 + +# else + +// OCTAVE_API_VERSION_NUMBER == 37 +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 2 +# define OCTAVE_PATCH_VERSION 0 + +# endif // defined(octave_Complex_LU_h) + +# endif // defined(octave_ov_h) + +// Correlation between Octave API and version numbers extracted from Octave's +// ChangeLogs; version is the *earliest* released Octave with that API number +# elif OCTAVE_API_VERSION_NUMBER >= 48 +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 6 +# define OCTAVE_PATCH_VERSION 0 + +# elif OCTAVE_API_VERSION_NUMBER >= 45 +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 4 +# define OCTAVE_PATCH_VERSION 1 + +# elif OCTAVE_API_VERSION_NUMBER >= 42 +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 3 +# define OCTAVE_PATCH_VERSION 54 + +# elif OCTAVE_API_VERSION_NUMBER >= 41 +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 3 +# define OCTAVE_PATCH_VERSION 53 + +# elif OCTAVE_API_VERSION_NUMBER >= 40 +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 3 +# define OCTAVE_PATCH_VERSION 52 + +# elif OCTAVE_API_VERSION_NUMBER >= 39 +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 3 +# define OCTAVE_PATCH_VERSION 51 + +# else // OCTAVE_API_VERSION_NUMBER == 38 +# define OCTAVE_MAJOR_VERSION 3 +# define OCTAVE_MINOR_VERSION 3 +# define OCTAVE_PATCH_VERSION 50 + +# endif // !defined(OCTAVE_API_VERSION_NUMBER) + +#endif // !defined(OCTAVE_MAJOR_VERSION) + +// Required Octave headers +#include +#include +#include +#include +#include +#include +#include +#if SWIG_OCTAVE_PREREQ(4,2,0) +#include +#else +#include +#endif +#include +#if SWIG_OCTAVE_PREREQ(4,2,0) +#include +#endif + +#endif // !defined(_SWIG_OCTAVE_OCTHEADERS_HPP) diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg index 325a4cca3..1069e0e54 100644 --- a/Lib/octave/octrun.swg +++ b/Lib/octave/octrun.swg @@ -89,10 +89,6 @@ SWIGRUNTIME void SWIG_Octave_SetModule(void *clientdata, swig_module_info *point // Runtime API implementation -#include -#include -#include - typedef octave_value_list(*octave_func) (const octave_value_list &, int); class octave_swig_type; @@ -203,11 +199,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); std::set dispatch_classes; - private: - - DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; - DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_swig_bound_func, "octave_swig_bound_func", "octave_swig_bound_func"); #else #define SWIG_OCTAVE_BOUND_FUNC(func, args) octave_value(func) #endif @@ -1066,7 +1058,13 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); octave_swig_type *ptr; public: octave_swig_ref(octave_swig_type *_ptr = 0) - :ptr(_ptr) { } + :ptr(_ptr) + { + // Ensure type_id() is set correctly + if (t_id == -1) { + t_id = octave_swig_ref::static_type_id(); + } + } ~octave_swig_ref() { if (ptr) ptr->decref(); } @@ -1207,8 +1205,13 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); public: octave_swig_packed(swig_type_info *_type = 0, const void *_buf = 0, size_t _buf_len = 0) - : type(_type), buf((const char*)_buf, (const char*)_buf + _buf_len) { - } + : type(_type), buf((const char*)_buf, (const char*)_buf + _buf_len) + { + // Ensure type_id() is set correctly + if (t_id == -1) { + t_id = octave_swig_packed::static_type_id(); + } + } bool copy(swig_type_info *outtype, void *ptr, size_t sz) const { if (outtype && outtype != type) diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg index f98bf4fe4..a397fb7c1 100644 --- a/Lib/octave/octruntime.swg +++ b/Lib/octave/octruntime.swg @@ -1,111 +1,10 @@ +#ifdef SWIG_OCTAVE_EXTERNAL_OCTHEADERS %insert(runtime) %{ - -#include -#include - -#include -#include - -// Macro for enabling features which require Octave version >= major.minor.patch -// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '' (released) and '+' (in development) patch numbers -#define SWIG_OCTAVE_PREREQ(major, minor, patch) \ - ( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + (OCTAVE_PATCH_VERSION + 0) >= ((major)<<16) + ((minor)<<8) + (patch) ) - -// Reconstruct Octave major, minor, and patch versions for releases prior to 3.8.1 -#if !defined(OCTAVE_MAJOR_VERSION) - -# if !defined(OCTAVE_API_VERSION_NUMBER) - -// Hack to distinguish between Octave 3.8.0, which removed OCTAVE_API_VERSION_NUMBER but did not yet -// introduce OCTAVE_MAJOR_VERSION, and Octave <= 3.2, which did not define OCTAVE_API_VERSION_NUMBER -# include -# if defined(octave_ov_h) -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 8 -# define OCTAVE_PATCH_VERSION 0 -# else - -// Hack to distinguish between Octave 3.2 and earlier versions, before OCTAVE_API_VERSION_NUMBER existed -# define ComplexLU __ignore -# include -# undef ComplexLU -# if defined(octave_Complex_LU_h) - -// We know only that this version is prior to Octave 3.2, i.e. OCTAVE_API_VERSION_NUMBER < 37 -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 1 -# define OCTAVE_PATCH_VERSION 99 - -# else - -// OCTAVE_API_VERSION_NUMBER == 37 -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 2 -# define OCTAVE_PATCH_VERSION 0 - -# endif // defined(octave_Complex_LU_h) - -# endif // defined(octave_ov_h) - -// Correlation between Octave API and version numbers extracted from Octave's -// ChangeLogs; version is the *earliest* released Octave with that API number -# elif OCTAVE_API_VERSION_NUMBER >= 48 -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 6 -# define OCTAVE_PATCH_VERSION 0 - -# elif OCTAVE_API_VERSION_NUMBER >= 45 -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 4 -# define OCTAVE_PATCH_VERSION 1 - -# elif OCTAVE_API_VERSION_NUMBER >= 42 -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 3 -# define OCTAVE_PATCH_VERSION 54 - -# elif OCTAVE_API_VERSION_NUMBER >= 41 -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 3 -# define OCTAVE_PATCH_VERSION 53 - -# elif OCTAVE_API_VERSION_NUMBER >= 40 -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 3 -# define OCTAVE_PATCH_VERSION 52 - -# elif OCTAVE_API_VERSION_NUMBER >= 39 -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 3 -# define OCTAVE_PATCH_VERSION 51 - -# else // OCTAVE_API_VERSION_NUMBER == 38 -# define OCTAVE_MAJOR_VERSION 3 -# define OCTAVE_MINOR_VERSION 3 -# define OCTAVE_PATCH_VERSION 50 - -# endif // !defined(OCTAVE_API_VERSION_NUMBER) - -#endif // !defined(OCTAVE_MAJOR_VERSION) - -#include -#include -#include -#include -#include -#include -#include -#if SWIG_OCTAVE_PREREQ(4,2,0) -#include -#else -#include -#endif -#include -#if SWIG_OCTAVE_PREREQ(4,2,0) -#include -#endif - +#include "octheaders.hpp" %} +#else +%insert(runtime) "octheaders.hpp"; +#endif %insert(runtime) "swigrun.swg"; %insert(runtime) "swigerrors.swg"; @@ -315,13 +214,29 @@ DEFUN_DLD( swig_octave_prereq, args, nargout, swig_octave_prereq_usage ) { return octave_value(prereq); } +static const char *const swig_exit_usage = "-*- texinfo -*- \n\ +@deftypefn {Loadable Function} {} swig_exit([@var{exit_status}])\n\ +Exit Octave without performing any memory cleanup.\n\ +@end deftypefn"; + +DEFUN_DLD( swig_exit, args, nargout, swig_exit_usage ) { + if (args.length() > 1) { + error("swig_exit: must be called with at most one arguments"); + return octave_value_list(); + } + int exit_status = 0; + if (args.length() == 1) { + exit_status = args(0).int_value(); + } + ::_Exit(exit_status); + return octave_value(); +} + static const char *const SWIG_name_usage = "-*- texinfo -*- \n\ @deftypefn {Loadable Module} {} " SWIG_name_d "\n\ Loads the SWIG-generated module `" SWIG_name_d "'.\n\ @end deftypefn"; -void __swig_atexit__(void) { ::_Exit(0); } - DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) { static octave_swig_type* module_ns = 0; @@ -329,14 +244,15 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) { // workaround to prevent octave seg-faulting on exit: set Octave exit function // octave_exit to _Exit, which exits immediately without trying to cleanup memory. // definitely affected version 3.2.*, not sure about 3.3.*, seems to be fixed in - // version 3.4.*, but reappeared in 4.2.*, so turn on for all versions after 3.2.*. + // version 3.4.*, reappeared in 4.2.*, hack not possible in 4.4.* or later due to + // removal of octave_exit, so turn on for all versions between 3.2.*. and 4.4.*. // can be turned off with macro definition. #ifndef SWIG_OCTAVE_NO_SEGFAULT_HACK -#if SWIG_OCTAVE_PREREQ(4,4,0) - atexit(__swig_atexit__); -#elif SWIG_OCTAVE_PREREQ(3,2,0) +#if !SWIG_OCTAVE_PREREQ(4,4,0) +#if SWIG_OCTAVE_PREREQ(3,2,0) octave_exit = ::_Exit; #endif +#endif #endif // check for no input and output args @@ -376,7 +292,6 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) { string_vector types = typeinfo.installed_type_names(); bool register_octave_swig_ref = true; bool register_octave_swig_packed = true; - bool register_octave_swig_bound_func = true; for (int i = 0; i < types.numel(); ++i) { if (types(i) == octave_swig_ref::static_type_name()) { register_octave_swig_ref = false; @@ -384,9 +299,6 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) { if (types(i) == octave_swig_packed::static_type_name()) { register_octave_swig_packed = false; } - if (types(i) == octave_swig_bound_func::static_type_name()) { - register_octave_swig_bound_func = false; - } } if (register_octave_swig_ref) { octave_swig_ref::register_type(); @@ -394,9 +306,6 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) { if (register_octave_swig_packed) { octave_swig_packed::register_type(); } - if (register_octave_swig_bound_func) { - octave_swig_bound_func::register_type(); - } } #else octave_swig_ref::register_type(); @@ -427,6 +336,9 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) { if (!SWIG_Octave_InstallFunction(me, "swig_octave_prereq")) { return octave_value_list(); } + if (!SWIG_Octave_InstallFunction(me, "swig_exit")) { + return octave_value_list(); + } octave_swig_type* cvar_ns=0; if (std::string(SWIG_global_name) != ".") { diff --git a/Lib/octave/std_complex.i b/Lib/octave/std_complex.i index 30c188244..461e2fdfc 100644 --- a/Lib/octave/std_complex.i +++ b/Lib/octave/std_complex.i @@ -4,10 +4,6 @@ %include -%{ -#include -%} - namespace std { %naturalvar complex; template class complex; diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index 1297d2445..b1769e42a 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -567,6 +567,10 @@ public: Wrapper *f = NewWrapper(); Octave_begin_function(n, f->def, iname, overname, !overloaded); + // Start default try block to execute + // cleanup code if exception is thrown + Printf(f->code, "try {\n"); + emit_parameter_variables(l, f); emit_attach_parmmaps(l, f); Setattr(n, "wrap:parms", l); @@ -754,9 +758,20 @@ public: } Printf(f->code, "return _out;\n"); - Printf(f->code, "fail:\n"); // we should free locals etc if this happens + + // Execute cleanup code if branched to fail: label + Printf(f->code, "fail:\n"); Printv(f->code, cleanup, NIL); Printf(f->code, "return octave_value_list();\n"); + + // Execute cleanup code if exception was thrown + Printf(f->code, "}\n"); + Printf(f->code, "catch(...) {\n"); + Printv(f->code, cleanup, NIL); + Printf(f->code, "throw;\n"); + Printf(f->code, "}\n"); + + // End wrapper function Printf(f->code, "}\n"); /* Substitute the cleanup code */ @@ -830,7 +845,7 @@ public: String *setwname = Swig_name_wrapper(setname); Octave_begin_function(n, setf->def, setname, setwname, true); - Printf(setf->def, "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();", iname); if (is_assignable(n)) { Setattr(n, "wrap:name", setname); if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { @@ -845,8 +860,9 @@ public: } else { Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0)); } + Append(setf->code, "return octave_value_list();\n"); Append(setf->code, "fail:\n"); - Printf(setf->code, "return octave_value_list();\n"); + Append(setf->code, "return octave_value_list();\n"); } else { Printf(setf->code, "return octave_set_immutable(args,nargout);"); } @@ -866,10 +882,10 @@ public: } else { Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0)); } - Append(getf->code, " return obj;\n"); + Append(getf->code, "return obj;\n"); if (addfail) { Append(getf->code, "fail:\n"); - Append(getf->code, " return octave_value_list();\n"); + Append(getf->code, "return octave_value_list();\n"); } Append(getf->code, "}\n"); Wrapper_print(getf, f_wrappers); diff --git a/Tools/travis-osx-install.sh b/Tools/travis-osx-install.sh index 393d96e60..71d2b2dd0 100755 --- a/Tools/travis-osx-install.sh +++ b/Tools/travis-osx-install.sh @@ -4,6 +4,9 @@ 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 travis_retry brew list @@ -23,7 +26,7 @@ case "$SWIGLANG" in travis_retry brew install lua ;; "octave") - travis_retry brew install octave + travis_retry Tools/brew-install octave ;; "python") WITHLANG=$SWIGLANG$PY3 diff --git a/configure.ac b/configure.ac index fce5b9ee5..336460889 100644 --- a/configure.ac +++ b/configure.ac @@ -333,6 +333,39 @@ case $host in *) ;; esac +# Check for compiler pre-compiled header support +AC_MSG_CHECKING([if compiler supports pre-compiled headers]) +PCHSUPPORT=no +if test "$CLANGXX" = "yes"; then + PCHINCLUDEARG="-include-pch" + PCHINCLUDEEXT=".gch" +else + PCHINCLUDEARG="-include" + PCHINCLUDEEXT="" +fi +AC_LANG_PUSH([C++]) +echo '#include ' > conftest.hpp +echo '#include "conftest.hpp"' > conftest.cpp +$CXX -c conftest.hpp 2>/dev/null +if test $? -eq 0; then + if test -f conftest.hpp.gch; then + $CXX -H -c -I. ${PCHINCLUDEARG} ./conftest.hpp${PCHINCLUDEEXT} -o conftest.o conftest.cpp >conftest.out 2>&1 + if test $? -eq 0; then + if test "$CLANGXX" = "yes"; then + PCHSUPPORT=yes + elif grep -q '^!.*conftest.hpp.gch$' conftest.out; then + PCHSUPPORT=yes + fi + fi + fi +fi +rm -f conftest.hpp conftest.cpp conftest.out +AC_LANG_POP([C++]) +AC_MSG_RESULT([$PCHSUPPORT]) +AC_SUBST(PCHSUPPORT) +AC_SUBST(PCHINCLUDEARG) +AC_SUBST(PCHINCLUDEEXT) + # Set info about shared libraries. AC_SUBST(SO) AC_SUBST(LDSHARED) @@ -1079,6 +1112,7 @@ if test -n "$OCTAVE"; then 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]) ],[ @@ -1093,7 +1127,7 @@ 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 `env - ${mkoctfile} -p ${var}`; do + for flag in `${mkoctfile} -p ${var}`; do case ${flag} in -D*|-I*) OCTAVE_CPPFLAGS="${OCTAVE_CPPFLAGS} ${flag}";; *) ;; @@ -1105,7 +1139,7 @@ if test -n "$OCTAVE"; then AC_MSG_CHECKING([for Octave compiler flags]) OCTAVE_CXXFLAGS= for var in CXX ALL_CXXFLAGS; do - for flag in `env - ${mkoctfile} -p ${var}`; do + for flag in `${mkoctfile} -p ${var}`; do case ${flag} in -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";; *) ;; @@ -1125,10 +1159,10 @@ if test -n "$OCTAVE"; then AC_MSG_CHECKING([for Octave linker flags]) OCTAVE_LDFLAGS= for var in OCTLIBDIR; do - OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`env - ${mkoctfile} -p ${var}` + OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`${mkoctfile} -p ${var}` done for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do - OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`env - ${mkoctfile} -p ${var}` + OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`${mkoctfile} -p ${var}` done AC_MSG_RESULT([$OCTAVE_LDFLAGS])