Skip to content

Commit 64e2c43

Browse files
committed
Merge branch 'octave-fixes'
* octave-fixes: octrun.swg: ensure type_id() is set correctly .travis.yml: build Octave on OSX with CPP=11 .travis.yml: require Octave build on OSX to pass .travis.yml: add Octave test on Ubuntu Bionic Octave: use pre-compiled headers to speed up test suite, if supported Tools/travis-osx-install.sh: disable 'brew cleanup' to save Travis job run time Tools/travis-osx-install.sh: use Tools/brew-install to install Octave octave.cxx: fix exception raising for newer Octave versions octave.cxx: add missing return statement before "fail:" label octave.cxx: this belongs in the code (as opposed to definition) section octave.cxx: remote whitespaces octave.cxx: replace Printf() with Append() for consistency octruntime.swg: do not use atexit() to quit Octave octrun.swg: remove octave_value type-id from octave_swig_bound_func configure.ac: fix calls to mkoctfile for Octave configuration
2 parents 3c9dd44 + d73ef20 commit 64e2c43

File tree

16 files changed

+317
-168
lines changed

16 files changed

+317
-168
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ Examples/ocaml/**/swigp4.ml
173173
# Octave
174174
swigexample*.oct
175175
Examples/test-suite/octave/*.oct
176+
Examples/test-suite/octave/octheaders.hpp
177+
Examples/test-suite/octave/octheaders.hpp.gch
176178

177179
# Perl5
178180
Examples/test-suite/perl5/*.pm

.travis.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,12 @@ matrix:
146146
os: linux
147147
env: SWIGLANG=octave SWIGJOBS=-j2
148148
sudo: required
149-
dist: xenial
149+
dist: xenial # Octave v4.0.0
150+
- compiler: gcc
151+
os: linux
152+
env: SWIGLANG=octave SWIGJOBS=-j2 CPP11=1
153+
sudo: required
154+
dist: bionic # Octave v4.2.2
150155
- compiler: gcc
151156
os: linux
152157
env: SWIGLANG=perl5
@@ -437,7 +442,7 @@ matrix:
437442
env: SWIGLANG=lua
438443
- compiler: clang
439444
os: osx
440-
env: SWIGLANG=octave SWIGJOBS=-j2
445+
env: SWIGLANG=octave SWIGJOBS=-j2 CPP11=1
441446
- compiler: clang
442447
os: osx
443448
env: SWIGLANG=perl5
@@ -475,10 +480,6 @@ matrix:
475480
env: SWIGLANG=php VER=7.2
476481
sudo: required
477482
dist: xenial
478-
# Sometimes hits the Travis 50 minute time limit
479-
- compiler: clang
480-
os: osx
481-
env: SWIGLANG=octave SWIGJOBS=-j2
482483
# Experimental languages
483484
- compiler: gcc
484485
os: linux

CHANGES.current

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@ Version 4.0.2 (in progress)
1616
2020-05-24: vapier
1717
[JS] #1796 Fix pkg-config invocation in configure.
1818

19+
2020-04-30: kwwette
20+
[Octave] Fix exception raising for newer Octave versions
21+
Since (at least) Octave 5.1.0, the Octave error() function now raises a C++ exception,
22+
which if uncaught immediately exits a SWIG wrapper function, bypassing any cleanup code
23+
that may appear after a "fail:" label. This patch adds a "try { ... } catch(...) { }"
24+
block around the contents of SWIG wrapper functions to first execute the cleanup code
25+
before rethrowing any exception raised. It is backward compatible with earlier versions
26+
of Octave where error() does not raise an exception, which will still branch to the
27+
"fail:" block to execute cleanup code if an error is encountered.
28+
29+
Note that the new "try { ... } catch(...) { }" block will localise any local variables
30+
used in typemaps that were NOT declared through SWIG's %typemap(...) syntax, so it's
31+
possible this could break existing SWIG wrappers which were implicitly sharing local
32+
variables between typemaps. This can be fixed, however, by declaring local variables
33+
which need to be shared between typemaps through SWIG's %typemap(...) syntax.
34+
1935
2020-02-18: ryannevell
2036
[Lua] #1728 Add support for LUA lightuserdata to SWIG_Lua_ConvertPtr.
2137

Examples/Makefile.in

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ INTERFACE =
5858
INTERFACEDIR =
5959
INTERFACEPATH = $(SRCDIR)$(INTERFACEDIR)$(INTERFACE)
6060
SWIGOPT =
61+
PCHSUPPORT = @PCHSUPPORT@
6162

6263
# SWIG_LIB_DIR and SWIGEXE must be explicitly set by Makefiles using this Makefile
6364
SWIG_LIB_DIR = ./Lib
@@ -438,14 +439,37 @@ OCTAVE_SO = @OCTAVE_SO@
438439

439440
OCTAVE_SCRIPT = $(SRCDIR)$(RUNME).m
440441

442+
# ----------------------------------------------------------------
443+
# Pre-compile Octave headers, if supported
444+
# ----------------------------------------------------------------
445+
446+
ifeq (yes,$(PCHSUPPORT))
447+
448+
octave_precompile_headers:
449+
echo "precompiling $(OCTHEADERS)"
450+
cp -f $(OCTHEADERSSRC) $(OCTHEADERS)
451+
if $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(OCTAVE_CXX) $(OCTHEADERS); then \
452+
: ; \
453+
else \
454+
rm -f $(OCTHEADERSGCH); \
455+
exit 1; \
456+
fi
457+
458+
else
459+
460+
octave_precompile_headers:
461+
echo "precompiling Octave headers not supported"; exit 1
462+
463+
endif
464+
441465
# ----------------------------------------------------------------
442466
# Build a C dynamically loadable module
443467
# Note: Octave requires C++ compiler when compiling C wrappers
444468
# ----------------------------------------------------------------
445469

446470
octave: $(SRCDIR_SRCS)
447-
$(SWIG) -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
448-
$(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
471+
$(SWIG) -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
472+
$(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
449473
$(CC) -g -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CSRCS) $(INCLUDES)
450474
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
451475

@@ -454,8 +478,8 @@ octave: $(SRCDIR_SRCS)
454478
# -----------------------------------------------------------------
455479

456480
octave_cpp: $(SRCDIR_SRCS)
457-
$(SWIG) -c++ -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
458-
$(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
481+
$(SWIG) -c++ -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
482+
$(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
459483
$(CXXSHARED) -g $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
460484

461485
# -----------------------------------------------------------------
@@ -481,6 +505,7 @@ octave_clean:
481505
rm -f *_wrap* *~ .~* myoctave@EXEEXT@ *.pyc
482506
rm -f core @EXTRA_CLEAN@
483507
rm -f *.@OBJEXT@ *@SO@ *$(OCTAVE_SO)
508+
rm -f $(OCTHEADERS) $(OCTHEADERSGCH)
484509

485510
##################################################################
486511
##### GUILE ######

Examples/octave/example.mk

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,30 @@ TARGET = swigexample
88
INTERFACE = example.i
99

1010
check: build
11-
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_run
11+
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_run
1212

1313
build:
1414
ifneq (,$(SRCS))
15-
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
15+
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
1616
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
1717
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave
1818
else
19-
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
19+
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
2020
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
2121
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave_cpp
2222
endif
2323
ifneq (,$(TARGET2)$(SWIGOPT2))
2424
ifneq (,$(SRCS))
25-
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
25+
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
2626
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
2727
SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave
2828
else
29-
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
29+
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
3030
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
3131
SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave_cpp
3232
endif
3333
endif
3434

3535

3636
clean:
37-
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_clean
37+
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_clean

Examples/test-suite/octave/Makefile.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
LANGUAGE = octave
66
OCTAVE = @OCTAVE@
77
SCRIPTSUFFIX = _runme.m
8+
PCHSUPPORT = @PCHSUPPORT@
89

910
srcdir = @srcdir@
1011
top_srcdir = @top_srcdir@
@@ -61,6 +62,23 @@ CSRCS = octave_empty.c
6162
+$(swig_and_compile_multi_cpp)
6263
$(run_testcase)
6364

65+
# Pre-compile Octave headers, if supported
66+
67+
ifeq (yes,$(PCHSUPPORT))
68+
69+
export OCTHEADERSSRC = @top_srcdir@/Lib/octave/octheaders.hpp
70+
export OCTHEADERS = @top_builddir@/Examples/test-suite/octave/octheaders.hpp
71+
export OCTHEADERSGCH = $(OCTHEADERS).gch
72+
export SWIGOCTHDROPT = -DSWIG_OCTAVE_EXTERNAL_OCTHEADERS
73+
export IOCTHEADERS = -I@top_builddir@/Examples/test-suite/octave @PCHINCLUDEARG@ $(OCTHEADERS)@PCHINCLUDEEXT@
74+
75+
$(OCTHEADERSGCH): $(OCTHEADERSSRC)
76+
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile octave_precompile_headers
77+
78+
$(NOT_BROKEN_TEST_CASES) $(BROKEN_TEST_CASES): $(OCTHEADERSGCH)
79+
80+
endif
81+
6482
# Runs the testcase. A testcase is only run if
6583
# a file is found which has _runme.m appended after the testcase name.
6684
run_testcase = \

Lib/octave/director.swg

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
# define SWIG_DIRECTOR_CAST(ARG) dynamic_cast<Swig::Director *>(ARG)
99

10-
#include <exception>
11-
1210
namespace Swig {
1311

1412
class Director {

Lib/octave/extra-install.list

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# see top-level Makefile.in
2+
octheaders.hpp

Lib/octave/octcontainer.swg

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@
1111
* be the case.
1212
* ----------------------------------------------------------------------------- */
1313

