changeset 5759:ce79d238f142

[project @ 2006-04-13 13:04:32 by jwe]
author jwe
date Thu, 13 Apr 2006 13:04:33 +0000
parents 65208d959bf1
children 8d7162924bd3
files ChangeLog configure.in src/ChangeLog src/DLD-FUNCTIONS/matrix_type.cc src/DLD-FUNCTIONS/sparse.cc src/DLD-FUNCTIONS/splu.cc src/ops.h src/ov-base-int.cc src/ov-base-int.h src/ov-base-mat.h src/ov-base-scalar.h src/ov-base-sparse.h src/ov-base.cc src/ov-base.h src/ov-bool-mat.cc src/ov-bool-mat.h src/ov-bool-sparse.cc src/ov-bool-sparse.h src/ov-bool.cc src/ov-bool.h src/ov-cell.cc src/ov-cell.h src/ov-ch-mat.h src/ov-colon.h src/ov-complex.cc src/ov-complex.h src/ov-cs-list.h src/ov-cx-mat.cc src/ov-cx-mat.h src/ov-cx-sparse.cc src/ov-cx-sparse.h src/ov-fcn-handle.h src/ov-fcn-inline.h src/ov-fcn.cc src/ov-fcn.h src/ov-intx.h src/ov-list.cc src/ov-list.h src/ov-range.cc src/ov-range.h src/ov-re-mat.cc src/ov-re-mat.h src/ov-re-sparse.cc src/ov-re-sparse.h src/ov-scalar.h src/ov-str-mat.cc src/ov-str-mat.h src/ov-streamoff.h src/ov-struct.cc src/ov-struct.h src/ov-type-conv.h src/ov-typeinfo.cc src/ov-typeinfo.h src/ov-va-args.h src/ov.cc src/ov.h src/pr-output.cc src/pr-output.h src/variables.cc
diffstat 59 files changed, 1189 insertions(+), 1120 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Apr 12 19:23:26 2006 +0000
+++ b/ChangeLog	Thu Apr 13 13:04:33 2006 +0000
@@ -1,3 +1,7 @@
+2006-04-12  John W. Eaton  <jwe@octave.org>
+
+	* configure.in: If using g++, also add -Wold-style-cast to CXXFLAGS.
+
 2006-03-28  John W. Eaton  <jwe@octave.org>
 
 	* configure.in: Don't check for MPI libraries.
--- a/configure.in	Wed Apr 12 19:23:26 2006 +0000
+++ b/configure.in	Thu Apr 13 13:04:33 2006 +0000
@@ -29,7 +29,7 @@
 EXTERN_CXXFLAGS="$CXXFLAGS"
 
 AC_INIT
-AC_REVISION($Revision: 1.505 $)
+AC_REVISION($Revision: 1.506 $)
 AC_PREREQ(2.57)
 AC_CONFIG_SRCDIR([src/octave.cc])
 AC_CONFIG_HEADER(config.h)
@@ -1588,10 +1588,11 @@
   OCTAVE_CXX_FLAG(-Wshadow, [
     WARN_CXXFLAGS="$WARN_CXXFLAGS -Wshadow";
     AC_MSG_RESULT([adding -Wshadow to WARN_CXXFLAGS])])
+  OCTAVE_CXX_FLAG(-Wold-style-cast, [
+    WARN_CXXFLAGS="$WARN_CXXFLAGS -Wold-style-cast";
+    AC_MSG_RESULT([adding -Wold-style-cast to WARN_CXXFLAGS])])
 fi
 
-### Someday, maybe include -ansi and even -pedantic in this list...
-
 GCC_PICKY_FLAGS="-Wcast-align -Wcast-qual -Wmissing-prototypes \
   -Wpointer-arith -Wstrict-prototypes -Wwrite-strings"
 
--- a/src/ChangeLog	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ChangeLog	Thu Apr 13 13:04:33 2006 +0000
@@ -1,4 +1,20 @@
-2006-04-12  John W. Eaton  <jwe@octave.org>
+2006-04-13  John W. Eaton  <jwe@octave.org>
+
+	* ov.h (OV_REP_TYPE): New macro.
+
+	* DLD-FUNCTIONS/sparse.cc (MINMAX_BODY): No need to cast arg1 to
+	const octave_sparse_matrix&.
+
+	* ov-base.cc (print_answer_id_name, warn_resize_on_range_error,
+	warn_num_to_str, silent_functions): Move here, from ov.cc.
+	(Vwarn_resize_on_range_error, Vsilent_functions): Likewise.
+	(Vprint_answer_id_name): Likewise.  Now static.
+	(symbols_of_ov_base): New function.  Move DEFVARs for
+	print_answer_id_name, warn_resize_on_range_error, warn_num_to_str,
+	and silent_functions here from symbols_of_ov in ov.cc.
+	* ov.h (Vprint_answer_id_name): Delete decl.
+	* ov-base.h (Vwarn_resize_on_range_error, Vwarn_num_to_str):	
+	Move decls here from ov.h.
 
 	* ov-str-mat.cc (warn_str_to_num): Move here, from ov.cc.
 	(Vwarn_str_to_num): Likewise.  Now static.
@@ -13,12 +29,11 @@
 	* ov-list.cc (octave_list::do_index_op): Allow index to extract
 	multiple items.  Result is always a list.
 
-	* ov-struct.cc (struct_levels_to_print): Move here from ov.cc.
-	(Vstruct-levels_to_print): Likewise.  Now static.
-	(symbols_of_ov_struct): New function.  Move DEFVAR for
-	struct_levels_to_print here from symbols_of_ov in ov.cc.
-
-	* ov.h (Vstruct-levels_to_print): Delete decl.
+	* pr-output.cc (struct_levels_to_print): Move here from ov.cc.
+	(Vstruct-levels_to_print): Likewise.
+	(symbols_of_pr_output): Move DEFVAR for struct_levels_to_print here
+	from symbols_of_ov in ov.cc.
+	* pr-output.h (Vstruct_levels_to_print): Nove decl here from ov.h.
 
 	* gripes.cc (warn_divide_by_zero): Move here from ov.cc.
 	(Vwarn_divide_by_zero): Likewise.  Now static.
@@ -29,6 +44,58 @@
 	* load-save.cc (do_load): Declare count octave_idx_type, not int.
 	* ls-oct-ascii.cc, ls-oct-ascii.h (read_ascii_data): Likewise.
 
+	Rearrange octave_value class hierarchy so that rep is a pointer
+	an octave_base_value object and the octave_base_value class
+	stores the reference count.  Virtualness now goes with the
+	octave_base_value class, not the octave_value class.
+
+	* ops.h, ov-base-int.cc, ov-base-int.h, ov-base-mat.h,
+	ov-base-scalar.h, ov-base-sparse.h, ov-base.cc, ov-base.h,
+	ov-bool-mat.cc, ov-bool-mat.h, ov-bool-sparse.cc,
+	ov-bool-sparse.h, ov-bool.cc, ov-bool.h, ov-cell.cc, ov-cell.h,
+	ov-ch-mat.h, ov-colon.h, ov-complex.cc, ov-complex.h,
+	ov-cs-list.h, ov-cx-mat.cc, ov-cx-mat.h, ov-cx-sparse.cc,
+	ov-cx-sparse.h, ov-fcn-handle.h, ov-fcn-inline.h, ov-fcn.cc,
+	ov-fcn.h, ov-intx.h, ov-list.cc, ov-list.h, ov-range.cc,
+	ov-range.h, ov-re-mat.cc, ov-re-mat.h, ov-re-sparse.cc,
+	ov-re-sparse.h, ov-scalar.h, ov-str-mat.cc, ov-str-mat.h,
+	ov-streamoff.h, ov-struct.cc, ov-struct.h, ov-type-conv.h,
+	ov-typeinfo.cc, ov-typeinfo.h, ov-va-args.h, ov.cc, ov.h,
+	variables.cc, DLD-FUNCTIONS/matrix_type.cc, DLD-FUNCTIONS/splu.cc,
+	OPERATORS/op-chm.cc: Cope with octave_value hierarchy changes
+	(apologies for the lack of detail).
+
+	* ov.cc (octave_value::nil_rep): Delete.
+	* ov.h (octave_value::nil_rep): Delete decl.
+
+	* ov-base.h (DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA,
+	DECLARE_OV_BASE_TYPEID_FUNCTIONS_AND_DATA, 
+	DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2,
+	DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA):
+	Move macro definitions here from ov.h.
+	(struct_indent, increment_struct_indent, decrement_struct_indent,
+	list_indent, increment_list_indent, decrement_list_indent):
+	Delete decls.
+
+	* ov-base.cc. ov-base.h (do_index_op, ndims, all, any,
+	convert_to_str, print_with_name, numeric_assign,
+	reset_indent_level, increment_indent_level,
+	decrement_indent_level, current_print_indent_level, newline,
+	indent, reset): Move member functions here from octave_value class.
+	(count, curr_print_indent_level, beginning_of_line):
+	Move data members here from octave_value class.
+	(gripe_indexed_assignment, gripe_assign_conversion_failed,
+	gripe_no_conversion): Move here from ov.cc.
+
+	* ov.h (class octave_xvalue): Delete.
+	(octave_value::octave_value (const octave_xvalue&)): Delete.
+	(anonymous union): Delete.
+	(octave_value::rep): Now a pointer to octave_base_value instead of
+	octave_value.
+
+	(octave_value::internal_rep): Return pointer to octave_base_value,
+	not octave_value.
+	
 2006-04-11  John W. Eaton  <jwe@octave.org>
 
 	* pt-assign.cc (tree_simple_assignment::rvalue,
--- a/src/DLD-FUNCTIONS/matrix_type.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/DLD-FUNCTIONS/matrix_type.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -112,7 +112,7 @@
 	  if (nargin == 1)
 	    {
 	      SparseType mattyp;
-	      const octave_value& rep = args(0).get_rep ();
+	      const octave_base_value& rep = args(0).get_rep ();
 
 	      if (args(0).type_name () == "sparse complex matrix" ) 
 		{
--- a/src/DLD-FUNCTIONS/sparse.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/DLD-FUNCTIONS/sparse.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -722,7 +722,7 @@
     } \
  \
   int dim; \
-  dim_vector dv = ((const octave_sparse_matrix&) arg1) .dims (); \
+  dim_vector dv = arg1.dims (); \
   if (error_state) \
     { \
       gripe_wrong_type_arg (#FCN, arg1);  \
--- a/src/DLD-FUNCTIONS/splu.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/DLD-FUNCTIONS/splu.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -421,7 +421,7 @@
     }
 
   octave_value arg = args(0);
-  const octave_value& rep = arg.get_rep ();
+  const octave_base_value& rep = arg.get_rep ();
 
   octave_idx_type nr = arg.rows ();
   octave_idx_type nc = arg.columns ();
--- a/src/ops.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ops.h	Thu Apr 13 13:04:33 2006 +0000
@@ -148,7 +148,13 @@
 
 #define ASSIGNOPDECL(name) \
   static octave_value \
-  oct_assignop_ ## name (octave_value& a1, \
+  oct_assignop_ ## name (octave_base_value& a1, \
+			 const octave_value_list& idx, \
+			 const octave_base_value& a2)
+
+#define ASSIGNANYOPDECL(name) \
+  static octave_value \
+  oct_assignop_ ## name (octave_base_value& a1, \
 			 const octave_value_list& idx, \
 			 const octave_value& a2)
 
@@ -174,7 +180,7 @@
   }
 
 #define DEFASSIGNANYOP_FN(name, t1, f) \
-  ASSIGNOPDECL (name) \
+  ASSIGNANYOPDECL (name) \
   { \
     octave_ ## t1& v1 = DYNAMIC_CAST (octave_ ## t1&, a1); \
  \
@@ -183,12 +189,12 @@
   }
 
 #define CONVDECL(name) \
-  static octave_value * \
-  oct_conv_ ## name (const octave_value& a)
+  static octave_base_value * \
+  oct_conv_ ## name (const octave_base_value& a)
 
 #define CONVDECLX(name) \
-  static octave_value * \
-  oct_conv_ ## name (const octave_value&)
+  static octave_base_value * \
+  oct_conv_ ## name (const octave_base_value&)
 
 #define DEFCONV(name, a_dummy, b_dummy) \
   CONVDECL (name)
@@ -223,7 +229,7 @@
 
 #define UNOPDECL(name, a) \
   static octave_value \
-  oct_unop_ ## name (const octave_value& a)
+  oct_unop_ ## name (const octave_base_value& a)
 
 #define DEFUNOPX(name, t) \
   UNOPDECL (name, , )
@@ -263,7 +269,7 @@
 
 #define DEFNCUNOP_METHOD(name, t, method) \
   static void \
