changeset 227:1a48a1b91489

[project @ 1993-11-15 10:10:35 by jwe]
author jwe
date Mon, 15 Nov 1993 10:11:59 +0000
parents c4027b057786
children ee01ac1c7acc
files libcruft/misc/lo-error.cc liboctave/Bounds.cc liboctave/ColVector.cc liboctave/CollocWt.cc liboctave/DASSL.cc liboctave/DiagMatrix.cc liboctave/FEGrid.cc liboctave/LSODE.cc liboctave/LinConst.cc liboctave/Matrix-ext.cc liboctave/Matrix.cc liboctave/Matrix.h liboctave/NLEqn.cc liboctave/RowVector.cc liboctave/idx-vector.cc liboctave/idx-vector.h liboctave/lo-error.h
diffstat 17 files changed, 1793 insertions(+), 520 deletions(-) [+]
line wrap: on
line diff
--- a/libcruft/misc/lo-error.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/libcruft/misc/lo-error.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -29,12 +29,8 @@
 #include <stdlib.h>
 #include <stdarg.h>
 
-#include "liboctave-error.h"
+#include "lo-error.h"
 
-static
-liboctave_error_handler default_liboctave_error_handler = liboctave_fatal;
-
-static
 liboctave_error_handler current_liboctave_error_handler = liboctave_fatal;
 
 static void
@@ -54,7 +50,7 @@
   if (f)
     current_liboctave_error_handler = f;
   else
-    current_liboctave_error_handler = default_liboctave_error_handler;
+    current_liboctave_error_handler = liboctave_fatal;
 }
 
 void
--- a/liboctave/Bounds.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/Bounds.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -27,14 +27,14 @@
 
 #include <iostream.h>
 #include "Bounds.h"
+#include "lo-error.h"
 
 // error handling
 
 void
 Bounds::error (const char* msg)
 {
-  cerr << "Fatal bounds error. " << msg << "\n";
-  exit(1);
+  (*current_liboctave_error_handler) ("fatal bounds error: ", msg);
 }
 
 Bounds::Bounds (void)
