changeset 1572:0d9e10d10bd7

[project @ 1995-10-19 04:31:30 by jwe]
author jwe
date Thu, 19 Oct 1995 04:31:30 +0000
parents 6ddabf91bc4e
children 403c60daa8c7
files src/data.cc src/dirfns.cc src/load-save.cc src/octave.cc src/pr-output.cc src/pr-output.h src/pt-const.cc src/pt-const.h src/pt-exp-base.cc src/strfns.cc src/toplev.h
diffstat 11 files changed, 461 insertions(+), 235 deletions(-) [+]
line wrap: on
line diff
--- a/src/data.cc	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/data.cc	Thu Oct 19 04:31:30 1995 +0000
@@ -756,15 +756,29 @@
 	{
 	  Octave_map m = args(0).map_value ();
 	  char **names = m.make_name_list ();
-	  Octave_str_obj list (m.length ());
+
 	  char **ptr = names;
+	  int max_len = 0;
+	  while (*ptr)
+	    {
+	      int len = strlen (*ptr);
+	      if (len > max_len)
+		max_len = len;
+	      ptr++;
+	    }
+
+	  charMatrix list (m.length (), max_len);
+
+	  ptr = names;
 	  int i = 0;
 	  while (*ptr)
 	    {
-	      list(i++) = *ptr;
+	      list.insert (*ptr, i++, 0);
 	      delete [] *ptr++;
 	    }
+
 	  delete [] names;
+
 	  retval(0) = list;
 	}
       else
--- a/src/dirfns.cc	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/dirfns.cc	Thu Oct 19 04:31:30 1995 +0000
@@ -54,7 +54,6 @@
 #include "gripes.h"
 #include "help.h"
 #include "oct-obj.h"
-#include "oct-str.h"
 #include "octave.h"
 #include "pager.h"
 #include "pathlen.h"
@@ -493,7 +492,7 @@
 is printed.")
 {
   Octave_object retval;
-  Octave_str_obj dirlist;
+  charMatrix dirlist;
   int status = 0;
 
   if (args.length () == 1)
@@ -516,20 +515,28 @@
 	  if (dir)
 	    {
 	      int count = 0;
-	      while (readdir (dir))
-		count++;
+	      int max_len = 0;
+
+	      struct dirent *dir_entry;
+
+	      while ((dir_entry = readdir (dir)))
+		{
+		  count++;
+		  int len = strlen (dir_entry->d_name);
+		  if (len > max_len)
+		    max_len = len;
+		}
 
 	      rewinddir (dir);
 
-	      dirlist.resize (count);
+	      dirlist.resize (count, max_len, 0);
 
-	      struct dirent *dir_entry;
 	      while ((dir_entry = readdir (dir)))
 		{
 		  if (--count < 0)
 		    break;
 
-		  dirlist (count) = dir_entry->d_name;
+		  dirlist.insert (dir_entry->d_name, count, 0);
 		}
 
 #if defined (CLOSEDIR_VOID)
@@ -559,7 +566,7 @@
     print_usage ("readdir");
 
   if (status == 0)
-    retval(0) = dirlist;
+    retval(0) = tree_constant (dirlist, 1);
 
   return retval;
 }
--- a/src/load-save.cc	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/load-save.cc	Thu Oct 19 04:31:30 1995 +0000
@@ -1365,7 +1365,11 @@
 	  int elements;
 	  if (extract_keyword (is, "elements", elements) && elements > 0)
 	    {
-	      Octave_str_obj s (elements);
+	      // XXX FIXME XXX -- need to be able to get max length
+	      // before doing anything.
+
+	      charMatrix chm (elements, 0);
+	      int max_len = 0;
 	      for (int i = 0; i < elements; i++)
 		{
 		  int len;
@@ -1378,7 +1382,14 @@
 			  break;
 			}
 		      else
-			s.elem (i).assign (tmp, len);
+			{
+			  if (len > max_len)
+			    {
+			      max_len = len;
+			      chm.resize (elements, max_len, 0);
+			    }
+			  chm.insert (tmp, i, 0);
+			}
 		      delete [] tmp;
 		    }
 		  else
@@ -1386,7 +1397,7 @@
 		}
 
 	      if (! error_state)
-		tc = s;
+		tc = chm;
 	    }
 	  else
 	    error ("load: failed to extract number of string elements");
@@ -1670,7 +1681,8 @@
 	  goto data_read_error;
 	if (swap)
 	  swap_4_bytes ((char *) &elements);
-	Octave_str_obj s (elements);
+	charMatrix chm (elements, 0);
+	int max_len = 0;
 	for (int i = 0; i < elements; i++)
 	  {
 	    FOUR_BYTE_INT len;
@@ -1684,10 +1696,15 @@
 		delete [] tmp;
 		goto data_read_error;
 	      }
-	    s.elem (i).assign (tmp, len);
+	    if (len > max_len)
+	      {
+		max_len = len;
+		chm.resize (elements, max_len, 0);
+	      }
+	    chm.insert (tmp, i, 0);
 	    delete [] tmp;
 	  }
-	tc = s;
+	tc = chm;
       }
       break;
 
@@ -2492,13 +2509,14 @@
       os.write (&tmp, 1);
       FOUR_BYTE_INT nr = tc.rows ();
       os.write (&nr, 4);
-      Octave_str_obj s = tc.all_strings ();
+      charMatrix chm = tc.all_strings ();
       for (int i = 0; i < nr; i++)
 	{
-	  FOUR_BYTE_INT len = s.elem (i).length ();
+	  FOUR_BYTE_INT len = chm.cols ();
 	  os.write (&len, 4);
-	  const char *tmp = s.elem (i).data ();
+	  const char *tmp = chm.row_as_string (i);
 	  os.write (tmp, len);
+	  delete [] tmp;
 	}
     }
   else if (tc.is_range ())
