changeset 15359:b6b261c3eab3 draft

Merge in Thorsten's changes
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Tue, 11 Sep 2012 15:12:44 -0400
parents 842ab161c10a (current diff) 93dff6435fe1 (diff)
children 75f28de3a387
files
diffstat 6 files changed, 372 insertions(+), 372 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac
+++ b/configure.ac
@@ -1230,7 +1230,7 @@
   [sqr1up],
   [Fortran 77], [don't use qrupdate, disable QR & Cholesky updating functions])
 
-if test "$octave_qrupdate_ok" = yes; then
+if test "$octave_cv_lib_qrupdate" = yes; then
   LIBS="$LIBS $QRUPDATE_LIBS"
   AC_LANG_PUSH([Fortran 77])
   AC_MSG_CHECKING([for slup1up in $QRUPDATE_LIBS])
@@ -1313,6 +1313,7 @@
 if test -z "$UMFPACK_LIBS"; then
   ## Invalidate the cache and try again with -lcblas.
   $as_unset ac_cv_lib_umfpack_umfpack_zi_get_determinant
+  $as_unset octave_cv_lib_umfpack
   save_LIBS="$LIBS"
   LIBS="-lcblas $AMD_LDFLAGS $AMD_LIBS $BLAS_LIBS $FLIBS $LIBS"
   OCTAVE_CHECK_LIB([umfpack], UMFPACK,
@@ -1331,7 +1332,7 @@
 if test -n "$UMFPACK_LIBS"; then
   ## SuiteSparse >= 4.0 needs additional link library for SuiteSparse_time()
   save_LIBS="$LIBS";
-  LIBS="$UMFPACK_LIBS $FLIBS $LIBS"
+  LIBS="$UMFPACK_LIBS $AMD_LDFLAGS $AMD_LIBS $BLAS_LIBS $FLIBS $LIBS"
   xtra_libs=
   OCTAVE_UMFPACK_NEED_SUITESPARSE_TIME
   if test "$octave_cv_umfpack_need_suitesparse_time" = yes; then
@@ -1357,7 +1358,7 @@
   ## Check for UMFPACK separately split complex matrix and RHS.
   if test -n "$UMFPACK_LIBS"; then
     save_LIBS="$LIBS";
-    LIBS="$UMFPACK_LIBS $CHOLMOD_LIBS $AMD_LIBS $COLAMD_LIBS $LAPACK_LIBS $BLAS_LIBS $FLIBS $LIBS $xtra_libs"
+    LIBS="$UMFPACK_LIBS $CHOLMOD_LDFLAGS $CHOLMOD_LIBS $AMD_LDFLAGS $AMD_LIBS $COLAMD_LDFLAGS $COLAMD_LIBS $LAPACK_LIBS $BLAS_LIBS $FLIBS $LIBS $xtra_libs"
     OCTAVE_UMFPACK_SEPARATE_SPLIT
     LIBS="$save_LIBS"
   fi
--- a/examples/mysparse.c
+++ b/examples/mysparse.c
@@ -56,7 +56,7 @@
     }
   else if (mxIsLogical (prhs[0]))
     {
-      bool *pbr, *pbr2;
+      mxLogical *pbr, *pbr2;
       mexPrintf ("Matrix is %d-by-%d logical",
                  " sparse matrix", m, n);
       mexPrintf (" with %d elements\n", nz);
--- a/libinterp/interp-core/mex.cc
+++ b/libinterp/interp-core/mex.cc
@@ -104,175 +104,12 @@
 
 // ------------------------------------------------------------------
 
-// A class to provide the default implemenation of some of the virtual
-// functions declared in the mxArray class.
-
-class mxArray_base : public mxArray
+void
+mxArray_base::error (const char *msg) const
 {
-protected:
-
-  mxArray_base (void) : mxArray (xmxArray ()) { }
-
-public:
-
-  mxArray *dup (void) const = 0;
-
-  ~mxArray_base (void) { }
-
-  bool is_octave_value (void) const { return false; }
-
-  int is_cell (void) const = 0;
-
-  int is_char (void) const = 0;
-
-  int is_class (const char *name_arg) const
-  {
-    int retval = 0;
-
-    const char *cname = get_class_name ();
-
-    if (cname && name_arg)
-      retval = ! strcmp (cname, name_arg);
-
-    return retval;
-  }
-
-  int is_complex (void) const = 0;
-
-  int is_double (void) const = 0;
-
-  int is_function_handle (void) const = 0;
-
-  int is_int16 (void) const = 0;
-
-  int is_int32 (void) const = 0;
-
-  int is_int64 (void) const = 0;
-
-  int is_int8 (void) const = 0;
-
-  int is_logical (void) const = 0;
-
-  int is_numeric (void) const = 0;
-
-  int is_single (void) const = 0;
-
-  int is_sparse (void) const = 0;
-
-  int is_struct (void) const = 0;
-
-  int is_uint16 (void) const = 0;
-
-  int is_uint32 (void) const = 0;
-
-  int is_uint64 (void) const = 0;
-
-  int is_uint8 (void) const = 0;
-
-  int is_logical_scalar (void) const
-  {
-    return is_logical () && get_number_of_elements () == 1;
-  }
-
-  int is_logical_scalar_true (void) const = 0;
-
-  mwSize get_m (void) const = 0;
-
-  mwSize get_n (void) const = 0;
-
-  mwSize *get_dimensions (void) const = 0;
-
-  mwSize get_number_of_dimensions (void) const = 0;
-
-  void set_m (mwSize m) = 0;
-
-  void set_n (mwSize n) = 0;
-
-  void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0;
-
-  mwSize get_number_of_elements (void) const = 0;
-
-  int is_empty (void) const = 0;
-
-  mxClassID get_class_id (void) const = 0;
-
-  const char *get_class_name (void) const = 0;
-
-  void set_class_name (const char *name_arg) = 0;
-
-  mxArray *get_cell (mwIndex /*idx*/) const
-  {
-    invalid_type_error ();
-    return 0;
-  }
-
-  void set_cell (mwIndex idx, mxArray *val) = 0;
-
-  double get_scalar (void) const = 0;
-
-  void *get_data (void) const = 0;
-
-  void *get_imag_data (void) const = 0;
-
-  void set_data (void *pr) = 0;
-
-  void set_imag_data (void *pi) = 0;
-
-  mwIndex *get_ir (void) const = 0;
-
-  mwIndex *get_jc (void) const = 0;
-
-  mwSize get_nzmax (void) const = 0;
-
-  void set_ir (mwIndex *ir) = 0;
-
-  void set_jc (mwIndex *jc) = 0;
-
-  void set_nzmax (mwSize nzmax) = 0;
-
-  int add_field (const char *key) = 0;
-
-  void remove_field (int key_num) = 0;
-
-  mxArray *get_field_by_number (mwIndex index, int key_num) const = 0;
-
-  void set_field_by_number (mwIndex index, int key_num, mxArray *val) = 0;
-
-  int get_number_of_fields (void) const = 0;
-
-  const char *get_field_name_by_number (int key_num) const = 0;
-
-  int get_field_number (const char *key) const = 0;
-
-  int get_string (char *buf, mwSize buflen) const = 0;
-
-  char *array_to_string (void) const = 0;
-
-  mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const = 0;
-
-  size_t get_element_size (void) const = 0;
-
-  bool mutation_needed (void) const { return false; }
-
-  mxArray *mutate (void) const { return 0; }
-
-protected:
-
-  octave_value as_octave_value (void) const = 0;
-
-  mxArray_base (const mxArray_base&) : mxArray (xmxArray ()) { }
-
-  void invalid_type_error (void) const
-  {
-    error ("invalid type for operation");
-  }
-
-  void error (const char *msg) const
-  {
-    // FIXME
-    ::error ("%s", msg);
-  }
-};
+  // FIXME
+  ::error ("%s", msg);
+}
 
 static mwIndex
 calc_single_subscript_internal (mwSize ndims, const mwSize *dims,
@@ -327,14 +164,11 @@
     : mxArray_base (), val (ov), mutate_flag (false),
       id (mxUNKNOWN_CLASS), class_name (0), ndims (-1), dims (0) { }
 
-  mxArray *dup (void) const
+  mxArray_base *dup (void) const { return new mxArray_octave_value (*this); }
+
+  mxArray *as_mxArray (void) const
   {
-    mxArray *retval = val.as_mxArray ();
-
-    if (! retval)
-      retval = new mxArray_octave_value (*this);
-
-    return retval;
+    return val.as_mxArray ();
   }
 
   ~mxArray_octave_value (void)
@@ -411,7 +245,7 @@
       {
         ndims = val.ndims ();
 
-        dims = static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)));
+        dims = static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize)));
 
         dim_vector dv = val.dims ();
 