@@ -54,7 +54,10 @@
 Bounds::Bounds (const ColumnVector l, const ColumnVector u)
 {
   if (l.capacity () != u.capacity ())
-    error ("inconsistent sizes for lower and upper bounds");
+    {
+      error ("inconsistent sizes for lower and upper bounds");
+      return;
+    }
 
   nb = l.capacity ();
   lb = l;
@@ -140,7 +143,10 @@
 Bounds::set_bounds (const ColumnVector l, const ColumnVector u)
 {
   if (l.capacity () != u.capacity ())
-    error ("inconsistent sizes for lower and upper bounds");
+    {
+      error ("inconsistent sizes for lower and upper bounds");
+      return *this;
+    }
 
   nb = l.capacity ();
   lb = l;
@@ -185,7 +191,10 @@
 Bounds::set_lower_bounds (const ColumnVector l)
 {
   if (nb != l.capacity ())
-    error ("inconsistent size for lower bounds");
+    {
+      error ("inconsistent size for lower bounds");
+      return *this;
+    }
 
   lb = l;
 
@@ -196,7 +205,10 @@
 Bounds::set_upper_bounds (const ColumnVector u)
 {
   if (nb != u.capacity ())
-    error ("inconsistent size for upper bounds");
+    {
+      error ("inconsistent size for upper bounds");
+      return *this;
+    }
 
   ub = u;
 
--- a/liboctave/ColVector.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/ColVector.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -30,6 +30,7 @@
 
 #include "Matrix.h"
 #include "mx-inlines.cc"
+#include "lo-error.h"
 
 /*
  * Column Vector class.
@@ -38,7 +39,13 @@
 ColumnVector::ColumnVector (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create column vector with negative dimension");
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   len = n;
   if (n > 0)
@@ -50,7 +57,13 @@
 ColumnVector::ColumnVector (int n, double val)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create column vector with negative dimension");
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   len = n;
   if (n > 0)
@@ -99,11 +112,44 @@
   return *this;
 }
 
+double&
+ColumnVector::checkelem (int n)
+{
+#ifndef NO_RANGE_CHECK
+  if (n < 0 || n >= len)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      static double foo = 0.0;
+      return foo;
+    }
+#endif
+
+  return elem (n);
+}
+
+double
+ColumnVector::checkelem (int n) const
+{
+#ifndef NO_RANGE_CHECK
+  if (n < 0 || n >= len)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      return 0.0;
+    }
+#endif
+
+  return elem (n);
+}
+
 ColumnVector&
 ColumnVector::resize (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return *this;
+    }
 
   double *new_data = (double *) NULL;
   if (n > 0)
@@ -153,7 +199,10 @@
 ColumnVector::insert (const ColumnVector& a, int r)
 {
   if (r < 0 || r + a.len - 1 > len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     data[r+i] = a.data[i];
@@ -173,7 +222,10 @@
 ColumnVector::fill (double val, int r1, int r2)
 {
   if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; }
 
@@ -298,7 +350,11 @@
 ColumnVector::operator * (const RowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector multiplication attempted");
+      return Matrix ();
+    }
 
   if (len == 0)
     return Matrix (len, len, 0.0);
@@ -331,7 +387,11 @@
 ColumnVector::operator + (const ColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector addition attempted");
+      return ColumnVector ();
+    }
 
   if (len == 0)
     return ColumnVector (0);
@@ -343,7 +403,11 @@
 ColumnVector::operator - (const ColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector subtraction attempted");
+      return ColumnVector ();
+    }
 
   if (len == 0)
     return ColumnVector (0);
@@ -355,7 +419,11 @@
 ColumnVector::operator + (const ComplexColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector addition attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -367,7 +435,11 @@
 ColumnVector::operator - (const ComplexColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector subtraction attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -379,7 +451,11 @@
 ColumnVector::product (const ColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector product attempted");
+      return ColumnVector ();
+    }
 
   if (len == 0)
     return ColumnVector (0);
@@ -391,7 +467,11 @@
 ColumnVector::quotient (const ColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector quotient attempted");
+      return ColumnVector ();
+    }
 
   if (len == 0)
     return ColumnVector (0);
@@ -403,7 +483,11 @@
 ColumnVector::product (const ComplexColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector product attempted");
+      return ColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -415,7 +499,11 @@
 ColumnVector::quotient (const ComplexColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector quotient attempted");
+      return ColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -427,7 +515,11 @@
 ColumnVector::operator += (const ColumnVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return ColumnVector ();
+    }
 
   if (len == 0)
     return *this;
@@ -440,7 +532,11 @@
 ColumnVector::operator -= (const ColumnVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return ColumnVector ();
+    }
 
   if (len == 0)
     return *this;
@@ -521,7 +617,13 @@
 ComplexColumnVector::ComplexColumnVector (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create column vector with negative dimension");
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   len = n;
   if (n > 0)
@@ -533,7 +635,13 @@
 ComplexColumnVector::ComplexColumnVector (int n, double val)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create column vector with negative dimension");
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   len = n;
   if (n > 0)
@@ -548,7 +656,13 @@
 ComplexColumnVector::ComplexColumnVector (int n, const Complex& val)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create column vector with negative dimension");
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   len = n;
   if (n > 0)
@@ -632,11 +746,44 @@
   return *this;
 }
 
+Complex&
+ComplexColumnVector::checkelem (int n)
+{
+#ifndef NO_RANGE_CHECK
+  if (n < 0 || n >= len)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      static Complex foo (0.0);
+      return foo;
+    }
+#endif
+
+  return elem (n);
+}
+
+Complex
+ComplexColumnVector::checkelem (int n) const
+{
+#ifndef NO_RANGE_CHECK
+  if (n < 0 || n >= len)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      return Complex (0.0);
+    }
+#endif
+
+  return elem (n);
+}
+
 ComplexColumnVector&
 ComplexColumnVector::resize (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return *this;
+    }
 
   Complex *new_data = (Complex *) NULL;
   if (n > 0)
@@ -699,7 +846,10 @@
 ComplexColumnVector::insert (const ColumnVector& a, int r)
 {
   if (r < 0 || r + a.len - 1 > len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     data[r+i] = a.data[i];
@@ -711,7 +861,10 @@
 ComplexColumnVector::insert (const ComplexColumnVector& a, int r)
 {
   if (r < 0 || r + a.len - 1 > len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     data[r+i] = a.data[i];
@@ -739,7 +892,10 @@
 ComplexColumnVector::fill (double val, int r1, int r2)
 {
   if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; }
 
@@ -753,7 +909,10 @@
 ComplexColumnVector::fill (const Complex& val, int r1, int r2)
 {
   if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; }
 
@@ -952,7 +1111,11 @@
 ComplexColumnVector::operator * (const ComplexRowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector multiplication attempted");
+      return ComplexMatrix ();
+    }
 
   if (len == 0)
     return ComplexMatrix (len, len, 0.0);
@@ -978,7 +1141,11 @@
 ComplexColumnVector::operator + (const ColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector addition attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -990,7 +1157,11 @@
 ComplexColumnVector::operator - (const ColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector subtraction attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -1002,7 +1173,11 @@
 ComplexColumnVector::operator + (const ComplexColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector addition attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -1014,7 +1189,11 @@
 ComplexColumnVector::operator - (const ComplexColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector subtraction attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -1026,7 +1205,11 @@
 ComplexColumnVector::product (const ColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector product attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -1038,7 +1221,11 @@
 ComplexColumnVector::quotient (const ColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector quotient attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -1050,7 +1237,11 @@
 ComplexColumnVector::product (const ComplexColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector product attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -1062,7 +1253,11 @@
 ComplexColumnVector::quotient (const ComplexColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector quotient attempted");
+      return ComplexColumnVector ();
+    }
 
   if (len == 0)
     return ComplexColumnVector (0);
@@ -1074,7 +1269,11 @@
 ComplexColumnVector::operator += (const ColumnVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
@@ -1087,7 +1286,11 @@
 ComplexColumnVector::operator -= (const ColumnVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
@@ -1100,7 +1303,11 @@
 ComplexColumnVector::operator += (const ComplexColumnVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
@@ -1113,7 +1320,11 @@
 ComplexColumnVector::operator -= (const ComplexColumnVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
--- a/liboctave/CollocWt.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/CollocWt.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -28,6 +28,7 @@
 #include <iostream.h>
 #include "CollocWt.h"
 #include "f77-uscore.h"
+#include "lo-error.h"
 
 extern "C"
 {
@@ -43,8 +44,7 @@
 void
 CollocWt::error (const char* msg)
 {
-  cerr << "Fatal CollocWt error. " << msg << "\n";
-  exit(1);
+  (*current_liboctave_error_handler) ("fatal CollocWt error: %s", msg);
 }
 
 CollocWt::CollocWt (void)
@@ -183,7 +183,10 @@
 CollocWt::set_left (double val)
 {
   if (val >= rb)
-    error ("left bound greater than right bound");
+    {
+      error ("left bound greater than right bound");
+      return *this;
+    }
 
   lb = val;
   initialized = 0;
@@ -210,7 +213,10 @@
 CollocWt::set_right (double val)
 {
   if (val <= lb)
-    error ("right bound less than left bound");
+    {
+      error ("right bound less than left bound");
+      return *this;
+    }
 
   rb = val;
   initialized = 0;
@@ -240,11 +246,17 @@
 
   double wid = rb - lb;
   if (wid <= 0.0)
-    error ("width less than or equal to zero");
+    {
+      error ("width less than or equal to zero");
+      return;
+    }
 
   nt = n + inc_left + inc_right;
   if (nt < 0)
-    error ("total number of collocation points less than zero");
+    {
+      error ("total number of collocation points less than zero");
+      return;
+    }
   else if (nt == 0)
     return;
 
--- a/liboctave/DASSL.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/DASSL.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -27,6 +27,7 @@
 
 #include <iostream.h>
 #include "DAE.h"
+#include "lo-error.h"
 
 extern "C"
 {
@@ -125,8 +126,11 @@
 {
   if (deriv.capacity () != state.capacity ())
     {
-      cerr << "x, xdot size mismatch in DAE constructor";
-      exit (1);
+      (*current_liboctave_error_handler)
+	("x, xdot size mismatch in DAE constructor");
+      n = 0;
+      t = 0.0;
+      return;
     }
 
   n = state.capacity ();
--- a/liboctave/DiagMatrix.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/DiagMatrix.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -30,6 +30,7 @@
 
 #include "Matrix.h"
 #include "mx-inlines.cc"
+#include "lo-error.h"
 
 /*
  * Diagonal Matrix class.
@@ -38,7 +39,15 @@
 DiagMatrix::DiagMatrix (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   nr = n;
   nc = n;
@@ -52,7 +61,15 @@
 DiagMatrix::DiagMatrix (int n, double val)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   nr = n;
   nc = n;
@@ -69,7 +86,15 @@
 DiagMatrix::DiagMatrix (int r, int c)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -83,7 +108,15 @@
 DiagMatrix::DiagMatrix (int r, int c, double val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -168,11 +201,44 @@
   return *this;
 }
 
+double&
+DiagMatrix::checkelem (int r, int c)
+{
+#ifndef NO_RANGE_CHECK
+  if (r < 0 || r >= nr || c < 0 || c >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      static double foo = 0.0;
+      return foo;
+    }
+#endif
+
+  return elem (r, c);
+}
+
+double
+DiagMatrix::checkelem (int r, int c) const
+{
+#ifndef NO_RANGE_CHECK
+  if (r < 0 || r >= nr || c < 0 || c >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      return 0.0;
+    }
+#endif
+
+  return elem (r, c);
+}
+
 DiagMatrix&
 DiagMatrix::resize (int r, int c)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r < c ? r : c;
   double *new_data = (double *) NULL;
@@ -199,7 +265,11 @@
 DiagMatrix::resize (int r, int c, double val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r < c ? r : c;
   double *new_data = (double *) NULL;
@@ -254,7 +324,10 @@
 DiagMatrix::fill (double val, int beg, int end)
 {
   if (beg < 0 || end >= len || end < beg)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (end > beg)
     copy (data+beg, beg-end, val);
@@ -265,7 +338,10 @@
 DiagMatrix::fill (const ColumnVector& a)
 {
   if (a.len != len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data, a.data, len);
   return *this;
@@ -275,7 +351,10 @@
 DiagMatrix::fill (const RowVector& a)
 {
   if (a.len != len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data, a.data, len);
   return *this;
@@ -285,7 +364,10 @@
 DiagMatrix::fill (const ColumnVector& a, int beg)
 {
   if (beg < 0 || beg + a.len >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data+beg, a.data, a.len);
   return *this;
@@ -295,7 +377,10 @@
 DiagMatrix::fill (const RowVector& a, int beg)
 {
   if (beg < 0 || beg + a.len >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data+beg, a.data, a.len);
   return *this;
@@ -331,7 +416,10 @@
 DiagMatrix::row (int i) const
 {
   if (i < 0 || i >= nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector (); 
+    }
 
   RowVector retval (nc, 0.0);
   if (nr <= nc || (nr > nc && i < nc))
@@ -344,7 +432,10 @@
 DiagMatrix::row (char *s) const
 {
   if (s == (char *) NULL)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector (); 
+    }
 
   char c = *s;
   if (c == 'f' || c == 'F')
@@ -352,14 +443,20 @@
   else if (c == 'l' || c == 'L')
     return row (nr - 1);
   else
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector (); 
+    }
 }
 
 ColumnVector
 DiagMatrix::column (int i) const
 {
   if (i < 0 || i >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector (); 
+    }
 
   ColumnVector retval (nr, 0.0);
   if (nr >= nc || (nr < nc && i < nr))
@@ -372,7 +469,10 @@
 DiagMatrix::column (char *s) const
 {
   if (s == (char *) NULL)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector (); 
+    }
 
   char c = *s;
   if (c == 'f' || c == 'F')
@@ -380,14 +480,20 @@
   else if (c == 'l' || c == 'L')
     return column (nc - 1);
   else
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector (); 
+    }
 }
 
 DiagMatrix
 DiagMatrix::inverse (int &info) const
 {
   if (nr != nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return DiagMatrix ();
+    }
 
   info = 0;
   double *tmp_data = dup (data, len);
@@ -505,7 +611,11 @@
 DiagMatrix::operator * (const ColumnVector& a) const
 {
   if (nc != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ColumnVector ();
+    }
 
   if (nc == 0 || nr == 0)
     return ColumnVector (0);
@@ -525,7 +635,11 @@
 DiagMatrix::operator * (const ComplexColumnVector& a) const
 {
   if (nc != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ColumnVector ();
+    }
 
   if (nc == 0 || nr == 0)
     return ComplexColumnVector (0);
@@ -547,7 +661,11 @@
 DiagMatrix::operator + (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return DiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return DiagMatrix (nr, nc);
@@ -559,7 +677,11 @@
 DiagMatrix::operator - (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return DiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return DiagMatrix (nr, nc);
@@ -571,7 +693,11 @@
 DiagMatrix::operator * (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return DiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return DiagMatrix (nr, nc);
@@ -583,7 +709,11 @@
 DiagMatrix::operator + (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -595,7 +725,11 @@
 DiagMatrix::operator - (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -607,7 +741,11 @@
 DiagMatrix::operator * (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -619,7 +757,11 @@
 DiagMatrix::product (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix product attempted");
+      return DiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return DiagMatrix (nr, nc);
@@ -631,7 +773,11 @@
 DiagMatrix::quotient (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix quotient attempted");
+      return DiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return DiagMatrix (nr, nc);
@@ -643,7 +789,11 @@
 DiagMatrix::product (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix product attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -655,7 +805,11 @@
 DiagMatrix::quotient (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix quotient attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nc == 0 || nr == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -667,7 +821,11 @@
 DiagMatrix::operator += (const DiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return *this;
+    }
 
   if (nc == 0 || nr == 0)
     return *this;
@@ -680,7 +838,11 @@
 DiagMatrix::operator -= (const DiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
 
@@ -694,7 +856,11 @@
 DiagMatrix::operator + (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
@@ -710,7 +876,11 @@
 DiagMatrix::operator - (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
@@ -726,7 +896,11 @@
 DiagMatrix::operator * (const Matrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return Matrix (nr, a.nc, 0.0);
@@ -766,7 +940,11 @@
 DiagMatrix::operator + (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -782,7 +960,11 @@
 DiagMatrix::operator - (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -798,7 +980,11 @@
 DiagMatrix::operator * (const ComplexMatrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return ComplexMatrix (nr, nc, 0.0);
@@ -916,7 +1102,15 @@
 ComplexDiagMatrix::ComplexDiagMatrix (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   nr = n;
   nc = n;
@@ -930,7 +1124,15 @@
 ComplexDiagMatrix::ComplexDiagMatrix (int n, double val)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   nr = n;
   nc = n;
@@ -947,7 +1149,15 @@
 ComplexDiagMatrix::ComplexDiagMatrix (int n, const Complex& val)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   nr = n;
   nc = n;
@@ -964,7 +1174,15 @@
 ComplexDiagMatrix::ComplexDiagMatrix (int r, int c)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -978,7 +1196,15 @@
 ComplexDiagMatrix::ComplexDiagMatrix (int r, int c, double val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -995,7 +1221,15 @@
 ComplexDiagMatrix::ComplexDiagMatrix (int r, int c, const Complex& val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -1149,11 +1383,44 @@
   return *this;
 }
 
+Complex&
+ComplexDiagMatrix::checkelem (int r, int c)
+{
+#ifndef NO_RANGE_CHECK
+  if (r < 0 || r >= nr || c < 0 || c >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      static Complex foo (0.0);
+      return foo;
+    }
+#endif
+
+  return elem (r, c);
+}
+
+Complex
+ComplexDiagMatrix::checkelem (int r, int c) const
+{
+#ifndef NO_RANGE_CHECK
+  if (r < 0 || r >= nr || c < 0 || c >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      return Complex (0.0);
+    }
+#endif
+
+  return elem (r, c);
+}
+
 ComplexDiagMatrix&
 ComplexDiagMatrix::resize (int r, int c)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r < c ? r : c;
   Complex *new_data = (Complex *) NULL;
@@ -1180,7 +1447,11 @@
 ComplexDiagMatrix::resize (int r, int c, double val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r < c ? r : c;
   Complex *new_data = (Complex *) NULL;
@@ -1210,7 +1481,11 @@
 ComplexDiagMatrix::resize (int r, int c, const Complex& val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r < c ? r : c;
   Complex *new_data = (Complex *) NULL;
@@ -1278,7 +1553,10 @@
 ComplexDiagMatrix::fill (double val, int beg, int end)
 {
   if (beg < 0 || end >= len || end < beg)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (end > beg)
     copy (data+beg, beg-end, val);
@@ -1289,7 +1567,10 @@
 ComplexDiagMatrix::fill (const Complex& val, int beg, int end)
 {
   if (beg < 0 || end >= len || end < beg)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (end > beg)
     copy (data+beg, beg-end, val);
@@ -1300,7 +1581,10 @@
 ComplexDiagMatrix::fill (const ColumnVector& a)
 {
   if (a.len != len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data, a.data, len);
   return *this;
@@ -1310,7 +1594,10 @@
 ComplexDiagMatrix::fill (const ComplexColumnVector& a)
 {
   if (a.len != len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data, a.data, len);
   return *this;
@@ -1320,7 +1607,10 @@
 ComplexDiagMatrix::fill (const RowVector& a)
 {
   if (a.len != len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data, a.data, len);
   return *this;
@@ -1330,7 +1620,10 @@
 ComplexDiagMatrix::fill (const ComplexRowVector& a)
 {
   if (a.len != len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data, a.data, len);
   return *this;
@@ -1340,7 +1633,10 @@
 ComplexDiagMatrix::fill (const ColumnVector& a, int beg)
 {
   if (beg < 0 || beg + a.len >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data+beg, a.data, a.len);
   return *this;
@@ -1350,7 +1646,10 @@
 ComplexDiagMatrix::fill (const ComplexColumnVector& a, int beg)
 {
   if (beg < 0 || beg + a.len >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data+beg, a.data, a.len);
   return *this;
@@ -1360,7 +1659,10 @@
 ComplexDiagMatrix::fill (const RowVector& a, int beg)
 {
   if (beg < 0 || beg + a.len >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data+beg, a.data, a.len);
   return *this;
@@ -1370,7 +1672,10 @@
 ComplexDiagMatrix::fill (const ComplexRowVector& a, int beg)
 {
   if (beg < 0 || beg + a.len >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   copy (data+beg, a.data, a.len);
   return *this;
@@ -1435,7 +1740,10 @@
 ComplexDiagMatrix::row (int i) const
 {
   if (i < 0 || i >= nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector (); 
+    }
 
   ComplexRowVector retval (nc, 0.0);
   if (nr <= nc || (nr > nc && i < nc))
@@ -1448,7 +1756,10 @@
 ComplexDiagMatrix::row (char *s) const
 {
   if (s == (char *) NULL)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return ComplexRowVector (); 
+    }
 
   char c = *s;
   if (c == 'f' || c == 'F')
@@ -1456,14 +1767,20 @@
   else if (c == 'l' || c == 'L')
     return row (nr - 1);
   else
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return ComplexRowVector ();
+    }
 }
 
 ComplexColumnVector
 ComplexDiagMatrix::column (int i) const
 {
   if (i < 0 || i >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector (); 
+    }
 
   ComplexColumnVector retval (nr, 0.0);
   if (nr >= nc || (nr < nc && i < nr))
@@ -1476,7 +1793,10 @@
 ComplexDiagMatrix::column (char *s) const
 {
   if (s == (char *) NULL)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector (); 
+    }
 
   char c = *s;
   if (c == 'f' || c == 'F')
@@ -1484,14 +1804,20 @@
   else if (c == 'l' || c == 'L')
     return column (nc - 1);
   else
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector (); 
+    }
 }
 
 ComplexDiagMatrix
 ComplexDiagMatrix::inverse (int& info) const
 {
   if (nr != nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return DiagMatrix ();
+    }
 
   info = 0;
   for (int i = 0; i < len; i++)
@@ -1629,7 +1955,11 @@
 ComplexDiagMatrix::operator * (const ColumnVector& a) const
 {
   if (nc != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix muliplication attempted");
+      return ComplexColumnVector ();
+    }
 
   if (nc == 0 || nr == 0)
     return ComplexColumnVector (0);
@@ -1649,7 +1979,11 @@
 ComplexDiagMatrix::operator * (const ComplexColumnVector& a) const
 {
   if (nc != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix muliplication attempted");
+      return ComplexColumnVector ();
+    }
 
   if (nc == 0 || nr == 0)
     return ComplexColumnVector (0);
@@ -1671,7 +2005,11 @@
 ComplexDiagMatrix::operator + (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1683,7 +2021,11 @@
 ComplexDiagMatrix::operator - (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1695,7 +2037,11 @@
 ComplexDiagMatrix::operator * (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1707,7 +2053,11 @@
 ComplexDiagMatrix::operator + (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1719,7 +2069,11 @@
 ComplexDiagMatrix::operator - (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1731,7 +2085,11 @@
 ComplexDiagMatrix::operator * (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1743,7 +2101,11 @@
 ComplexDiagMatrix::product (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix product attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1755,7 +2117,11 @@
 ComplexDiagMatrix::quotient (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix quotient attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1767,7 +2133,11 @@
 ComplexDiagMatrix::product (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix product attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1779,7 +2149,11 @@
 ComplexDiagMatrix::quotient (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix quotient attempted");
+      return ComplexDiagMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
@@ -1791,7 +2165,11 @@
 ComplexDiagMatrix::operator += (const DiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
@@ -1804,7 +2182,11 @@
 ComplexDiagMatrix::operator -= (const DiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
@@ -1817,7 +2199,11 @@
 ComplexDiagMatrix::operator += (const ComplexDiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
@@ -1830,7 +2216,11 @@
 ComplexDiagMatrix::operator -= (const ComplexDiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
@@ -1845,7 +2235,11 @@
 ComplexDiagMatrix::operator + (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -1861,7 +2255,11 @@
 ComplexDiagMatrix::operator - (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -1877,7 +2275,11 @@
 ComplexDiagMatrix::operator * (const Matrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return ComplexMatrix (nr, a.nc, 0.0);
@@ -1917,7 +2319,11 @@
 ComplexDiagMatrix::operator + (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -1933,7 +2339,11 @@
 ComplexDiagMatrix::operator - (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -1949,7 +2359,11 @@
 ComplexDiagMatrix::operator * (const ComplexMatrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return ComplexMatrix (nr, a.nc, 0.0);
--- a/liboctave/FEGrid.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/FEGrid.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -26,14 +26,14 @@
 #endif
 
 #include "FEGrid.h"
+#include "lo-error.h"
 
 // error handling
 
 void
 FEGrid::error (const char* msg) const
 {
-  cerr << "Fatal FEGrid error. " << msg << "\n";
-  exit(1);
+  (*current_liboctave_error_handler) ("fatal FEGrid error: %s", msg);
 }
 
 void
@@ -47,7 +47,10 @@
 FEGrid::FEGrid (int nel, double width)
 {
   if (nel < 1)
-    nel_error ();
+    {
+      nel_error ();
+      return;
+    }
 
   elem.resize (nel+1);
 
@@ -58,7 +61,10 @@
 FEGrid::FEGrid (int nel, double left, double right)
 {
   if (nel < 1)
-    nel_error ();
+    {
+      nel_error ();
+      return;
+    }
 
   elem.resize (nel+1);
 
@@ -74,7 +80,10 @@
 FEGrid::element (double x) const
 {
   if (! in_bounds (x))
-    error ("value not within grid boundaries");
+    {
+      error ("value not within grid boundaries");
+      return -1;
+    }
 
   int nel = elem.capacity () - 1;
   for (int i = 1; i <= nel; i++)
@@ -91,15 +100,24 @@
 {
   int nel = elem.capacity () - 1;
   if (nel < 1)
-    nel_error ();
+    {
+      nel_error ();
+      return;
+    }
 
   for (int i = 1; i <= nel; i++)
     {
       if (elem.elem (i-1) > elem.elem (i))
-	error ("element boundaries not in ascending order");
+	{
+	  error ("element boundaries not in ascending order");
+	  return;
+	}
 
       if (elem.elem (i-1) == elem.elem (i))
-	error ("zero width element");
+	{
+	  error ("zero width element");
+	  return;
+	}
     }
 }
 
--- a/liboctave/LSODE.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/LSODE.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -28,6 +28,7 @@
 #include <iostream.h>
 #include "ODE.h"
 #include "f77-uscore.h"
+#include "lo-error.h"
 
 extern "C"
 {
@@ -252,8 +253,10 @@
       working_too_hard++;
       if (working_too_hard > 20)
 	{
-	  cerr << "Shut 'er down Slim!  She's a suckin' mud!\n";
-	  exit (1);
+	  (*current_liboctave_error_handler)
+	    ("giving up after more than %d steps attempted in lsode",
+	     iwork[5] * 20);
+	  return ColumnVector ();
 	}
       else
 	{
--- a/liboctave/LinConst.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/LinConst.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -27,14 +27,14 @@
 
 #include <iostream.h>
 #include "LinConst.h"
+#include "lo-error.h"
 
 // error handling
 
 void
 LinConst::error (const char* msg)
 {
-  cerr << "Fatal LinConst error. " << msg << "\n";
-  exit(1);
+  (*current_liboctave_error_handler) ("fatal LinConst error: %s", msg);
 }
 
 LinConst::LinConst (const Matrix& a_eq, const Vector& b_eq,
--- a/liboctave/Matrix-ext.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/Matrix-ext.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -27,6 +27,7 @@
 
 #include "Matrix.h"
 #include "mx-inlines.cc"
+#include "lo-error.h"
 
 /*
  * AEPBALANCE operations
@@ -36,7 +37,10 @@
 AEPBALANCE::init (const Matrix& a, const char *balance_job)
 {
   if (a.nr != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("AEPBALANCE requires square matrix");
+      return -1;
+    }
 
   int n = a.nc;
 
@@ -110,7 +114,11 @@
 GEPBALANCE::init (const Matrix& a, const Matrix& b, const char *balance_job)
 {
   if (a.nr != a.nc || a.nr != b.nr || b.nr != b.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("GEPBALANCE requires square matrices of the same size");
+      return -1;
+    }
 
   int n = a.nc;
 
@@ -236,7 +244,10 @@
 CHOL::init (const Matrix& a)
 {
   if (a.nr != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("CHOL requires square matrix");
+      return -1;
+    }
 
   char uplo = 'U';
 
@@ -266,7 +277,11 @@
 ComplexCHOL::init (const ComplexMatrix& a)
 {
    if (a.nr != a.nc)
-     FAIL;
+     {
+       (*current_liboctave_error_handler)
+	 ("ComplexCHOL requires square matrix");
+       return -1;
+     }
 
    char uplo = 'U';
 
@@ -299,7 +314,10 @@
 HESS::init (const Matrix& a)
 {
   if (a.nr != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("HESS requires square matrix");
+      return -1;
+    }
 
   char jobbal = 'N';
   char side = 'R';
@@ -357,7 +375,11 @@
 ComplexHESS::init (const ComplexMatrix& a)
 {
    if (a.nr != a.nc)
-     FAIL;
+     {
+       (*current_liboctave_error_handler)
+	 ("ComplexHESS requires square matrix");
+       return -1;
+     }
 
    char job = 'N';
    char side = 'R';
@@ -429,7 +451,10 @@
 SCHUR::init (const Matrix& a, const char *ord)
 {
   if (a.nr != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("SCHUR requires square matrix");
+      return -1;
+    }
 
   char jobvs = 'V';
   char sort;
@@ -516,7 +541,11 @@
 ComplexSCHUR::init (const ComplexMatrix& a, const char *ord)
 {
   if (a.nr != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("ComplexSCHUR requires square matrix");
+      return -1;
+    }
 
   char jobvs = 'V';
   char sort;
@@ -688,7 +717,10 @@
 EIG::init (const Matrix& a)
 {
   if (a.nr != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
 
   int n = a.nr;
 
@@ -725,7 +757,10 @@
       else
 	{
 	  if (j+1 >= n)
-	    FAIL;
+	    {
+	      (*current_liboctave_error_handler) ("EIG: internal error");
+	      return -1;
+	    }
 
 	  for (int i = 0; i < n; i++)
 	    {
@@ -753,7 +788,10 @@
 {
 
   if (a.nr != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("EIG requires square matrix");
+      return -1;
+    }
 
   int n = a.nr;
 
@@ -795,7 +833,10 @@
 LU::LU (const Matrix& a)
 {
   if (a.nr == 0 || a.nc == 0 || a.nr != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("LU requires square matrix");
+      return;
+    }
 
   int n = a.nr;
 
@@ -854,7 +895,10 @@
 ComplexLU::ComplexLU (const ComplexMatrix& a)
 {
   if (a.nr == 0 || a.nc == 0 || a.nr != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("ComplexLU requires square matrix");
+      return;
+    }
 
   int n = a.nr;
 
@@ -920,7 +964,10 @@
   int n = a.nc;
 
   if (m == 0 || n == 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("QR must have non-empty matrix");
+      return;
+    }
 
   double *tmp_data;
   int min_mn = m < n ? m : n;
@@ -966,7 +1013,11 @@
   int n = a.nc;
 
   if (m == 0 || n == 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("ComplexQR must have non-empty matrix");
+      return;
+    }
 
   Complex *tmp_data;
   int min_mn = m < n ? m : n;
--- a/liboctave/Matrix.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/Matrix.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -30,6 +30,7 @@
 
 #include "Matrix.h"
 #include "mx-inlines.cc"
+#include "lo-error.h"
 
 /*
  * Matrix class.
@@ -38,7 +39,15 @@
 Matrix::Matrix (int r, int c)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't construct matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -52,7 +61,15 @@
 Matrix::Matrix (int r, int c, double val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't construct matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -125,11 +142,44 @@
   return *this;
 }
 
+double&
+Matrix::checkelem (int r, int c)
+{
+#ifndef NO_RANGE_CHECK
+  if (r < 0 || r >= nr || c < 0 || c >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      static double foo = 0.0;
+      return foo;
+    }
+#endif
+
+  return elem (r, c);
+}
+
+double
+Matrix::checkelem (int r, int c) const
+{
+#ifndef NO_RANGE_CHECK
+  if (r < 0 || r >= nr || c < 0 || c >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      return 0.0;
+    }
+#endif
+
+  return elem (r, c);
+}
+
 Matrix&
 Matrix::resize (int r, int c)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r * c;
   double* new_data = (double *) NULL;
@@ -158,7 +208,11 @@
 Matrix::resize (int r, int c, double val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r * c;
   double *new_data = (double *) NULL;
@@ -207,7 +261,10 @@
 Matrix::insert (const Matrix& a, int r, int c)
 {
   if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int j = 0; j < a.nc; j++)
     for (int i = 0; i < a.nr; i++)
@@ -220,7 +277,10 @@
 Matrix::insert (const RowVector& a, int r, int c)
 {
   if (r < 0 || r >= nr || c < 0 || c + a.len - 1 > nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (r, c+i) = a.data[i];
@@ -232,7 +292,10 @@
 Matrix::insert (const ColumnVector& a, int r, int c)
 {
   if (r < 0 || r + a.len - 1 > nr || c < 0 || c >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (r+i, c) = a.data[i];
@@ -244,7 +307,10 @@
 Matrix::insert (const DiagMatrix& a, int r, int c)
 {
   if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (r+i, c+i) = a.data[i];
@@ -265,7 +331,10 @@
 {
   if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
       || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; }
   if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; }
@@ -281,20 +350,26 @@
 Matrix::append (const Matrix& a) const
 {
   if (nr != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return Matrix ();
+    }
 
   int nc_insert = nc;
   Matrix retval (nr, nc + a.nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
-  return retval;;
+  return retval;
 }
 
 Matrix
 Matrix::append (const RowVector& a) const
 {
   if (nr != 1)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return Matrix ();
+    }
 
   int nc_insert = nc;
   Matrix retval (nr, nc + a.len);
@@ -307,7 +382,10 @@
 Matrix::append (const ColumnVector& a) const
 {
   if (nr != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return Matrix ();
+    }
 
   int nc_insert = nc;
   Matrix retval (nr, nc + 1);
@@ -320,7 +398,10 @@
 Matrix::append (const DiagMatrix& a) const
 {
   if (nr != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
 
   int nc_insert = nc;
   Matrix retval (nr, nc + a.nc);
@@ -333,7 +414,11 @@
 Matrix::stack (const Matrix& a) const
 {
   if (nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return Matrix ();
+    }
 
   int nr_insert = nr;
   Matrix retval (nr + a.nr, nc);
@@ -346,7 +431,11 @@
 Matrix::stack (const RowVector& a) const
 {
   if (nc != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return Matrix ();
+    }
 
   int nr_insert = nr;
   Matrix retval (nr + 1, nc);
@@ -359,7 +448,11 @@
 Matrix::stack (const ColumnVector& a) const
 {
   if (nc != 1)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return Matrix ();
+    }
 
   int nr_insert = nr;
   Matrix retval (nr + a.len, nc);
@@ -372,7 +465,11 @@
 Matrix::stack (const DiagMatrix& a) const
 {
   if (nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return Matrix ();
+    }
 
   int nr_insert = nr;
   Matrix retval (nr + a.nr, nc);
@@ -418,7 +515,10 @@
 Matrix::row (int i) const
 {
   if (i < 0 || i >= nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector ();
+    }
 
   RowVector retval (nc);
   for (int j = 0; j < nc; j++)
@@ -431,7 +531,10 @@
 Matrix::row (char *s) const
 {
   if (s == (char *) NULL)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector ();
+    }
 
   char c = *s;
   if (c == 'f' || c == 'F')
@@ -439,14 +542,20 @@
   else if (c == 'l' || c == 'L')
     return row (nr - 1);
   else
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return RowVector ();
+    }
 }
 
 ColumnVector
 Matrix::column (int i) const
 {
   if (i < 0 || i >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector ();
+    }
 
   ColumnVector retval (nr);
   for (int j = 0; j < nr; j++)
@@ -459,7 +568,10 @@
 Matrix::column (char *s) const
 {
   if (s == (char *) NULL)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector ();
+    }
 
   char c = *s;
   if (c == 'f' || c == 'F')
@@ -467,14 +579,20 @@
   else if (c == 'l' || c == 'L')
     return column (nc - 1);
   else
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ColumnVector ();
+    }
 }
 
 Matrix
 Matrix::inverse (int& info, double& rcond) const
 {
-  if (nr != nc)
-    FAIL;
+  if (nr != nc || nr == 0 || nc == 0)
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return Matrix ();
+    }
 
   info = 0;
 
@@ -655,7 +773,11 @@
   Matrix retval;
 
   if (nr == 0 || nc == 0 || nr != nc || nr != b.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("matrix dimension mismatch solution of linear equations");
+      return Matrix ();
+    }
 
   info = 0;
   int *ipvt = new int [nr];
@@ -730,7 +852,11 @@
   ColumnVector retval;
 
   if (nr == 0 || nc == 0 || nr != nc || nr != b.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("matrix dimension mismatch solution of linear equations");
+      return ColumnVector ();
+    }
 
   info = 0;
   int *ipvt = new int [nr];
@@ -807,7 +933,11 @@
   int n = nc;
 
   if (m == 0 || n == 0 || m != b.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("matrix dimension mismatch in solution of least squares problem");
+      return Matrix ();
+    }
 
   double *tmp_data = dup (data, len);
 
@@ -892,7 +1022,11 @@
   int n = nc;
 
   if (m == 0 || n == 0 || m != b.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("matrix dimension mismatch in solution of least squares problem");
+      return ColumnVector ();
+    }
 
   double *tmp_data = dup (data, len);
 
@@ -1033,7 +1167,11 @@
 Matrix::operator * (const ColumnVector& a) const
 {
   if (nc != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ColumnVector ();
+    }
 
   if (nr == 0 || nc == 0)
     return ColumnVector (0);
@@ -1065,7 +1203,11 @@
 Matrix::operator + (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
@@ -1081,7 +1223,11 @@
 Matrix::operator - (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
@@ -1097,7 +1243,11 @@
 Matrix::operator * (const DiagMatrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return Matrix (nr, a.nc, 0.0);
@@ -1139,7 +1289,11 @@
 Matrix::operator + (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -1155,7 +1309,11 @@
 Matrix::operator - (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -1171,7 +1329,11 @@
 Matrix::operator * (const ComplexDiagMatrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return ComplexMatrix (nr, a.nc, 0.0);
@@ -1213,7 +1375,11 @@
 Matrix::operator += (const DiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (i, i) += a.data[i];
@@ -1225,7 +1391,11 @@
 Matrix::operator -= (const DiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (i, i) -= a.data[i];
@@ -1239,7 +1409,11 @@
 Matrix::operator + (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
@@ -1251,7 +1425,11 @@
 Matrix::operator - (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
@@ -1263,7 +1441,11 @@
 Matrix::operator * (const Matrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return Matrix (nr, a.nc, 0.0);
@@ -1290,7 +1472,11 @@
 Matrix::operator + (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexMatrix ();
+    }
 
   return ComplexMatrix (add (data, a.data, len), nr, nc);
 }
@@ -1299,7 +1485,11 @@
 Matrix::operator - (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -1318,7 +1508,11 @@
 Matrix::product (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix product attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
@@ -1330,7 +1524,11 @@
 Matrix::quotient (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix quotient attempted");
+      return Matrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
@@ -1342,7 +1540,11 @@
 Matrix::product (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix product attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -1354,7 +1556,11 @@
 Matrix::quotient (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix quotient attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -1366,7 +1572,11 @@
 Matrix::operator += (const Matrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
@@ -1379,7 +1589,11 @@
 Matrix::operator -= (const Matrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
@@ -1919,7 +2133,7 @@
 
       for (int j = 0; j < nc; j++)
         {
-          int res = 0.0;
+          int res = 0;
           for (int i = 0; i < nr; i++)
             if (elem (i, j) < elem (res, j))
               res = i;
@@ -2020,7 +2234,15 @@
 ComplexMatrix::ComplexMatrix (int r, int c)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't construct matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -2034,7 +2256,15 @@
 ComplexMatrix::ComplexMatrix (int r, int c, double val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't construct matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -2051,7 +2281,15 @@
 ComplexMatrix::ComplexMatrix (int r, int c, const Complex& val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't construct matrix with negative dimensions");
+      nr = 0;
+      nc = 0;
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   nr = r;
   nc = c;
@@ -2180,11 +2418,44 @@
   return *this;
 }
 
+Complex&
+ComplexMatrix::checkelem (int r, int c)
+{
+#ifndef NO_RANGE_CHECK
+  if (r < 0 || r >= nr || c < 0 || c >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      static Complex foo (0.0);
+      return foo;
+    }
+#endif
+
+  return elem (r, c);
+}
+
+Complex
+ComplexMatrix::checkelem (int r, int c) const
+{
+#ifndef NO_RANGE_CHECK
+  if (r < 0 || r >= nr || c < 0 || c >= nc)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      return Complex (0.0);
+    }
+#endif
+
+  return elem (r, c);
+}
+
 ComplexMatrix&
 ComplexMatrix::resize (int r, int c)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r * c;
   Complex* new_data = (Complex *) NULL;
@@ -2213,7 +2484,11 @@
 ComplexMatrix::resize (int r, int c, double val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r * c;
   Complex *new_data = (Complex *) NULL;
@@ -2247,7 +2522,11 @@
 ComplexMatrix::resize (int r, int c, const Complex& val)
 {
   if (r < 0 || c < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimensions");
+      return *this;
+    }
 
   int new_len = r * c;
   Complex *new_data = (Complex *) NULL;
@@ -2298,7 +2577,10 @@
 ComplexMatrix::insert (const Matrix& a, int r, int c)
 {
   if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int j = 0; j < a.nc; j++)
     for (int i = 0; i < a.nr; i++)
@@ -2311,7 +2593,10 @@
 ComplexMatrix::insert (const RowVector& a, int r, int c)
 {
   if (r < 0 || r >= nr || c < 0 || c + a.len - 1 > nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (r, c+i) = a.data[i];
@@ -2323,7 +2608,10 @@
 ComplexMatrix::insert (const ColumnVector& a, int r, int c)
 {
   if (r < 0 || r + a.len - 1 > nr || c < 0 || c >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (r+i, c) = a.data[i];
@@ -2335,7 +2623,10 @@
 ComplexMatrix::insert (const DiagMatrix& a, int r, int c)
 {
   if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (r+i, c+i) = a.data[i];
@@ -2347,7 +2638,10 @@
 ComplexMatrix::insert (const ComplexMatrix& a, int r, int c)
 {
   if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int j = 0; j < a.nc; j++)
     for (int i = 0; i < a.nr; i++)
@@ -2360,7 +2654,10 @@
 ComplexMatrix::insert (const ComplexRowVector& a, int r, int c)
 {
   if (r < 0 || r >= nr || c < 0 || c + a.len - 1 > nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (r, c+i) = a.data[i];
@@ -2372,7 +2669,10 @@
 ComplexMatrix::insert (const ComplexColumnVector& a, int r, int c)
 {
   if (r < 0 || r + a.len - 1 > nr || c < 0 || c >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (r+i, c) = a.data[i];
@@ -2384,7 +2684,10 @@
 ComplexMatrix::insert (const ComplexDiagMatrix& a, int r, int c)
 {
   if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (r+i, c+i) = a.data[i];
@@ -2413,7 +2716,10 @@
 {
   if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
       || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; }
   if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; }
@@ -2430,7 +2736,10 @@
 {
   if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
       || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; }
   if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; }
@@ -2446,7 +2755,10 @@
 ComplexMatrix::append (const Matrix& a) const
 {
   if (nr != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
 
   int nc_insert = nc;
   ComplexMatrix retval (nr, nc + a.nc);
@@ -2459,7 +2771,10 @@
 ComplexMatrix::append (const RowVector& a) const
 {
   if (nr != 1)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
 
   int nc_insert = nc;
   ComplexMatrix retval (nr, nc + a.len);
@@ -2472,7 +2787,10 @@
 ComplexMatrix::append (const ColumnVector& a) const
 {
   if (nr != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
 
   int nc_insert = nc;
   ComplexMatrix retval (nr, nc + 1);
@@ -2485,7 +2803,10 @@
 ComplexMatrix::append (const DiagMatrix& a) const
 {
   if (nr != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
 
   int nc_insert = nc;
   ComplexMatrix retval (nr, nc + a.nc);
@@ -2498,7 +2819,10 @@
 ComplexMatrix::append (const ComplexMatrix& a) const
 {
   if (nr != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
 
   int nc_insert = nc;
   ComplexMatrix retval (nr, nc + a.nc);
@@ -2511,7 +2835,10 @@
 ComplexMatrix::append (const ComplexRowVector& a) const
 {
   if (nr != 1)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
 
   int nc_insert = nc;
   ComplexMatrix retval (nr, nc + a.len);
@@ -2524,7 +2851,10 @@
 ComplexMatrix::append (const ComplexColumnVector& a) const
 {
   if (nr != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
 
   int nc_insert = nc;
   ComplexMatrix retval (nr, nc + 1);
@@ -2537,7 +2867,10 @@
 ComplexMatrix::append (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("row dimension mismatch for append");
+      return *this;
+    }
 
   int nc_insert = nc;
   ComplexMatrix retval (nr, nc + a.nc);
@@ -2550,7 +2883,11 @@
 ComplexMatrix::stack (const Matrix& a) const
 {
   if (nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
 
   int nr_insert = nr;
   ComplexMatrix retval (nr + a.nr, nc);
@@ -2563,7 +2900,11 @@
 ComplexMatrix::stack (const RowVector& a) const
 {
   if (nc != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
 
   int nr_insert = nr;
   ComplexMatrix retval (nr + 1, nc);
@@ -2576,7 +2917,11 @@
 ComplexMatrix::stack (const ColumnVector& a) const
 {
   if (nc != 1)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
 
   int nr_insert = nr;
   ComplexMatrix retval (nr + a.len, nc);
@@ -2589,7 +2934,11 @@
 ComplexMatrix::stack (const DiagMatrix& a) const
 {
   if (nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
 
   int nr_insert = nr;
   ComplexMatrix retval (nr + a.nr, nc);
@@ -2602,7 +2951,11 @@
 ComplexMatrix::stack (const ComplexMatrix& a) const
 {
   if (nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
 
   int nr_insert = nr;
   ComplexMatrix retval (nr + a.nr, nc);
@@ -2615,7 +2968,11 @@
 ComplexMatrix::stack (const ComplexRowVector& a) const
 {
   if (nc != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
 
   int nr_insert = nr;
   ComplexMatrix retval (nr + 1, nc);
@@ -2628,7 +2985,11 @@
 ComplexMatrix::stack (const ComplexColumnVector& a) const
 {
   if (nc != 1)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
 
   int nr_insert = nr;
   ComplexMatrix retval (nr + a.len, nc);
@@ -2641,7 +3002,11 @@
 ComplexMatrix::stack (const ComplexDiagMatrix& a) const
 {
   if (nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("column dimension mismatch for stack");
+      return *this;
+    }
 
   int nr_insert = nr;
   ComplexMatrix retval (nr + a.nr, nc);
@@ -2730,7 +3095,10 @@
 ComplexMatrix::row (int i) const
 {
   if (i < 0 || i >= nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return ComplexRowVector ();
+    }
 
   ComplexRowVector retval (nc);
   for (int j = 0; j < nc; j++)
@@ -2743,7 +3111,10 @@
 ComplexMatrix::row (char *s) const
 {
   if (s == (char *) NULL)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return ComplexRowVector ();
+    }
 
   char c = *s;
   if (c == 'f' || c == 'F')
@@ -2751,14 +3122,20 @@
   else if (c == 'l' || c == 'L')
     return row (nr - 1);
   else
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid row selection");
+      return ComplexRowVector ();
+    }
 }
 
 ComplexColumnVector
 ComplexMatrix::column (int i) const
 {
   if (i < 0 || i >= nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ComplexColumnVector ();
+    }
 
   ComplexColumnVector retval (nr);
   for (int j = 0; j < nr; j++)
@@ -2771,7 +3148,10 @@
 ComplexMatrix::column (char *s) const
 {
   if (s == (char *) NULL)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ComplexColumnVector ();
+    }
 
   char c = *s;
   if (c == 'f' || c == 'F')
@@ -2779,14 +3159,20 @@
   else if (c == 'l' || c == 'L')
     return column (nc - 1);
   else
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("invalid column selection");
+      return ComplexColumnVector ();
+    }
 }
 
 ComplexMatrix
 ComplexMatrix::inverse (int& info, double& rcond) const
 {
   if (nr != nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return ComplexMatrix ();
+    }
 
   info = 0;
 
@@ -2989,7 +3375,11 @@
   ComplexMatrix retval;
 
   if (nr == 0 || nc == 0 || nr != nc || nr != b.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("matrix dimension mismatch in solution of linear equations");
+      return ComplexMatrix ();
+    }
 
   info = 0;
   int *ipvt = new int [nr];
@@ -3066,7 +3456,11 @@
   ComplexColumnVector retval;
 
   if (nr == 0 || nc == 0 || nr != nc || nr != b.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("matrix dimension mismatch in solution of linear equations");
+      return ComplexColumnVector ();
+    }
 
   info = 0;
   int *ipvt = new int [nr];
@@ -3144,7 +3538,11 @@
   int n = nc;
 
   if (m == 0 || n == 0 || m != b.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("matrix dimension mismatch solution of linear equations");
+      return Matrix ();
+    }
 
   Complex *tmp_data = dup (data, len);
 
@@ -3236,7 +3634,11 @@
   int n = nc;
 
   if (m == 0 || n == 0 || m != b.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("matrix dimension mismatch solution of least squares problem");
+      return ComplexColumnVector ();
+    }
 
   Complex *tmp_data = dup (data, len);
 
@@ -3392,7 +3794,11 @@
 ComplexMatrix::operator * (const ComplexColumnVector& a) const
 {
   if (nc != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexColumnVector ();
+    }
 
   if (nc == 0 || nr == 0)
     return ComplexColumnVector (0);
@@ -3417,7 +3823,11 @@
 ComplexMatrix::operator + (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3433,7 +3843,11 @@
 ComplexMatrix::operator - (const DiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3449,7 +3863,11 @@
 ComplexMatrix::operator * (const DiagMatrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return ComplexMatrix (nr, nc, 0.0);
@@ -3491,7 +3909,11 @@
 ComplexMatrix::operator + (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3507,7 +3929,11 @@
 ComplexMatrix::operator - (const ComplexDiagMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3523,7 +3949,11 @@
 ComplexMatrix::operator * (const ComplexDiagMatrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return ComplexMatrix (nr, nc, 0.0);
@@ -3565,7 +3995,11 @@
 ComplexMatrix::operator += (const DiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return ComplexMatrix ();
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (i, i) += a.data[i];
@@ -3577,7 +4011,11 @@
 ComplexMatrix::operator -= (const DiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return ComplexMatrix ();
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (i, i) -= a.data[i];
@@ -3589,7 +4027,11 @@
 ComplexMatrix::operator += (const ComplexDiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return ComplexMatrix ();
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (i, i) += a.data[i];
@@ -3601,7 +4043,11 @@
 ComplexMatrix::operator -= (const ComplexDiagMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return ComplexMatrix ();
+    }
 
   for (int i = 0; i < a.len; i++)
     elem (i, i) -= a.data[i];
@@ -3615,7 +4061,11 @@
 ComplexMatrix::operator + (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3627,7 +4077,11 @@
 ComplexMatrix::operator - (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3646,7 +4100,11 @@
 ComplexMatrix::operator + (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix addition attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3658,7 +4116,11 @@
 ComplexMatrix::operator - (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix subtraction attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3670,7 +4132,11 @@
 ComplexMatrix::operator * (const ComplexMatrix& a) const
 {
   if (nc != a.nr)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix multiplication attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0 || a.nc == 0)
     return ComplexMatrix (nr, nc, 0.0);
@@ -3697,7 +4163,11 @@
 ComplexMatrix::product (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix product attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3709,7 +4179,11 @@
 ComplexMatrix::quotient (const Matrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix quotient attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3721,7 +4195,11 @@
 ComplexMatrix::product (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix product attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3733,7 +4211,11 @@
 ComplexMatrix::quotient (const ComplexMatrix& a) const
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix quotient attempted");
+      return ComplexMatrix ();
+    }
 
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
@@ -3745,7 +4227,11 @@
 ComplexMatrix::operator += (const Matrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
@@ -3758,7 +4244,11 @@
 ComplexMatrix::operator -= (const Matrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
@@ -3771,7 +4261,11 @@
 ComplexMatrix::operator += (const ComplexMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
@@ -3784,7 +4278,11 @@
 ComplexMatrix::operator -= (const ComplexMatrix& a)
 {
   if (nr != a.nr || nc != a.nc)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return *this;
+    }
 
   if (nr == 0 || nc == 0)
     return *this;
--- a/liboctave/Matrix.h	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/Matrix.h	Mon Nov 15 10:11:59 1993 +0000
@@ -47,8 +47,6 @@
 // #include <iomanip.h>  // We don\'t use this yet.
 #include <Complex.h>
 
-#define FAIL assert(0) /* XXX FIXME XXX */
-
 #ifndef MAPPER_FCN_TYPEDEFS
 #define MAPPER_FCN_TYPEDEFS 1
 
@@ -554,31 +552,11 @@
 
 inline double& Matrix::elem (int r, int c) { return data[nr*c+r]; }
 
-inline double& Matrix::checkelem (int r, int c)
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    FAIL;
-#endif
-
-  return elem (r, c);
-}
-
 inline double& Matrix::operator () (int r, int c)
   { return checkelem (r, c); }
 
 inline double Matrix::elem (int r, int c) const { return data[nr*c+r]; }
 
-inline double Matrix::checkelem (int r, int c) const
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    FAIL;
-#endif
-
-  return elem (r, c);
-}
-
 inline double Matrix::operator () (int r, int c) const
   { return checkelem (r, c); }
 
@@ -715,32 +693,10 @@
 
 inline double& ColumnVector::elem (int n) { return data[n]; }
 
-inline double&
-ColumnVector::checkelem (int n)
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    FAIL;
-#endif
-
-  return elem (n);
-}
-
 inline double& ColumnVector::operator () (int n) { return checkelem (n); }
 
 inline double ColumnVector::elem (int n) const { return data[n]; }
 
-inline double
-ColumnVector::checkelem (int n) const
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    FAIL;
-#endif
-
-  return elem (n);
-}
-
 inline double ColumnVector::operator () (int n) const { return checkelem (n); }
 
 inline double *ColumnVector::fortran_vec (void) const { return data; }