@@ -2796,14 +2814,16 @@
   else if (tc.is_string ())
     {
       ascii_save_type (os, "string array", mark_as_global);
-      Octave_str_obj tmp = tc.all_strings ();
-      int elements = tmp.length ();
+      charMatrix chm = tc.all_strings ();
+      int elements = chm.rows ();
       os << "# elements: " << elements << "\n";
       for (int i = 0; i < elements; i++)
 	{
-	  int len = tmp.elem (i).length ();
+	  int len = chm.cols ();
 	  os << "# length: " << len << "\n";
-	  os.write (tmp.elem (i).data (), len);
+	  char *tmp = chm.row_as_string (i);
+	  os.write (tmp, len);
+	  delete [] tmp;
 	  os << "\n";
 	}
     }
--- a/src/octave.cc	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/octave.cc	Thu Oct 19 04:31:30 1995 +0000
@@ -58,7 +58,6 @@
 #include "help.h"
 #include "input.h"
 #include "lex.h"
-#include "oct-str.h"
 #include "octave-hist.h"
 #include "octave.h"
 #include "pager.h"
@@ -133,7 +132,7 @@
 int input_from_startup_file = 0;
 
 // The command-line options.
-Octave_str_obj octave_argv;
+charMatrix octave_argv;
 
 // Nonzero means that input is coming from a file that was named on
 // the command line.
@@ -211,9 +210,18 @@
 {
   if (argc > 1)
     {
-      octave_argv.resize (argc-1);
+      int max_len = 0;
       for (int i = 1; i < argc; i++)
-	octave_argv.elem (i-1) = argv[i];
+	{
+	  int tmp_len = strlen (argv[i]);
+	  if (tmp_len > max_len)
+	    max_len = tmp_len;
+	}
+
+      octave_argv.resize (argc-1, max_len, 0);
+
+      for (int i = 1; i < argc; i++)
+	octave_argv.insert (argv[i], i-1, 0);
 
       bind_builtin_variable ("argv", octave_argv, 1, 1, 0);
     }
--- a/src/pr-output.cc	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/pr-output.cc	Thu Oct 19 04:31:30 1995 +0000
@@ -42,7 +42,6 @@
 #include "error.h"
 #include "help.h"
 #include "mappers.h"
-#include "oct-str.h"
 #include "pager.h"
 #include "pr-output.h"
 #include "sysdep.h"
@@ -1454,29 +1453,36 @@
 }
 
 void