-  oct_unop_ ## name (octave_value& a) \
+  oct_unop_ ## name (octave_base_value& a) \
   { \
     CAST_UNOP_ARG (octave_ ## t&); \
     v.method (); \
@@ -271,7 +277,7 @@
 
 #define BINOPDECL(name, a1, a2) \
   static octave_value \
-  oct_binop_ ## name (const octave_value& a1, const octave_value& a2)
+  oct_binop_ ## name (const octave_base_value& a1, const octave_base_value& a2)
 
 #define DEFBINOPX(name, t1, t2) \
   BINOPDECL (name, , )
@@ -319,7 +325,7 @@
 
 #define CATOPDECL(name, a1, a2)	\
   static octave_value \
-  oct_catop_ ## name (octave_value& a1, const octave_value& a2, \
+  oct_catop_ ## name (octave_base_value& a1, const octave_base_value& a2, \
 		      const Array<int>& ra_idx)
 
 #define DEFCATOPX(name, t1, t2)	\
--- a/src/ov-base-int.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-base-int.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -57,10 +57,10 @@
 #include "ls-hdf5.h"
 
 template <class T>
-octave_value *
+octave_base_value *
 octave_base_int_matrix<T>::try_narrowing_conversion (void)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   if (this->matrix.nelem () == 1)
     retval = new typename octave_value_int_traits<T>::scalar_type (this->matrix (0));
--- a/src/ov-base-int.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-base-int.h	Thu Apr 13 13:04:33 2006 +0000
@@ -54,10 +54,10 @@
 
   ~octave_base_int_matrix (void) { }
 
-  octave_value *clone (void) const { return new octave_base_int_matrix (*this); }
-  octave_value *empty_clone (void) const { return new octave_base_int_matrix (); }
+  octave_base_value *clone (void) const { return new octave_base_int_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_base_int_matrix (); }
 
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 
   bool is_real_type (void) const { return true; }
 
@@ -98,10 +98,10 @@
 
   ~octave_base_int_scalar (void) { }
 
-  octave_value *clone (void) const { return new octave_base_int_scalar (*this); }
-  octave_value *empty_clone (void) const { return new octave_base_int_scalar (); }
+  octave_base_value *clone (void) const { return new octave_base_int_scalar (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_base_int_scalar (); }
 
-  octave_value *try_narrowing_conversion (void) { return 0; }
+  octave_base_value *try_narrowing_conversion (void) { return 0; }
 
   bool is_real_type (void) const { return true; }
 
--- a/src/ov-base-mat.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-base-mat.h	Thu Apr 13 13:04:33 2006 +0000
@@ -64,8 +64,8 @@
 
   ~octave_base_matrix (void) { }
 
-  octave_value *clone (void) const { return new octave_base_matrix (*this); }
-  octave_value *empty_clone (void) const { return new octave_base_matrix (); }
+  octave_base_value *clone (void) const { return new octave_base_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_base_matrix (); }
 
   size_t byte_size (void) const { return matrix.byte_size (); }
 
--- a/src/ov-base-scalar.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-base-scalar.h	Thu Apr 13 13:04:33 2006 +0000
@@ -56,8 +56,8 @@
 
   ~octave_base_scalar (void) { }
 
-  octave_value *clone (void) const { return new octave_base_scalar (*this); }
-  octave_value *empty_clone (void) const { return new octave_base_scalar (); }
+  octave_base_value *clone (void) const { return new octave_base_scalar (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_base_scalar (); }
 
   octave_value squeeze (void) const { return scalar; }
 
--- a/src/ov-base-sparse.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-base-sparse.h	Thu Apr 13 13:04:33 2006 +0000
@@ -71,8 +71,8 @@
 
   ~octave_base_sparse (void) { }
 
-  octave_value *clone (void) const { return new octave_base_sparse (*this); }
-  octave_value *empty_clone (void) const 
+  octave_base_value *clone (void) const { return new octave_base_sparse (*this); }
+  octave_base_value *empty_clone (void) const 
     { return new octave_base_sparse (); }
 
   octave_idx_type nnz (void) const { return matrix.nnz (); }
--- a/src/ov-base.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-base.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -29,10 +29,12 @@
 
 #include <iostream>
 
+#include "Array-flags.h"
 #include "lo-ieee.h"
 #include "lo-mappers.h"
 #include "so-array.h"
 
+#include "defun.h"
 #include "gripes.h"
 #include "oct-map.h"
 #include "oct-obj.h"
@@ -50,11 +52,28 @@
 #include "ov-scalar.h"
 #include "ov-str-mat.h"
 #include "ov-fcn-handle.h"
+#include "parse.h"
+#include "utils.h"
 #include "variables.h"
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_base_value,
 				     "<unknown type>", "unknown");
 
+// If TRUE, print the name along with the value.
+static bool Vprint_answer_id_name;
+
+// If TRUE, turn off printing of results in functions (as if a
+// semicolon has been appended to each statement).
+static bool Vsilent_functions;
+
+// Should we print a warning when converting `[97, 98, 99, "123"]'
+// to a character string?
+bool Vwarn_num_to_str;
+
+// If TRUE, print a warning when a matrix is resized by an indexed
+// assignment with indices outside the current bounds.
+bool Vwarn_resize_on_range_error;
+
 octave_value
 octave_base_value::squeeze (void) const
 {
@@ -89,6 +108,12 @@
   return octave_value ();
 }
 
+octave_value
+octave_base_value::do_index_op (const octave_value_list& idx)
+{
+  return do_index_op (idx, 0);
+}
+
 octave_value_list
 octave_base_value::do_multi_index_op (int, const octave_value_list&)
 {
@@ -105,6 +130,31 @@
   return idx_vector ();
 }
 
+int
+octave_base_value::ndims (void) const
+{
+  dim_vector dv = dims ();
+
+  int n_dims = dv.length ();
+     
+   // Remove trailing singleton dimensions.
+
+   for (int i = n_dims; i > 2; i--)
+     {
+       if (dv(i-1) == 1)
+	 n_dims--;
+       else
+	 break;
+     }
+   
+   // The result is always >= 2.
+
+   if (n_dims < 2)
+     n_dims = 2;
+
+   return n_dims;
+}
+
 octave_value
 octave_base_value::subsasgn (const std::string& type,
 			     const std::list<octave_value_list>& idx,
@@ -209,6 +259,29 @@
 }
 
 octave_value
+octave_base_value::all (int) const
+{
+  return 0.0;
+}
+
+octave_value
+octave_base_value::any (int) const
+{
+  return 0.0;
+}
+
+octave_value
+octave_base_value::convert_to_str (bool pad, bool force, char type) const
+{
+  octave_value retval = convert_to_str_internal (pad, force, type);
+
+  if (! force && is_numeric_type () && Vwarn_num_to_str)
+    gripe_implicit_conversion (type_name (), retval.type_name ());
+
+  return retval;
+}
+
+octave_value
 octave_base_value::convert_to_str_internal (bool, bool, char) const
 {
   gripe_wrong_type_arg ("octave_base_value::convert_to_str_internal ()",
@@ -257,6 +330,25 @@
 }
 
 void
+octave_base_value::print_with_name (std::ostream& output_buf,
+				    const std::string& name, 
+				    bool print_padding) const
+{
+  if (! (evaluating_function_body && Vsilent_functions))
+    {
+      bool pad_after = false;
+
+      if (Vprint_answer_id_name)
+	pad_after = print_name_tag (output_buf, name);
+
+      print (output_buf);
+
+      if (print_padding && pad_after)
+	newline (output_buf);
+    }
+}
+
+void
 octave_base_value::print_info (std::ostream& os,
 			       const std::string& /* prefix */) const
 {
@@ -773,6 +865,193 @@
   return false;
 }
 
+static void
+gripe_indexed_assignment (const std::string& tn1, const std::string& tn2)
+{
+  error ("assignment of `%s' to indexed `%s' not implemented",
+	 tn2.c_str (), tn1.c_str ());
+}
+
+static void
+gripe_assign_conversion_failed (const std::string& tn1,
+				const std::string& tn2)
+{
+  error ("type conversion for assignment of `%s' to indexed `%s' failed",
+	 tn2.c_str (), tn1.c_str ());
+}
+
+static void
+gripe_no_conversion (const std::string& on, const std::string& tn1,
+		     const std::string& tn2)
+{
+  error ("operator %s: no conversion for assignment of `%s' to indexed `%s'",
+	 on.c_str (), tn2.c_str (), tn1.c_str ());
+}
+
+octave_value
+octave_base_value::numeric_assign (const std::string& type,
+				   const std::list<octave_value_list>& idx,
+				   const octave_value& rhs)
+{
+  octave_value retval;
+
+  int t_lhs = type_id ();
+  int t_rhs = rhs.type_id ();
+
+  octave_value_typeinfo::assign_op_fcn f
+    = octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
+					       t_lhs, t_rhs);
+
+  bool done = false;
+
+  if (f)
+    {
+      f (*this, idx.front (), rhs.get_rep ());
+
+      done = (! error_state);
+    }
+
+  if (done)
+    {
+      count++;
+      retval = octave_value (this);
+    }
+  else
+    {
+      int t_result
+	= octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs);
+
+      if (t_result >= 0)
+	{
+	  octave_base_value::type_conv_fcn cf
+	    = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result);
+
+	  if (cf)
+	    {
+	      octave_base_value *tmp (cf (*this));
+
+	      if (tmp)
+		{
+		  retval = tmp->subsasgn (type, idx, rhs);
+
+		  done = (! error_state);
+		}
+	      else
+		gripe_assign_conversion_failed (type_name (),
+						rhs.type_name ());
+	    }
+	  else
+	    gripe_indexed_assignment (type_name (), rhs.type_name ());
+	}
+
+      if (! (done || error_state))
+	{
+	  octave_value tmp_rhs;
+
+	  octave_base_value::type_conv_fcn cf_rhs
+	    = rhs.numeric_conversion_function ();
+
+	  if (cf_rhs)
+	    {
+	      octave_base_value *tmp = cf_rhs (rhs.get_rep ());
+
+	      if (tmp)
+		tmp_rhs = octave_value (tmp);
+	      else
+		{
+		  gripe_assign_conversion_failed (type_name (),
+						  rhs.type_name ());
+		  return octave_value ();
+		}
+	    }
+	  else
+	    tmp_rhs = rhs;
+
+	  octave_base_value::type_conv_fcn cf_this
+	    = numeric_conversion_function ();
+
+	  octave_base_value *tmp_lhs = this;
+
+	  if (cf_this)
+	    {
+	      octave_base_value *tmp = cf_this (*this);
+
+	      if (tmp)
+		tmp_lhs = tmp;
+	      else
+		{
+		  gripe_assign_conversion_failed (type_name (),
+						  rhs.type_name ());
+		  return octave_value ();
+		}
+	    }
+
+	  if (cf_this || cf_rhs)
+	    {
+	      retval = tmp_lhs->subsasgn (type, idx, tmp_rhs);
+
+	      done = (! error_state);
+	    }
+	  else
+	    gripe_no_conversion (octave_value::assign_op_as_string (octave_value::op_asn_eq),
+				 type_name (), rhs.type_name ());
+	}
+    }
+
+  // The assignment may have converted to a type that is wider than
+  // necessary.
+
+  retval.maybe_mutate ();
+
+  return retval;
+}
+
+// Current indentation.
+int octave_base_value::curr_print_indent_level = 0;
+
+// TRUE means we are at the beginning of a line.
+bool octave_base_value::beginning_of_line = true;
+
+// Each print() function should call this before printing anything.
+//
+// This doesn't need to be fast, but isn't there a better way?
+
+void
+octave_base_value::indent (std::ostream& os) const
+{
+  assert (curr_print_indent_level >= 0);
+ 
+  if (beginning_of_line)
+    {
+      // XXX FIXME XXX -- do we need this?
+      // os << prefix;
+
+      for (int i = 0; i < curr_print_indent_level; i++)
+	os << " ";
+
+      beginning_of_line = false;
+    }
+}
+
+// All print() functions should use this to print new lines.
+
+void
+octave_base_value::newline (std::ostream& os) const
+{
+  os << "\n";
+
+  beginning_of_line = true;
+}
+
+// For ressetting print state.
+
+void
+octave_base_value::reset (void) const
+{
+  beginning_of_line = true;
+  curr_print_indent_level = 0;
+}
+
 CONVDECLX (matrix_conv)
 {
   return new octave_matrix ();
@@ -810,6 +1089,100 @@
   INSTALL_WIDENOP (octave_base_value, octave_cell, cell_conv);
 }
 