@@ -882,32 +838,10 @@
 
 inline double& RowVector::elem (int n) { return data[n]; }
 
-inline double&
-RowVector::checkelem (int n)
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    FAIL;
-#endif
-
-  return elem (n);
-}
-
 inline double& RowVector::operator () (int n) { return checkelem (n); }
 
 inline double RowVector::elem (int n) const { return data[n]; }
 
-inline double
-RowVector::checkelem (int n) const
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    FAIL;
-#endif
-
-  return elem (n);
-}
-
 inline double RowVector::operator () (int n) const { return checkelem (n); }
 
 inline double *RowVector::fortran_vec (void) const { return data; }
@@ -1076,32 +1010,12 @@
 inline double& DiagMatrix::elem (int r, int c)
   { return (r == c) ? data[r] : 0; }
 
-inline double& DiagMatrix::checkelem (int r, int c)
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    FAIL;
-#endif
-
-  return elem (r, c);
-}
-
 inline double& DiagMatrix::operator () (int r, int c)
   { return checkelem (r, c); }
 
 inline double DiagMatrix::elem (int r, int c) const
   { return (r == c) ? data[r] : 0; }
 
-inline double DiagMatrix::checkelem (int r, int c) const
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    FAIL;
-#endif
-
-  return elem (r, c);
-}
-
 inline double DiagMatrix::operator () (int r, int c) const
   { return checkelem (r, c); }
 