-octave_print_internal (ostream& os, Octave_str_obj& s,
-		       int pr_as_read_syntax)
+octave_print_internal (ostream& os, const charMatrix& chm,
+		       int pr_as_read_syntax, int pr_as_string)
 {
-  int nstr = s.num_strings ();
+  if (pr_as_string)
+    {
+      int nstr = chm.rows ();
 
-  if (pr_as_read_syntax && nstr > 1)
-    os << "[ ";
+      if (pr_as_read_syntax && nstr > 1)
+	os << "[ ";
 
-  for (int i = 0; i < nstr; i++)
-    {
-      if (pr_as_read_syntax)
+      for (int i = 0; i < nstr; i++)
 	{
-	  os << "\"" << s.elem (i) << "\"";
+	  if (pr_as_read_syntax)
+	    {
+	      os << "\"" << chm.row_as_string (i) << "\"";
 
-	  if (i < nstr - 1)
-	    os << "; ";
+	      if (i < nstr - 1)
+		os << "; ";
+	    }
+	  else
+	    os << chm.row_as_string (i) << "\n";
 	}
-      else
-	os << s.elem (i) << "\n";
+
+      if (pr_as_read_syntax && nstr > 1)
+	os << " ]";
     }
-
-  if (pr_as_read_syntax && nstr > 1)
-    os << " ]";
+  else
+    {
+      os << "sorry, printing char matrices not implemented yet\n";
+    }
 }
 
 DEFUN ("disp", Fdisp, Sdisp, 10,
--- a/src/pr-output.h	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/pr-output.h	Thu Oct 19 04:31:30 1995 +0000
@@ -29,8 +29,8 @@
 class Matrix;
 class Complex;
 class ComplexMatrix;
+class charMatrix;
 class Range;
-class Octave_str_obj;
 
 extern void octave_print_internal (ostream& os, double d,
 				   int pr_as_read_syntax = 0);
@@ -47,8 +47,9 @@
 extern void octave_print_internal (ostream& os, const Range& r,
 				   int pr_as_read_syntax = 0);
 
-extern void octave_print_internal (ostream& os, Octave_str_obj& s,
-				   int pr_as_read_syntax = 0);
+extern void octave_print_internal (ostream& os, const charMatrix& chm,
+				   int pr_as_read_syntax = 0,
+				   int pr_as_string = 0);
 
 extern void set_format_style (int argc, char **argv);
 
--- a/src/pt-const.cc	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/pt-const.cc	Thu Oct 19 04:31:30 1995 +0000
@@ -44,7 +44,6 @@
 #include "gripes.h"
 #include "idx-vector.h"
 #include "oct-map.h"
-#include "oct-str.h"
 #include "pager.h"
 #include "pr-output.h"
 #include "sysdep.h"
@@ -611,15 +610,15 @@
 
 TC_REP::tree_constant_rep (const char *s)
 {
-  str_obj = new Octave_str_obj (s);
-  type_tag = string_constant;
+  char_matrix = new charMatrix (s);
+  type_tag = char_matrix_constant_str;
   orig_text = 0;
 }
 
-TC_REP::tree_constant_rep (const Octave_str_obj& s)
+TC_REP::tree_constant_rep (const charMatrix& chm, int is_str)
 {
-  str_obj = new Octave_str_obj (s);
-  type_tag = string_constant;
+  char_matrix = new charMatrix (chm);
+  type_tag = is_str ? char_matrix_constant_str : char_matrix_constant;
   orig_text = 0;
 }
 
@@ -715,8 +714,12 @@
       matrix = new Matrix (*(t.matrix));
       break;
 
-    case string_constant:
-      str_obj = new Octave_str_obj (*(t.str_obj));
+    case char_matrix_constant:
+      char_matrix = new charMatrix (*(t.char_matrix));
+      break;
+
+    case char_matrix_constant_str:
+      char_matrix = new charMatrix (*(t.char_matrix));
       break;
 
     case complex_matrix_constant:
@@ -759,8 +762,9 @@
       delete complex_matrix;
       break;
 
-    case string_constant:
-      delete str_obj;
+    case char_matrix_constant:
+    case char_matrix_constant_str:
+      delete char_matrix;
       break;
 
     case range_constant:
@@ -824,8 +828,9 @@
       retval = 1;
       break;
 
-    case string_constant:
-      retval = str_obj->num_strings ();
+    case char_matrix_constant:
+    case char_matrix_constant_str:
+      retval = char_matrix->rows ();
       break;
 
     case range_constant:
@@ -867,8 +872,9 @@
       retval = complex_matrix->columns ();
       break;
 
-    case string_constant:
-      retval = str_obj->max_length ();
+    case char_matrix_constant:
+    case char_matrix_constant_str:
+      retval = char_matrix->columns ();
       break;
 
     case range_constant:
@@ -1059,7 +1065,7 @@
 }
 
 double
-TC_REP::double_value (int force_string_conversion) const
+TC_REP::double_value (int force_str_conv) const
 {
   double retval = octave_NaN;
 
@@ -1106,20 +1112,31 @@
       }
       break;
 
-    case string_constant:
+    case char_matrix_constant:
       {
-	int flag = force_string_conversion;
+	int len = char_matrix->rows ();
+	if ((char_matrix->rows () == 1 && len == 1)
+	    || (len > 1 && user_pref.do_fortran_indexing))
+	  retval = toascii ((int) char_matrix->elem (0, 0));
+	else
+	  gripe_invalid_conversion ("char matrix", "real scalar");
+      }
+      break;
+
+    case char_matrix_constant_str:
+      {
+	int flag = force_str_conv;
 	if (! flag)
 	  flag = user_pref.implicit_str_to_num_ok;
 
 	if (flag < 0)
 	  warn_implicit_conversion ("string", "real scalar");
 
-	int len = str_obj->max_length ();
+	int len = char_matrix->rows ();
 	if (flag
-	    && ((str_obj->num_strings () == 1 && len == 1)
+	    && ((char_matrix->rows () == 1 && len == 1)
 		|| (len > 1 && user_pref.do_fortran_indexing)))
-	  retval = toascii ((int) str_obj->elem (0, 0));
+	  retval = toascii ((int) char_matrix->elem (0, 0));
 	else
 	  gripe_invalid_conversion ("string", "real scalar");
       }
@@ -1144,7 +1161,7 @@
 }
 
 Matrix
-TC_REP::matrix_value (int force_string_conversion) const
+TC_REP::matrix_value (int force_str_conv) const
 {
   Matrix retval;
 
@@ -1179,9 +1196,13 @@
       }
       break;
 
-    case string_constant:
+    case char_matrix_constant:
+      retval = Matrix (*char_matrix);
+      break;
+
+    case char_matrix_constant_str:
       {
-	int flag = force_string_conversion;
+	int flag = force_str_conv;
 	if (! flag)
 	  flag = user_pref.implicit_str_to_num_ok;
 
@@ -1189,26 +1210,7 @@
 	  warn_implicit_conversion ("string", "real matrix");
 
 	if (flag)
-	  {
-	    int nr = str_obj->num_strings ();
-	    int nc = str_obj->max_length ();
-
-	    if (nr > 0 && nc > 0)
-	      {
-		retval.resize (nr, nc);
-
-		for (int i = 0; i < nr; i++)
-		  {
-		    for (int j = 0; j < nc; j++)
-		      {
-			int c = (int) str_obj->elem (i, j);
-			retval.elem (i, j) = toascii (c);
-		      }
-		  }
-	      }
-	    else
-	      retval = Matrix ();  // XXX FIXME XXX -- is this correct?
-	  }
+	  retval = Matrix (*char_matrix);
 	else
 	  gripe_invalid_conversion ("string", "real matrix");
       }
@@ -1227,7 +1229,7 @@
 }
 
 Complex
-TC_REP::complex_value (int force_string_conversion) const
+TC_REP::complex_value (int force_str_conv) const
 {
   Complex retval (octave_NaN, octave_NaN);
 
@@ -1256,20 +1258,31 @@
       }
       break;
 