+static int
+print_answer_id_name (void)
+{
+  Vprint_answer_id_name = check_preference ("print_answer_id_name");
+
+  return 0;
+}
+
+static int
+silent_functions (void)
+{
+  Vsilent_functions = check_preference ("silent_functions");
+
+  return 0;
+}
+
+static int
+warn_num_to_str (void)
+{
+  Vwarn_num_to_str = check_preference ("warn_num_to_str");
+
+  return 0;
+}
+
+static int
+warn_resize_on_range_error (void)
+{
+  Vwarn_resize_on_range_error
+    = check_preference ("warn_resize_on_range_error");
+
+  liboctave_wrore_flag = Vwarn_resize_on_range_error;
+
+  return 0;
+}
+
+void
+symbols_of_ov_base (void)
+{
+  DEFVAR (print_answer_id_name, true, print_answer_id_name,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} print_answer_id_name\n\
+If the value of @code{print_answer_id_name} is nonzero, variable\n\
+names are printed along with the result.  Otherwise, only the result\n\
+values are printed.  The default value is 1.\n\
+@end defvr");
+
+  DEFVAR (silent_functions, false, silent_functions,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} silent_functions\n\
+If the value of @code{silent_functions} is nonzero, internal output\n\
+from a function is suppressed.  Otherwise, the results of expressions\n\
+within a function body that are not terminated with a semicolon will\n\
+have their values printed.  The default value is 0.\n\
+\n\
+For example, if the function\n\
+\n\
+@example\n\
+function f ()\n\
+  2 + 2\n\
+endfunction\n\
+@end example\n\
+\n\
+@noindent\n\
+is executed, Octave will either print @samp{ans = 4} or nothing\n\
+depending on the value of @code{silent_functions}.\n\
+@end defvr");
+
+  DEFVAR (warn_num_to_str, true, warn_num_to_str,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} warn_num_to_str\n\
+If the value of @code{warn_num_to_str} is nonzero, a warning is\n\
+printed for implicit conversions of numbers to their ASCII character\n\
+equivalents when strings are constructed using a mixture of strings and\n\
+numbers in matrix notation.  For example,\n\
+\n\
+@example\n\
+@group\n\
+[ \"f\", 111, 111 ]\n\
+     @result{} \"foo\"\n\
+@end group\n\
+@end example\n\
+elicits a warning if @code{warn_num_to_str} is nonzero.  The default\n\
+value is 1.\n\
+@end defvr");
+
+  DEFVAR (warn_resize_on_range_error, false, warn_resize_on_range_error,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} warn_resize_on_range_error\n\
+If the value of @code{warn_resize_on_range_error} is nonzero, print a\n\
+warning when a matrix is resized by an indexed assignment with\n\
+indices outside the current bounds.  The default value is 0.\n\
+@end defvr");
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/ov-base.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-base.h	Thu Apr 13 13:04:33 2006 +0000
@@ -27,305 +27,430 @@
 #include <cstdlib>
 
 #include <iostream>
+#include <list>
 #include <string>
 
+#if defined (HAVE_HDF5)
+#include <hdf5.h>
+#endif
+
+#include "Range.h"
 #include "mx-base.h"
 #include "str-vec.h"
 
 #include "error.h"
-#include "ov.h"
-#include "ov-typeinfo.h"
 
 class Cell;
+class streamoff_array;
 class Octave_map;
+class octave_value;
 class octave_value_list;
+class octave_stream;
+class octave_streamoff;
+class octave_function;
+class octave_user_function;
+class octave_fcn_handle;
+class octave_fcn_inline;
+class octave_value_list;
+class octave_lvalue;
 
 class tree_walker;
 
+// T_ID is the type id of struct objects, set by register_type().
+// T_NAME is the type name of struct objects.
+#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA \
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2()
+
+#define DECLARE_OV_BASE_TYPEID_FUNCTIONS_AND_DATA \
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2(virtual)
+
+#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2(VIRTUAL) \
+  public: \
+    VIRTUAL int type_id (void) const { return t_id; } \
+    VIRTUAL std::string type_name (void) const { return t_name; } \
+    VIRTUAL std::string class_name (void) const { return c_name; } \
+    static int static_type_id (void) { return t_id; } \
+    static std::string static_type_name (void) { return t_name; } \
+    static std::string static_class_name (void) { return c_name; } \
+    static void register_type (void); \
+ \
+  private: \
+    static int t_id; \
+    static const std::string t_name; \
+    static const std::string c_name;
+
+
+#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c) \
+  int t::t_id (-1); \
+  const std::string t::t_name (n); \
+  const std::string t::c_name (c); \
+  void t::register_type (void) \
+    { \
+      t_id = octave_value_typeinfo::register_type (t::t_name, \
+						   t::c_name, \
+						   octave_value (new t ())); \
+    }
+
+// Should we print a warning when converting `[97, 98, 99, "123"]'
+// to a character string?
+extern bool Vwarn_num_to_str;
+
+// If TRUE, print a warning when a matrix is resized by an indexed
+// assignment with indices outside the current bounds.
+extern bool Vwarn_resize_on_range_error;
+
 // A base value type, so that derived types only have to redefine what
 // they need (if they are derived from octave_base_value instead of
 // octave_value).
 
 class
-octave_base_value : public octave_value
+octave_base_value
 {
 public:
 
-  octave_base_value (void)
-    : octave_value (octave_xvalue ()) { }
+  typedef octave_base_value * (*type_conv_fcn) (const octave_base_value&);
+
+  friend class octave_value;
 
-  octave_base_value (const octave_base_value&)
-    : octave_value (octave_xvalue ()) { }
+  octave_base_value (void) : count (1) { }
+
+  octave_base_value (const octave_base_value&) { }
 
-  ~octave_base_value (void) { }
+  virtual ~octave_base_value (void) { }
+
+  virtual octave_base_value *
+  clone (void) const { return new octave_base_value (*this); }
 
-  octave_value *clone (void) const { return new octave_base_value (*this); }
-  octave_value *empty_clone (void) const { return new octave_base_value (); }
+  virtual octave_base_value *
+  empty_clone (void) const { return new octave_base_value (); }
 
-  type_conv_fcn numeric_conversion_function (void) const
+  virtual type_conv_fcn
+  numeric_conversion_function (void) const
     { return static_cast<type_conv_fcn> (0); }
 
-  octave_value squeeze (void) const;
+  virtual octave_value squeeze (void) const;
+
+  virtual octave_base_value *try_narrowing_conversion (void) { return 0; }
 
-  octave_value *try_narrowing_conversion (void)
-    { return static_cast<octave_value *> (0); }
-
-  octave_value subsref (const std::string& type,
-			const std::list<octave_value_list>& idx);
+  virtual octave_value
+  subsref (const std::string& type,
+	   const std::list<octave_value_list>& idx);
 
-  octave_value_list subsref (const std::string& type,
-			     const std::list<octave_value_list>& idx,
-			     int nargout);
+  virtual octave_value_list
+  subsref (const std::string& type,
+	   const std::list<octave_value_list>& idx,
+	   int nargout);
 
-  octave_value do_index_op (const octave_value_list& idx, int resize_ok);
+  virtual octave_value
+  do_index_op (const octave_value_list& idx, int resize_ok);
 
-  octave_value do_index_op (const octave_value_list& idx)
-    { return do_index_op (idx, 0); }
+  virtual octave_value
+  do_index_op (const octave_value_list& idx);
 
-  octave_value_list
+  virtual octave_value_list
   do_multi_index_op (int nargout, const octave_value_list& idx);
 
-  idx_vector index_vector (void) const;
+  virtual octave_value
+  subsasgn (const std::string& type,
+	    const std::list<octave_value_list>& idx,
+	    const octave_value& rhs);
 
-  octave_value subsasgn (const std::string& type,
-			 const std::list<octave_value_list>& idx,
-			 const octave_value& rhs);
+  virtual idx_vector index_vector (void) const;
 
-  dim_vector dims (void) const { return dim_vector (-1, -1); }
+  virtual dim_vector dims (void) const { return dim_vector (-1, -1); }
 
-  octave_idx_type numel (void) const { return dims ().numel (); }
-
-  octave_idx_type capacity (void) const { return numel (); }
+  octave_idx_type rows (void) const
+    {
+      dim_vector dv = dims ();
 
-  size_t byte_size (void) const { return 0; }
+      return (dv.length () > 0) ? dv(0) : -1;
+    }
 
-  octave_idx_type nnz (void) const;
+  octave_idx_type columns (void) const
+    {
+      dim_vector dv = dims ();
 
-  octave_idx_type nzmax (void) const;
+      return (dv.length () > 1) ? dv(1) : -1;
+    }
 
-  octave_value reshape (const dim_vector&) const;
+  virtual int ndims (void) const;
 
-  octave_value permute (const Array<int>& vec, bool = false) const;
+  virtual octave_idx_type numel (void) const { return dims ().numel (); }
 
-  octave_value resize (const dim_vector&, bool fill = false) const;
+  virtual octave_idx_type capacity (void) const { return numel (); }
+
+  virtual size_t byte_size (void) const { return 0; }
 
-  bool is_defined (void) const { return false; }
+  virtual octave_idx_type nnz (void) const;
 
-  bool is_cell (void) const { return false; }
+  virtual octave_idx_type nzmax (void) const;
+
+  virtual octave_value reshape (const dim_vector&) const;
 
-  bool is_real_scalar (void) const { return false; }
+  virtual octave_value permute (const Array<int>& vec, bool = false) const;
 
-  bool is_real_matrix (void) const { return false; }
+  virtual octave_value resize (const dim_vector&, bool fill = false) const;
 
-  bool is_real_nd_array (void) const { return false; }
+  virtual bool is_defined (void) const { return false; }
 
-  bool is_complex_scalar (void) const { return false; }
+  bool is_empty (void) const { return numel () == 0; }
 
-  bool is_complex_matrix (void) const { return false; }
+  virtual bool is_cell (void) const { return false; }
 
-  bool is_bool_matrix (void) const { return false; }
+  virtual bool is_real_scalar (void) const { return false; }
 
-  bool is_char_matrix (void) const { return false; }
+  virtual bool is_real_matrix (void) const { return false; }
+
+  virtual bool is_real_nd_array (void) const { return false; }
 
-  bool is_string (void) const { return false; }
+  virtual bool is_complex_scalar (void) const { return false; }
 
-  bool is_sq_string (void) const { return false; }
+  virtual bool is_complex_matrix (void) const { return false; }
+
+  virtual bool is_bool_matrix (void) const { return false; }
 
-  bool is_range (void) const { return false; }
+  virtual bool is_char_matrix (void) const { return false; }
 
-  bool is_map (void) const { return false; }
+  virtual bool is_string (void) const { return false; }
 
-  bool is_streamoff (void) const { return false; }
+  virtual bool is_sq_string (void) const { return false; }
 
-  bool is_cs_list (void) const { return false; }
+  virtual bool is_range (void) const { return false; }
 
-  bool is_list (void) const { return false; }
+  virtual bool is_map (void) const { return false; }
+
+  virtual bool is_streamoff (void) const { return false; }
 
-  bool is_magic_colon (void) const { return false; }
+  virtual bool is_cs_list (void) const { return false; }
 
-  bool is_all_va_args (void) const { return false; }
+  virtual bool is_list (void) const { return false; }
+
+  virtual bool is_magic_colon (void) const { return false; }
 
-  octave_value all (int = 0) const { return 0.0; }
+  virtual bool is_all_va_args (void) const { return false; }
 
-  octave_value any (int = 0) const { return 0.0; }
+  virtual octave_value all (int = 0) const;
+
+  virtual octave_value any (int = 0) const;
 
-  bool is_bool_type (void) const { return false; }
+  virtual bool is_bool_type (void) const { return false; }
 
-  bool is_real_type (void) const { return false; }
+  virtual bool is_real_type (void) const { return false; }
 
-  bool is_complex_type (void) const { return false; }
+  virtual bool is_complex_type (void) const { return false; }
 
   // Would be nice to get rid of the next four functions:
 
-  bool is_scalar_type (void) const { return false; }
+  virtual bool is_scalar_type (void) const { return false; }
 
-  bool is_matrix_type (void) const { return false; }
+  virtual bool is_matrix_type (void) const { return false; }
 
-  bool is_numeric_type (void) const { return false; }
+  virtual bool is_numeric_type (void) const { return false; }
 
-  bool is_sparse_type (void) const { return false; }
+  virtual bool is_sparse_type (void) const { return false; }
 
-  bool valid_as_scalar_index (void) const { return false; }
+  virtual bool valid_as_scalar_index (void) const { return false; }
 
-  bool valid_as_zero_index (void) const { return false; }
+  virtual bool valid_as_zero_index (void) const { return false; }
 
-  bool is_true (void) const { return false; }
+  virtual bool is_true (void) const { return false; }
+
+  virtual bool is_constant (void) const { return false; }
 
-  bool is_zero_by_zero (void) const
-    { return (rows () == 0 && columns () == 0); }
+  virtual bool is_function_handle (void) const { return false; }
 
-  bool is_constant (void) const { return false; }
+  virtual bool is_inline_function (void) const { return false; }
 
-  bool is_function_handle (void) const { return false; }
-
-  bool is_inline_function (void) const { return false; }
+  virtual bool is_function (void) const { return false; }
 
-  bool is_function (void) const { return false; }
+  virtual bool is_builtin_function (void) const { return false; }
 
-  bool is_builtin_function (void) const { return false; }
-
-  bool is_dld_function (void) const { return false; }
+  virtual bool is_dld_function (void) const { return false; }
 
-  short int short_value (bool = false, bool = false) const;
+  virtual short int short_value (bool = false, bool = false) const;
 
-  unsigned short int ushort_value (bool = false, bool = false) const;
+  virtual unsigned short int ushort_value (bool = false, bool = false) const;
 
-  int int_value (bool = false, bool = false) const;
+  virtual int int_value (bool = false, bool = false) const;
 
-  unsigned int uint_value (bool = false, bool = false) const;
+  virtual unsigned int uint_value (bool = false, bool = false) const;
 
-  int nint_value (bool = false) const;
+  virtual int nint_value (bool = false) const;
 
-  long int long_value (bool = false, bool = false) const;
+  virtual long int long_value (bool = false, bool = false) const;
 
-  unsigned long int ulong_value (bool = false, bool = false) const;
+  virtual unsigned long int ulong_value (bool = false, bool = false) const;
 
-  double double_value (bool = false) const;
+  virtual double double_value (bool = false) const;
 
-  double scalar_value (bool frc_str_conv = false) const
+  virtual double scalar_value (bool frc_str_conv = false) const
     { return double_value (frc_str_conv); }
 
-  Cell cell_value (void) const;
+  virtual Cell cell_value (void) const;
 
-  Matrix matrix_value (bool = false) const;
+  virtual Matrix matrix_value (bool = false) const;
 
-  NDArray array_value (bool = false) const;
+  virtual NDArray array_value (bool = false) const;
 
-  Complex complex_value (bool = false) const;
+  virtual Complex complex_value (bool = false) const;
 
-  ComplexMatrix complex_matrix_value (bool = false) const;
+  virtual ComplexMatrix complex_matrix_value (bool = false) const;
 
-  ComplexNDArray complex_array_value (bool = false) const;
+  virtual ComplexNDArray complex_array_value (bool = false) const;
 
-  bool bool_value (void) const;
+  virtual bool bool_value (void) const;
 
-  boolMatrix bool_matrix_value (void) const;
+  virtual boolMatrix bool_matrix_value (void) const;
 
-  boolNDArray bool_array_value (void) const;
+  virtual boolNDArray bool_array_value (void) const;
 
-  charMatrix char_matrix_value (bool force = false) const;
+  virtual charMatrix char_matrix_value (bool force = false) const;
+
+  virtual charNDArray char_array_value (bool = false) const;
 
-  charNDArray char_array_value (bool = false) const;
+  virtual SparseMatrix sparse_matrix_value (bool = false) const;
 
-  SparseMatrix sparse_matrix_value (bool = false) const;
+  virtual SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
 
-  SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
+  virtual SparseBoolMatrix sparse_bool_matrix_value (bool = false) const;
 
-  SparseBoolMatrix sparse_bool_matrix_value (bool = false) const;
+  virtual octave_int8 int8_scalar_value (void) const;
 
-  octave_int8 int8_scalar_value (void) const;
+  virtual octave_int16 int16_scalar_value (void) const;
 
-  octave_int16 int16_scalar_value (void) const;
+  virtual octave_int32 int32_scalar_value (void) const;
+
+  virtual octave_int64 int64_scalar_value (void) const;
 
-  octave_int32 int32_scalar_value (void) const;
+  virtual octave_uint8 uint8_scalar_value (void) const;
 
-  octave_int64 int64_scalar_value (void) const;
+  virtual octave_uint16 uint16_scalar_value (void) const;
 
-  octave_uint8 uint8_scalar_value (void) const;
+  virtual octave_uint32 uint32_scalar_value (void) const;
 
-  octave_uint16 uint16_scalar_value (void) const;
+  virtual octave_uint64 uint64_scalar_value (void) const;
 
-  octave_uint32 uint32_scalar_value (void) const;
+  virtual int8NDArray int8_array_value (void) const;
 
-  octave_uint64 uint64_scalar_value (void) const;
+  virtual int16NDArray int16_array_value (void) const;
 
-  int8NDArray int8_array_value (void) const;
+  virtual int32NDArray int32_array_value (void) const;
 
-  int16NDArray int16_array_value (void) const;
+  virtual int64NDArray int64_array_value (void) const;
 
-  int32NDArray int32_array_value (void) const;
+  virtual uint8NDArray uint8_array_value (void) const;
 
-  int64NDArray int64_array_value (void) const;
+  virtual uint16NDArray uint16_array_value (void) const;
 
-  uint8NDArray uint8_array_value (void) const;
+  virtual uint32NDArray uint32_array_value (void) const;
 
-  uint16NDArray uint16_array_value (void) const;
+  virtual uint64NDArray uint64_array_value (void) const;
 
-  uint32NDArray uint32_array_value (void) const;
+  virtual string_vector all_strings (bool pad = false) const;
 
-  uint64NDArray uint64_array_value (void) const;
+  virtual std::string string_value (bool force = false) const;
 
-  string_vector all_strings (bool pad = false) const;
+  virtual Range range_value (void) const;
 
-  std::string string_value (bool force = false) const;
+  virtual Octave_map map_value (void) const;
 
-  Range range_value (void) const;
+  virtual string_vector map_keys (void) const;
 
-  Octave_map map_value (void) const;
+  virtual std::streamoff streamoff_value (void) const;
 
-  string_vector map_keys (void) const;
+  virtual streamoff_array streamoff_array_value (void) const;
+
+  virtual octave_function *function_value (bool silent = false);
 
-  std::streamoff streamoff_value (void) const;
+  virtual octave_user_function *user_function_value (bool silent = false);
 
-  streamoff_array streamoff_array_value (void) const;
+  virtual octave_fcn_handle *fcn_handle_value (bool silent = false);
 
-  octave_function *function_value (bool silent = false);
+  virtual octave_fcn_inline *fcn_inline_value (bool silent = false);
 
-  octave_user_function *user_function_value (bool silent = false);
-
-  octave_fcn_handle *fcn_handle_value (bool silent = false);
+  virtual octave_value_list list_value (void) const;
 
-  octave_fcn_inline *fcn_inline_value (bool silent = false);
+  virtual octave_value convert_to_str (bool pad = false, bool force = false,
+				       char type = '"') const;
+  virtual octave_value
+  convert_to_str_internal (bool pad, bool force, char type) const;
 
-  octave_value_list list_value (void) const;
+  virtual void convert_to_row_or_column_vector (void);
 
-  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
+  virtual bool print_as_scalar (void) const { return false; }
 
-  void convert_to_row_or_column_vector (void);
+  virtual void print (std::ostream& os, bool pr_as_read_syntax = false) const;
 
-  bool print_as_scalar (void) const { return false; }
+  virtual void
+  print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  virtual bool
+  print_name_tag (std::ostream& os, const std::string& name) const;
 
-  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
-
-  bool print_name_tag (std::ostream& os, const std::string& name) const;
+  virtual void
+  print_with_name (std::ostream& output_buf, const std::string& name, 
+		   bool print_padding = true) const;
 
-  void print_info (std::ostream& os, const std::string& prefix) const;
+  virtual void print_info (std::ostream& os, const std::string& prefix) const;
 
-  bool save_ascii (std::ostream& os, bool& infnan_warned,
+  virtual bool save_ascii (std::ostream& os, bool& infnan_warned,
 			   bool strip_nan_and_inf);
 
-  bool load_ascii (std::istream& is);
+  virtual bool load_ascii (std::istream& is);
 
-  bool save_binary (std::ostream& os, bool& save_as_floats);
+  virtual bool save_binary (std::ostream& os, bool& save_as_floats);
 
-  bool load_binary (std::istream& is, bool swap, 
-		    oct_mach_info::float_format fmt);
+  virtual bool load_binary (std::istream& is, bool swap, 
+			    oct_mach_info::float_format fmt);
 
 #if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  virtual bool
+  save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+  virtual bool
+  load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
 #endif
 
-  int write (octave_stream& os, int block_size,
-	     oct_data_conv::data_type output_type, int skip,
-	     oct_mach_info::float_format flt_fmt) const;
+  virtual int
+  write (octave_stream& os, int block_size,
+	 oct_data_conv::data_type output_type, int skip,
+	 oct_mach_info::float_format flt_fmt) const;
+
+protected:
+
+  // This should only be called for derived types.
+
+  octave_value numeric_assign (const std::string& type,
+			       const std::list<octave_value_list>& idx,
+			       const octave_value& rhs);
+
+  void reset_indent_level (void) const
+    { curr_print_indent_level = 0; }
+
+  void increment_indent_level (void) const
+    { curr_print_indent_level += 2; }
+
+  void decrement_indent_level (void) const
+    { curr_print_indent_level -= 2; }
+
+  int current_print_indent_level (void) const
+    { return curr_print_indent_level; }
+
+  void indent (std::ostream& os) const;
+
+  void newline (std::ostream& os) const;
+
+  void reset (void) const;
+
+  // A reference count.
+  int count;
 
 private:
 
-  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+  static int curr_print_indent_level;
+  static bool beginning_of_line;
+
+  DECLARE_OV_BASE_TYPEID_FUNCTIONS_AND_DATA
 };
 
 #endif
--- a/src/ov-bool-mat.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-bool-mat.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -54,24 +54,24 @@
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_bool_matrix,
 				     "bool matrix", "logical");
 
-static octave_value *
-default_numeric_conversion_function (const octave_value& a)
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
 {
   CAST_CONV_ARG (const octave_bool_matrix&);
 
   return new octave_matrix (NDArray (v.bool_array_value ()));
 }
 
-type_conv_fcn
+octave_base_value::type_conv_fcn
 octave_bool_matrix::numeric_conversion_function (void) const
 {
   return default_numeric_conversion_function;
 }
 
-octave_value *
+octave_base_value *
 octave_bool_matrix::try_narrowing_conversion (void)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   if (matrix.ndims () == 2)
     {
--- a/src/ov-bool-mat.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-bool-mat.h	Thu Apr 13 13:04:33 2006 +0000
@@ -67,12 +67,12 @@
 
   ~octave_bool_matrix (void) { }
 
-  octave_value *clone (void) const { return new octave_bool_matrix (*this); }
-  octave_value *empty_clone (void) const { return new octave_bool_matrix (); }
+  octave_base_value *clone (void) const { return new octave_bool_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_bool_matrix (); }
 
   type_conv_fcn numeric_conversion_function (void) const;
 
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 
   idx_vector index_vector (void) const { return idx_vector (matrix); }
 
--- a/src/ov-bool-sparse.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-bool-sparse.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -49,24 +49,24 @@
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_bool_matrix, "sparse bool matrix", "sparse");
 
-static octave_value *
-default_numeric_conversion_function (const octave_value& a)
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
 {
   CAST_CONV_ARG (const octave_sparse_bool_matrix&);
 
   return new octave_sparse_matrix (SparseMatrix (v.sparse_bool_matrix_value ()));
 }
 
-type_conv_fcn
+octave_base_value::type_conv_fcn
 octave_sparse_bool_matrix::numeric_conversion_function (void) const
 {
   return default_numeric_conversion_function;
 }
 
-octave_value *
+octave_base_value *
 octave_sparse_bool_matrix::try_narrowing_conversion (void)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   // Don't use numel, since it can overflow for very large matrices
   // Note that for the second test, this means it becomes approximative
--- a/src/ov-bool-sparse.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-bool-sparse.h	Thu Apr 13 13:04:33 2006 +0000
@@ -76,12 +76,12 @@
 
   ~octave_sparse_bool_matrix (void) { }
 
-  octave_value *clone (void) const { return new octave_sparse_bool_matrix (*this); }
-  octave_value *empty_clone (void) const { return new octave_sparse_bool_matrix (); }
+  octave_base_value *clone (void) const { return new octave_sparse_bool_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_sparse_bool_matrix (); }
 
   type_conv_fcn numeric_conversion_function (void) const;
 
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 
   // XXX FIXME XXX Adapt idx_vector to allow sparse logical indexing!!
   idx_vector index_vector (void) const 
--- a/src/ov-bool.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-bool.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -50,15 +50,15 @@
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_bool, "bool", "logical");
 
-static octave_value *
-default_numeric_conversion_function (const octave_value& a)
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
 {
   CAST_CONV_ARG (const octave_bool&);
 
   return new octave_scalar (v.bool_value ());
 }
 
-type_conv_fcn
+octave_base_value::type_conv_fcn
 octave_bool::numeric_conversion_function (void) const
 {
   return default_numeric_conversion_function;
--- a/src/ov-bool.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-bool.h	Thu Apr 13 13:04:33 2006 +0000
@@ -62,8 +62,8 @@
 
   ~octave_bool (void) { }
 
-  octave_value *clone (void) const { return new octave_bool (*this); }
-  octave_value *empty_clone (void) const { return new octave_bool (); }
+  octave_base_value *clone (void) const { return new octave_bool (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_bool (); }
 
   type_conv_fcn numeric_conversion_function (void) const;
 
--- a/src/ov-cell.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-cell.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -213,7 +213,8 @@
 	      else
 		octave_base_matrix<Cell>::assign (i, Cell (t_rhs));
 
-	    retval = octave_value (this, count + 1);
+	    count++;
+	    retval = octave_value (this);
 	  }
 	  break;
 
@@ -223,7 +224,8 @@
 
 	    octave_base_matrix<Cell>::assign (i, Cell (t_rhs));
 
-	    retval = octave_value (this, count + 1);
+	    count++;
+	    retval = octave_value (this);
 	  }
 	  break;
 