@@ -1398,32 +1312,12 @@
 
 inline Complex& ComplexMatrix::elem (int r, int c) { return data[nr*c+r]; }
 
-inline Complex& ComplexMatrix::checkelem (int r, int c)
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    FAIL;
-#endif
-
-  return elem (r, c);
-}
-
 inline Complex& ComplexMatrix::operator () (int r, int c)
   { return checkelem (r, c); }
 
 inline Complex ComplexMatrix::elem (int r, int c) const
   { return data[nr*c+r]; }
 
-inline Complex ComplexMatrix::checkelem (int r, int c) const
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    FAIL;
-#endif
-
-  return elem (r, c);
-}
-
 inline Complex ComplexMatrix::operator () (int r, int c) const
   { return checkelem (r, c); }
 
@@ -1591,33 +1485,11 @@
 
 inline Complex& ComplexColumnVector::elem (int n) { return data[n]; }
 
-inline Complex&
-ComplexColumnVector::checkelem (int n)
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    FAIL;
-#endif
-
-  return elem (n);
-}
-
 inline Complex& ComplexColumnVector::operator () (int n)
   { return checkelem (n); }
 
 inline Complex ComplexColumnVector::elem (int n) const { return data[n]; }
 
-inline Complex
-ComplexColumnVector::checkelem (int n) const
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    FAIL;
-#endif
-
-  return elem (n);
-}
-
 inline Complex ComplexColumnVector::operator () (int n) const
   { return checkelem (n); }
 