-    case string_constant:
+    case char_matrix_constant:
       {
-	int flag = force_string_conversion;
+	int len = char_matrix->cols ();
+	if ((char_matrix->rows () == 1 && len == 1)
+	    || (len > 1 && user_pref.do_fortran_indexing))
+	  retval = toascii ((int) char_matrix->elem (0, 0));
+	else
+	  gripe_invalid_conversion ("char matrix", "complex scalar");
+      }
+      break;
+
+    case char_matrix_constant_str:
+      {
+	int flag = force_str_conv;
 	if (! flag)
 	  flag = user_pref.implicit_str_to_num_ok;
 
 	if (flag < 0)
 	  warn_implicit_conversion ("string", "complex scalar");
 
-	int len = str_obj->max_length ();
+	int len = char_matrix->cols ();
 	if (flag
-	    && ((str_obj->num_strings () == 1 && len == 1)
+	    && ((char_matrix->rows () == 1 && len == 1)
 		|| (len > 1 && user_pref.do_fortran_indexing)))
-	  retval = toascii ((int) str_obj->elem (0, 0));
+	  retval = toascii ((int) char_matrix->elem (0, 0));
 	else
 	  gripe_invalid_conversion ("string", "complex scalar");
       }
@@ -1294,7 +1307,7 @@
 }
 
 ComplexMatrix
-TC_REP::complex_matrix_value (int force_string_conversion) const
+TC_REP::complex_matrix_value (int force_str_conv) const
 {
   ComplexMatrix retval;
 
@@ -1316,9 +1329,13 @@
       retval = *complex_matrix;
       break;
 
-    case string_constant:
+    case char_matrix_constant:
+      retval = ComplexMatrix (*char_matrix);
+      break;
+
+    case char_matrix_constant_str:
       {
-	int flag = force_string_conversion;
+	int flag = force_str_conv;
 	if (! flag)
 	  flag = user_pref.implicit_str_to_num_ok;
 
@@ -1326,28 +1343,9 @@
 	  warn_implicit_conversion ("string", "complex matrix");
 
 	if (flag)
-	  {
-	    int nr = str_obj->num_strings ();
-	    int nc = str_obj->max_length ();
-
-	    if (nr > 0 && nc > 0)
-	      {
-		retval.resize (nr, nc);
-
-		for (int i = 0; i < nr; i++)
-		  {
-		    for (int j = 0; j < nc; j++)
-		      {
-			int c = (int) str_obj->elem (i, j);
-			retval.elem (i, j) = toascii (c);
-		      }
-		  }
-	      }
-	    else
-	      panic_impossible ();
-	  }
+	  retval = ComplexMatrix (*char_matrix);
 	else
-	  gripe_invalid_conversion ("string", "real matrix");
+	  gripe_invalid_conversion ("complex", "real matrix");
       }
       break;
 
@@ -1363,11 +1361,47 @@
   return retval;
 }
 
-Octave_str_obj
+// XXX FIXME XXX -- this needs to try to do some conversions...
+
+charMatrix
+TC_REP::char_matrix_value (int force_str_conv) const
+{
+  charMatrix retval;
+
+  int flag = force_str_conv;
+  if (! flag)
+    flag = user_pref.implicit_str_to_num_ok;
+#if 0
+
+  if (flag < 0)
+    warn_implicit_conversion ("string", "complex matrix");
+
+  if (flag)
+    retval = ComplexMatrix (*char_matrix);
+  else
+    gripe_invalid_conversion ("complex", "real matrix");
+#endif
+
+  switch (type_tag)
+    {
+    case char_matrix_constant:
+    case char_matrix_constant_str:
+      retval = *char_matrix;
+      break;
+
+    default:
+      gripe_invalid_conversion (type_as_string (), "string");
+      break;
+    }
+
+  return retval;
+}
+
+charMatrix
 TC_REP::all_strings (void) const
 {
-  if (type_tag == string_constant)
-    return *str_obj;
+  if (type_tag == char_matrix_constant_str)
+    return *char_matrix;
   else
     {
       gripe_invalid_conversion (type_as_string (), "string");
@@ -1378,8 +1412,8 @@
 const char *
 TC_REP::string_value (void) const
 {
-  if (type_tag == string_constant)
-    return str_obj->elem (0).c_str ();  // XXX FIXME??? XXX
+  if (type_tag == char_matrix_constant_str)
+    return char_matrix->row_as_string (0);  // XXX FIXME??? XXX
   else
     {
       gripe_invalid_conversion (type_as_string (), "string");
@@ -1427,12 +1461,12 @@
 // than relying on matrix_value() to do any possible type conversions.
 
 ColumnVector
-TC_REP::vector_value (int force_string_conversion,
+TC_REP::vector_value (int force_str_conv,
 		      int force_vector_conversion) const
 {
   ColumnVector retval;
 
-  Matrix m = matrix_value (force_string_conversion);
+  Matrix m = matrix_value (force_str_conv);
 
   if (error_state)
     return retval;
@@ -1471,12 +1505,12 @@
 // conversions.
 
 ComplexColumnVector
-TC_REP::complex_vector_value (int force_string_conversion,
+TC_REP::complex_vector_value (int force_str_conv,
 			      int force_vector_conversion) const
 {
   ComplexColumnVector retval;
 
-  ComplexMatrix m = complex_matrix_value (force_string_conversion);
+  ComplexMatrix m = complex_matrix_value (force_str_conv);
 
   if (error_state)
     return retval;
@@ -1535,7 +1569,7 @@
 	    char s[2];
 	    s[0] = (char) i;
 	    s[1] = '\0';
-	    retval = s;
+	    retval = tree_constant (s, 1);
 	  }
       }
       break;
@@ -1546,7 +1580,7 @@
 	if (rows () == 0 && columns () == 0)
 	  {
 	    char s = '\0';
-	    retval = &s;
+	    retval = tree_constant (&s, 1);
 	  }
 	else
 	  {
@@ -1558,18 +1592,15 @@
 	    if (nr == 0 || nc == 0)
 	      {
 		char s = '\0';
-		retval = &s;
+		retval = tree_constant (&s, 1);
 	      }
 	    else
 	      {
-		Octave_str_obj s (nr);
-
-		for (int i = 0; i < nr; i++)
+		charMatrix chm (nr, nc);
+
+		for (int j = 0; j < nc; j++)
 		  {
-		    char buf[nc+1];
-		    buf[nc] = '\0';
-
-		    for (int j = 0; j < nc; j++)
+		    for (int i = 0; i < nr; i++)
 		      {
 			double d = m.elem (i, j);
 
@@ -1584,14 +1615,12 @@
 			    // range conversions?
 
 			    int ival = NINT (d);
-			    buf[j] = (char) ival;
+			    chm.elem (i, j) = (char) ival;
 			  }
 		      }
-
-		    s.elem (i).assign (buf, nc);
 		  }
 
-		retval = s;
+		retval = tree_constant (chm, 1);
 	      }
 	  }
       }
@@ -1624,13 +1653,17 @@
 		s[i] = (char) ival;
 	      }
 	  }
-	retval = s;
+	retval = tree_constant (s, 1);
 	delete [] s;
       }
       break;
 
-    case string_constant:
-      retval = *str_obj;
+    case char_matrix_constant:
+      retval = tree_constant (*char_matrix, 1);
+      break;
+
+    case char_matrix_constant_str:
+      retval = tree_constant (*char_matrix, 1);
       break;
 
     default:
@@ -1728,6 +1761,15 @@
       }
       break;
 