14-
%{
15-
#include <climits>
16-
#include <iostream>
17-
%}
18-
19-
2014
#if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS)
2115
# if !defined(SWIG_EXPORT_ITERATOR_METHODS)
2216
# define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS
@@ -64,7 +58,6 @@ namespace swig {
6458

6559
%fragment("OctSequence_Base","header",fragment="<stddef.h>")
6660
{
67-
%#include <functional>
6861

6962
namespace std {
7063
template <>

Lib/octave/octheaders.hpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
//
2+
// This header includes all C++ headers required for generated Octave wrapper code.
3+
// Using a single header file allows pre-compilation of Octave headers, as follows:
4+
// * Check out this header file:
5+
// swig -octave -co octheaders.hpp
6+
// * Pre-compile header file into octheaders.hpp.gch:
7+
// g++ -c ... octheaders.hpp
8+
// * Use pre-compiled header file:
9+
// g++ -c -include octheaders.hpp ...
10+
//
11+
12+
#if !defined(_SWIG_OCTAVE_OCTHEADERS_HPP)
13+
#define _SWIG_OCTAVE_OCTHEADERS_HPP
14+
15+
// Required C++ headers
16+
#include <cstdlib>
17+
#include <climits>
18+
#include <iostream>
19+
#include <exception>
20+
#include <functional>
21+
#include <complex>
22+
#include <string>
23+
#include <vector>
24+
#include <map>
25+
26+
// Minimal headers to define Octave version
27+
#include <octave/oct.h>
28+
#include <octave/version.h>
29+
30+
// Macro for enabling features which require Octave version >= major.minor.patch
31+
// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '<digit>' (released) and '<digit>+' (in development) patch numbers
32+
#define SWIG_OCTAVE_PREREQ(major, minor, patch) \
33+
( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + (OCTAVE_PATCH_VERSION + 0) >= ((major)<<16) + ((minor)<<8) + (patch) )
34+
35+
// Reconstruct Octave major, minor, and patch versions for releases prior to 3.8.1
36+
#if !defined(OCTAVE_MAJOR_VERSION)
37+
38+
# if !defined(OCTAVE_API_VERSION_NUMBER)
39+
40+
// Hack to distinguish between Octave 3.8.0, which removed OCTAVE_API_VERSION_NUMBER but did not yet
41+
// introduce OCTAVE_MAJOR_VERSION, and Octave <= 3.2, which did not define OCTAVE_API_VERSION_NUMBER
42+
# include <octave/ov.h>
43+
# if defined(octave_ov_h)
44+
# define OCTAVE_MAJOR_VERSION 3
45+
# define OCTAVE_MINOR_VERSION 8
46+
# define OCTAVE_PATCH_VERSION 0
47+
# else
48+
49+
// Hack to distinguish between Octave 3.2 and earlier versions, before OCTAVE_API_VERSION_NUMBER existed
50+
# define ComplexLU __ignore
51+
# include <octave/CmplxLU.h>
52+
# undef ComplexLU
53+
# if defined(octave_Complex_LU_h)
54+
55+
// We know only that this version is prior to Octave 3.2, i.e. OCTAVE_API_VERSION_NUMBER < 37
56+
# define OCTAVE_MAJOR_VERSION 3
57+
# define OCTAVE_MINOR_VERSION 1
58+
# define OCTAVE_PATCH_VERSION 99
59+
60+
# else
61+
62+
// OCTAVE_API_VERSION_NUMBER == 37
63+
# define OCTAVE_MAJOR_VERSION 3
64+
# define OCTAVE_MINOR_VERSION 2
65+
# define OCTAVE_PATCH_VERSION 0
66+
67+
# endif // defined(octave_Complex_LU_h)
68+
69+
# endif // defined(octave_ov_h)
70+
71+
// Correlation between Octave API and version numbers extracted from Octave's
72+
// ChangeLogs; version is the *earliest* released Octave with that API number
73+
# elif OCTAVE_API_VERSION_NUMBER >= 48
74+
# define OCTAVE_MAJOR_VERSION 3
75+
# define OCTAVE_MINOR_VERSION 6
76+
# define OCTAVE_PATCH_VERSION 0
77+
78+
# elif OCTAVE_API_VERSION_NUMBER >= 45
79+
# define OCTAVE_MAJOR_VERSION 3
80+
# define OCTAVE_MINOR_VERSION 4
81+
# define OCTAVE_PATCH_VERSION 1
82+
83+
# elif OCTAVE_API_VERSION_NUMBER >= 42
84+
# define OCTAVE_MAJOR_VERSION 3
85+
# define OCTAVE_MINOR_VERSION 3
86+
# define OCTAVE_PATCH_VERSION 54
87+
88+
# elif OCTAVE_API_VERSION_NUMBER >= 41
89+
# define OCTAVE_MAJOR_VERSION 3
90+
# define OCTAVE_MINOR_VERSION 3
91+
# define OCTAVE_PATCH_VERSION 53
92+
93+
# elif OCTAVE_API_VERSION_NUMBER >= 40
94+
# define OCTAVE_MAJOR_VERSION 3
95+
# define OCTAVE_MINOR_VERSION 3
96+
# define OCTAVE_PATCH_VERSION 52
97+
98+
# elif OCTAVE_API_VERSION_NUMBER >= 39
99+
# define OCTAVE_MAJOR_VERSION 3
100+
# define OCTAVE_MINOR_VERSION 3
101+
# define OCTAVE_PATCH_VERSION 51
102+
103+
# else // OCTAVE_API_VERSION_NUMBER == 38
104+
# define OCTAVE_MAJOR_VERSION 3
105+
# define OCTAVE_MINOR_VERSION 3
106+
# define OCTAVE_PATCH_VERSION 50
107+
108+
# endif // !defined(OCTAVE_API_VERSION_NUMBER)
109+
110+
#endif // !defined(OCTAVE_MAJOR_VERSION)
111+
112+
// Required Octave headers
113+
#include <octave/Cell.h>
114+
#include <octave/dynamic-ld.h>
115+
#include <octave/oct-env.h>
116+
#include <octave/oct-map.h>
117+
#include <octave/ov-scalar.h>
118+
#include <octave/ov-fcn-handle.h>
119+
#include <octave/parse.h>
120+
#if SWIG_OCTAVE_PREREQ(4,2,0)
121+
#include <octave/interpreter.h>
122+
#else
123+
#include <octave/toplev.h>
124+
#endif
125+
#include <octave/unwind-prot.h>
126+
#if SWIG_OCTAVE_PREREQ(4,2,0)
127+
#include <octave/call-stack.h>
128+
#endif
129+
130+
#endif // !defined(_SWIG_OCTAVE_OCTHEADERS_HPP)

0 commit comments

Comments
 (0)