@@ -514,7 +516,7 @@
 
 		  // recurse to read cell elements
 		  std::string nm = read_ascii_data (is, std::string (), 
-						    dummy, t2, count);
+						    dummy, t2, i);
 
 		  if (nm == CELL_ELT_TAG)
 		    {
@@ -563,7 +565,7 @@
 
 			  // recurse to read cell elements
 			  std::string nm = read_ascii_data (is, std::string (),
-							    dummy, t2, count);
+							    dummy, t2, i);
 
 			  if (nm == CELL_ELT_TAG)
 			    {
--- a/src/ov-cell.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-cell.h	Thu Apr 13 13:04:33 2006 +0000
@@ -63,11 +63,11 @@
 
   void assign (const octave_value_list& idx, const octave_value& rhs);
 
-  octave_value *clone (void) const { return new octave_cell (*this); }
-  octave_value *empty_clone (void) const { return new octave_cell (); }
+  octave_base_value *clone (void) const { return new octave_cell (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_cell (); }
 
 #if 0
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 #endif
 
   octave_value subsref (const std::string&,
--- a/src/ov-ch-mat.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-ch-mat.h	Thu Apr 13 13:04:33 2006 +0000
@@ -77,8 +77,8 @@
 
   ~octave_char_matrix (void) { }
 
-  octave_value *clone (void) const { return new octave_char_matrix (*this); }
-  octave_value *empty_clone (void) const { return new octave_char_matrix (); }
+  octave_base_value *clone (void) const { return new octave_char_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_char_matrix (); }
 
   idx_vector index_vector (void) const
     { return idx_vector (array_value (true)); }
--- a/src/ov-colon.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-colon.h	Thu Apr 13 13:04:33 2006 +0000
@@ -56,8 +56,8 @@
 
   ~octave_magic_colon (void) { }
 
-  octave_value *clone (void) const { return new octave_magic_colon (*this); }
-  octave_value *empty_clone (void) const { return new octave_magic_colon (); }
+  octave_base_value *clone (void) const { return new octave_magic_colon (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_magic_colon (); }
 
   idx_vector index_vector (void) const { return idx_vector (':'); }
 
--- a/src/ov-complex.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-complex.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -51,10 +51,10 @@
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex,
 				     "complex scalar", "double");
 
-octave_value *
+octave_base_value *
 octave_complex::try_narrowing_conversion (void)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   double im = std::imag (scalar);
 
--- a/src/ov-complex.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-complex.h	Thu Apr 13 13:04:33 2006 +0000
@@ -64,16 +64,16 @@
 
   ~octave_complex (void) { }
 
-  octave_value *clone (void) const { return new octave_complex (*this); }
+  octave_base_value *clone (void) const { return new octave_complex (*this); }
 
   // We return an octave_complex_matrix object here instead of an
   // octave_complex object so that in expressions like A(2,2,2) = 2
   // (for A previously undefined), A will be empty instead of a 1x1
   // object.
-  octave_value *empty_clone (void) const
+  octave_base_value *empty_clone (void) const
     { return new octave_complex_matrix (); }
 
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 
   octave_value do_index_op (const octave_value_list& idx, int resize_ok);
 
--- a/src/ov-cs-list.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-cs-list.h	Thu Apr 13 13:04:33 2006 +0000
@@ -57,12 +57,12 @@
   octave_cs_list (const Cell& c);
 
   octave_cs_list (const octave_cs_list& l)
-    : octave_base_value (), lst (l) { }
+    : octave_base_value (), lst (l.lst) { }
 
   ~octave_cs_list (void) { }
 
-  octave_value *clone (void) const { return new octave_cs_list (*this); }
-  octave_value *empty_clone (void) const { return new octave_cs_list (); }
+  octave_base_value *clone (void) const { return new octave_cs_list (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_cs_list (); }
 
   dim_vector dims (void) const { return dim_vector (1, lst.length ()); }
 
--- a/src/ov-cx-mat.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-cx-mat.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -58,10 +58,10 @@
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex_matrix,
 				     "complex matrix", "double");
 
-octave_value *
+octave_base_value *
 octave_complex_matrix::try_narrowing_conversion (void)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   if (matrix.ndims () == 2)
     {
--- a/src/ov-cx-mat.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-cx-mat.h	Thu Apr 13 13:04:33 2006 +0000
@@ -77,10 +77,10 @@
 
   ~octave_complex_matrix (void) { }
 
-  octave_value *clone (void) const { return new octave_complex_matrix (*this); }
-  octave_value *empty_clone (void) const { return new octave_complex_matrix (); }
+  octave_base_value *clone (void) const { return new octave_complex_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_complex_matrix (); }
 
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 
   void assign (const octave_value_list& idx, const ComplexNDArray& rhs);
 
--- a/src/ov-cx-sparse.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-cx-sparse.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -48,10 +48,10 @@
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_complex_matrix, "sparse complex matrix", "sparse");
 
-octave_value *
+octave_base_value *
 octave_sparse_complex_matrix::try_narrowing_conversion (void)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   int nr = matrix.rows ();
   int nc = matrix.cols ();
--- a/src/ov-cx-sparse.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-cx-sparse.h	Thu Apr 13 13:04:33 2006 +0000
@@ -77,10 +77,10 @@
 
   ~octave_sparse_complex_matrix (void) { }
 
-  octave_value *clone (void) const { return new octave_sparse_complex_matrix (*this); }
-  octave_value *empty_clone (void) const { return new octave_sparse_complex_matrix (); }
+  octave_base_value *clone (void) const { return new octave_sparse_complex_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_sparse_complex_matrix (); }
 
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 
   void assign (const octave_value_list& idx, const SparseComplexMatrix& rhs);
 
--- a/src/ov-fcn-handle.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-fcn-handle.h	Thu Apr 13 13:04:33 2006 +0000
@@ -55,8 +55,8 @@
 
   ~octave_fcn_handle (void) { }
 
-  octave_value *clone (void) const { return new octave_fcn_handle (*this); }
-  octave_value *empty_clone (void) const { return new octave_fcn_handle (); }
+  octave_base_value *clone (void) const { return new octave_fcn_handle (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_fcn_handle (); }
 
   octave_value subsref (const std::string&,
 			const std::list<octave_value_list>&)
--- a/src/ov-fcn-inline.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-fcn-inline.h	Thu Apr 13 13:04:33 2006 +0000
@@ -52,8 +52,8 @@
 
   ~octave_fcn_inline (void) { }
 
-  octave_value *clone (void) const { return new octave_fcn_inline (*this); }
-  octave_value *empty_clone (void) const { return new octave_fcn_inline (); }
+  octave_base_value *clone (void) const { return new octave_fcn_inline (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_fcn_inline (); }
 
   bool is_inline_function (void) const { return true; }
 
--- a/src/ov-fcn.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-fcn.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -31,14 +31,14 @@
 
 DEFINE_OCTAVE_ALLOCATOR (octave_function);
 
-octave_value *
+octave_base_value *
 octave_function::clone (void) const
 {
   panic_impossible ();
   return 0;
 }
 
-octave_value *
+octave_base_value *
 octave_function::empty_clone (void) const
 {
   panic_impossible ();
--- a/src/ov-fcn.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-fcn.h	Thu Apr 13 13:04:33 2006 +0000
@@ -47,8 +47,8 @@
 
   ~octave_function (void) { }
 
-  octave_value *clone (void) const;
-  octave_value *empty_clone (void) const;
+  octave_base_value *clone (void) const;
+  octave_base_value *empty_clone (void) const;
 
   bool is_defined (void) const { return true; }
 
--- a/src/ov-intx.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-intx.h	Thu Apr 13 13:04:33 2006 +0000
@@ -52,10 +52,10 @@
 
   ~OCTAVE_VALUE_INT_MATRIX_T (void) { }
 
-  octave_value *clone (void) const
+  octave_base_value *clone (void) const
     { return new OCTAVE_VALUE_INT_MATRIX_T (*this); }
 
-  octave_value *empty_clone (void) const
+  octave_base_value *empty_clone (void) const
     { return new OCTAVE_VALUE_INT_MATRIX_T (); }
 
   int8NDArray
@@ -165,10 +165,10 @@
 
   ~OCTAVE_VALUE_INT_SCALAR_T (void) { }
 
-  octave_value *clone (void) const
+  octave_base_value *clone (void) const
     { return new OCTAVE_VALUE_INT_SCALAR_T (*this); }
 
-  octave_value *empty_clone (void) const
+  octave_base_value *empty_clone (void) const
     { return new OCTAVE_VALUE_INT_SCALAR_T (); }
 
   octave_value do_index_op (const octave_value_list& idx, int resize_ok)
--- a/src/ov-list.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-list.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -131,9 +131,9 @@
 
   if (idx.length () == 1)
     {
-      idx_vector i = idx (0).index_vector ();
+      idx_vector iidx = idx (0).index_vector ();
 
-      Cell tcell = data.index (i, resize_ok);
+      Cell tcell = data.index (iidx, resize_ok);
 
       octave_value_list result;
 
@@ -213,7 +213,8 @@
 
 	    ::assign (data, Cell (t_rhs), Cell::resize_fill_value ());
 
-	    retval = octave_value (this, count + 1);
+	    count++;
+	    retval = octave_value (this);
 	  }
 	  break;
 
--- a/src/ov-list.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-list.h	Thu Apr 13 13:04:33 2006 +0000
@@ -60,8 +60,8 @@
 
   ~octave_list (void) { }
 
-  octave_value *clone (void) const { return new octave_list (*this); }
-  octave_value *empty_clone (void) const { return new octave_list (); }
+  octave_base_value *clone (void) const { return new octave_list (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_list (); }
 
   octave_value subsref (const std::string&,
 			const std::list<octave_value_list>&)
--- a/src/ov-range.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-range.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -46,24 +46,24 @@
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_range, "range", "double");
 
-static octave_value *
-default_numeric_conversion_function (const octave_value& a)
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
 {
   CAST_CONV_ARG (const octave_range&);
 
   return new octave_matrix (v.matrix_value ());
 }
 
-type_conv_fcn
+octave_base_value::type_conv_fcn
 octave_range::numeric_conversion_function (void) const
 {
   return default_numeric_conversion_function;
 }
 
-octave_value *
+octave_base_value *
 octave_range::try_narrowing_conversion (void)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   switch (range.nelem ())
     {
--- a/src/ov-range.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-range.h	Thu Apr 13 13:04:33 2006 +0000
@@ -76,12 +76,12 @@
 
   ~octave_range (void) { }
 
-  octave_value *clone (void) const { return new octave_range (*this); }
-  octave_value *empty_clone (void) const { return new octave_range (); }
+  octave_base_value *clone (void) const { return new octave_range (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_range (); }
 
   type_conv_fcn numeric_conversion_function (void) const;
 
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 
   octave_value subsref (const std::string& type,
 			const std::list<octave_value_list>& idx);
--- a/src/ov-re-mat.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-re-mat.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -67,10 +67,10 @@
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_matrix, "matrix", "double");
 
-octave_value *
+octave_base_value *
 octave_matrix::try_narrowing_conversion (void)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   if (matrix.nelem () == 1)
     retval = new octave_scalar (matrix (0));
--- a/src/ov-re-mat.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-re-mat.h	Thu Apr 13 13:04:33 2006 +0000
@@ -78,10 +78,10 @@
 
   ~octave_matrix (void) { }
 
-  octave_value *clone (void) const { return new octave_matrix (*this); }
-  octave_value *empty_clone (void) const { return new octave_matrix (); }
+  octave_base_value *clone (void) const { return new octave_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_matrix (); }
 
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 
   idx_vector index_vector (void) const { return idx_vector (matrix); }
 
--- a/src/ov-re-sparse.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-re-sparse.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -61,10 +61,10 @@
     }
 }
 
-octave_value *
+octave_base_value *
 octave_sparse_matrix::try_narrowing_conversion (void)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   // Don't use numel, since it can overflow for very large matrices
   // Note that for the second test, this means it becomes approximative
--- a/src/ov-re-sparse.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-re-sparse.h	Thu Apr 13 13:04:33 2006 +0000
@@ -77,10 +77,10 @@
 
   ~octave_sparse_matrix (void) { }
 
-  octave_value *clone (void) const { return new octave_sparse_matrix (*this); }
-  octave_value *empty_clone (void) const { return new octave_sparse_matrix (); }
+  octave_base_value *clone (void) const { return new octave_sparse_matrix (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_sparse_matrix (); }
 
-  octave_value *try_narrowing_conversion (void);
+  octave_base_value *try_narrowing_conversion (void);
 
   idx_vector index_vector (void) const;
 
--- a/src/ov-scalar.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-scalar.h	Thu Apr 13 13:04:33 2006 +0000
@@ -64,12 +64,12 @@
 
   ~octave_scalar (void) { }
 
-  octave_value *clone (void) const { return new octave_scalar (*this); }
+  octave_base_value *clone (void) const { return new octave_scalar (*this); }
 
   // We return an octave_matrix here instead of an octave_scalar so
   // that in expressions like A(2,2,2) = 2 (for A previously
   // undefined), A will be empty instead of a 1x1 object.
-  octave_value *empty_clone (void) const { return new octave_matrix (); }
+  octave_base_value *empty_clone (void) const { return new octave_matrix (); }
 
   octave_value do_index_op (const octave_value_list& idx, int resize_ok);
 
--- a/src/ov-str-mat.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-str-mat.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -60,12 +60,12 @@
 //   octave> 'abc' + 0
 //   97 98 99
 //
-static bool Vwarn_str_to_num;
+static int Vwarn_str_to_num;
 
-static octave_value *
-default_numeric_conversion_function (const octave_value& a)
+static octave_base_value *
+default_numeric_conversion_function (const octave_base_value& a)
 {
-  octave_value *retval = 0;
+  octave_base_value *retval = 0;
 
   CAST_CONV_ARG (const octave_char_matrix_str&);
 
@@ -82,7 +82,7 @@
   return retval;
 }
 
-type_conv_fcn
+octave_base_value::type_conv_fcn
 octave_char_matrix_str::numeric_conversion_function (void) const
 {
   return default_numeric_conversion_function;
@@ -792,7 +792,6 @@
 @end defvr");
 }
 
-
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/ov-str-mat.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-str-mat.h	Thu Apr 13 13:04:33 2006 +0000
@@ -80,8 +80,8 @@
 
   ~octave_char_matrix_str (void) { }
 
-  octave_value *clone (void) const { return new octave_char_matrix_str (*this); }
-  octave_value *empty_clone (void) const { return new octave_char_matrix_str (); }
+  octave_base_value *clone (void) const { return new octave_char_matrix_str (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_char_matrix_str (); }
 
   type_conv_fcn numeric_conversion_function (void) const;
 
@@ -197,8 +197,8 @@
 
   ~octave_char_matrix_sq_str (void) { }
 
-  octave_value *clone (void) const { return new octave_char_matrix_sq_str (*this); }
-  octave_value *empty_clone (void) const { return new octave_char_matrix_sq_str (); }
+  octave_base_value *clone (void) const { return new octave_char_matrix_sq_str (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_char_matrix_sq_str (); }
 
   octave_value reshape (const dim_vector& new_dims) const
     { return octave_value (charNDArray (matrix.reshape (new_dims)), true, '\''); }
--- a/src/ov-streamoff.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-streamoff.h	Thu Apr 13 13:04:33 2006 +0000
@@ -57,8 +57,8 @@
 
   ~octave_streamoff (void) { }
 
-  octave_value *clone (void) const { return new octave_streamoff (*this); }
-  octave_value *empty_clone (void) const { return new octave_streamoff (); }
+  octave_base_value *clone (void) const { return new octave_streamoff (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_streamoff (); }
 
   bool is_defined (void) const { return true; }
 
--- a/src/ov-struct.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-struct.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -44,14 +44,12 @@
 #include "ls-oct-binary.h"
 #include "ls-hdf5.h"
 #include "ls-utils.h"
+#include "pr-output.h"
 
 DEFINE_OCTAVE_ALLOCATOR(octave_struct);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_struct, "struct", "struct");
 
-// How many levels of structure elements should we print?
-static int Vstruct_levels_to_print;
-
 Cell
 octave_struct::dotref (const octave_value_list& idx)
 {
@@ -304,7 +302,10 @@
 		    map.assign (idx.front (), key, t_rhs);
 
 		    if (! error_state)
-		      retval = octave_value (this, count + 1);
+		      {
+			count++;
+			retval = octave_value (this);
+		      }
 		    else
 		      gripe_failed_assignment ();
 		  }
@@ -322,7 +323,10 @@
 			map.assign (idx.front (), rhs_map);
 
 			if (! error_state)
-			  retval = octave_value (this, count + 1);
+			  {
+			    count++;
+			    retval = octave_value (this);
+			  }
 			else
 			  gripe_failed_assignment ();
 		      }
@@ -336,7 +340,10 @@
 			map.maybe_delete_elements (idx.front());
 
 			if (! error_state)
-			  retval = octave_value (this, count + 1);
+			  {
+			    count++;
+			    retval = octave_value (this);
+			  }
 			else
 			  gripe_failed_assignment ();
 		      }
@@ -358,7 +365,10 @@
 	    map.assign (key, t_rhs);
 
 	    if (! error_state)
-	      retval = octave_value (this, count + 1);
+	      {
+		count++;
+		retval = octave_value (this);
+	      }
 	    else
 	      gripe_failed_assignment ();
 	  }
@@ -1266,35 +1276,6 @@
 
 #endif
 
-static int
-struct_levels_to_print (void)
-{
-  double val;
-  if (builtin_real_scalar_variable ("struct_levels_to_print", val)
-      && ! xisnan (val))
-    {
-      int ival = NINT (val);
-      if (ival == val)
-	{
-	  Vstruct_levels_to_print = ival;
-	  return 0;
-	}
-    }
-  gripe_invalid_value_specified ("struct_levels_to_print");
-  return -1;
-}
-
-void
-symbols_of_ov_struct (void)
-{
-  DEFVAR (struct_levels_to_print, 2.0, struct_levels_to_print,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} struct_levels_to_print\n\
-You can tell Octave how many structure levels to display by setting the\n\
-built-in variable @code{struct_levels_to_print}.  The default value is 2.\n\
-@end defvr");
-}
-
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/ov-struct.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-struct.h	Thu Apr 13 13:04:33 2006 +0000
@@ -61,8 +61,8 @@
 
   ~octave_struct (void) { }
 
-  octave_value *clone (void) const { return new octave_struct (*this); }
-  octave_value *empty_clone (void) const { return new octave_struct (); }
+  octave_base_value *clone (void) const { return new octave_struct (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_struct (); }
 
   Cell dotref (const octave_value_list& idx);
 
--- a/src/ov-type-conv.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-type-conv.h	Thu Apr 13 13:04:33 2006 +0000
@@ -41,12 +41,12 @@
 	} \
       else \
         { \
-          type_conv_fcn cf \
+          octave_base_value::type_conv_fcn cf \
 	    = octave_value_typeinfo::lookup_type_conv_op (t_arg, t_result); \
  \
           if (cf) \
 	    { \
-	      octave_value *tmp (cf (*(arg.internal_rep ()))); \
+	      octave_base_value *tmp (cf (*(arg.internal_rep ()))); \
  \
 	      if (tmp) \
 		{ \
--- a/src/ov-typeinfo.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-typeinfo.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -43,25 +43,25 @@
 
 #include <Array.cc>
 
-INSTANTIATE_ARRAY (unary_op_fcn);
-template class Array2<unary_op_fcn>;
+INSTANTIATE_ARRAY (octave_value_typeinfo::unary_op_fcn);
+template class Array2<octave_value_typeinfo::unary_op_fcn>;
 
-INSTANTIATE_ARRAY (non_const_unary_op_fcn);
-template class Array2<non_const_unary_op_fcn>;
+INSTANTIATE_ARRAY (octave_value_typeinfo::non_const_unary_op_fcn);
+template class Array2<octave_value_typeinfo::non_const_unary_op_fcn>;
 
-INSTANTIATE_ARRAY (binary_op_fcn);
-template class Array2<binary_op_fcn>;
-template class Array3<binary_op_fcn>;
+INSTANTIATE_ARRAY (octave_value_typeinfo::binary_op_fcn);
+template class Array2<octave_value_typeinfo::binary_op_fcn>;
+template class Array3<octave_value_typeinfo::binary_op_fcn>;
 
-INSTANTIATE_ARRAY (cat_op_fcn);
-template class Array2<cat_op_fcn>;
+INSTANTIATE_ARRAY (octave_value_typeinfo::cat_op_fcn);
+template class Array2<octave_value_typeinfo::cat_op_fcn>;
 
-INSTANTIATE_ARRAY (assign_op_fcn);
-template class Array2<assign_op_fcn>;
-template class Array3<assign_op_fcn>;
+INSTANTIATE_ARRAY (octave_value_typeinfo::assign_op_fcn);
+template class Array2<octave_value_typeinfo::assign_op_fcn>;
+template class Array3<octave_value_typeinfo::assign_op_fcn>;
 
-INSTANTIATE_ARRAY (type_conv_fcn);
-template class Array2<type_conv_fcn>;
+INSTANTIATE_ARRAY (octave_base_value::type_conv_fcn);
+template class Array2<octave_base_value::type_conv_fcn>;
 
 bool
 octave_value_typeinfo::instance_ok (void)
@@ -91,7 +91,7 @@
 
 bool
 octave_value_typeinfo::register_unary_op (octave_value::unary_op op,
-					   int t, unary_op_fcn f)
+					   int t, octave_value_typeinfo::unary_op_fcn f)
 {
   return (instance_ok ())
     ? instance->do_register_unary_op (op, t, f) : false;
@@ -100,7 +100,7 @@
 bool
 octave_value_typeinfo::register_non_const_unary_op (octave_value::unary_op op,
 						    int t,
-						    non_const_unary_op_fcn f)
+						    octave_value_typeinfo::non_const_unary_op_fcn f)
 {
   return (instance_ok ())
     ? instance->do_register_non_const_unary_op (op, t, f) : false;
@@ -109,14 +109,14 @@
 bool
 octave_value_typeinfo::register_binary_op (octave_value::binary_op op,
 					   int t1, int t2,
-					   binary_op_fcn f)
+					   octave_value_typeinfo::binary_op_fcn f)
 {
   return (instance_ok ())
     ? instance->do_register_binary_op (op, t1, t2, f) : false;
 }
 
 bool
-octave_value_typeinfo::register_cat_op (int t1, int t2, cat_op_fcn f)
+octave_value_typeinfo::register_cat_op (int t1, int t2, octave_value_typeinfo::cat_op_fcn f)
 {
   return (instance_ok ())
     ? instance->do_register_cat_op (t1, t2, f) : false;
@@ -125,7 +125,7 @@
 bool
 octave_value_typeinfo::register_assign_op (octave_value::assign_op op,
 					   int t_lhs, int t_rhs,
-					   assign_op_fcn f)
+					   octave_value_typeinfo::assign_op_fcn f)
 {
   return (instance_ok ())
     ? instance->do_register_assign_op (op, t_lhs, t_rhs, f) : -1;
@@ -133,7 +133,7 @@
 
 bool
 octave_value_typeinfo::register_assignany_op (octave_value::assign_op op,
-					       int t_lhs, assign_op_fcn f)
+					      int t_lhs, octave_value_typeinfo::assignany_op_fcn f)
 {
   return (instance_ok ())
     ? instance->do_register_assignany_op (op, t_lhs, f) : -1;
@@ -149,7 +149,7 @@
 
 bool
 octave_value_typeinfo::register_type_conv_op (int t, int t_result,
-					      type_conv_fcn f)
+					      octave_base_value::type_conv_fcn f)
 {
   return (instance_ok ())
     ? instance->do_register_type_conv_op (t, t_result, f) : false;
@@ -157,7 +157,7 @@
 
 bool
 octave_value_typeinfo::register_widening_op (int t, int t_result,
-					     type_conv_fcn f)
+					     octave_base_value::type_conv_fcn f)
 {
   return (instance_ok ())
     ? instance->do_register_widening_op (t, t_result, f) : false;
@@ -188,28 +188,28 @@
       vals.resize (len, octave_value ());
 
       unary_ops.resize (static_cast<int> (octave_value::num_unary_ops),
-			len, static_cast<unary_op_fcn> (0));
+			len, static_cast<octave_value_typeinfo::unary_op_fcn> (0));
 
       non_const_unary_ops.resize
 	(static_cast<int> (octave_value::num_unary_ops),
-	 len, static_cast<non_const_unary_op_fcn> (0));
+	 len, static_cast<octave_value_typeinfo::non_const_unary_op_fcn> (0));
 
       binary_ops.resize (static_cast<int> (octave_value::num_binary_ops),
-			 len, len, static_cast<binary_op_fcn> (0));
+			 len, len, static_cast<octave_value_typeinfo::binary_op_fcn> (0));
 
-      cat_ops.resize (len, len, static_cast<cat_op_fcn> (0));
+      cat_ops.resize (len, len, static_cast<octave_value_typeinfo::cat_op_fcn> (0));
 
       assign_ops.resize (static_cast<int> (octave_value::num_assign_ops),
-			 len, len, static_cast<assign_op_fcn> (0));
+			 len, len, static_cast<octave_value_typeinfo::assign_op_fcn> (0));
 
       assignany_ops.resize (static_cast<int> (octave_value::num_assign_ops),
-			    len, static_cast<assign_op_fcn> (0));
+			    len, static_cast<octave_value_typeinfo::assignany_op_fcn> (0));
 
       pref_assign_conv.resize (len, len, -1);
 
-      type_conv_ops.resize (len, len, static_cast<type_conv_fcn> (0));
+      type_conv_ops.resize (len, len, static_cast<octave_base_value::type_conv_fcn> (0));
 
-      widening_ops.resize (len, len, static_cast<type_conv_fcn> (0));
+      widening_ops.resize (len, len, static_cast<octave_base_value::type_conv_fcn> (0));
     }
 
   types (i) = t_name;
@@ -223,7 +223,7 @@
 
 bool
 octave_value_typeinfo::do_register_unary_op (octave_value::unary_op op,
-					     int t, unary_op_fcn f)
+					     int t, octave_value_typeinfo::unary_op_fcn f)
 {
   if (lookup_unary_op (op, t))
     {
@@ -241,7 +241,7 @@
 
 bool
 octave_value_typeinfo::do_register_non_const_unary_op
-  (octave_value::unary_op op, int t, non_const_unary_op_fcn f)
+  (octave_value::unary_op op, int t, octave_value_typeinfo::non_const_unary_op_fcn f)
 {
   if (lookup_non_const_unary_op (op, t))
     {
@@ -260,7 +260,7 @@
 bool
 octave_value_typeinfo::do_register_binary_op (octave_value::binary_op op,
 					      int t1, int t2,
-					      binary_op_fcn f)
+					      octave_value_typeinfo::binary_op_fcn f)
 {
   if (lookup_binary_op (op, t1, t2))
     {
@@ -278,7 +278,7 @@
 }
 
 bool
-octave_value_typeinfo::do_register_cat_op (int t1, int t2, cat_op_fcn f)
+octave_value_typeinfo::do_register_cat_op (int t1, int t2, octave_value_typeinfo::cat_op_fcn f)
 {
   if (lookup_cat_op (t1, t2))
     {
@@ -297,7 +297,7 @@
 bool
 octave_value_typeinfo::do_register_assign_op (octave_value::assign_op op,
 					      int t_lhs, int t_rhs,
-					      assign_op_fcn f)
+					      octave_value_typeinfo::assign_op_fcn f)
 {
   if (lookup_assign_op (op, t_lhs, t_rhs))
     {
@@ -316,7 +316,7 @@
 
 bool
 octave_value_typeinfo::do_register_assignany_op (octave_value::assign_op op,
-						 int t_lhs, assign_op_fcn f)
+						 int t_lhs, octave_value_typeinfo::assignany_op_fcn f)
 {
   if (lookup_assignany_op (op, t_lhs))
     {
@@ -352,7 +352,7 @@
 
 bool
 octave_value_typeinfo::do_register_type_conv_op
-  (int t, int t_result, type_conv_fcn f)
+  (int t, int t_result, octave_base_value::type_conv_fcn f)
 {
   if (lookup_type_conv_op (t, t_result))
     {
@@ -370,7 +370,7 @@
 
 bool
 octave_value_typeinfo::do_register_widening_op
-  (int t, int t_result, type_conv_fcn f)
+  (int t, int t_result, octave_base_value::type_conv_fcn f)
 {
   if (lookup_widening_op (t, t_result))
     {
@@ -404,40 +404,40 @@
   return retval;
 }
 
-unary_op_fcn
+octave_value_typeinfo::unary_op_fcn
 octave_value_typeinfo::do_lookup_unary_op (octave_value::unary_op op, int t)
 {
   return unary_ops.checkelem (static_cast<int> (op), t);
 }
 
-non_const_unary_op_fcn
+octave_value_typeinfo::non_const_unary_op_fcn
 octave_value_typeinfo::do_lookup_non_const_unary_op
   (octave_value::unary_op op, int t)
 {
   return non_const_unary_ops.checkelem (static_cast<int> (op), t);
 }
 
-binary_op_fcn
+octave_value_typeinfo::binary_op_fcn
 octave_value_typeinfo::do_lookup_binary_op (octave_value::binary_op op,
 					    int t1, int t2)
 {
   return binary_ops.checkelem (static_cast<int> (op), t1, t2);
 }
 
-cat_op_fcn
+octave_value_typeinfo::cat_op_fcn
 octave_value_typeinfo::do_lookup_cat_op (int t1, int t2)
 {
   return cat_ops.checkelem (t1, t2);
 }
 
-assign_op_fcn
+octave_value_typeinfo::assign_op_fcn
 octave_value_typeinfo::do_lookup_assign_op (octave_value::assign_op op,
 					    int t_lhs, int t_rhs)
 {
   return assign_ops.checkelem (static_cast<int> (op), t_lhs, t_rhs);
 }
 
-assign_op_fcn
+octave_value_typeinfo::assignany_op_fcn
 octave_value_typeinfo::do_lookup_assignany_op (octave_value::assign_op op,
 					       int t_lhs)
 {
@@ -450,13 +450,13 @@
   return pref_assign_conv.checkelem (t_lhs, t_rhs);
 }
 
-type_conv_fcn
+octave_base_value::type_conv_fcn
 octave_value_typeinfo::do_lookup_type_conv_op (int t, int t_result)
 {
   return type_conv_ops.checkelem (t, t_result);
 }
 
-type_conv_fcn
+octave_base_value::type_conv_fcn
 octave_value_typeinfo::do_lookup_widening_op (int t, int t_result)
 {
   return widening_ops.checkelem (t, t_result);
--- a/src/ov-typeinfo.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-typeinfo.h	Thu Apr 13 13:04:33 2006 +0000
@@ -39,6 +39,22 @@
 {
 public:
 
+  typedef octave_value (*unary_op_fcn) (const octave_base_value&);
+
+  typedef void (*non_const_unary_op_fcn) (octave_base_value&);
+
+  typedef octave_value (*binary_op_fcn)
+    (const octave_base_value&, const octave_base_value&);
+
+  typedef octave_value (*cat_op_fcn)
+    (octave_base_value&, const octave_base_value&, const Array<int>& ra_idx);
+
+  typedef octave_value (*assign_op_fcn)
+    (octave_base_value&, const octave_value_list&, const octave_base_value&);
+
+  typedef octave_value (*assignany_op_fcn)
+    (octave_base_value&, const octave_value_list&, const octave_value&);
+
   static bool instance_ok (void);
 
   static int register_type (const std::string&, const std::string&,
@@ -58,13 +74,15 @@
 				  assign_op_fcn);
 
   static bool register_assignany_op (octave_value::assign_op, int,
-				     assign_op_fcn);
+				     assignany_op_fcn);
 
   static bool register_pref_assign_conv (int, int, int);
 
-  static bool register_type_conv_op (int, int, type_conv_fcn);
+  static bool
+  register_type_conv_op (int, int, octave_base_value::type_conv_fcn);
 
-  static bool register_widening_op (int, int, type_conv_fcn);
+  static bool
+  register_widening_op (int, int, octave_base_value::type_conv_fcn);
 
   static octave_value
   lookup_type (const std::string& nm)
@@ -102,7 +120,7 @@
     return instance->do_lookup_assign_op (op, t_lhs, t_rhs);
   }
 
-  static assign_op_fcn
+  static assignany_op_fcn
   lookup_assignany_op (octave_value::assign_op op, int t_lhs)
   {
     return instance->do_lookup_assignany_op (op, t_lhs);
@@ -114,13 +132,13 @@
     return instance->do_lookup_pref_assign_conv (t_lhs, t_rhs);
   }
 
-  static type_conv_fcn
+  static octave_base_value::type_conv_fcn
   lookup_type_conv_op (int t, int t_result)
   {
     return instance->do_lookup_type_conv_op (t, t_result);
   }
 
-  static type_conv_fcn
+  static octave_base_value::type_conv_fcn
   lookup_widening_op (int t, int t_result)
   {
     return instance->do_lookup_widening_op (t, t_result);
@@ -146,10 +164,10 @@
       assign_ops (octave_value::num_assign_ops, init_tab_sz,
 		  init_tab_sz, (assign_op_fcn) 0),
       assignany_ops (octave_value::num_assign_ops, init_tab_sz,
-		     (assign_op_fcn) 0),
+		     (assignany_op_fcn) 0),
       pref_assign_conv (init_tab_sz, init_tab_sz, -1),
-      type_conv_ops (init_tab_sz, init_tab_sz, (type_conv_fcn) 0),
-      widening_ops (init_tab_sz, init_tab_sz, (type_conv_fcn) 0)  { }
+      type_conv_ops (init_tab_sz, init_tab_sz, (octave_base_value::type_conv_fcn) 0),
+      widening_ops (init_tab_sz, init_tab_sz, (octave_base_value::type_conv_fcn) 0)  { }
 
 private:
 
@@ -173,13 +191,13 @@
 
   Array3<assign_op_fcn> assign_ops;
 
-  Array2<assign_op_fcn> assignany_ops;
+  Array2<assignany_op_fcn> assignany_ops;
 
   Array2<int> pref_assign_conv;
 
-  Array2<type_conv_fcn> type_conv_ops;
+  Array2<octave_base_value::type_conv_fcn> type_conv_ops;
 
-  Array2<type_conv_fcn> widening_ops;
+  Array2<octave_base_value::type_conv_fcn> widening_ops;
 
   int do_register_type (const std::string&, const std::string&,
 			const octave_value&);
@@ -198,13 +216,13 @@
 			      assign_op_fcn);
 
   bool do_register_assignany_op (octave_value::assign_op, int,
-				 assign_op_fcn);
+				 assignany_op_fcn);
 
   bool do_register_pref_assign_conv (int, int, int);
 
-  bool do_register_type_conv_op (int, int, type_conv_fcn);
+  bool do_register_type_conv_op (int, int, octave_base_value::type_conv_fcn);
 
-  bool do_register_widening_op (int, int, type_conv_fcn);
+  bool do_register_widening_op (int, int, octave_base_value::type_conv_fcn);
 
   octave_value do_lookup_type (const std::string& nm);
 
@@ -219,13 +237,13 @@
 
   assign_op_fcn do_lookup_assign_op (octave_value::assign_op, int, int);
 
-  assign_op_fcn do_lookup_assignany_op (octave_value::assign_op, int);
+  assignany_op_fcn do_lookup_assignany_op (octave_value::assign_op, int);
 
   int do_lookup_pref_assign_conv (int, int);
 
-  type_conv_fcn do_lookup_type_conv_op (int, int);
+  octave_base_value::type_conv_fcn do_lookup_type_conv_op (int, int);
 
-  type_conv_fcn do_lookup_widening_op (int, int);
+  octave_base_value::type_conv_fcn do_lookup_widening_op (int, int);
 
   string_vector do_installed_type_names (void);
 
--- a/src/ov-va-args.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov-va-args.h	Thu Apr 13 13:04:33 2006 +0000
@@ -56,8 +56,8 @@
 
   ~octave_all_va_args (void) { }
 
-  octave_value *clone (void) const { return new octave_all_va_args (*this); }
-  octave_value *empty_clone (void) const { return new octave_all_va_args (); }
+  octave_base_value *clone (void) const { return new octave_all_va_args (*this); }
+  octave_base_value *empty_clone (void) const { return new octave_all_va_args (); }
 
   bool is_defined (void) const { return true; }
 
--- a/src/ov.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -82,10 +82,6 @@
 // make the grow_size large.
 DEFINE_OCTAVE_ALLOCATOR2(octave_value, 1024);
 
-// If TRUE, turn off printing of results in functions (as if a
-// semicolon has been appended to each statement).
-static bool Vsilent_functions;
-
 // If TRUE, print a warning for assignments like
 //
 //   octave> A(1) = 3; A(2) = 5
@@ -96,17 +92,6 @@
 // Should we warn about conversions from complex to real?
 int Vwarn_imag_to_real;
 
-// Should we print a warning when converting `[97, 98, 99, "123"]'
-// to a character string?
-bool Vwarn_num_to_str;
-
-// If TRUE, print the name along with the value.
-bool Vprint_answer_id_name;
-
-// If TRUE, print a warning when a matrix is resized by an indexed
-// assignment with indices outside the current bounds.
-bool Vwarn_resize_on_range_error;
-
 // XXX FIXME XXX
 
 // Octave's value type.
@@ -325,60 +310,45 @@
   return retval;
 }
 
-octave_value *
-octave_value::nil_rep (void) const
+octave_value::octave_value (void)
+  : rep (new octave_base_value ())
 {
-  static octave_base_value *nr = new octave_base_value ();
-  return nr;
-}
-
-octave_value::octave_value (void)
-  : rep (nil_rep ())
-{
-  rep->count++;
 }
 
 octave_value::octave_value (short int i)
   : rep (new octave_scalar (i))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (unsigned short int i)
   : rep (new octave_scalar (i))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (int i)
   : rep (new octave_scalar (i))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (unsigned int i)
   : rep (new octave_scalar (i))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (long int i)
   : rep (new octave_scalar (i))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (unsigned long int i)
   : rep (new octave_scalar (i))
 {
-  rep->count = 1;
 }
 
 #if defined (HAVE_LONG_LONG_INT)
 octave_value::octave_value (long long int i)
   : rep (new octave_scalar (i))
 {
-  rep->count = 1;
 }
 #endif
 
@@ -386,146 +356,125 @@
 octave_value::octave_value (unsigned long long int i)
   : rep (new octave_scalar (i))
 {
-  rep->count = 1;
 }
 #endif
 
 octave_value::octave_value (octave_time t)
   : rep (new octave_scalar (t))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (double d)
   : rep (new octave_scalar (d))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (const Cell& c, bool is_csl)
   : rep (is_csl
-	 ? dynamic_cast<octave_value *> (new octave_cs_list (c))
-	 : dynamic_cast<octave_value *> (new octave_cell (c)))
+	 ? dynamic_cast<octave_base_value *> (new octave_cs_list (c))
+	 : dynamic_cast<octave_base_value *> (new octave_cell (c)))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (const ArrayN<octave_value>& a, bool is_csl)
   : rep (is_csl
-	 ? dynamic_cast<octave_value *> (new octave_cs_list (Cell (a)))
-	 : dynamic_cast<octave_value *> (new octave_cell (Cell (a))))
+	 ? dynamic_cast<octave_base_value *> (new octave_cs_list (Cell (a)))
+	 : dynamic_cast<octave_base_value *> (new octave_cell (Cell (a))))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (const Matrix& m)
   : rep (new octave_matrix (m))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const NDArray& a)
   : rep (new octave_matrix (a))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const ArrayN<double>& a)
   : rep (new octave_matrix (a))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const DiagMatrix& d)
   : rep (new octave_matrix (d))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const RowVector& v)
   : rep (new octave_matrix (v))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const ColumnVector& v)
   : rep (new octave_matrix (v))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const Complex& C)
   : rep (new octave_complex (C))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const ComplexMatrix& m)
   : rep (new octave_complex_matrix (m))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const ComplexNDArray& a)
   : rep (new octave_complex_matrix (a))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const ArrayN<Complex>& a)
   : rep (new octave_complex_matrix (a))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const ComplexDiagMatrix& d)
   : rep (new octave_complex_matrix (d))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const ComplexRowVector& v)
   : rep (new octave_complex_matrix (v))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const ComplexColumnVector& v)
   : rep (new octave_complex_matrix (v))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (bool b)
   : rep (new octave_bool (b))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (const boolMatrix& bm)
   : rep (new octave_bool_matrix (bm))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const boolNDArray& bnda)
   : rep (new octave_bool_matrix (bnda))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