+    case range_constant:
+      {
+	Matrix *tmp = new Matrix (range->matrix_value ());
+	delete range;
+	matrix = tmp;
+	type_tag = matrix_constant;
+      }
+      break;
+
     default:
       panic_impossible ();
       break;
@@ -1743,9 +1785,10 @@
     case matrix_constant:
     case complex_scalar_constant:
     case complex_matrix_constant:
+    case char_matrix_constant:
       break;
 
-    case string_constant:
+    case char_matrix_constant_str:
       {
 	if (! force_str_conv && ! user_pref.implicit_str_to_num_ok)
 	  {
@@ -1754,16 +1797,19 @@
 	    return;
 	  }
 
-	int nr = str_obj->num_strings ();
-	int nc = str_obj->max_length ();
+	int nr = char_matrix->rows ();
+	int nc = char_matrix->cols ();
 
 	if (nr == 1 && nc == 1)
 	  {
 	    type_tag = scalar_constant;
-	    scalar = toascii ((int) str_obj->elem (0, 0));
+	    double tmp = toascii ((int) char_matrix->elem (0, 0));
+	    delete char_matrix;
+	    scalar = tmp;
 	  }
 	else if (nr == 0 || nc == 0)
 	  {
+	    delete char_matrix;
 	    type_tag = matrix_constant;
 	    matrix = new Matrix (0, 0);
 	  }
@@ -1777,10 +1823,11 @@
 	      {
 		for (int j = 0; j < nc; j++)
 		  {
-		    int c = (int) str_obj->elem (i, j);
+		    int c = (int) char_matrix->elem (i, j);
 		    tm->elem (i, j) = toascii (c);
 		  }
 	      }
+	    delete char_matrix;
 	    matrix = tm;
 	  }
 	else
@@ -1799,6 +1846,7 @@
 	    double increment = range->inc ();
 	    for (int i = 0; i < len; i++)
 	      tm->elem (0, i) = b + i * increment;
+	    delete range;
 	    matrix = tm;
 	  }
 	else if (len == 1)
@@ -1838,9 +1886,27 @@
       retval = *complex_matrix;
       break;
 
-    case string_constant:
-      retval = *str_obj;
-      retval.force_numeric (force_str_conv);
+    case char_matrix_constant:
+      retval = *char_matrix;
+      break;
+
+    case char_matrix_constant_str:
+      {
+	int flag = force_str_conv;
+	if (! flag)
+	  flag = user_pref.implicit_str_to_num_ok;
+
+	if (flag < 0)
+	  warn_implicit_conversion ("string", "char matrix");
+
+	if (flag)
+	  {
+	    retval = *char_matrix;
+	    retval.force_numeric (force_str_conv);
+	  }
+	else
+	  gripe_invalid_conversion ("string", "char matrix");
+      }
       break;
 
     case range_constant:
@@ -2065,8 +2131,12 @@
       octave_print_internal (output_buf, *complex_matrix);
       break;
 
-    case string_constant:
-      octave_print_internal (output_buf, *str_obj);
+    case char_matrix_constant:
+      octave_print_internal (output_buf, *char_matrix);
+      break;
+
+    case char_matrix_constant_str:
+      octave_print_internal (output_buf, *char_matrix, 0, 1);
       break;
 
     case range_constant:
@@ -2159,8 +2229,12 @@
       octave_print_internal (os, *complex_matrix, 1);
       break;
 
-    case string_constant:
-      octave_print_internal (os, *str_obj, 1);
+    case char_matrix_constant:
+      octave_print_internal (os, *char_matrix, 1);
+      break;
+
+    case char_matrix_constant_str:
+      octave_print_internal (os, *char_matrix, 1, 1);
       break;
 
     case range_constant:
@@ -2209,7 +2283,10 @@
     case complex_matrix_constant:
       return "complex matrix";
 
-    case string_constant:
+    case char_matrix_constant:
+      return "char matrix";
+
+    case char_matrix_constant_str:
       return "string";
 
     case range_constant:
@@ -2275,6 +2352,7 @@
 	  break;
 
 	case TC_REP::matrix_constant:
+	case TC_REP::char_matrix_constant:
 	  m2 = tmp_b.matrix_value ();
 	  retval = do_binary_op (d1, m2, t);
 	  break;
@@ -2296,6 +2374,7 @@
       break;
 
     case TC_REP::matrix_constant:
+    case TC_REP::char_matrix_constant:
 
       m1 = tmp_a.matrix_value ();
 