@@ -488,7 +322,7 @@
     if (! class_name)
       {
         std::string s = val.class_name ();
-        class_name = strsave (s.c_str ());
+        class_name = mxArray::strsave (s.c_str ());
       }
 
     return class_name;
@@ -629,7 +463,7 @@
       {
         mwSize nel = get_number_of_elements ();
 
-        buf = static_cast<char *> (malloc (nel + 1));
+        buf = static_cast<char *> (mxArray::malloc (nel + 1));
 
         if (buf)
           {
@@ -693,14 +527,15 @@
 
   mxArray *mutate (void) const { return val.as_mxArray (); }
 
+  octave_value as_octave_value (void) const { return val; }
+
 protected:
 
-  octave_value as_octave_value (void) const { return val; }
-
   mxArray_octave_value (const mxArray_octave_value& arg)
     : mxArray_base (arg), val (arg.val), mutate_flag (arg.mutate_flag),
-      id (arg.id), class_name (strsave (arg.class_name)), ndims (arg.ndims),
-      dims (ndims > 0 ? static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))) : 0)
+      id (arg.id), class_name (mxArray::strsave (arg.class_name)),
+      ndims (arg.ndims),
+      dims (ndims > 0 ? static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize))) : 0)
   {
     if (dims)
       {
@@ -743,7 +578,7 @@
   mxArray_matlab (mxClassID id_arg, mwSize ndims_arg, const mwSize *dims_arg)
     : mxArray_base (), class_name (0), id (id_arg),
       ndims (ndims_arg < 2 ? 2 : ndims_arg),
-      dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))))
+      dims (static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize))))
   {
     if (ndims_arg < 2)
       {
@@ -766,7 +601,7 @@
   mxArray_matlab (mxClassID id_arg, const dim_vector& dv)
     : mxArray_base (), class_name (0), id (id_arg),
       ndims (dv.length ()),
-      dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))))
+      dims (static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize))))
   {
     for (mwIndex i = 0; i < ndims; i++)
       dims[i] = dv(i);
@@ -782,7 +617,7 @@
 
   mxArray_matlab (mxClassID id_arg, mwSize m, mwSize n)
     : mxArray_base (), class_name (0), id (id_arg), ndims (2),
-      dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))))
+      dims (static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize))))
   {
     dims[0] = m;
     dims[1] = n;
@@ -911,7 +746,7 @@
   void set_class_name (const char *name_arg)
   {
     mxFree (class_name);
-    class_name = static_cast<char *> (malloc (strlen (name_arg) + 1));
+    class_name = static_cast<char *> (mxArray::malloc (strlen (name_arg) + 1));
     strcpy (class_name, name_arg);
   }
 
@@ -1069,9 +904,9 @@
 protected:
 
   mxArray_matlab (const mxArray_matlab& val)
-    : mxArray_base (val), class_name (strsave (val.class_name)),
+    : mxArray_base (val), class_name (mxArray::strsave (val.class_name)),
       id (val.id), ndims (val.ndims),
-      dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))))
+      dims (static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize))))
   {
     for (mwIndex i = 0; i < ndims; i++)
       dims[i] = val.dims[i];
@@ -1122,23 +957,23 @@
   mxArray_number (mxClassID id_arg, mwSize ndims_arg, const mwSize *dims_arg,
                   mxComplexity flag = mxREAL)
     : mxArray_matlab (id_arg, ndims_arg, dims_arg),
-      pr (calloc (get_number_of_elements (), get_element_size ())),
-      pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { }
+      pr (mxArray::calloc (get_number_of_elements (), get_element_size ())),
+      pi (flag == mxCOMPLEX ? mxArray::calloc (get_number_of_elements (), get_element_size ()) : 0) { }
 
   mxArray_number (mxClassID id_arg, const dim_vector& dv,
                   mxComplexity flag = mxREAL)
     : mxArray_matlab (id_arg, dv),
-      pr (calloc (get_number_of_elements (), get_element_size ())),
-      pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { }
+      pr (mxArray::calloc (get_number_of_elements (), get_element_size ())),
+      pi (flag == mxCOMPLEX ? mxArray::calloc (get_number_of_elements (), get_element_size ()) : 0) { }
 
   mxArray_number (mxClassID id_arg, mwSize m, mwSize n, mxComplexity flag = mxREAL)
     : mxArray_matlab (id_arg, m, n),
-      pr (calloc (get_number_of_elements (), get_element_size ())),
-      pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { }
+      pr (mxArray::calloc (get_number_of_elements (), get_element_size ())),
+      pi (flag == mxCOMPLEX ? mxArray::calloc (get_number_of_elements (), get_element_size ()) : 0) { }
 
   mxArray_number (mxClassID id_arg, double val)
     : mxArray_matlab (id_arg, 1, 1),
-      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pr (mxArray::calloc (get_number_of_elements (), get_element_size ())),
       pi (0)
   {
     double *dpr = static_cast<double *> (pr);
@@ -1147,7 +982,7 @@
 
   mxArray_number (mxClassID id_arg, mxLogical val)
     : mxArray_matlab (id_arg, 1, 1),
-      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pr (mxArray::calloc (get_number_of_elements (), get_element_size ())),
       pi (0)
   {
     mxLogical *lpr = static_cast<mxLogical *> (pr);
@@ -1158,7 +993,7 @@
     : mxArray_matlab (mxCHAR_CLASS,
                       str ? (strlen (str) ? 1 : 0) : 0,
                       str ? strlen (str) : 0),
-      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pr (mxArray::calloc (get_number_of_elements (), get_element_size ())),
       pi (0)
   {
     mxChar *cpr = static_cast<mxChar *> (pr);
@@ -1170,7 +1005,7 @@
   // FIXME??
   mxArray_number (mwSize m, const char **str)
     : mxArray_matlab (mxCHAR_CLASS, m, max_str_len (m, str)),
-      pr (calloc (get_number_of_elements (), get_element_size ())),
+      pr (mxArray::calloc (get_number_of_elements (), get_element_size ())),
       pi (0)
   {
     mxChar *cpr = static_cast<mxChar *> (pr);
@@ -1193,7 +1028,7 @@
       }
   }
 
-  mxArray_number *dup (void) const { return new mxArray_number (*this); }
+  mxArray_base *dup (void) const { return new mxArray_number (*this); }
 
   ~mxArray_number (void)
   {
@@ -1305,7 +1140,7 @@
 
     mwSize nel = get_number_of_elements ();
 
-    char *buf = static_cast<char *> (malloc (nel + 1));
+    char *buf = static_cast<char *> (mxArray::malloc (nel + 1));
 
     if (buf)
       {
@@ -1320,35 +1155,6 @@
     return buf;
   }
 
-protected:
-
-  template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T>
-  octave_value
-  int_to_ov (const dim_vector& dv) const
-  {
-    octave_value retval;
-
-    mwSize nel = get_number_of_elements ();
-
-    ELT_T *ppr = static_cast<ELT_T *> (pr);
-
-    if (pi)
-      error ("complex integer types are not supported");
-    else
-      {
-        ARRAY_T val (dv);
-
-        ARRAY_ELT_T *ptr = val.fortran_vec ();
-
-        for (mwIndex i = 0; i < nel; i++)
-          ptr[i] = ppr[i];
-
-        retval = val;
-      }
-
-    return retval;
-  }
-
   octave_value as_octave_value (void) const
   {
     octave_value retval;
@@ -1483,10 +1289,39 @@
     return retval;
   }
 
+protected:
+
+  template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T>
+  octave_value
+  int_to_ov (const dim_vector& dv) const
+  {
+    octave_value retval;
+
+    mwSize nel = get_number_of_elements ();
+
+    ELT_T *ppr = static_cast<ELT_T *> (pr);
+
+    if (pi)
+      error ("complex integer types are not supported");
+    else
+      {
+        ARRAY_T val (dv);
+
+        ARRAY_ELT_T *ptr = val.fortran_vec ();
+
+        for (mwIndex i = 0; i < nel; i++)
+          ptr[i] = ppr[i];
+
+        retval = val;
+      }
+
+    return retval;
+  }
+
   mxArray_number (const mxArray_number& val)
     : mxArray_matlab (val),
-      pr (malloc (get_number_of_elements () * get_element_size ())),
-      pi (val.pi ? malloc (get_number_of_elements () * get_element_size ()) : 0)
+      pr (mxArray::malloc (get_number_of_elements () * get_element_size ())),
+      pi (val.pi ? mxArray::malloc (get_number_of_elements () * get_element_size ()) : 0)
   {
     size_t nbytes = get_number_of_elements () * get_element_size ();
 
@@ -1517,13 +1352,13 @@
   mxArray_sparse (mxClassID id_arg, mwSize m, mwSize n, mwSize nzmax_arg,
                   mxComplexity flag = mxREAL)
     : mxArray_matlab (id_arg, m, n), nzmax (nzmax_arg),
-      pr (calloc (nzmax, get_element_size ())),
-      pi (flag == mxCOMPLEX ? calloc (nzmax, get_element_size ()) : 0),
-      ir (static_cast<mwIndex *> (calloc (nzmax, sizeof (mwIndex)))),
-      jc (static_cast<mwIndex *> (calloc (n + 1, sizeof (mwIndex))))
+      pr (mxArray::calloc (nzmax, get_element_size ())),
+      pi (flag == mxCOMPLEX ? mxArray::calloc (nzmax, get_element_size ()) : 0),
+      ir (static_cast<mwIndex *> (mxArray::calloc (nzmax, sizeof (mwIndex)))),
+      jc (static_cast<mwIndex *> (mxArray::calloc (n + 1, sizeof (mwIndex))))
     { }
 
-  mxArray_sparse *dup (void) const { return new mxArray_sparse (*this); }
+  mxArray_base *dup (void) const { return new mxArray_sparse (*this); }
 
   ~mxArray_sparse (void)
   {
@@ -1557,8 +1392,6 @@
 
   void set_nzmax (mwSize nzmax_arg) { nzmax = nzmax_arg; }
 
-protected:
-
   octave_value as_octave_value (void) const
   {
     octave_value retval;
@@ -1651,10 +1484,10 @@
 
   mxArray_sparse (const mxArray_sparse& val)
     : mxArray_matlab (val), nzmax (val.nzmax),
-      pr (malloc (nzmax * get_element_size ())),
-      pi (val.pi ? malloc (nzmax * get_element_size ()) : 0),
-      ir (static_cast<mwIndex *> (malloc (nzmax * sizeof (mwIndex)))),
-      jc (static_cast<mwIndex *> (malloc (nzmax * sizeof (mwIndex))))
+      pr (mxArray::malloc (nzmax * get_element_size ())),
+      pi (val.pi ? mxArray::malloc (nzmax * get_element_size ()) : 0),
+      ir (static_cast<mwIndex *> (mxArray::malloc (nzmax * sizeof (mwIndex)))),
+      jc (static_cast<mwIndex *> (mxArray::malloc (nzmax * sizeof (mwIndex))))
   {
     size_t nbytes = nzmax * get_element_size ();
 
@@ -1686,24 +1519,24 @@
   mxArray_struct (mwSize ndims_arg, const mwSize *dims_arg, int num_keys_arg,
                   const char **keys)
     : mxArray_matlab (mxSTRUCT_CLASS, ndims_arg, dims_arg), nfields (num_keys_arg),
-      fields (static_cast<char **> (calloc (nfields, sizeof (char *)))),
-      data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *))))
+      fields (static_cast<char **> (mxArray::calloc (nfields, sizeof (char *)))),
+      data (static_cast<mxArray **> (mxArray::calloc (nfields * get_number_of_elements (), sizeof (mxArray *))))
   {
     init (keys);
   }
 
   mxArray_struct (const dim_vector& dv, int num_keys_arg, const char **keys)
     : mxArray_matlab (mxSTRUCT_CLASS, dv), nfields (num_keys_arg),
-      fields (static_cast<char **> (calloc (nfields, sizeof (char *)))),
-      data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *))))
+      fields (static_cast<char **> (mxArray::calloc (nfields, sizeof (char *)))),
+      data (static_cast<mxArray **> (mxArray::calloc (nfields * get_number_of_elements (), sizeof (mxArray *))))
   {
     init (keys);
   }
 
   mxArray_struct (mwSize m, mwSize n, int num_keys_arg, const char **keys)
     : mxArray_matlab (mxSTRUCT_CLASS, m, n), nfields (num_keys_arg),