@@ -534,7 +483,6 @@
 	 ? new octave_char_matrix_dq_str (c)
 	 : new octave_char_matrix_sq_str (c))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
@@ -543,7 +491,6 @@
 	 ? new octave_char_matrix_dq_str (s)
 	 : new octave_char_matrix_sq_str (s))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
@@ -552,7 +499,6 @@
 	 ? new octave_char_matrix_dq_str (s)
 	 : new octave_char_matrix_sq_str (s))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
@@ -561,7 +507,6 @@
 	 ? new octave_char_matrix_dq_str (s)
 	 : new octave_char_matrix_sq_str (s))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
@@ -572,7 +517,6 @@
 	    : new octave_char_matrix_sq_str (chm))
 	 : new octave_char_matrix (chm))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
@@ -583,7 +527,6 @@
 	    : new octave_char_matrix_sq_str (chm))
 	 : new octave_char_matrix (chm))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
@@ -594,213 +537,179 @@
 	    : new octave_char_matrix_sq_str (chm))
 	 : new octave_char_matrix (chm))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const SparseMatrix& m, const SparseType &t)
   : rep (new octave_sparse_matrix (m, t))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const SparseComplexMatrix& m, const SparseType &t)
   : rep (new octave_sparse_complex_matrix (m, t))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const SparseBoolMatrix& bm, const SparseType &t)
   : rep (new octave_sparse_bool_matrix (bm, t))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const octave_int8& i)
   : rep (new octave_int8_scalar (i))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const octave_uint8& i)
   : rep (new octave_uint8_scalar (i))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const octave_int16& i)
   : rep (new octave_int16_scalar (i))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const octave_uint16& i)
   : rep (new octave_uint16_scalar (i))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const octave_int32& i)
   : rep (new octave_int32_scalar (i))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const octave_uint32& i)
   : rep (new octave_uint32_scalar (i))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const octave_int64& i)
   : rep (new octave_int64_scalar (i))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const octave_uint64& i)
   : rep (new octave_uint64_scalar (i))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const int8NDArray& inda)
   : rep (new octave_int8_matrix (inda))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const uint8NDArray& inda)
   : rep (new octave_uint8_matrix (inda))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const int16NDArray& inda)
   : rep (new octave_int16_matrix (inda))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const uint16NDArray& inda)
   : rep (new octave_uint16_matrix (inda))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const int32NDArray& inda)
   : rep (new octave_int32_matrix (inda))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const uint32NDArray& inda)
   : rep (new octave_uint32_matrix (inda))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const int64NDArray& inda)
   : rep (new octave_int64_matrix (inda))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const uint64NDArray& inda)
   : rep (new octave_uint64_matrix (inda))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (double base, double limit, double inc)
   : rep (new octave_range (base, limit, inc))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const Range& r)
   : rep (new octave_range (r))
 {
-  rep->count = 1;
   maybe_mutate ();
 }
 
 octave_value::octave_value (const Octave_map& m)
   : rep (new octave_struct (m))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (const streamoff_array& off)
   : rep (new octave_streamoff (off))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (const octave_value_list& l, bool is_csl)
   : rep (is_csl
-	 ? dynamic_cast<octave_value *> (new octave_cs_list (l))
-	 : dynamic_cast<octave_value *> (new octave_list (l)))
+	 ? dynamic_cast<octave_base_value *> (new octave_cs_list (l))
+	 : dynamic_cast<octave_base_value *> (new octave_list (l)))
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (octave_value::magic_colon)
   : rep (new octave_magic_colon ())
 {
-  rep->count = 1;
 }
 
 octave_value::octave_value (octave_value::all_va_args)
   : rep (new octave_all_va_args ())
 {
-  rep->count = 1;
 }
 