@@ -2307,6 +2386,7 @@
 	  break;
 
 	case TC_REP::matrix_constant:
+	case TC_REP::char_matrix_constant:
 	  m2 = tmp_b.matrix_value ();
 	  retval = do_binary_op (m1, m2, t);
 	  break;
@@ -2339,6 +2419,7 @@
 	  break;
 
 	case TC_REP::matrix_constant:
+	case TC_REP::char_matrix_constant:
 	  m2 = tmp_b.matrix_value ();
 	  retval = do_binary_op (c1, m2, t);
 	  break;
@@ -2371,6 +2452,7 @@
 	  break;
 
 	case TC_REP::matrix_constant:
+	case TC_REP::char_matrix_constant:
 	  m2 = tmp_b.matrix_value ();
 	  retval = do_binary_op (cm1, m2, t);
 	  break;
@@ -2468,6 +2550,11 @@
       complex_matrix->clear_index ();
       break;
 
+    case char_matrix_constant:
+    case char_matrix_constant_str:
+      char_matrix->clear_index ();
+      break;
+
     default:
       panic_impossible ();
       break;
@@ -2488,6 +2575,11 @@
       complex_matrix->set_index (d);
       break;
 
+    case TC_REP::char_matrix_constant:
+    case TC_REP::char_matrix_constant_str:
+      char_matrix->set_index (d);
+      break;
+
     default:
       panic_impossible ();
       break;
@@ -2508,6 +2600,11 @@
       complex_matrix->set_index (r);
       break;
 
+    case TC_REP::char_matrix_constant:
+    case TC_REP::char_matrix_constant_str:
+      char_matrix->set_index (r);
+      break;
+
     default:
       panic_impossible ();
       break;
@@ -2527,6 +2624,11 @@
       complex_matrix->set_index (v);
       break;
 
+    case TC_REP::char_matrix_constant:
+    case TC_REP::char_matrix_constant_str:
+      char_matrix->set_index (v);
+      break;
+
     default:
       panic_impossible ();
       break;
@@ -2552,6 +2654,11 @@
 	  complex_matrix->set_index (m);
 	  break;
 
+	case TC_REP::char_matrix_constant:
+	case TC_REP::char_matrix_constant_str:
+	  char_matrix->set_index (m);
+	  break;
+
 	default:
 	  panic_impossible ();
 	  break;
@@ -2576,6 +2683,11 @@
       complex_matrix->set_index (c);
       break;
 
+    case TC_REP::char_matrix_constant:
+    case TC_REP::char_matrix_constant_str:
+      char_matrix->set_index (c);
+      break;
+
     default:
       panic_impossible ();
       break;
@@ -2686,6 +2798,14 @@
 	      retval = ComplexMatrix (complex_matrix->value ());
 	      break;
 
+	    case char_matrix_constant:
+	      retval = charMatrix (char_matrix->value ());
+	      break;
+
+	    case char_matrix_constant_str:
+	      retval = tree_constant (charMatrix (char_matrix->value ()), 1);
+	      break;
+
 	    default:
 	      error ("can't index %s variables", type_as_string ());
 	      break;
@@ -2724,6 +2844,34 @@
 	}
       break;
 
+    case char_matrix_constant:
+      switch (rhs_type)
+	{
+	case scalar_constant:
+	case matrix_constant:
+	  {
+	    Matrix *m = new Matrix (*char_matrix);
+	    delete matrix;
+	    matrix = m;
+	    type_tag = matrix_constant;
+	  }
+	  break;
+
+	case complex_scalar_constant:
+	case complex_matrix_constant:
+	  {
+	    ComplexMatrix *cm = new ComplexMatrix (*char_matrix);
+	    delete matrix;
+	    complex_matrix = cm;
+	    type_tag = complex_matrix_constant;
+	  }
+	  break;
+
+	default:
+	  break;
+	}
+      break;
+
     default:
       break;
     }
@@ -2735,9 +2883,17 @@
 // decide if the left-hand side is currently a scalar or a matrix and
 // hand off to other functions to do the real work.
 
+// XXX FIXME XXX -- need some other way to make these functions
+// visible here (they should be in some header file...)
+
 extern void assign (Array2<Complex>&, const Array2<Complex>&);
 extern void assign (Array2<Complex>&, const Array2<double>&);
+extern void assign (Array2<Complex>&, const Array2<char>&);
+
 extern void assign (Array2<double>&, const Array2<double>&);
+extern void assign (Array2<double>&, const Array2<char>&);
+
+extern void assign (Array2<char>&, const Array2<char>&);
 
 void
 TC_REP::assign (tree_constant& rhs, const Octave_object& args)
@@ -2747,20 +2903,19 @@
   if (error_state)
     return;
 
-  // This is easier than actually handling assignments to strings.  An
-  // assignment to a range will normally require a conversion to a
-  // vector since it will normally destroy the equally-spaced property
-  // of the range elements.
-
-  if (is_defined () && ! is_numeric_type ())
+  // An assignment to a range will normally require a conversion to a
+  // vector in the end anyway, since it will normally destroy the
+  // equally-spaced property of the range elements.  This is not as
+  // memory efficient as possible, but it is much simpler than writing
+  // additional indexing and assignment functions especially for
+  // Ranges.
+
+  if (is_defined () && ! (is_numeric_type () || is_string ()))
     force_numeric ();
 
   if (error_state)
     return;
 
-// Do this before setting the index so that we don't have to copy
-// indices in the Array class.
-
   maybe_widen (rhs.const_type ());
 
   set_index (args);
@@ -2792,9 +2947,30 @@
 
 	case scalar_constant:
 	case matrix_constant:
-	  ::assign (*matrix, rhs.matrix_value ());
+	  {
+	    switch (rhs.const_type ())
+	      {
+	      case scalar_constant:
+	      case matrix_constant:
+		::assign (*matrix, rhs.matrix_value ());
+		break;
+
+	      case char_matrix_constant:
+		::assign (*matrix, rhs.char_matrix_value ());
+		break;
+
+	      default:
+		panic_impossible ();
+		break;
+	      }
+	  }
 	  break;
 
+	case char_matrix_constant:
+	case char_matrix_constant_str:
+	  ::assign (*char_matrix, rhs.char_matrix_value ());
+      break;
+
 	default:
 	  panic_impossible ();
 	  break;
--- a/src/pt-const.h	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/pt-const.h	Thu Oct 19 04:31:30 1995 +0000
@@ -68,7 +68,8 @@
 	    matrix_constant,
 	    complex_scalar_constant,
 	    complex_matrix_constant,
-	    string_constant,
+	    char_matrix_constant,
+	    char_matrix_constant_str,
 	    range_constant,
 	    map_constant,
 	    magic_colon,
@@ -97,7 +98,7 @@
 	tree_constant_rep (const ComplexColumnVector& v, int pcv);
 
 	tree_constant_rep (const char *s);
-	tree_constant_rep (const Octave_str_obj& s);
+	tree_constant_rep (const charMatrix& chm, int is_string);
 
 	tree_constant_rep (double base, double limit, double inc);
 	tree_constant_rep (const Range& r);
@@ -117,40 +118,43 @@
 	int columns (void) const;
 
 	int is_defined (void) const
-	  { return type_tag != tree_constant_rep::unknown_constant; }
+	  { return type_tag != unknown_constant; }
 
 	int is_undefined (void) const
-	  { return type_tag == tree_constant_rep::unknown_constant; }
+	  { return type_tag == unknown_constant; }
 
 	int is_unknown (void) const
-	  { return type_tag == tree_constant_rep::unknown_constant; }
+	  { return type_tag == unknown_constant; }
 
 	int is_real_scalar (void) const
-	  { return type_tag == tree_constant_rep::scalar_constant; }
+	  { return type_tag == scalar_constant; }
 
 	int is_real_matrix (void) const
-	  { return type_tag == tree_constant_rep::matrix_constant; }
+	  { return type_tag == matrix_constant; }
 
 	int is_complex_scalar (void) const
-	  { return type_tag == tree_constant_rep::complex_scalar_constant; }
+	  { return type_tag == complex_scalar_constant; }
 
 	int is_complex_matrix (void) const
-	  { return type_tag == tree_constant_rep::complex_matrix_constant; }
+	  { return type_tag == complex_matrix_constant; }
+
+	int is_char_matrix (void) const
+	  { return type_tag == char_matrix_constant; }
 
 	int is_string (void) const
-	  { return type_tag == tree_constant_rep::string_constant; }
+	  { return type_tag == char_matrix_constant_str; }
 
 	int is_range (void) const
-	  { return type_tag == tree_constant_rep::range_constant; }
+	  { return type_tag == range_constant; }
 
 	int is_map (void) const
-	  { return type_tag == tree_constant_rep::map_constant; }
+	  { return type_tag == map_constant; }
 
 	int is_magic_colon (void) const
-	  { return type_tag == tree_constant_rep::magic_colon; }
+	  { return type_tag == magic_colon; }
 
 	int is_all_va_args (void) const
-	  { return type_tag == tree_constant_rep::all_va_args; }
+	  { return type_tag == all_va_args; }
 
 	tree_constant all (void) const;
 	tree_constant any (void) const;
@@ -160,7 +164,8 @@
 	    return (type_tag == scalar_constant
 		    || type_tag == matrix_constant
 		    || type_tag == range_constant
-		    || type_tag == string_constant);
+		    || type_tag == char_matrix_constant
+		    || type_tag == char_matrix_constant_str);
 	  }
 
 	int is_complex_type (void) const
@@ -209,7 +214,8 @@
 	Matrix matrix_value (int frc_str_conv = 0) const;
 	Complex complex_value (int frc_str_conv = 0) const;
 	ComplexMatrix complex_matrix_value (int frc_str_conv = 0) const;
-	Octave_str_obj all_strings (void) const;
+	charMatrix char_matrix_value (int frc_str_conv = 0) const;
+	charMatrix all_strings (void) const;
 	const char *string_value (void) const;
 	Range range_value (void) const;
 	Octave_map map_value (void) const;
@@ -293,7 +299,7 @@
 	    Matrix *matrix;		    // A real matrix constant.
 	    Complex *complex_scalar;	    // A real scalar constant.
 	    ComplexMatrix *complex_matrix;  // A real matrix constant.
-	    Octave_str_obj *str_obj;	    // A character string constant.
+	    charMatrix *char_matrix;	    // A character string constant.
 	    Range *range;		    // A set of evenly spaced values.
 	    Octave_map *a_map;	      	    // An associative array.
 
@@ -334,8 +340,9 @@
   //                  ComplexDiagMatrix
   //                  ComplexRowVector
   //                  ComplexColumnVector
+  // char matrix      charMatrix
   // string           char* (null terminated)
-  //                  Octave_str_obj
+  //                  charMatrix
   // range            double, double, double
   //                  Range
   // map              Octave_map
@@ -370,16 +377,16 @@
     { rep = new tree_constant_rep (d); rep->count = 1; }
 
   tree_constant (const ComplexRowVector& v, int pcv = -1) : tree_fvc ()