@@ -1786,32 +1658,10 @@
 
 inline Complex& ComplexRowVector::elem (int n) { return data[n]; }
 
-inline Complex&
-ComplexRowVector::checkelem (int n)
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    FAIL;
-#endif
-
-  return elem (n);
-}
-
 inline Complex& ComplexRowVector::operator () (int n) { return checkelem (n); }
 
 inline Complex ComplexRowVector::elem (int n) const { return data[n]; }
 
-inline Complex
-ComplexRowVector::checkelem (int n) const
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    FAIL;
-#endif
-
-  return elem (n);
-}
-
 inline Complex ComplexRowVector::operator () (int n) const
   { return checkelem (n); }
 
@@ -2014,32 +1864,12 @@
 inline Complex& ComplexDiagMatrix::elem (int r, int c)
   { Complex czero (0.0, 0.0); return (r == c) ? data[r] : czero; }
 
-inline Complex& ComplexDiagMatrix::checkelem (int r, int c)
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    FAIL;
-#endif
-
-  return elem (r, c);
-}
-
 inline Complex& ComplexDiagMatrix::operator () (int r, int c)
   { return checkelem (r, c); }
 
 inline Complex ComplexDiagMatrix::elem (int r, int c) const
   { Complex czero (0.0, 0.0); return (r == c) ? data[r] : czero; }
 
