Octave: add support for version 4.2

- .travis.yml:
  - ppa:kwwette/octaves has Octave version 4.2, also run C++11 tests
- configure.ac:
  - prefer Octave program "octave-cli" to "octave"
  - extract any -std=* flags from CXX, add to OCTAVE_CXXFLAGS
- Lib/typemaps/fragments.swg:
  - SWIG_isfinite_func(): extern "C++" is required as this fragment can
    end up inside an extern "C" { } block
- Lib/octave:
  - add std_wstring.i (copied from std_string.i) for C++11 tests
- Lib/octave/octrun.swg:
  - move Octave version-checking macros to octruntime.swg
  - Octave single()/double() functions now call .as_single()/.as_double()
    methods; redirect calls to __float__() method as per .scalar_value()
  - << and >> operators are no longer supported by Octave
- Lib/octave/octruntime.swg:
  - move Octave version-checking macros here for conditional #includes
  - #include interpreter.h instead of #toplev.h
  - #include call-stack.h (now needed for octave_call_stack)
  - unwind_protect is now in octave:: namespace
  - error_state and warning_state are deprecated; use try/catch to catch
    errors in feval() instead
  - always set octave_exit = ::_Exit, to try to prevent segfault on exit
- Lib/octave/octopers.swg:
  - << and >> operators are no longer supported by Octave
- Lib/octave/exception.i:
  - Add macro SWIG_RETHROW_OCTAVE_EXCEPTIONS which rethrows any
    exceptions raised by Octave >= 4.2
- Examples/test-suite/exception_order.i:
  - Use macro SWIG_RETHROW_OCTAVE_EXCEPTIONS to rethrow exceptions
    raised by error() function in Octave >= 4.2
- Update Doc/Manual/Octave.html and CHANGES.current
diff --git a/.travis.yml b/.travis.yml
index 7e4aac3..2723781 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -87,6 +87,11 @@
       dist: trusty
     - compiler: gcc
       os: linux
+      env: SWIGLANG=octave SWIGJOBS=-j2 VER=4.2 CPP11=1
+      sudo: required
+      dist: trusty
+    - compiler: gcc
+      os: linux
       env: SWIGLANG=perl5
       sudo: required
       dist: trusty
diff --git a/CHANGES.current b/CHANGES.current
index 2bb4589..9a078cc 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,30 @@
 Version 3.0.12 (in progress)
 ============================
 