-      { rep = new tree_constant_rep (v, pcv); rep->count = 1; }
+    { rep = new tree_constant_rep (v, pcv); rep->count = 1; }
 
   tree_constant (const ComplexColumnVector& v, int pcv = -1) : tree_fvc () 
-      { rep = new tree_constant_rep (v, pcv); rep->count = 1; }
+    { rep = new tree_constant_rep (v, pcv); rep->count = 1; }
 
   tree_constant (const char *s) : tree_fvc ()
     { rep = new tree_constant_rep (s); rep->count = 1; }
 
-  tree_constant (const Octave_str_obj& s) : tree_fvc ()
-    { rep = new tree_constant_rep (s); rep->count = 1; }
+  tree_constant (const charMatrix& chm, int is_string = 0) : tree_fvc ()
+    { rep = new tree_constant_rep (chm, is_string); rep->count = 1; }
 
   tree_constant (double base, double limit, double inc) : tree_fvc ()
     { rep = new tree_constant_rep (base, limit, inc); rep->count = 1; }
@@ -534,7 +541,10 @@
   ComplexMatrix complex_matrix_value (int frc_str_conv = 0) const
     { return rep->complex_matrix_value (frc_str_conv); }
 
-  Octave_str_obj all_strings (void) const
+  charMatrix char_matrix_value (int frc_str_conv = 0) const
+    { return rep->char_matrix_value (frc_str_conv); }
+
+  charMatrix all_strings (void) const
     { return rep->all_strings (); }
 
   const char *string_value (void) const
--- a/src/pt-exp-base.cc	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/pt-exp-base.cc	Thu Oct 19 04:31:30 1995 +0000
@@ -392,8 +392,7 @@
 
   Matrix m;
   ComplexMatrix cm;
-
-  Octave_str_obj string;
+  charMatrix chm;
 
   // Eliminate empties and gather stats.
 
@@ -498,8 +497,11 @@
 		else
 		  {
 		    cols_this_row += nc;
+
 		    if (first_row)
 		      col_total = cols_this_row;
+		    else if (all_strings && cols_this_row > col_total)
+		      col_total = cols_this_row;
 		  }
 	      }
 	      break;
@@ -527,7 +529,11 @@
 
   // Don't forget to check to see if the last element will fit.
 
-  if (cols_this_row != col_total && ! all_strings)
+  if (all_strings && cols_this_row > col_total)
+    {
+      col_total = cols_this_row;
+    }
+  else if (cols_this_row != col_total)
     {
       ::error ("number of columns must match");
       goto done;
@@ -537,7 +543,7 @@
   // them in the result matrix.
 
   if (all_strings)
-    string.resize (row_total);
+    chm.resize (row_total, col_total, 0);
   else if (found_complex)
     cm.resize (row_total, col_total, 0.0);
   else
@@ -609,24 +615,12 @@
 	    }
 	  else if (tmp.is_string () && all_strings)
 	    {
-	      switch (list[i].direction)
-		{
-		case md_right:
-		  if (nr == 1)
-		    string.append_right (put_row, tmp.string_value ());
-		  else
-		    string.append_right (tmp.all_strings ());
-		  break;
-
-		case md_none:
-		case md_down:
-		  string.append_down (put_row, tmp.all_strings ());
-		  break;
-		  
-		default:
-		  panic_impossible ();
-		  break;
-		}
+	      charMatrix chm_tmp = tmp.all_strings ();
+
+	      if (error_state)
+		goto done;
+
+	      chm.insert (chm_tmp, put_row, put_col);
 	    }
 	  else
 	    {
@@ -643,8 +637,8 @@
       prev_nc = nc;
     }
 
-  if (all_strings && string.num_strings () > 0)
-    retval = string;
+  if (all_strings && chm.rows () > 0 && chm.cols () > 0)
+    retval = tree_constant (chm, 1);
   else if (found_complex)
     retval = cm;
   else
@@ -2532,7 +2526,11 @@
 	{
 	  tree_constant tmp = apply_mapper_fcn (args(0), mapper_fcn, 0);
 	  retval(0) = tmp;
-	}	
+	}
+      else
+	{
+	  ::error ("%s: too few arguments", my_name);
+	}
     }
   else
     {
--- a/src/strfns.cc	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/strfns.cc	Thu Oct 19 04:31:30 1995 +0000
@@ -80,23 +80,9 @@
 
       if (arg.is_string ())
 	{
-	  Octave_str_obj str = args(0).all_strings ();
-
-	  int nr = str.num_strings ();
-	  int nc = str.max_length ();
-
-	  // XXX FIXME XXX -- should fill with user-specified value.
-
-	  Matrix m (nr, nc, 0);
+	  charMatrix chm = args(0).all_strings ();
 
-	  for (int i = 0; i < nr; i++)
-	    {
-	      nc = str.elem (i).length ();
-	      for (int j = 0; j < nc; j++)
-		m (i, j) = toascii (str.elem (i) [j]);
-	    }
-
-	  retval = m;
+	  retval = Matrix (chm);
 	}
       else
 	gripe_wrong_type_arg ("toascii", arg);
--- a/src/toplev.h	Thu Oct 19 04:21:41 1995 +0000
+++ b/src/toplev.h	Thu Oct 19 04:31:30 1995 +0000
@@ -29,7 +29,7 @@
 class tree_constant;
 class tree_function;
 class tree_statement_list;
-class Octave_str_obj;
+class charMatrix;
 
 extern void clean_up_and_exit (int) NORETURN;
 
@@ -88,7 +88,7 @@
 extern int input_from_startup_file;
 
 // The command-line options.
-extern Octave_str_obj octave_argv;
+extern charMatrix octave_argv;
 
 // Nonzero means that input is coming from a file that was named on
 // the command line.