-inline Complex ComplexDiagMatrix::checkelem (int r, int c) const
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    FAIL;
-#endif
-
-  return elem (r, c);
-}
-
 inline Complex ComplexDiagMatrix::operator () (int r, int c) const
   { return checkelem (r, c); }
 
@@ -2072,7 +1902,7 @@
 
 inline AEPBALANCE::AEPBALANCE (const Matrix& a,const char * balance_job) 
 {
-  init (a,balance_job); 
+  init (a, balance_job); 
 }
 
 inline AEPBALANCE::AEPBALANCE (const AEPBALANCE& a)
@@ -2123,7 +1953,7 @@
 inline ComplexAEPBALANCE::ComplexAEPBALANCE (const ComplexMatrix& a,
 					     const char * balance_job)
 {
-  init(a,balance_job); 
+  init(a, balance_job); 
 }
 
 inline ComplexAEPBALANCE::ComplexAEPBALANCE (const ComplexAEPBALANCE& a)
@@ -2276,7 +2106,7 @@
 inline GEPBALANCE::GEPBALANCE (const Matrix& a, const Matrix& b, 
   const char * balance_job) 
 {
-  init (a,b,balance_job); 
+  init (a, b, balance_job); 
 }
 
 inline GEPBALANCE::GEPBALANCE (const GEPBALANCE& a)