+2017-01-22: kwwette
+            [Octave] add support for version 4.2
+            - The Octave API now uses some C++11 features. It is recommended to use
+              the mkoctfile program supplied by Octave to compile the SWIG-generated
+              wrapper code, as mkoctfile will ensure the correct C++ compiler/options
+              are used. Otherwise, the value of `mkoctfile -p CXX` should be parsed
+              for any -std=* flags which might be present.
+            - Octave has dropped support for << and >> operators, so SWIG now
+              ignores them.
+            - The Octave error() function now raises C++ exceptions to propagate
+              Octave errors, so %exception directives may need to be modified.
+              For convenience the SWIG_RETHROW_OCTAVE_EXCEPTIONS macro can be used
+              to rethrow any Octave exceptions for Octave itself to handle, e.g.:
+
+                try {
+                  $action                        // may call error()
+                }
+                SWIG_RETHROW_OCTAVE_EXCEPTIONS   // error() exceptions are rethrown
+                catch(...) {
+                  ...                            // all other exceptions
+                }
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
 2017-01-16: wkalinin
             [C#] Fix #733 regression introduced in swig-3.0.9.
             Missing virtual function override in C# layer when using %import.
diff --git a/Doc/Manual/Octave.html b/Doc/Manual/Octave.html
index 2bc590e..616b28c 100644
--- a/Doc/Manual/Octave.html
+++ b/Doc/Manual/Octave.html
@@ -64,7 +64,7 @@
 
 
 <p>
-SWIG is regularly tested against the following versions of Octave: 3.8, 4.0.
+SWIG is regularly tested against the following versions of Octave: 3.8, 4.0, 4.2.
 </p>
 
 <p>
diff --git a/Examples/test-suite/exception_order.i b/Examples/test-suite/exception_order.i
index bca745c..02674fe 100644
--- a/Examples/test-suite/exception_order.i
+++ b/Examples/test-suite/exception_order.i
@@ -23,7 +23,17 @@
    user's throw declarations.
 */
 
-#if defined(SWIGUTL)
+#if defined(SWIGOCTAVE)
+%exception {
+  try {
+    $action
+  }
+  SWIG_RETHROW_OCTAVE_EXCEPTIONS
+  catch(...) {
+    SWIG_exception(SWIG_RuntimeError,"postcatch unknown");
+  }
+}
+#elif defined(SWIGUTL)
 %exception {
   try {
     $action
diff --git a/Lib/octave/exception.i b/Lib/octave/exception.i
index bb0b15c..2f0f489 100644
--- a/Lib/octave/exception.i
+++ b/Lib/octave/exception.i
@@ -1,6 +1,14 @@
 %include <typemaps/exception.swg>
 
-
 %insert("runtime") {
   %define_as(SWIG_exception(code, msg), %block(%error(code, msg); SWIG_fail; ))
 }
+
+%define SWIG_RETHROW_OCTAVE_EXCEPTIONS
+  /* rethrow any exceptions thrown by Octave */
+%#if SWIG_OCTAVE_PREREQ(4,2,0)
+  catch (octave::execution_exception& _e) { throw; }
+  catch (octave::exit_exception& _e) { throw; }
+  catch (octave::interrupt_exception& _e) { throw; }
+%#endif
+%enddef
diff --git a/Lib/octave/octopers.swg b/Lib/octave/octopers.swg
index c38e64d..665b703 100644
--- a/Lib/octave/octopers.swg
+++ b/Lib/octave/octopers.swg
@@ -25,8 +25,6 @@
 // __div__        a / b
 // __pow__        a ^ b
 // __ldiv__       a \ b
-// __lshift__     a << b
-// __rshift__     a >> b
 // __lt__         a < b
 // __le__         a <= b
 // __eq__         a == b
@@ -51,8 +49,6 @@
 %rename(__mul__)       *::operator*;
 %rename(__div__)       *::operator/;
 %rename(__mod__)       *::operator%;
-%rename(__lshift__)    *::operator<<;
-%rename(__rshift__)    *::operator>>;
 %rename(__el_and__)    *::operator&&;
 %rename(__el_or__)     *::operator||;
 %rename(__xor__)       *::operator^;
@@ -84,5 +80,7 @@
 // Ignored operators
 %ignoreoperator(EQ)         operator=;
 %ignoreoperator(ARROWSTAR)  operator->*;
+%ignoreoperator(LSHIFT)     operator<<;
+%ignoreoperator(RSHIFT)     operator>>;
 
 #endif /* __cplusplus */
diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg
index c1c0dcd..57a888f 100644
--- a/Lib/octave/octrun.swg
+++ b/Lib/octave/octrun.swg
@@ -1,87 +1,3 @@
-
-#include <octave/version.h>
-
-// Macro for enabling features which require Octave version >= major.minor.patch
-#define SWIG_OCTAVE_PREREQ(major, minor, patch) \
-  ( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + OCTAVE_PATCH_VERSION >= ((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 <octave/ov.h>
-#  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 <octave/CmplxLU.h>
-#   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)
-
 #if !SWIG_OCTAVE_PREREQ(3,2,0)
 #define SWIG_DEFUN(cname, wname, doc) DEFUNX_DLD(#cname, wname, FS ## cname, args, nargout, doc)
 #else
@@ -824,6 +740,24 @@
       return ret.scalar_value();
     }
 
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+    virtual octave_value as_double(void) const {
+      octave_value ret;
+      if (!dispatch_unary_op("__float__", ret)) {
+        error("__float__ method not defined");
+      }
+      return ret.as_double();
+    }
+
+    virtual octave_value as_single(void) const {
+      octave_value ret;
+      if (!dispatch_unary_op("__float__", ret)) {
+        error("__float__ method not defined");
+      }
+      return ret.as_single();
+    }
+#endif
+
 #if SWIG_OCTAVE_PREREQ(3,8,0)
     virtual octave_value map(octave_base_value::unary_mapper_t umap) const {
       const std::string opname = std::string("__") + octave_base_value::get_umap_name(umap) + std::string("__");
@@ -1092,6 +1026,14 @@
     virtual double scalar_value(bool frc_str_conv = false) const
       { return ptr->scalar_value(frc_str_conv); }
 
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+    virtual octave_value as_double(void) const
+      { return ptr->as_double(); }
+
+    virtual octave_value as_single(void) const
+      { return ptr->as_single(); }
+#endif
+
 #if SWIG_OCTAVE_PREREQ(3,8,0)
     virtual octave_value map(octave_base_value::unary_mapper_t umap) const
       { return ptr->map(umap); }
@@ -1340,8 +1282,10 @@
   swig_binary_op(div);
   swig_binary_op(pow);
   swig_binary_op(ldiv);
+#if !SWIG_OCTAVE_PREREQ(4,2,0)
   swig_binary_op(lshift);
   swig_binary_op(rshift);
+#endif
   swig_binary_op(lt);
   swig_binary_op(le);
   swig_binary_op(eq);
@@ -1371,8 +1315,10 @@
     swigreg_binary_op(div);
     swigreg_binary_op(pow);
     swigreg_binary_op(ldiv);
+#if !SWIG_OCTAVE_PREREQ(4,2,0)
     swigreg_binary_op(lshift);
     swigreg_binary_op(rshift);
+#endif
     swigreg_binary_op(lt);
     swigreg_binary_op(le);
     swigreg_binary_op(eq);
diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg
index 1efc96f..f5e6871 100644
--- a/Lib/octave/octruntime.swg
+++ b/Lib/octave/octruntime.swg
@@ -1,7 +1,93 @@
 %insert(runtime) %{
+
 #include <cstdlib>
 #include <iostream>
+
 #include <octave/oct.h>
+#include <octave/version.h>
+
+// Macro for enabling features which require Octave version >= major.minor.patch
+// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '<digit>' (released) and '<digit>+' (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 <octave/ov.h>
+#  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 <octave/CmplxLU.h>
+#   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 <octave/Cell.h>
 #include <octave/dynamic-ld.h>
 #include <octave/oct-env.h>
@@ -9,8 +95,16 @@
 #include <octave/ov-scalar.h>
 #include <octave/ov-fcn-handle.h>
 #include <octave/parse.h>
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+#include <octave/interpreter.h>
+#else
 #include <octave/toplev.h>
+#endif
 #include <octave/unwind-prot.h>
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+#include <octave/call-stack.h>
+#endif
+
 %}
 
 %insert(runtime) "swigrun.swg";
@@ -24,27 +118,34 @@
 static bool SWIG_init_user(octave_swig_type* module_ns);
 
 SWIGINTERN bool SWIG_Octave_LoadModule(std::string name) {
-  bool retn;
+  bool retn = false;
   {
-#if !SWIG_OCTAVE_PREREQ(3,3,50)
-    unwind_protect::begin_frame("SWIG_Octave_LoadModule");
-    unwind_protect_int(error_state);
-    unwind_protect_int(warning_state);
-    unwind_protect_bool(discard_error_messages);
-    unwind_protect_bool(discard_warning_messages);
-#else
+#if 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;
+#elif SWIG_OCTAVE_PREREQ(3,3,50)
     unwind_protect frame;
-    frame.protect_var(error_state);
-    frame.protect_var(warning_state);
-    frame.protect_var(discard_error_messages);
-    frame.protect_var(discard_warning_messages);
+    frame.protect_var(error_state);                     error_state = 0;
+    frame.protect_var(warning_state);                   warning_state = 0;
+    frame.protect_var(discard_error_messages);          discard_error_messages = true;
+    frame.protect_var(discard_warning_messages);        discard_warning_messages = true;
+#else
+    unwind_protect::begin_frame("SWIG_Octave_LoadModule");
+    unwind_protect_int(error_state);                    error_state = 0;
+    unwind_protect_int(warning_state);                  warning_state = 0;
+    unwind_protect_bool(discard_error_messages);        discard_error_messages = true;
+    unwind_protect_bool(discard_warning_messages);      discard_warning_messages = true;
 #endif
-    error_state = 0;
-    warning_state = 0;
-    discard_error_messages = true;
-    discard_warning_messages = true;
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+    try {
+      feval(name, octave_value_list(), 0);
+      retn = true;
+    } catch (octave::execution_exception&) { }
+#else
     feval(name, octave_value_list(), 0);
     retn = (error_state == 0);
+#endif
 #if !SWIG_OCTAVE_PREREQ(3,3,50)
     unwind_protect::run_frame("SWIG_Octave_LoadModule");
 #endif
@@ -56,31 +157,37 @@
 }
 
 SWIGINTERN bool SWIG_Octave_InstallFunction(octave_function *octloadfcn, std::string name) {
-  bool retn;
+  bool retn = false;
   {
-#if !SWIG_OCTAVE_PREREQ(3,3,50)
-    unwind_protect::begin_frame("SWIG_Octave_InstallFunction");
-    unwind_protect_int(error_state);
-    unwind_protect_int(warning_state);
-    unwind_protect_bool(discard_error_messages);
-    unwind_protect_bool(discard_warning_messages);
-#else
+#if 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;
+#elif SWIG_OCTAVE_PREREQ(3,3,50)
     unwind_protect frame;
-    frame.protect_var(error_state);
-    frame.protect_var(warning_state);
-    frame.protect_var(discard_error_messages);
-    frame.protect_var(discard_warning_messages);
+    frame.protect_var(error_state);                     error_state = 0;
+    frame.protect_var(warning_state);                   warning_state = 0;
+    frame.protect_var(discard_error_messages);          discard_error_messages = true;
+    frame.protect_var(discard_warning_messages);        discard_warning_messages = true;
+#else
+    unwind_protect::begin_frame("SWIG_Octave_LoadModule");
+    unwind_protect_int(error_state);                    error_state = 0;
+    unwind_protect_int(warning_state);                  warning_state = 0;
+    unwind_protect_bool(discard_error_messages);        discard_error_messages = true;
+    unwind_protect_bool(discard_warning_messages);      discard_warning_messages = true;
 #endif
-    error_state = 0;
-    warning_state = 0;
-    discard_error_messages = true;
-    discard_warning_messages = true;
     octave_value_list args;
     args.append(name);
     args.append(octloadfcn->fcn_file_name());
-    error_state = 0;
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+    try {
+      feval("autoload", args, 0);
+      retn = true;
+    } catch (octave::execution_exception&) { }
+#else
     feval("autoload", args, 0);
     retn = (error_state == 0);
+#endif
 #if !SWIG_OCTAVE_PREREQ(3,3,50)
     unwind_protect::run_frame("SWIG_Octave_InstallFunction");
 #endif
@@ -211,10 +318,11 @@
 
   // 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 affects version 3.2.*, not sure about 3.3.*, seems to be fixed in
-  // version 3.4.* and above. can be turned off with macro definition.
+  // 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.*.
+  // can be turned off with macro definition.
 #ifndef SWIG_OCTAVE_NO_SEGFAULT_HACK
-#if SWIG_OCTAVE_PREREQ(3,2,0) && !SWIG_OCTAVE_PREREQ(3,4,1)
+#if SWIG_OCTAVE_PREREQ(3,2,0)
   octave_exit = ::_Exit;
 #endif
 #endif
diff --git a/Lib/octave/std_wstring.i b/Lib/octave/std_wstring.i
new file mode 100644
index 0000000..dc1378a
--- /dev/null
+++ b/Lib/octave/std_wstring.i
@@ -0,0 +1 @@
+%include <typemaps/std_string.swg>
diff --git a/Lib/typemaps/fragments.swg b/Lib/typemaps/fragments.swg
index f89a16e..3f33ca9 100644
--- a/Lib/typemaps/fragments.swg
+++ b/Lib/typemaps/fragments.swg
@@ -177,9 +177,11 @@
  * versions.
  *
  * Make sure namespace std exists to avoid compiler warnings.
+ *
+ * extern "C++" is required as this fragment can end up inside an extern "C" { } block
  */
 namespace std { }
-template<typename T>
+extern "C++" template<typename T>
 inline int SWIG_isfinite_func(T x) {
   using namespace std;
   return isfinite(x);
diff --git a/configure.ac b/configure.ac
index ed8a0c6..69041ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1017,30 +1017,31 @@
 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"])
 
-# First, check for "--without-octave" or "--with-octave=no".
+# Check for "--without-octave" or "--with-octave=no".
 if test x"${OCTAVEBIN}" = xno; then
    AC_MSG_NOTICE([Disabling Octave])
    OCTAVE=
 
-# First figure out what the name of Octave is
+# 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])
+   AC_PATH_PROG(OCTAVE, [octave-cli octave])
 
 else
    OCTAVE="$OCTAVEBIN"
 fi
 
+# Check for required Octave helper program "mkoctfile"
 if test -n "$OCTAVE"; then
-   AC_MSG_CHECKING([for mkoctfile])
-   mkoctfile="$(dirname $OCTAVE)/$(basename $OCTAVE | sed -e 's/octave/mkoctfile/')"
-   AS_IF([test -x "${mkoctfile}"],[
-      AC_MSG_RESULT([${mkoctfile}])
-   ],[
-      AC_MSG_RESULT([not found, disabling Octave])
+   AC_PATH_PROG(mkoctfile, [mkoctfile], [], [`dirname $OCTAVE`])
+   AS_IF([test "x${mkoctfile}" = x],[
+      AC_MSG_NOTICE([mkoctfile not found, disabling Octave])
       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
@@ -1052,12 +1053,13 @@
       done
    done
    AC_MSG_RESULT([$OCTAVE_CPPFLAGS])
+
    AC_MSG_CHECKING([for Octave compiler flags])
    OCTAVE_CXXFLAGS=
-   for var in ALL_CXXFLAGS; do
+   for var in CXX ALL_CXXFLAGS; do
       for flag in `env - ${mkoctfile} -p ${var}`; do
          case ${flag} in
-            -g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
+            -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
             *) ;;
          esac
       done
@@ -1065,19 +1067,25 @@
    save_CXXFLAGS="${CXXFLAGS}"
    CXXFLAGS="-Werror -O0"
    AC_COMPILE_IFELSE([
-      AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],[])
+      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 RDYNAMIC_FLAG LFLAGS RLD_FLAG OCTAVE_LIBS LIBS; do
      OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`env - ${mkoctfile} -p ${var}`
    done
    AC_MSG_RESULT([$OCTAVE_LDFLAGS])
-   for octave_opt in --silent --norc --no-history --no-window-system; do
+
+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],[