-octave_value::octave_value (octave_value *new_rep, int cnt)
+octave_value::octave_value (octave_base_value *new_rep)
   : rep (new_rep)
 {
-  rep->count = cnt;
 }
 
 octave_value::~octave_value (void)
 {
 #if defined (MDEBUG)
-  if (rep)
-    std::cerr << "~octave_value: rep: " << rep
-	      << " rep->count: " << rep->count << std::endl;
-  else
-    std::cerr << "~octave_value: rep is 0!" << std::endl;
+  std::cerr << "~octave_value: rep: " << rep
+	    << " rep->count: " << rep->count << std::endl;
 #endif
 
-  if (rep && --rep->count == 0)
-    {
-      delete rep;
-      rep = 0;
-    }
+  if (--rep->count == 0)
+    delete rep;
 }
 
-octave_value *
+octave_base_value *
 octave_value::clone (void) const
 {
   panic_impossible ();
@@ -810,7 +719,7 @@
 void
 octave_value::maybe_mutate (void)
 {
-  octave_value *tmp = rep->try_narrowing_conversion ();
+  octave_base_value *tmp = rep->try_narrowing_conversion ();
 
   if (tmp && tmp != rep)
     {
@@ -818,7 +727,6 @@
 	delete rep;
 
       rep = tmp;
-      rep->count = 1;
     }    
 }
 
@@ -881,14 +789,6 @@
   return rep->do_multi_index_op (nargout, idx);
 }
 
-static void
-gripe_no_conversion (const std::string& on, const std::string& tn1,
-		     const std::string& tn2)
-{
-  error ("operator %s: no conversion for assignment of `%s' to indexed `%s'",
-	 on.c_str (), tn2.c_str (), tn1.c_str ());
-}
-
 #if 0
 static void
 gripe_assign_failed (const std::string& on, const std::string& tn1,
@@ -1000,22 +900,6 @@
 }
 
 octave_idx_type
-octave_value::rows (void) const
-{
-  dim_vector dv = dims ();
-
-  return (dv.length () > 0) ? dv(0) : -1;
-}
-
-octave_idx_type
-octave_value::columns (void) const
-{
-  dim_vector dv = dims ();
-
-  return (dv.length () > 1) ? dv(1) : -1;
-}
-
-octave_idx_type
 octave_value::length (void) const
 {
   int retval = 0;
@@ -1043,31 +927,6 @@
   return retval;
 }
 
-int
-octave_value::ndims (void) const
-{
-  dim_vector dv = dims ();
-
-  int n_dims = dv.length ();
-     
-   // Remove trailing singleton dimensions.
-
-   for (int i = n_dims; i > 2; i--)
-     {
-       if (dv(i-1) == 1)
-	 n_dims--;
-       else
-	 break;
-     }
-   
-   // The result is always >= 2.
-
-   if (n_dims < 2)
-     n_dims = 2;
-
-   return n_dims;
-}
-
 Matrix
 octave_value::size (void) const
 {
@@ -1447,51 +1306,6 @@
   return retval;
 }
 
-octave_value
-octave_value::convert_to_str (bool pad, bool force, char type) const
-{
-  octave_value retval = convert_to_str_internal (pad, force, type);
-
-  if (! force && is_numeric_type () && Vwarn_num_to_str)
-    gripe_implicit_conversion (type_name (), retval.type_name ());
-
-  return retval;
-}
-
-void
-octave_value::print_with_name (std::ostream& output_buf,
-			       const std::string& name, 
-			       bool print_padding) const
-{
-  if (! (evaluating_function_body && Vsilent_functions))
-    {
-      bool pad_after = false;
-
-      if (Vprint_answer_id_name)
-	pad_after = print_name_tag (output_buf, name);
-
-      print (output_buf);
-
-      if (print_padding && pad_after)
-	newline (output_buf);
-    }
-}
-
-static void
-gripe_indexed_assignment (const std::string& tn1, const std::string& tn2)
-{
-  error ("assignment of `%s' to indexed `%s' not implemented",
-	 tn2.c_str (), tn1.c_str ());
-}
-
-static void
-gripe_assign_conversion_failed (const std::string& tn1,
-				const std::string& tn2)
-{
-  error ("type conversion for assignment of `%s' to indexed `%s' failed",
-	 tn2.c_str (), tn1.c_str ());
-}
-
 int
 octave_value::write (octave_stream& os, int block_size,
 		     oct_data_conv::data_type output_type, int skip,
@@ -1500,117 +1314,6 @@
   return rep->write (os, block_size, output_type, skip, flt_fmt);
 }
 
-octave_value
-octave_value::numeric_assign (const std::string& type,
-			      const std::list<octave_value_list>& idx,
-			      const octave_value& rhs)
-{
-  octave_value retval;
-
-  int t_lhs = type_id ();
-  int t_rhs = rhs.type_id ();
-
-  assign_op_fcn f
-    = octave_value_typeinfo::lookup_assign_op (op_asn_eq, t_lhs, t_rhs);
-
-  bool done = false;
-
-  if (f)
-    {
-      f (*this, idx.front (), rhs.get_rep ());
-
-      done = (! error_state);
-    }
-
-  if (done)
-    retval = octave_value (this, count + 1);
-  else
-    {
-      int t_result
-	= octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs);
-
-      if (t_result >= 0)
-	{
-	  type_conv_fcn cf
-	    = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result);
-
-	  if (cf)
-	    {
-	      octave_value *tmp (cf (*this));
-
-	      if (tmp)
-		{
-		  retval = tmp->subsasgn (type, idx, rhs);
-
-		  done = (! error_state);
-		}
-	      else
-		gripe_assign_conversion_failed (type_name (),
-						rhs.type_name ());
-	    }
-	  else
-	    gripe_indexed_assignment (type_name (), rhs.type_name ());
-	}
-
-      if (! (done || error_state))
-	{
-	  octave_value tmp_rhs;
-	  type_conv_fcn cf_rhs = rhs.numeric_conversion_function ();
-
-	  if (cf_rhs)
-	    {
-	      octave_value *tmp = cf_rhs (rhs.get_rep ());
-
-	      if (tmp)
-		tmp_rhs = octave_value (tmp);
-	      else
-		{
-		  gripe_assign_conversion_failed (type_name (),
-						  rhs.type_name ());
-		  return octave_value ();
-		}
-	    }
-	  else
-	    tmp_rhs = rhs;
-
-	  type_conv_fcn cf_this = numeric_conversion_function ();
-
-	  octave_value *tmp_lhs = this;
-
-	  if (cf_this)
-	    {
-	      octave_value *tmp = cf_this (*this);
-
-	      if (tmp)
-		tmp_lhs = tmp;
-	      else
-		{
-		  gripe_assign_conversion_failed (type_name (),
-						  rhs.type_name ());
-		  return octave_value ();
-		}
-	    }
-
-	  if (cf_this || cf_rhs)
-	    {
-	      retval = tmp_lhs->subsasgn (type, idx, tmp_rhs);
-
-	      done = (! error_state);
-	    }
-	  else
-	    gripe_no_conversion (assign_op_as_string (op_asn_eq),
-				 type_name (), rhs.type_name ());
-	}
-    }
-
-  // The assignment may have converted to a type that is wider than
-  // necessary.
-
-  retval.maybe_mutate ();
-
-  return retval;
-}
-
 static void
 gripe_binary_op (const std::string& on, const std::string& tn1,
 		 const std::string& tn2)
@@ -1634,18 +1337,19 @@
   int t1 = v1.type_id ();
   int t2 = v2.type_id ();
 