-      fields (static_cast<char **> (calloc (nfields, sizeof (char *)))),
-      data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *))))
+      fields (static_cast<char **> (mxArray::calloc (nfields, sizeof (char *)))),
+      data (static_cast<mxArray **> (mxArray::calloc (nfields * get_number_of_elements (), sizeof (mxArray *))))
   {
     init (keys);
   }
@@ -1711,10 +1544,10 @@
   void init (const char **keys)
   {
     for (int i = 0; i < nfields; i++)
-      fields[i] = strsave (keys[i]);
+      fields[i] = mxArray::strsave (keys[i]);
   }
 
-  mxArray_struct *dup (void) const { return new mxArray_struct (*this); }
+  mxArray_base *dup (void) const { return new mxArray_struct (*this); }
 
   ~mxArray_struct (void)
   {
@@ -1743,13 +1576,13 @@
 
         if (fields)
           {
-            fields[nfields-1] = strsave (key);
+            fields[nfields-1] = mxArray::strsave (key);
 
             mwSize nel = get_number_of_elements ();
 
             mwSize ntot = nfields * nel;
 
-            mxArray **new_data = static_cast<mxArray **> (malloc (ntot * sizeof (mxArray *)));
+            mxArray **new_data = static_cast<mxArray **> (mxArray::malloc (ntot * sizeof (mxArray *)));
 
             if (new_data)
               {
@@ -1790,9 +1623,9 @@
 
         int new_nfields = nfields - 1;
 
-        char **new_fields = static_cast<char **> (malloc (new_nfields * sizeof (char *)));
-
-        mxArray **new_data = static_cast<mxArray **> (malloc (new_nfields * nel * sizeof (mxArray *)));
+        char **new_fields = static_cast<char **> (mxArray::malloc (new_nfields * sizeof (char *)));
+
+        mxArray **new_data = static_cast<mxArray **> (mxArray::malloc (new_nfields * nel * sizeof (mxArray *)));
 
         for (int i = 0; i < key_num; i++)
           new_fields[i] = fields[i];
@@ -1863,8 +1696,6 @@
 
   void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); }
 
-protected:
-
   octave_value as_octave_value (void) const
   {
     dim_vector dv = dims_to_dim_vector ();
@@ -1901,11 +1732,11 @@
 
   mxArray_struct (const mxArray_struct& val)
     : mxArray_matlab (val), nfields (val.nfields),
-      fields (static_cast<char **> (malloc (nfields * sizeof (char *)))),
-      data (static_cast<mxArray **> (malloc (nfields * get_number_of_elements () * sizeof (mxArray *))))
+      fields (static_cast<char **> (mxArray::malloc (nfields * sizeof (char *)))),
+      data (static_cast<mxArray **> (mxArray::malloc (nfields * get_number_of_elements () * sizeof (mxArray *))))
   {
     for (int i = 0; i < nfields; i++)
-      fields[i] = strsave (val.fields[i]);
+      fields[i] = mxArray::strsave (val.fields[i]);
 
     mwSize nel = get_number_of_elements ();
 
@@ -1930,17 +1761,17 @@
 
   mxArray_cell (mwSize ndims_arg, const mwSize *dims_arg)
     : mxArray_matlab (mxCELL_CLASS, ndims_arg, dims_arg),
-      data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
+      data (static_cast<mxArray **> (mxArray::calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
 
   mxArray_cell (const dim_vector& dv)
     : mxArray_matlab (mxCELL_CLASS, dv),
-      data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
+      data (static_cast<mxArray **> (mxArray::calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
 
   mxArray_cell (mwSize m, mwSize n)
     : mxArray_matlab (mxCELL_CLASS, m, n),
-      data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
-
-  mxArray_cell *dup (void) const { return new mxArray_cell (*this); }
+      data (static_cast<mxArray **> (mxArray::calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
+
+  mxArray_base *dup (void) const { return new mxArray_cell (*this); }
 
   ~mxArray_cell (void)
   {
@@ -1963,8 +1794,6 @@
 
   void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); }
 
-protected:
-
   octave_value as_octave_value (void) const
   {
     dim_vector dv = dims_to_dim_vector ();
@@ -1987,7 +1816,7 @@
 
   mxArray_cell (const mxArray_cell& val)
     : mxArray_matlab (val),
-      data (static_cast<mxArray **> (malloc (get_number_of_elements () * sizeof (mxArray *))))
+      data (static_cast<mxArray **> (mxArray::malloc (get_number_of_elements () * sizeof (mxArray *))))
   {
     mwSize nel = get_number_of_elements ();
 
@@ -2062,11 +1891,11 @@
 mxArray::set_name (const char *name_arg)
 {
   mxFree (name);
-  name = strsave (name_arg);
+  name = mxArray::strsave (name_arg);
 }
 
 octave_value
-mxArray::as_octave_value (mxArray *ptr)
+mxArray::as_octave_value (const mxArray *ptr)
 {
   return ptr ? ptr->as_octave_value () : octave_value (Matrix ());
 }
@@ -2532,7 +2361,7 @@
 void *
 mxCalloc (size_t n, size_t size)
 {
-  return mex_context ? mex_context->calloc (n, size) : calloc (n, size);
+  return mex_context ? mex_context->calloc (n, size) : ::calloc (n, size);
 }
 
 void *
@@ -3180,8 +3009,8 @@
 }
 
 int
-mexCallMATLAB (int nargout, mxArray *argout[], int nargin, mxArray *argin[],
-               const char *fname)
+mexCallMATLAB (int nargout, mxArray *argout[], int nargin,
+               const mxArray *argin[], const char *fname)
 {
   octave_value_list args;
 
@@ -3386,7 +3215,7 @@
 }
 
 int
-mexPutVariable (const char *space, const char *name, mxArray *ptr)
+mexPutVariable (const char *space, const char *name, const mxArray *ptr)
 {
   if (! ptr)
     return 1;
--- a/libinterp/interp-core/mexproto.h
+++ b/libinterp/interp-core/mexproto.h
@@ -87,7 +87,8 @@
 extern OCTINTERP_API mxArray *mexGetVariable (const char *space, const char *name);
 extern OCTINTERP_API const mxArray *mexGetVariablePtr (const char *space, const char *name);
 
-extern OCTINTERP_API int mexPutVariable (const char *space, const char *name, mxArray *ptr);
+extern OCTINTERP_API int mexPutVariable (const char *space, const char *name,
+                                         const mxArray *ptr);
 
 extern OCTINTERP_API void mexMakeArrayPersistent (mxArray *ptr);
 extern OCTINTERP_API void mexMakeMemoryPersistent (void *ptr);
--- a/libinterp/interp-core/mxarray.in.h
+++ b/libinterp/interp-core/mxarray.in.h
@@ -116,13 +116,174 @@
       rep->METHOD_CALL; \
     }
 
-// This just provides a way to avoid infinite recursion when building
-// mxArray objects.
+// A class to provide the default implemenation of some of the virtual
+// functions declared in the mxArray class.
+
+class mxArray;
+
+class mxArray_base
+{
+protected:
+
+  mxArray_base (void) { }
+
+public:
+
+  virtual mxArray_base *dup (void) const = 0;
+
+  virtual mxArray *as_mxArray (void) const { return 0; }
+
+  virtual ~mxArray_base (void) { }
+
+  virtual bool is_octave_value (void) const { return false; }
+
+  virtual int is_cell (void) const = 0;
+
+  virtual int is_char (void) const = 0;
+
+  virtual int is_class (const char *name_arg) const
+  {
+    int retval = 0;
+
+    const char *cname = get_class_name ();
+
+    if (cname && name_arg)
+      retval = ! strcmp (cname, name_arg);
+
+    return retval;
+  }
+
+  virtual int is_complex (void) const = 0;
+
+  virtual int is_double (void) const = 0;
+
+  virtual int is_function_handle (void) const = 0;
+
+  virtual int is_int16 (void) const = 0;
+
+  virtual int is_int32 (void) const = 0;
+
+  virtual int is_int64 (void) const = 0;
+
+  virtual int is_int8 (void) const = 0;
+
+  virtual int is_logical (void) const = 0;
+
+  virtual int is_numeric (void) const = 0;
+
+  virtual int is_single (void) const = 0;
+
+  virtual int is_sparse (void) const = 0;
+
+  virtual int is_struct (void) const = 0;
+
+  virtual int is_uint16 (void) const = 0;
+
+  virtual int is_uint32 (void) const = 0;
+
+  virtual int is_uint64 (void) const = 0;
+
+  virtual int is_uint8 (void) const = 0;
+
+  virtual int is_logical_scalar (void) const
+  {
+    return is_logical () && get_number_of_elements () == 1;
+  }
+
+  virtual int is_logical_scalar_true (void) const = 0;
+
+  virtual mwSize get_m (void) const = 0;
+
+  virtual mwSize get_n (void) const = 0;
+
+  virtual mwSize *get_dimensions (void) const = 0;
+
+  virtual mwSize get_number_of_dimensions (void) const = 0;
 
-struct
-xmxArray
-{
-  xmxArray (void) { }
+  virtual void set_m (mwSize m) = 0;
+
+  virtual void set_n (mwSize n) = 0;
+
+  virtual void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0;
+
+  virtual mwSize get_number_of_elements (void) const = 0;
+
+  virtual int is_empty (void) const = 0;
+
+  virtual mxClassID get_class_id (void) const = 0;
+
+  virtual const char *get_class_name (void) const = 0;
+
+  virtual void set_class_name (const char *name_arg) = 0;
+
+  virtual mxArray *get_cell (mwIndex /*idx*/) const
+  {
+    invalid_type_error ();
+    return 0;
+  }
+
+  virtual void set_cell (mwIndex idx, mxArray *val) = 0;
+
+  virtual double get_scalar (void) const = 0;
+
+  virtual void *get_data (void) const = 0;
+
+  virtual void *get_imag_data (void) const = 0;
+
+  virtual void set_data (void *pr) = 0;
+
+  virtual void set_imag_data (void *pi) = 0;
+
+  virtual mwIndex *get_ir (void) const = 0;
+
+  virtual mwIndex *get_jc (void) const = 0;
+
+  virtual mwSize get_nzmax (void) const = 0;
+
+  virtual void set_ir (mwIndex *ir) = 0;
+
+  virtual void set_jc (mwIndex *jc) = 0;
+
+  virtual void set_nzmax (mwSize nzmax) = 0;
+
+  virtual int add_field (const char *key) = 0;
+
+  virtual void remove_field (int key_num) = 0;
+
+  virtual mxArray *get_field_by_number (mwIndex index, int key_num) const = 0;
+
+  virtual void set_field_by_number (mwIndex index, int key_num, mxArray *val) = 0;
+
+  virtual int get_number_of_fields (void) const = 0;
+
+  virtual const char *get_field_name_by_number (int key_num) const = 0;
+
+  virtual int get_field_number (const char *key) const = 0;
+
+  virtual int get_string (char *buf, mwSize buflen) const = 0;
+
+  virtual char *array_to_string (void) const = 0;
+
+  virtual mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const = 0;
+
+  virtual size_t get_element_size (void) const = 0;
+
+  virtual bool mutation_needed (void) const { return false; }
+
+  virtual mxArray *mutate (void) const { return 0; }
+
+  virtual octave_value as_octave_value (void) const = 0;
+
+protected:
+
+  mxArray_base (const mxArray_base&) { }
+
+  void invalid_type_error (void) const
+  {
+    error ("invalid type for operation");
+  }
+
+  void error (const char *msg) const;
 };
 
 // The main interface class.  The representation can be based on an
@@ -165,138 +326,147 @@
 
   mxArray (mwSize m, mwSize n);
 
-  virtual mxArray *dup (void) const
+  mxArray *dup (void) const
   {
-    mxArray *new_rep = rep->dup ();
+    mxArray *retval = rep->as_mxArray ();
 
-    return new mxArray (new_rep, name);
+    if (retval)
+      retval->set_name (name);
+    else
+      {
+        mxArray_base *new_rep = rep->dup ();
+
+        retval = new mxArray (new_rep, name);
+      }
+
+    return retval;
   }
 
-  virtual ~mxArray (void);
+  ~mxArray (void);
 
-  virtual bool is_octave_value (void) const { return rep->is_octave_value (); }
+  bool is_octave_value (void) const { return rep->is_octave_value (); }
 
-  virtual int is_cell (void) const { return rep->is_cell (); }
+  int is_cell (void) const { return rep->is_cell (); }
 
-  virtual int is_char (void) const { return rep->is_char (); }
+  int is_char (void) const { return rep->is_char (); }
 
-  virtual int is_class (const char *name_arg) const { return rep->is_class (name_arg); }
+  int is_class (const char *name_arg) const { return rep->is_class (name_arg); }
 
-  virtual int is_complex (void) const { return rep->is_complex (); }
+  int is_complex (void) const { return rep->is_complex (); }
 
-  virtual int is_double (void) const { return rep->is_double (); }
+  int is_double (void) const { return rep->is_double (); }
 
-  virtual int is_function_handle (void) const { return rep->is_function_handle (); }
+  int is_function_handle (void) const { return rep->is_function_handle (); }
 
-  virtual int is_int16 (void) const { return rep->is_int16 (); }
+  int is_int16 (void) const { return rep->is_int16 (); }
 
-  virtual int is_int32 (void) const { return rep->is_int32 (); }
+  int is_int32 (void) const { return rep->is_int32 (); }
 
-  virtual int is_int64 (void) const { return rep->is_int64 (); }
+  int is_int64 (void) const { return rep->is_int64 (); }
 
-  virtual int is_int8 (void) const { return rep->is_int8 (); }
+  int is_int8 (void) const { return rep->is_int8 (); }
 
-  virtual int is_logical (void) const { return rep->is_logical (); }
+  int is_logical (void) const { return rep->is_logical (); }
 
-  virtual int is_numeric (void) const { return rep->is_numeric (); }
+  int is_numeric (void) const { return rep->is_numeric (); }
 
-  virtual int is_single (void) const { return rep->is_single (); }
+  int is_single (void) const { return rep->is_single (); }
 
-  virtual int is_sparse (void) const { return rep->is_sparse (); }
+  int is_sparse (void) const { return rep->is_sparse (); }
 
-  virtual int is_struct (void) const { return rep->is_struct (); }
+  int is_struct (void) const { return rep->is_struct (); }
 
-  virtual int is_uint16 (void) const { return rep->is_uint16 (); }
+  int is_uint16 (void) const { return rep->is_uint16 (); }
 
-  virtual int is_uint32 (void) const { return rep->is_uint32 (); }
+  int is_uint32 (void) const { return rep->is_uint32 (); }
 
-  virtual int is_uint64 (void) const { return rep->is_uint64 (); }
+  int is_uint64 (void) const { return rep->is_uint64 (); }
 
-  virtual int is_uint8 (void) const { return rep->is_uint8 (); }
+  int is_uint8 (void) const { return rep->is_uint8 (); }
 
-  virtual int is_logical_scalar (void) const { return rep->is_logical_scalar (); }
+  int is_logical_scalar (void) const { return rep->is_logical_scalar (); }
 
-  virtual int is_logical_scalar_true (void) const { return rep->is_logical_scalar_true (); }
+  int is_logical_scalar_true (void) const { return rep->is_logical_scalar_true (); }
 
-  virtual mwSize get_m (void) const { return rep->get_m (); }
+  mwSize get_m (void) const { return rep->get_m (); }
 
-  virtual mwSize get_n (void) const { return rep->get_n (); }
+  mwSize get_n (void) const { return rep->get_n (); }
 
-  virtual mwSize *get_dimensions (void) const { return rep->get_dimensions (); }
+  mwSize *get_dimensions (void) const { return rep->get_dimensions (); }
 
-  virtual mwSize get_number_of_dimensions (void) const { return rep->get_number_of_dimensions (); }
+  mwSize get_number_of_dimensions (void) const { return rep->get_number_of_dimensions (); }
 
-  virtual void set_m (mwSize m) { DO_VOID_MUTABLE_METHOD (set_m (m)); }
+  void set_m (mwSize m) { DO_VOID_MUTABLE_METHOD (set_m (m)); }
 
-  virtual void set_n (mwSize n) { DO_VOID_MUTABLE_METHOD (set_n (n)); }
+  void set_n (mwSize n) { DO_VOID_MUTABLE_METHOD (set_n (n)); }
 
-  virtual void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) { DO_VOID_MUTABLE_METHOD (set_dimensions (dims_arg, ndims_arg)); }
+  void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) { DO_VOID_MUTABLE_METHOD (set_dimensions (dims_arg, ndims_arg)); }
 
-  virtual mwSize get_number_of_elements (void) const { return rep->get_number_of_elements (); }
+  mwSize get_number_of_elements (void) const { return rep->get_number_of_elements (); }
 
-  virtual int is_empty (void) const { return get_number_of_elements () == 0; }
+  int is_empty (void) const { return get_number_of_elements () == 0; }
 
   const char *get_name (void) const { return name; }
 
   void set_name (const char *name_arg);
 
-  virtual mxClassID get_class_id (void) const { return rep->get_class_id (); }
+  mxClassID get_class_id (void) const { return rep->get_class_id (); }
 
-  virtual const char *get_class_name (void) const { return rep->get_class_name (); }
+  const char *get_class_name (void) const { return rep->get_class_name (); }
 
-  virtual void set_class_name (const char *name_arg) { DO_VOID_MUTABLE_METHOD (set_class_name (name_arg)); }
+  void set_class_name (const char *name_arg) { DO_VOID_MUTABLE_METHOD (set_class_name (name_arg)); }
 
-  virtual mxArray *get_cell (mwIndex idx) const { DO_MUTABLE_METHOD (mxArray *, get_cell (idx)); }
+  mxArray *get_cell (mwIndex idx) const { DO_MUTABLE_METHOD (mxArray *, get_cell (idx)); }
 
-  virtual void set_cell (mwIndex idx, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_cell (idx, val)); }
+  void set_cell (mwIndex idx, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_cell (idx, val)); }
 
-  virtual double get_scalar (void) const { return rep->get_scalar (); }
+  double get_scalar (void) const { return rep->get_scalar (); }
 
-  virtual void *get_data (void) const { DO_MUTABLE_METHOD (void *, get_data ()); }
+  void *get_data (void) const { DO_MUTABLE_METHOD (void *, get_data ()); }
 
-  virtual void *get_imag_data (void) const { DO_MUTABLE_METHOD (void *, get_imag_data ()); }
+  void *get_imag_data (void) const { DO_MUTABLE_METHOD (void *, get_imag_data ()); }
 
-  virtual void set_data (void *pr) { DO_VOID_MUTABLE_METHOD (set_data (pr)); }
+  void set_data (void *pr) { DO_VOID_MUTABLE_METHOD (set_data (pr)); }
 
-  virtual void set_imag_data (void *pi) { DO_VOID_MUTABLE_METHOD (set_imag_data (pi)); }
+  void set_imag_data (void *pi) { DO_VOID_MUTABLE_METHOD (set_imag_data (pi)); }
 
-  virtual mwIndex *get_ir (void) const { DO_MUTABLE_METHOD (mwIndex *, get_ir ()); }
+  mwIndex *get_ir (void) const { DO_MUTABLE_METHOD (mwIndex *, get_ir ()); }
 
-  virtual mwIndex *get_jc (void) const { DO_MUTABLE_METHOD (mwIndex *, get_jc ()); }
+  mwIndex *get_jc (void) const { DO_MUTABLE_METHOD (mwIndex *, get_jc ()); }
 
-  virtual mwSize get_nzmax (void) const { return rep->get_nzmax (); }
+  mwSize get_nzmax (void) const { return rep->get_nzmax (); }
 
-  virtual void set_ir (mwIndex *ir) { DO_VOID_MUTABLE_METHOD (set_ir (ir)); }
+  void set_ir (mwIndex *ir) { DO_VOID_MUTABLE_METHOD (set_ir (ir)); }
 
-  virtual void set_jc (mwIndex *jc) { DO_VOID_MUTABLE_METHOD (set_jc (jc)); }
+  void set_jc (mwIndex *jc) { DO_VOID_MUTABLE_METHOD (set_jc (jc)); }
 
-  virtual void set_nzmax (mwSize nzmax) { DO_VOID_MUTABLE_METHOD (set_nzmax (nzmax)); }
+  void set_nzmax (mwSize nzmax) { DO_VOID_MUTABLE_METHOD (set_nzmax (nzmax)); }
 
-  virtual int add_field (const char *key) { DO_MUTABLE_METHOD (int, add_field (key)); }
+  int add_field (const char *key) { DO_MUTABLE_METHOD (int, add_field (key)); }
 
-  virtual void remove_field (int key_num) { DO_VOID_MUTABLE_METHOD (remove_field (key_num)); }
+  void remove_field (int key_num) { DO_VOID_MUTABLE_METHOD (remove_field (key_num)); }
 
-  virtual mxArray *get_field_by_number (mwIndex index, int key_num) const { DO_MUTABLE_METHOD (mxArray *, get_field_by_number (index, key_num)); }
+  mxArray *get_field_by_number (mwIndex index, int key_num) const { DO_MUTABLE_METHOD (mxArray *, get_field_by_number (index, key_num)); }
 
-  virtual void set_field_by_number (mwIndex index, int key_num, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_field_by_number (index, key_num, val)); }
+  void set_field_by_number (mwIndex index, int key_num, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_field_by_number (index, key_num, val)); }
 
-  virtual int get_number_of_fields (void) const { return rep->get_number_of_fields (); }
+  int get_number_of_fields (void) const { return rep->get_number_of_fields (); }
 
-  virtual const char *get_field_name_by_number (int key_num) const { DO_MUTABLE_METHOD (const char*, get_field_name_by_number (key_num)); }
+  const char *get_field_name_by_number (int key_num) const { DO_MUTABLE_METHOD (const char*, get_field_name_by_number (key_num)); }
 
-  virtual int get_field_number (const char *key) const { DO_MUTABLE_METHOD (int, get_field_number (key)); }
+  int get_field_number (const char *key) const { DO_MUTABLE_METHOD (int, get_field_number (key)); }
 
-  virtual int get_string (char *buf, mwSize buflen) const { return rep->get_string (buf, buflen); }
+  int get_string (char *buf, mwSize buflen) const { return rep->get_string (buf, buflen); }
 
-  virtual char *array_to_string (void) const { return rep->array_to_string (); }
+  char *array_to_string (void) const { return rep->array_to_string (); }
 
-  virtual mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const { return rep->calc_single_subscript (nsubs, subs); }
+  mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const { return rep->calc_single_subscript (nsubs, subs); }
 
-  virtual size_t get_element_size (void) const { return rep->get_element_size (); }
+  size_t get_element_size (void) const { return rep->get_element_size (); }
 
-  virtual bool mutation_needed (void) const { return rep->mutation_needed (); }
+  bool mutation_needed (void) const { return rep->mutation_needed (); }
 
-  virtual mxArray *mutate (void) const { return rep->mutate (); }
+  mxArray *mutate (void) const { return rep->mutate (); }
 
   static void *malloc (size_t n);
 
@@ -316,22 +486,20 @@
     return retval;
   }
 
-  static octave_value as_octave_value (mxArray *ptr);
+  static octave_value as_octave_value (const mxArray *ptr);
 
 protected:
 
-  virtual octave_value as_octave_value (void) const;
-
-  mxArray (const xmxArray&) : rep (0), name (0) { }
+  octave_value as_octave_value (void) const;
 
 private:
 
-  mutable mxArray *rep;
+  mutable mxArray_base *rep;
 
   char *name;
 
-  mxArray (mxArray *r, const char *n)
-    : rep (r), name (strsave (n)) { }
+  mxArray (mxArray_base *r, const char *n)
+    : rep (r), name (mxArray::strsave (n)) { }
 
   void maybe_mutate (void) const;
 
--- a/m4/acinclude.m4
+++ b/m4/acinclude.m4
@@ -313,34 +313,35 @@
 
   if test -n "$m4_toupper([$1])_LIBS"; then
     ac_octave_save_CPPFLAGS="$CPPFLAGS"
+    ac_octave_save_LDFLAGS="$LDFLAGS"
+    ac_octave_save_LIBS="$LIBS"
     CPPFLAGS="$m4_toupper([$1])_CPPFLAGS $CPPFLAGS"
+    LDFLAGS="$m4_toupper([$1])_LDFLAGS $LDFLAGS"
+    LIBS="$m4_toupper([$1])_LIBS $LIBS"
     m4_ifnblank([$6], [AC_LANG_PUSH($6)])
-    octave_$1_check_for_lib=false
-    m4_ifblank([$4], [octave_$1_check_for_lib=true],
-               [AC_CHECK_HEADERS([$4], [octave_$1_check_for_lib=true; break])])
-    if $octave_$1_check_for_lib; then
-      ac_octave_save_LDFLAGS="$LDFLAGS"
-      LDFLAGS="$m4_toupper([$1])_LDFLAGS $LDFLAGS"
-      ac_octave_save_LIBS="$LIBS"
-      LIBS="$m4_toupper([$1])_LIBS $LIBS"
-      octave_$1_ok=no
-      AC_MSG_CHECKING([for $5 in $m4_toupper([$1])_LIBS])
-      AC_LINK_IFELSE([AC_LANG_CALL([], [$5])],
-        [octave_$1_ok=yes])
-      AC_MSG_RESULT([$octave_$1_ok])
-      if test $octave_$1_ok = yes; then
+    ac_octave_$1_check_for_lib=false
+    m4_ifblank([$4], [ac_octave_$1_check_for_lib=true],
+               [AC_CHECK_HEADERS([$4], [ac_octave_$1_check_for_lib=true; break])])
+    if $ac_octave_$1_check_for_lib; then
+      AC_CACHE_CHECK([for $5 in $m4_toupper([$1])_LIBS],
+        [octave_cv_lib_$1],
+        [AC_LINK_IFELSE([AC_LANG_CALL([], [$5])],
+          [octave_cv_lib_$1=yes], [octave_cv_lib_$1=no])
+      ])
+      if test "$octave_cv_lib_$1" = yes; then
         m4_ifblank([$8], [
           warn_$1=
           AC_DEFINE([HAVE_]m4_toupper([$1]), 1,
             [Define to 1 if $2 is available.])
           [TEXINFO_]m4_toupper([$1])="@set [HAVE_]m4_toupper([$1])"], [$8])
       fi
-      LIBS="$ac_octave_save_LIBS"
-      LDFLAGS="$ac_octave_save_LDFLAGS"
     fi
     m4_ifnblank([$6], [AC_LANG_POP($6)])
     CPPFLAGS="$ac_octave_save_CPPFLAGS"
+    LDFLAGS="$ac_octave_save_LDFLAGS"
+    LIBS="$ac_octave_save_LIBS"
   fi
+
   AC_SUBST(m4_toupper([$1])_LIBS)
   AC_SUBST([TEXINFO_]m4_toupper([$1]))
   if test -n "$warn_$1"; then