--- a/liboctave/NLEqn.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/NLEqn.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -29,6 +29,7 @@
 #include <float.h>
 #include "NLEqn.h"
 #include "f77-uscore.h"
+#include "lo-error.h"
 
 extern "C"
 {
@@ -48,8 +49,7 @@
 void
 NLEqn::error (const char* msg)
 {
-  cerr << "Fatal NLEqn error. " << msg << "\n";
-  exit(1);
+  (*current_liboctave_error_handler) ("fatal NLEqn error: %s", msg);
 }
 
 // Constructors
@@ -99,7 +99,10 @@
 NLEqn::set_states (const Vector& xvec)
 {
   if (xvec.capacity () != n)
-    error ("dimension error");
+    {
+      error ("dimension error");
+      return;
+    }
 
   x = xvec;
 }
@@ -187,7 +190,10 @@
   int tmp_info = 0;
 
   if (n == 0)
-    error ("Equation set not initialized");
+    {
+      error ("equation set not initialized");
+      return Vector ();
+    }
 
   double tol = sqrt (DBL_EPSILON);
 
--- a/liboctave/RowVector.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/RowVector.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -30,6 +30,7 @@
 
 #include "Matrix.h"
 #include "mx-inlines.cc"
+#include "lo-error.h"
 
 /*
  * Row Vector class.
@@ -38,7 +39,13 @@
 RowVector::RowVector (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create vector with negative dimension");
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   len = n;
   if (len > 0)
@@ -50,7 +57,13 @@
 RowVector::RowVector (int n, double val)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create vector with negative dimension");
+      len = 0;
+      data = (double *) NULL;
+      return;
+    }
 
   len = n;
   if (len > 0)
@@ -99,11 +112,44 @@
   return *this;
 }
 
+double&
+RowVector::checkelem (int n)
+{
+#ifndef NO_RANGE_CHECK
+  if (n < 0 || n >= len)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      static double foo = 0.0;
+      return foo;
+    }
+#endif
+
+  return elem (n);
+}
+
+double
+RowVector::checkelem (int n) const
+{
+#ifndef NO_RANGE_CHECK
+  if (n < 0 || n >= len)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      return 0.0;
+    }
+#endif
+
+  return elem (n);
+}
+
 RowVector&
 RowVector::resize (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return *this;
+    }
 
   double *new_data = (double *) NULL;
   if (n > 0)
@@ -153,7 +199,10 @@
 RowVector::insert (const RowVector& a, int c)
 {
   if (c < 0 || c + a.len - 1 > len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     data[c+i] = a.data[i];
@@ -173,7 +222,10 @@
 RowVector::fill (double val, int c1, int c2)
 {
   if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; }
 
@@ -296,7 +348,11 @@
 RowVector::operator * (const ColumnVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector multiplication attempted");
+      return 0.0;
+    }
 
   int i_one = 1;
   return F77_FCN (ddot) (&len, data, &i_one, a.data, &i_one);
@@ -315,7 +371,11 @@
 RowVector::operator * (const Matrix& a) const
 {
   if (a.nr != len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector multiplication attempted");
+      return RowVector ();
+    }
 
   if (len == 0 || a.nc == 0)
     return RowVector (0);
@@ -352,7 +412,11 @@
 RowVector::operator + (const RowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector addition attempted");
+      return RowVector ();
+    }
 
   if (len == 0)
     return RowVector (0);
@@ -364,7 +428,11 @@
 RowVector::operator - (const RowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector subtraction attempted");
+      return RowVector ();
+    }
 
   if (len == 0)
     return RowVector (0);
@@ -376,7 +444,11 @@
 RowVector::operator + (const ComplexRowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector addition attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -388,7 +460,11 @@
 RowVector::operator - (const ComplexRowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector subtraction attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -400,7 +476,11 @@
 RowVector::product (const RowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector product attempted");
+      return RowVector ();
+    }
 
   if (len == 0)
     return RowVector (0);
@@ -412,7 +492,11 @@
 RowVector::quotient (const RowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector quotient attempted");
+      return RowVector ();
+    }
 
   if (len == 0)
     return RowVector (0);
@@ -424,7 +508,11 @@
 RowVector::product (const ComplexRowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector product attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -436,7 +524,11 @@
 RowVector::quotient (const ComplexRowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector quotient attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -448,7 +540,11 @@
 RowVector::operator += (const RowVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
@@ -461,7 +557,11 @@
 RowVector::operator -= (const RowVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
@@ -542,7 +642,13 @@
 ComplexRowVector::ComplexRowVector (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create vector with negative dimension");
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   len = n;
   if (len > 0)
@@ -554,7 +660,13 @@
 ComplexRowVector::ComplexRowVector (int n, double val)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create vector with negative dimension");
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   len = n;
   if (len > 0)
@@ -569,7 +681,13 @@
 ComplexRowVector::ComplexRowVector (int n, const Complex& val)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't create vector with negative dimension");
+      len = 0;
+      data = (Complex *) NULL;
+      return;
+    }
 
   len = n;
   if (len > 0)
@@ -653,11 +771,44 @@
   return *this;
 }
 
+Complex&
+ComplexRowVector::checkelem (int n)
+{
+#ifndef NO_RANGE_CHECK
+  if (n < 0 || n >= len)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      static Complex foo (0.0);
+      return foo;
+    }
+#endif
+
+  return elem (n);
+}
+
+Complex
+ComplexRowVector::checkelem (int n) const
+{
+#ifndef NO_RANGE_CHECK
+  if (n < 0 || n >= len)
+    {
+      (*current_liboctave_error_handler) ("range error");
+      return Complex (0.0);
+    }
+#endif
+
+  return elem (n);
+}
+
 ComplexRowVector&
 ComplexRowVector::resize (int n)
 {
   if (n < 0)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return *this;
+    }
 
   Complex *new_data = (Complex *) NULL;
   if (n > 0)
@@ -720,7 +871,10 @@
 ComplexRowVector::insert (const RowVector& a, int c)
 {
   if (c < 0 || c + a.len - 1 > len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     data[c+i] = a.data[i];
@@ -732,7 +886,10 @@
 ComplexRowVector::insert (const ComplexRowVector& a, int c)
 {
   if (c < 0 || c + a.len - 1 > len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
 
   for (int i = 0; i < a.len; i++)
     data[c+i] = a.data[i];
@@ -760,7 +917,10 @@
 ComplexRowVector::fill (double val, int c1, int c2)
 {
   if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; }
 
@@ -774,7 +934,10 @@
 ComplexRowVector::fill (const Complex& val, int c1, int c2)
 {
   if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler) ("range error for fill");
+      return *this;
+    }
 
   if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; }
 
@@ -990,7 +1153,11 @@
 ComplexRowVector::operator * (const ComplexMatrix& a) const
 {
   if (a.nr != len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector multiplication attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0 || a.nc == 0)
     return ComplexRowVector (0);
@@ -1020,7 +1187,11 @@
 ComplexRowVector::operator + (const RowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector addition attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -1032,7 +1203,11 @@
 ComplexRowVector::operator - (const RowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector subtraction attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -1044,7 +1219,11 @@
 ComplexRowVector::operator + (const ComplexRowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector addition attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -1056,7 +1235,11 @@
 ComplexRowVector::operator - (const ComplexRowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector subtraction attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -1068,7 +1251,11 @@
 ComplexRowVector::product (const RowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector product attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -1080,7 +1267,11 @@
 ComplexRowVector::quotient (const RowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector quotient attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -1092,7 +1283,11 @@
 ComplexRowVector::product (const ComplexRowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector product attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -1104,7 +1299,11 @@
 ComplexRowVector::quotient (const ComplexRowVector& a) const
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector quotient attempted");
+      return ComplexRowVector ();
+    }
 
   if (len == 0)
     return ComplexRowVector (0);
@@ -1116,7 +1315,11 @@
 ComplexRowVector::operator += (const RowVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
@@ -1129,7 +1332,11 @@
 ComplexRowVector::operator -= (const RowVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
@@ -1142,7 +1349,11 @@
 ComplexRowVector::operator += (const ComplexRowVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
@@ -1155,7 +1366,11 @@
 ComplexRowVector::operator -= (const ComplexRowVector& a)
 {
   if (len != a.len)
-    FAIL;
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
 
   if (len == 0)
     return *this;
--- a/liboctave/idx-vector.cc	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/idx-vector.cc	Mon Nov 15 10:11:59 1993 +0000
@@ -270,6 +270,18 @@
   return (*i - *j);
 }
 
+int
+idx_vector::checkelem (int n) const
+{
+  if (n < 0 || n >= len)
+    {
+      error ("idx-vector: index out of range");
+      return 0;
+    }
+
+  return elem (n);
+}
+
 void
 idx_vector::sort (void)
 {
--- a/liboctave/idx-vector.h	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/idx-vector.h	Mon Nov 15 10:11:59 1993 +0000
@@ -28,10 +28,6 @@
 #pragma interface
 #endif
 
-#include <assert.h>
-
-#define FAIL assert(0) /* XXX FIXME XXX */
-
 class ostream;
 class Matrix;
 class Range;
@@ -121,15 +117,6 @@
 
 inline int idx_vector::elem (int n) const { return data[n]; }
 
-inline int
-idx_vector::checkelem (int n) const
-{
-  if (n < 0 || n >= len)
-    FAIL;
-
-  return elem (n);
-}
-
 inline int idx_vector::operator () (int n) const { return checkelem (n); }
 
 inline int idx_vector::max (void) const { return max_val; }
--- a/liboctave/lo-error.h	Mon Nov 15 10:06:26 1993 +0000
+++ b/liboctave/lo-error.h	Mon Nov 15 10:11:59 1993 +0000
@@ -21,8 +21,8 @@
 
 */
 
-#if !defined (_error_h)
-#define _error_h 1
+#if !defined (_liboctave_error_h)
+#define _liboctave_error_h 1
 
 #ifdef __GNUG__
 #pragma interface
@@ -35,12 +35,16 @@
 volatile v_fcn_cpc_x fatal;
 #endif
 
+extern void liboctave_fatal (const char *fmt, ...);
+
 typedef void (*liboctave_error_handler) (const char *, ...);
 
+// Would be nice to make this private, but we want to share it among
+// all the liboctave classes.
+extern liboctave_error_handler current_liboctave_error_handler;
+
 extern void set_liboctave_error_handler (liboctave_error_handler f);
 
-extern void liboctave_fatal (const char *fmt, ...);
-
 #endif
 
 /*