-  binary_op_fcn f = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
+  octave_value_typeinfo::binary_op_fcn f
+    = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
 
   if (f)
     retval = f (*v1.rep, *v2.rep);
   else
     {
       octave_value tv1;
-      type_conv_fcn cf1 = v1.numeric_conversion_function ();
+      octave_base_value::type_conv_fcn cf1 = v1.numeric_conversion_function ();
 
       if (cf1)
 	{
-	  octave_value *tmp = cf1 (*v1.rep);
+	  octave_base_value *tmp = cf1 (*v1.rep);
 
 	  if (tmp)
 	    {
@@ -1662,11 +1366,11 @@
 	tv1 = v1;
 
       octave_value tv2;
-      type_conv_fcn cf2 = v2.numeric_conversion_function ();
+      octave_base_value::type_conv_fcn cf2 = v2.numeric_conversion_function ();
 
       if (cf2)
 	{
-	  octave_value *tmp = cf2 (*v2.rep);
+	  octave_base_value *tmp = cf2 (*v2.rep);
 
 	  if (tmp)
 	    {
@@ -1729,18 +1433,19 @@
   int t1 = v1.type_id ();
   int t2 = v2.type_id ();
 
-  cat_op_fcn f = octave_value_typeinfo::lookup_cat_op (t1, t2);
+  octave_value_typeinfo::cat_op_fcn f
+    = octave_value_typeinfo::lookup_cat_op (t1, t2);
 
   if (f)
     retval = f (*v1.rep, *v2.rep, ra_idx);
   else
     {
       octave_value tv1;
-      type_conv_fcn cf1 = v1.numeric_conversion_function ();
+      octave_base_value::type_conv_fcn cf1 = v1.numeric_conversion_function ();
 
       if (cf1)
 	{
-	  octave_value *tmp = cf1 (*v1.rep);
+	  octave_base_value *tmp = cf1 (*v1.rep);
 
 	  if (tmp)
 	    {
@@ -1757,11 +1462,11 @@
 	tv1 = v1;
 
       octave_value tv2;
-      type_conv_fcn cf2 = v2.numeric_conversion_function ();
+      octave_base_value::type_conv_fcn cf2 = v2.numeric_conversion_function ();
 
       if (cf2)
 	{
-	  octave_value *tmp = cf2 (*v2.rep);
+	  octave_base_value *tmp = cf2 (*v2.rep);
 
 	  if (tmp)
 	    {
@@ -1823,18 +1528,19 @@
 
   int t = v.type_id ();
 
-  unary_op_fcn f = octave_value_typeinfo::lookup_unary_op (op, t);
+  octave_value_typeinfo::unary_op_fcn f
+    = octave_value_typeinfo::lookup_unary_op (op, t);
 
   if (f)
     retval = f (*v.rep);
   else
     {
       octave_value tv;
-      type_conv_fcn cf = v.numeric_conversion_function ();
+      octave_base_value::type_conv_fcn cf = v.numeric_conversion_function ();
 
       if (cf)
 	{
-	  octave_value *tmp = cf (*v.rep);
+	  octave_base_value *tmp = cf (*v.rep);
 
 	  if (tmp)
 	    {
@@ -1875,7 +1581,7 @@
 
   int t = type_id ();
 
-  non_const_unary_op_fcn f
+  octave_value_typeinfo::non_const_unary_op_fcn f
     = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
 
   if (f)
@@ -1886,17 +1592,16 @@
     }
   else
     {
-      type_conv_fcn cf = numeric_conversion_function ();
+      octave_base_value::type_conv_fcn cf = numeric_conversion_function ();
 
       if (cf)
 	{
-	  octave_value *tmp = cf (*rep);
+	  octave_base_value *tmp = cf (*rep);
 
 	  if (tmp)
 	    {
-	      octave_value *old_rep = rep;
+	      octave_base_value *old_rep = rep;
 	      rep = tmp;
-	      rep->count = 1;
 
 	      t = type_id ();
 
@@ -1976,52 +1681,6 @@
   return retval;
 }
 
-// Current indentation.
-int octave_value::curr_print_indent_level = 0;
-
-// TRUE means we are at the beginning of a line.
-bool octave_value::beginning_of_line = true;
-
-// Each print() function should call this before printing anything.
-//
-// This doesn't need to be fast, but isn't there a better way?
-
-void
-octave_value::indent (std::ostream& os) const
-{
-  assert (curr_print_indent_level >= 0);
- 
-  if (beginning_of_line)
-    {
-      // XXX FIXME XXX -- do we need this?
-      // os << prefix;
-
-      for (int i = 0; i < curr_print_indent_level; i++)
-	os << " ";
-
-      beginning_of_line = false;
-    }
-}
-
-// All print() functions should use this to print new lines.
-
-void
-octave_value::newline (std::ostream& os) const
-{
-  os << "\n";
-
-  beginning_of_line = true;
-}
-
-// For ressetting print state.
-
-void
-octave_value::reset (void) const
-{
-  beginning_of_line = true;
-  curr_print_indent_level = 0;
-}
-
 octave_value::assign_op
 octave_value::unary_op_to_assign_op (unary_op op)
 {
@@ -2257,73 +1916,9 @@
   return 0;
 }
 
-static int
-warn_num_to_str (void)
-{
-  Vwarn_num_to_str = check_preference ("warn_num_to_str");
-
-  return 0;
-}
-
-static int
-print_answer_id_name (void)
-{
-  Vprint_answer_id_name = check_preference ("print_answer_id_name");
-
-  return 0;
-}
-
-static int
-warn_resize_on_range_error (void)
-{
-  Vwarn_resize_on_range_error
-    = check_preference ("warn_resize_on_range_error");
-
-  liboctave_wrore_flag = Vwarn_resize_on_range_error;
-
-  return 0;
-}
-
-static int
-silent_functions (void)
-{
-  Vsilent_functions = check_preference ("silent_functions");
-
-  return 0;
-}
-
 void
 symbols_of_ov (void)
 {
-  DEFVAR (print_answer_id_name, true, print_answer_id_name,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} print_answer_id_name\n\
-If the value of @code{print_answer_id_name} is nonzero, variable\n\
-names are printed along with the result.  Otherwise, only the result\n\
-values are printed.  The default value is 1.\n\
-@end defvr");
-
-  DEFVAR (silent_functions, false, silent_functions,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} silent_functions\n\
-If the value of @code{silent_functions} is nonzero, internal output\n\
-from a function is suppressed.  Otherwise, the results of expressions\n\
-within a function body that are not terminated with a semicolon will\n\
-have their values printed.  The default value is 0.\n\
-\n\
-For example, if the function\n\
-\n\
-@example\n\
-function f ()\n\
-  2 + 2\n\
-endfunction\n\
-@end example\n\
-\n\
-@noindent\n\
-is executed, Octave will either print @samp{ans = 4} or nothing\n\
-depending on the value of @code{silent_functions}.\n\
-@end defvr");
-
   DEFVAR (warn_fortran_indexing, false, warn_fortran_indexing,
     "-*- texinfo -*-\n\
 @defvr {Built-in Variable} warn_fortran_indexing\n\
@@ -2339,33 +1934,6 @@
 printed for implicit conversions of complex numbers to real numbers.\n\
 The default value is 0.\n\
 @end defvr");
-
-  DEFVAR (warn_num_to_str, true, warn_num_to_str,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} warn_num_to_str\n\
-If the value of @code{warn_num_to_str} is nonzero, a warning is\n\
-printed for implicit conversions of numbers to their ASCII character\n\
-equivalents when strings are constructed using a mixture of strings and\n\
-numbers in matrix notation.  For example,\n\
-\n\
-@example\n\
-@group\n\
-[ \"f\", 111, 111 ]\n\
-     @result{} \"foo\"\n\
-@end group\n\
-@end example\n\
-elicits a warning if @code{warn_num_to_str} is nonzero.  The default\n\
-value is 1.\n\
-@end defvr");
-
-  DEFVAR (warn_resize_on_range_error, false, warn_resize_on_range_error,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} warn_resize_on_range_error\n\
-If the value of @code{warn_resize_on_range_error} is nonzero, print a\n\
-warning when a matrix is resized by an indexed assignment with\n\
-indices outside the current bounds.  The default value is 0.\n\
-@end defvr");
-
 }
 
 /*
--- a/src/ov.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/ov.h	Thu Apr 13 13:04:33 2006 +0000
@@ -54,42 +54,12 @@
 class octave_value_list;
 class octave_lvalue;
 
-// Constants.
-
-// This just provides a way to avoid infinite recursion when building
-// octave_value objects.
+#include "ov-base.h"
 
-class
-octave_xvalue
-{
-public:
-
-  octave_xvalue (void) { }
-};
+// Constants.
 
 class octave_value;
 
-// XXX FIXME XXX -- these should probably really be inside the scope
-// of the octave_value class, but the cygwin32 beta16 version of g++
-// can't handle that.
-
-typedef octave_value (*unary_op_fcn)
-  (const octave_value&);
-
-typedef void (*non_const_unary_op_fcn)
-  (octave_value&);
-
-typedef octave_value (*binary_op_fcn)
-  (const octave_value&, const octave_value&);
-
-typedef octave_value (*cat_op_fcn)
-  (octave_value&, const octave_value&, const Array<int>& ra_idx);
-
-typedef octave_value (*assign_op_fcn)
-  (octave_value&, const octave_value_list&, const octave_value&);
-
-typedef octave_value * (*type_conv_fcn) (const octave_value&);
-
 class
 octave_value
 {
@@ -248,7 +218,7 @@
   octave_value (octave_value::magic_colon);
   octave_value (octave_value::all_va_args);
 
-  octave_value (octave_value *new_rep, int count = 1);
+  octave_value (octave_base_value *new_rep);
 
   // Copy constructor.
 
@@ -260,15 +230,15 @@
 
   // This should only be called for derived types.
 
-  virtual octave_value *clone (void) const;
+  octave_base_value *clone (void) const;
 
-  virtual octave_value *empty_clone (void) const
+  octave_base_value *empty_clone (void) const
     { return rep->empty_clone (); }
 
   // Delete the representation of this constant if the count drops to
   // zero.
 
-  virtual ~octave_value (void);
+  ~octave_value (void);
 
   void make_unique (void)
     {
@@ -298,25 +268,25 @@
 
   int get_count (void) const { return rep->count; }
 
-  virtual type_conv_fcn numeric_conversion_function (void) const
+  octave_base_value::type_conv_fcn numeric_conversion_function (void) const
     { return rep->numeric_conversion_function (); }
 
   void maybe_mutate (void);
 
-  virtual octave_value squeeze (void) const
+  octave_value squeeze (void) const
     { return rep->squeeze (); }
 
-  virtual octave_value *try_narrowing_conversion (void)
+  octave_base_value *try_narrowing_conversion (void)
     { return rep->try_narrowing_conversion (); }
 
   octave_value single_subsref (const std::string& type,
 			       const octave_value_list& idx);
 
-  virtual octave_value subsref (const std::string& type,
+  octave_value subsref (const std::string& type,
 				const std::list<octave_value_list>& idx)
     { return rep->subsref (type, idx); }
 
-  virtual octave_value_list subsref (const std::string& type,
+  octave_value_list subsref (const std::string& type,
 				     const std::list<octave_value_list>& idx,
     				     int nargout);
 
@@ -329,17 +299,17 @@
 				  std::list<octave_value_list>& idx,
 				  size_t skip = 1);
 
-  virtual octave_value do_index_op (const octave_value_list& idx,
+  octave_value do_index_op (const octave_value_list& idx,
 				    int resize_ok)
     { return rep->do_index_op (idx, resize_ok); }
 
   octave_value do_index_op (const octave_value_list& idx)
     { return do_index_op (idx, 0); }
 
-  virtual octave_value_list
+  octave_value_list
   do_multi_index_op (int nargout, const octave_value_list& idx);
 
-  virtual octave_value subsasgn (const std::string& type,
+  octave_value subsasgn (const std::string& type,
 				 const std::list<octave_value_list>& idx,
 				 const octave_value& rhs);
 
@@ -349,335 +319,335 @@
 
   const octave_value& assign (assign_op, const octave_value& rhs);
 
-  virtual idx_vector index_vector (void) const
+  idx_vector index_vector (void) const
     { return rep->index_vector (); }
 
   // Size.
 
-  virtual dim_vector dims (void) const
+  dim_vector dims (void) const
     { return rep->dims (); }
 
-  octave_idx_type rows (void) const;
+  octave_idx_type rows (void) const { return rep->rows (); }
 
-  octave_idx_type columns (void) const;
+  octave_idx_type columns (void) const { return rep->columns (); }
 
   octave_idx_type length (void) const;
 
-  int ndims (void) const;
+  int ndims (void) const { return rep->ndims (); }
 
   bool all_zero_dims (void) const { return dims().all_zero (); }
 
-  virtual octave_idx_type numel (void) const
+  octave_idx_type numel (void) const
     { return rep->numel (); }
 
-  virtual octave_idx_type capacity (void) const
+  octave_idx_type capacity (void) const
     { return rep->capacity (); }
 
   Matrix size (void) const;
 
-  virtual size_t byte_size (void) const
+  size_t byte_size (void) const
     { return rep->byte_size (); }
 
-  virtual octave_idx_type nnz (void) const { return rep->nnz (); }
+  octave_idx_type nnz (void) const { return rep->nnz (); }
 
-  virtual octave_idx_type nzmax (void) const { return rep->nzmax (); }
+  octave_idx_type nzmax (void) const { return rep->nzmax (); }
 
-  virtual octave_value reshape (const dim_vector& dv) const
+  octave_value reshape (const dim_vector& dv) const
     { return rep->reshape (dv); }
 
-  virtual octave_value permute (const Array<int>& vec, bool inv = false) const
+  octave_value permute (const Array<int>& vec, bool inv = false) const
     { return rep->permute (vec, inv); }
 
   octave_value ipermute (const Array<int>& vec) const
     { return rep->permute (vec, true); }
 
-  virtual octave_value resize (const dim_vector& dv, bool fill = false) const
-     { return rep->resize (dv, fill);}
+  octave_value resize (const dim_vector& dv, bool fill = false) const
+    { return rep->resize (dv, fill);}
 
   // Does this constant have a type?  Both of these are provided since
   // it is sometimes more natural to write is_undefined() instead of
   // ! is_defined().
 
-  virtual bool is_defined (void) const
+  bool is_defined (void) const
     { return rep->is_defined (); }
 
   bool is_undefined (void) const
     { return ! is_defined (); }
 
   bool is_empty (void) const
-    { return numel () == 0; }
+    { return rep->is_empty (); }
 
-  virtual bool is_cell (void) const
+  bool is_cell (void) const
     { return rep->is_cell (); }
 
-  virtual bool is_real_scalar (void) const
+  bool is_real_scalar (void) const
     { return rep->is_real_scalar (); }
 
-  virtual bool is_real_matrix (void) const
+  bool is_real_matrix (void) const
     { return rep->is_real_matrix (); }
 
-  virtual bool is_real_nd_array (void) const
+  bool is_real_nd_array (void) const
     { return rep->is_real_nd_array (); }
 
-  virtual bool is_complex_scalar (void) const
+  bool is_complex_scalar (void) const
     { return rep->is_complex_scalar (); }
 
-  virtual bool is_complex_matrix (void) const
+  bool is_complex_matrix (void) const
     { return rep->is_complex_matrix (); }
 
-  virtual bool is_bool_matrix (void) const
+  bool is_bool_matrix (void) const
     { return rep->is_bool_matrix (); }
 
-  virtual bool is_char_matrix (void) const
+  bool is_char_matrix (void) const
     { return rep->is_char_matrix (); }
 
-  virtual bool is_string (void) const
+  bool is_string (void) const
     { return rep->is_string (); }
 
-  virtual bool is_sq_string (void) const
+  bool is_sq_string (void) const
     { return rep->is_sq_string (); }
 
   bool is_dq_string (void) const
     { return rep->is_string () && ! rep->is_sq_string (); }
 
-  virtual bool is_range (void) const
+  bool is_range (void) const
     { return rep->is_range (); }
 
-  virtual bool is_map (void) const
+  bool is_map (void) const
     { return rep->is_map (); }
 
-  virtual bool is_streamoff (void) const
+  bool is_streamoff (void) const
     { return rep->is_streamoff (); }
 
-  virtual bool is_cs_list (void) const
+  bool is_cs_list (void) const
     { return rep->is_cs_list (); }
 
-  virtual bool is_list (void) const
+  bool is_list (void) const
     { return rep->is_list (); }
 
-  virtual bool is_magic_colon (void) const
+  bool is_magic_colon (void) const
     { return rep->is_magic_colon (); }
 
-  virtual bool is_all_va_args (void) const
+  bool is_all_va_args (void) const
     { return rep->is_all_va_args (); }
 
   // Are any or all of the elements in this constant nonzero?
 
-  virtual octave_value all (int dim = 0) const
+  octave_value all (int dim = 0) const
     { return rep->all (dim); }
 
-  virtual octave_value any (int dim = 0) const
+  octave_value any (int dim = 0) const
     { return rep->any (dim); }
 
   // Other type stuff.
 
-  virtual bool is_bool_type (void) const
+  bool is_bool_type (void) const
     { return rep->is_bool_type (); }
 
-  virtual bool is_real_type (void) const
+  bool is_real_type (void) const
     { return rep->is_real_type (); }
 
-  virtual bool is_complex_type (void) const
+  bool is_complex_type (void) const
     { return rep->is_complex_type (); }
 
-  virtual bool is_scalar_type (void) const
+  bool is_scalar_type (void) const
     { return rep->is_scalar_type (); }
 
-  virtual bool is_matrix_type (void) const
+  bool is_matrix_type (void) const
     { return rep->is_matrix_type (); }
 
-  virtual bool is_numeric_type (void) const
+  bool is_numeric_type (void) const
     { return rep->is_numeric_type (); }
 
-  virtual bool is_sparse_type (void) const
+  bool is_sparse_type (void) const
     { return rep->is_sparse_type (); }
 
-  virtual bool valid_as_scalar_index (void) const
+  bool valid_as_scalar_index (void) const
     { return rep->valid_as_scalar_index (); }
 
-  virtual bool valid_as_zero_index (void) const
+  bool valid_as_zero_index (void) const
     { return rep->valid_as_zero_index (); }
 
   // Does this constant correspond to a truth value?
 
-  virtual bool is_true (void) const
+  bool is_true (void) const
     { return rep->is_true (); }
 
   // Are the dimensions of this constant zero by zero?
 
-  virtual bool is_zero_by_zero (void) const
-    { return rep->is_zero_by_zero (); }
+  bool is_zero_by_zero (void) const
+    { return (rows () == 0 && columns () == 0); }
 
-  virtual bool is_constant (void) const
+  bool is_constant (void) const
     { return rep->is_constant (); }
 
-  virtual bool is_function_handle (void) const
+  bool is_function_handle (void) const
     { return rep->is_function_handle (); }
 
-  virtual bool is_inline_function (void) const
+  bool is_inline_function (void) const
     { return rep->is_inline_function (); }
 
-  virtual bool is_function (void) const
+  bool is_function (void) const
     { return rep->is_function (); }
 
-  virtual bool is_builtin_function (void) const
+  bool is_builtin_function (void) const
     { return rep->is_builtin_function (); }
 
-  virtual bool is_dld_function (void) const
+  bool is_dld_function (void) const
     { return rep->is_dld_function (); }
 
   // Values.
 
   octave_value eval (void) { return *this; }
 
-  virtual short int
+  short int
   short_value (bool req_int = false, bool frc_str_conv = false) const
     { return rep->short_value (req_int, frc_str_conv); }
 
-  virtual unsigned short int
+  unsigned short int
   ushort_value (bool req_int = false, bool frc_str_conv = false) const
     { return rep->ushort_value (req_int, frc_str_conv); }
 
-  virtual int int_value (bool req_int = false, bool frc_str_conv = false) const
+  int int_value (bool req_int = false, bool frc_str_conv = false) const
     { return rep->int_value (req_int, frc_str_conv); }
 
-  virtual unsigned int
+  unsigned int
   uint_value (bool req_int = false, bool frc_str_conv = false) const
     { return rep->uint_value (req_int, frc_str_conv); }
 
-  virtual int nint_value (bool frc_str_conv = false) const
+  int nint_value (bool frc_str_conv = false) const
     { return rep->nint_value (frc_str_conv); }
 
-  virtual long int
+  long int
   long_value (bool req_int = false, bool frc_str_conv = false) const
     { return rep->long_value (req_int, frc_str_conv); }
 
-  virtual unsigned long int
+  unsigned long int
   ulong_value (bool req_int = false, bool frc_str_conv = false) const
     { return rep->ulong_value (req_int, frc_str_conv); }
 
-  virtual double double_value (bool frc_str_conv = false) const
+  double double_value (bool frc_str_conv = false) const
     { return rep->double_value (frc_str_conv); }
 
-  virtual double scalar_value (bool frc_str_conv = false) const
+  double scalar_value (bool frc_str_conv = false) const
     { return rep->scalar_value (frc_str_conv); }
 
-  virtual Cell cell_value (void) const;
+  Cell cell_value (void) const;
 
-  virtual Matrix matrix_value (bool frc_str_conv = false) const
+  Matrix matrix_value (bool frc_str_conv = false) const
     { return rep->matrix_value (frc_str_conv); }
 
-  virtual NDArray array_value (bool frc_str_conv = false) const
+  NDArray array_value (bool frc_str_conv = false) const
     { return rep->array_value (frc_str_conv); }
 
-  virtual Complex complex_value (bool frc_str_conv = false) const
+  Complex complex_value (bool frc_str_conv = false) const
     { return rep->complex_value (frc_str_conv); }
 
-  virtual ComplexMatrix complex_matrix_value (bool frc_str_conv = false) const
+  ComplexMatrix complex_matrix_value (bool frc_str_conv = false) const
     { return rep->complex_matrix_value (frc_str_conv); }
 
-  virtual ComplexNDArray complex_array_value (bool frc_str_conv = false) const
+  ComplexNDArray complex_array_value (bool frc_str_conv = false) const
     { return rep->complex_array_value (frc_str_conv); }
 
-  virtual bool bool_value (void) const
+  bool bool_value (void) const
     { return rep->bool_value (); }
 
-  virtual boolMatrix bool_matrix_value (void) const
+  boolMatrix bool_matrix_value (void) const
     { return rep->bool_matrix_value (); }
 
-  virtual boolNDArray bool_array_value (void) const
+  boolNDArray bool_array_value (void) const
     { return rep->bool_array_value (); }
 
-  virtual charMatrix char_matrix_value (bool frc_str_conv = false) const
+  charMatrix char_matrix_value (bool frc_str_conv = false) const
     { return rep->char_matrix_value (frc_str_conv); }
 
-  virtual charNDArray char_array_value (bool frc_str_conv = false) const
+  charNDArray char_array_value (bool frc_str_conv = false) const
     { return rep->char_array_value (frc_str_conv); }
 
-  virtual SparseMatrix sparse_matrix_value (bool frc_str_conv = false) const
-  { return rep->sparse_matrix_value (frc_str_conv); }
+  SparseMatrix sparse_matrix_value (bool frc_str_conv = false) const
+    { return rep->sparse_matrix_value (frc_str_conv); }
 
-  virtual SparseComplexMatrix sparse_complex_matrix_value (bool frc_str_conv = false) const
-  { return rep->sparse_complex_matrix_value (frc_str_conv); }
+  SparseComplexMatrix sparse_complex_matrix_value (bool frc_str_conv = false) const
+    { return rep->sparse_complex_matrix_value (frc_str_conv); }
 
-  virtual SparseBoolMatrix sparse_bool_matrix_value (bool frc_str_conv = false) const
-  { return rep->sparse_bool_matrix_value (frc_str_conv); }
+  SparseBoolMatrix sparse_bool_matrix_value (bool frc_str_conv = false) const
+    { return rep->sparse_bool_matrix_value (frc_str_conv); }
 
-  virtual octave_int8 int8_scalar_value (void) const
+  octave_int8 int8_scalar_value (void) const
     { return rep->int8_scalar_value (); }
 
-  virtual octave_int16 int16_scalar_value (void) const
+  octave_int16 int16_scalar_value (void) const
     { return rep->int16_scalar_value (); }
 
-  virtual octave_int32 int32_scalar_value (void) const
+  octave_int32 int32_scalar_value (void) const
     { return rep->int32_scalar_value (); }
 
-  virtual octave_int64 int64_scalar_value (void) const
+  octave_int64 int64_scalar_value (void) const
     { return rep->int64_scalar_value (); }
 
-  virtual octave_uint8 uint8_scalar_value (void) const
+  octave_uint8 uint8_scalar_value (void) const
     { return rep->uint8_scalar_value (); }
 
-  virtual octave_uint16 uint16_scalar_value (void) const
+  octave_uint16 uint16_scalar_value (void) const
     { return rep->uint16_scalar_value (); }
 
-  virtual octave_uint32 uint32_scalar_value (void) const
+  octave_uint32 uint32_scalar_value (void) const
     { return rep->uint32_scalar_value (); }
 
-  virtual octave_uint64 uint64_scalar_value (void) const
+  octave_uint64 uint64_scalar_value (void) const
     { return rep->uint64_scalar_value (); }
 
-  virtual int8NDArray int8_array_value (void) const
+  int8NDArray int8_array_value (void) const
     { return rep->int8_array_value (); }
 
-  virtual int16NDArray int16_array_value (void) const
+  int16NDArray int16_array_value (void) const
     { return rep->int16_array_value (); }
 
-  virtual int32NDArray int32_array_value (void) const
+  int32NDArray int32_array_value (void) const
     { return rep->int32_array_value (); }
 
-  virtual int64NDArray int64_array_value (void) const
+  int64NDArray int64_array_value (void) const
     { return rep->int64_array_value (); }
 
-  virtual uint8NDArray uint8_array_value (void) const
+  uint8NDArray uint8_array_value (void) const
     { return rep->uint8_array_value (); }
 
-  virtual uint16NDArray uint16_array_value (void) const
+  uint16NDArray uint16_array_value (void) const
     { return rep->uint16_array_value (); }
 
-  virtual uint32NDArray uint32_array_value (void) const
+  uint32NDArray uint32_array_value (void) const
     { return rep->uint32_array_value (); }
 
-  virtual uint64NDArray uint64_array_value (void) const
+  uint64NDArray uint64_array_value (void) const
     { return rep->uint64_array_value (); }
 
-  virtual string_vector all_strings (bool pad = false) const
+  string_vector all_strings (bool pad = false) const
     { return rep->all_strings (pad); }
 
-  virtual std::string string_value (bool force = false) const
+  std::string string_value (bool force = false) const
     { return rep->string_value (force); }
 
-  virtual Range range_value (void) const
+  Range range_value (void) const
     { return rep->range_value (); }
 
-  virtual Octave_map map_value (void) const;
+  Octave_map map_value (void) const;
 
-  virtual string_vector map_keys (void) const
+  string_vector map_keys (void) const
     { return rep->map_keys (); }
 
-  virtual std::streamoff streamoff_value (void) const;
+  std::streamoff streamoff_value (void) const;
 
-  virtual streamoff_array streamoff_array_value (void) const;
+  streamoff_array streamoff_array_value (void) const;
 
-  virtual octave_function *function_value (bool silent = false);
+  octave_function *function_value (bool silent = false);
 
-  virtual octave_user_function *user_function_value (bool silent = false);
+  octave_user_function *user_function_value (bool silent = false);
 
-  virtual octave_fcn_handle *fcn_handle_value (bool silent = false);
+  octave_fcn_handle *fcn_handle_value (bool silent = false);
 
-  virtual octave_fcn_inline *fcn_inline_value (bool silent = false);
+  octave_fcn_inline *fcn_inline_value (bool silent = false);
 
-  virtual octave_value_list list_value (void) const;
+  octave_value_list list_value (void) const;
 
   ColumnVector column_vector_value (bool frc_str_conv = false,
 			     bool frc_vec_conv = false) const;
@@ -708,36 +678,38 @@
   // it, and we should convert it if possible.
 
   octave_value convert_to_str (bool pad = false, bool force = false,
-			       char type = '"') const;
+			       char type = '"') const
+  { return rep->convert_to_str (pad, force, type); }
 
-  virtual octave_value
+  octave_value
   convert_to_str_internal (bool pad, bool force, char type) const
     { return rep->convert_to_str_internal (pad, force, type); }
 
-  virtual void convert_to_row_or_column_vector (void)
+  void convert_to_row_or_column_vector (void)
     { rep->convert_to_row_or_column_vector (); }
 
-  virtual bool print_as_scalar (void) const
+  bool print_as_scalar (void) const
     { return rep->print_as_scalar (); }
 
-  virtual void print (std::ostream& os, bool pr_as_read_syntax = false) const
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const
     { rep->print (os, pr_as_read_syntax); }
 
-  virtual void print_raw (std::ostream& os,
+  void print_raw (std::ostream& os,
 			  bool pr_as_read_syntax = false) const
     { rep->print_raw (os, pr_as_read_syntax); }
 
-  virtual bool print_name_tag (std::ostream& os, const std::string& name) const
+  bool print_name_tag (std::ostream& os, const std::string& name) const
     { return rep->print_name_tag (os, name); }
 
   void print_with_name (std::ostream& os, const std::string& name,
-			bool print_padding = true) const;
-
-  virtual int type_id (void) const { return rep->type_id (); }
+			bool print_padding = true) const
+    { rep->print_with_name (os, name, print_padding); }
 
-  virtual std::string type_name (void) const { return rep->type_name (); }
+  int type_id (void) const { return rep->type_id (); }
 
-  virtual std::string class_name (void) const { return rep->class_name (); }
+  std::string type_name (void) const { return rep->type_name (); }
+
+  std::string class_name (void) const { return rep->class_name (); }
 
   // Unary and binary operations.
 
@@ -759,86 +731,52 @@
 				 const octave_value& b,
 				 const Array<int>& ra_idx);
 
-  const octave_value& get_rep (void) const { return *rep; }
+  const octave_base_value& get_rep (void) const { return *rep; }
 
-  virtual void print_info (std::ostream& os,
+  void print_info (std::ostream& os,
 			   const std::string& prefix = std::string ()) const;
 
-  virtual bool save_ascii (std::ostream& os, bool& infnan_warned,
+  bool save_ascii (std::ostream& os, bool& infnan_warned,
 			   bool strip_nan_and_inf) 
     { return rep->save_ascii (os, infnan_warned, strip_nan_and_inf); }
 
-  virtual bool load_ascii (std::istream& is)
+  bool load_ascii (std::istream& is)
     { return rep->load_ascii (is); }
 
-  virtual bool save_binary (std::ostream& os, bool& save_as_floats)
+  bool save_binary (std::ostream& os, bool& save_as_floats)
     { return rep->save_binary (os, save_as_floats); }
 
-  virtual bool load_binary (std::istream& is, bool swap,
+  bool load_binary (std::istream& is, bool swap,
 			    oct_mach_info::float_format fmt)
     { return rep->load_binary (is, swap, fmt); }
 
 #if defined (HAVE_HDF5)
-  virtual bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
     { return rep->save_hdf5 (loc_id, name, save_as_floats); }
 
-  virtual bool load_hdf5 (hid_t loc_id, const char *name,
+  bool load_hdf5 (hid_t loc_id, const char *name,
 			  bool have_h5giterate_bug)
     { return rep->load_hdf5 (loc_id, name, have_h5giterate_bug); }
 #endif
 
-  virtual int write (octave_stream& os, int block_size,
+  int write (octave_stream& os, int block_size,
 		     oct_data_conv::data_type output_type, int skip,
 		     oct_mach_info::float_format flt_fmt) const;
 
-  octave_value *internal_rep (void) const { return rep; }
+  octave_base_value *internal_rep (void) const { return rep; }
 
 protected:
 
-  octave_value (const octave_xvalue&) : rep (0) { }
-
-  // This should only be called for derived types.
-
-  octave_value numeric_assign (const std::string& type,
-			       const std::list<octave_value_list>& idx,
-			       const octave_value& rhs);
-
-  void reset_indent_level (void) const
-    { curr_print_indent_level = 0; }
-
-  void increment_indent_level (void) const
-    { curr_print_indent_level += 2; }
-
-  void decrement_indent_level (void) const
-    { curr_print_indent_level -= 2; }
-
-  int current_print_indent_level (void) const
-    { return curr_print_indent_level; }
-
-  void newline (std::ostream& os) const;
-
-  void indent (std::ostream& os) const;
-
-  void reset (void) const;
-
-  union
-    {
-      octave_value *rep;      // The real representation.
-      int count;              // A reference count.
-    };
+  // The real representation.
+  octave_base_value *rep;
 
 private:
 
-  static int curr_print_indent_level;
-  static bool beginning_of_line;
-
   assign_op unary_op_to_assign_op (unary_op op);
 
   binary_op op_eq_to_binary_op (assign_op op);
 
   DECLARE_OCTAVE_ALLOCATOR
-
-  octave_value *nil_rep (void) const;
 };
 
 // Publish externally used friend functions.
@@ -923,34 +861,6 @@
 
 OV_BINOP_FN (op_struct_ref)
 
-// T_ID is the type id of struct objects, set by register_type().
-// T_NAME is the type name of struct objects.
-#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA \
-  public: \
-    int type_id (void) const { return t_id; } \
-    std::string type_name (void) const { return t_name; } \
-    std::string class_name (void) const { return c_name; } \
-    static int static_type_id (void) { return t_id; } \
-    static std::string static_type_name (void) { return t_name; } \
-    static std::string static_class_name (void) { return c_name; } \
-    static void register_type (void); \
- \
-  private: \
-    static int t_id; \
-    static const std::string t_name; \
-    static const std::string c_name;
-
-#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c) \
-  int t::t_id (-1); \
-  const std::string t::t_name (n); \
-  const std::string t::c_name (c); \
-  void t::register_type (void) \
-    { \
-      t_id = octave_value_typeinfo::register_type (t::t_name, \
-						   t::c_name, \
-						   octave_value (new t ())); \
-    }
-
 // If TRUE, print a warning for assignments like
 //
 //   octave> A(1) = 3; A(2) = 5
@@ -958,32 +868,9 @@
 // for A already defined and a matrix type.
 extern bool Vwarn_fortran_indexing;
 
-// Should we print a warning when converting `[97, 98, 99, "123"]'
-// to a character string?
-extern bool Vwarn_num_to_str;
-
 // Should we warn about conversions from complex to real?
 extern int Vwarn_imag_to_real;
 
-// If TRUE, print the name along with the value.
-extern bool Vprint_answer_id_name;
-
-// If TRUE, print a warning when a matrix is resized by an indexed
-// assignment with indices outside the current bounds.
-extern bool Vwarn_resize_on_range_error;
-
-// Indentation level for structures.
-extern int struct_indent;
-
-extern void increment_struct_indent (void);
-extern void decrement_struct_indent (void);
-
-// Indentation level for lists.
-extern int list_indent;
-
-extern void increment_list_indent (void);
-extern void decrement_list_indent (void);
-
 extern void install_types (void);
 
 // XXX FIXME XXX -- these trait classes probably belong somehwere else...
@@ -1042,6 +929,12 @@
 OCTAVE_ARRAY_TYPE_TRAIT (uint64NDArray, octave_uint64);
 OCTAVE_ARRAY_TYPE_TRAIT (NDArray, double);
 
+// This will eventually go away, but for now it can be used to
+// simplify the transition to the new octave_value class hierarchy,
+// which uses octave_base_value instead of octave_value for the type
+// of octave_value::rep.
+#define OV_REP_TYPE octave_base_value
+
 #endif
 
 /*
--- a/src/pr-output.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/pr-output.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -78,6 +78,9 @@
 // smaller slices that fit on the screen.
 static bool Vsplit_long_rows;
 
+// How many levels of structure elements should we print?
+int Vstruct_levels_to_print;
+
 // TRUE means don't do any fancy formatting.
 static bool free_format = false;
 
@@ -3019,6 +3022,24 @@
   return 0;
 }
 
+static int
+struct_levels_to_print (void)
+{
+  double val;
+  if (builtin_real_scalar_variable ("struct_levels_to_print", val)
+      && ! xisnan (val))
+    {
+      int ival = NINT (val);
+      if (ival == val)
+	{
+	  Vstruct_levels_to_print = ival;
+	  return 0;
+	}
+    }
+  gripe_invalid_value_specified ("struct_levels_to_print");
+  return -1;
+}
+
 void
 symbols_of_pr_output (void)
 {
@@ -3119,6 +3140,13 @@
 @noindent\n\
 The default value of @code{split_long_rows} is nonzero.\n\
 @end defvr");
+
+  DEFVAR (struct_levels_to_print, 2.0, struct_levels_to_print,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} struct_levels_to_print\n\
+You can tell Octave how many structure levels to display by setting the\n\
+built-in variable @code{struct_levels_to_print}.  The default value is 2.\n\
+@end defvr");
 }
 
 /*
--- a/src/pr-output.h	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/pr-output.h	Thu Apr 13 13:04:33 2006 +0000
@@ -129,6 +129,9 @@
 // like this: x = [](2x0).
 extern bool Vprint_empty_dimensions;
 
+// How many levels of structure elements should we print?
+extern int Vstruct_levels_to_print;
+
 #endif
 
 /*
--- a/src/variables.cc	Wed Apr 12 19:23:26 2006 +0000
+++ b/src/variables.cc	Thu Apr 13 13:04:33 2006 +0000
@@ -2554,10 +2554,10 @@
 	  if (fsr && fsr->is_user_function ())
 	    {
 	      octave_value tmp = fsr->def ();
-	      const octave_value& rep = tmp.get_rep ();
+	      const octave_base_value& rep = tmp.get_rep ();
 	      
 	      const octave_user_function& fcn
-		= static_cast<const octave_user_function&> (rep);
+		= dynamic_cast<const octave_user_function&> (rep);
 
 	      fcn.print_symtab_info (octave_stdout);
 	    }