Allows different types and different array sizes in switch tag and
case labels.  Allows multiple labels in the same case statement
using cell arrays.

Oops! I've accidentally left in the debugging statements!  You will
have to remove the "cout <<" lines by hand.  

This patch is against octave-2.1.31, and has already been applied 
in octave-2.1.32.

*** src/pt-select.cc	2000/10/05 12:32:11	1.1
--- src/pt-select.cc	2000/10/06 12:16:15
***************
*** 36,41 ****
--- 36,43 ----
  #include "pt-select.h"
  #include "pt-stmt.h"
  #include "pt-walk.h"
+ #include "Cell.h"
+ #include "ov-typeinfo.h"
  
  // If clauses.
  
***************
*** 121,157 ****
    delete lead_comm;
  }
  
  bool
  tree_switch_case::label_matches (const octave_value& val)
  {
-   bool retval = false;
- 
    octave_value label_value = label->rvalue ();
  
!   if (! error_state)
      {
!       if (label_value.is_defined ())
  	{
! 	  octave_value tmp = do_binary_op (octave_value::op_eq,
! 					   val, label_value);
  
! 	  if (! error_state)
  	    {
! 	      if (tmp.is_defined ())
! 		retval = tmp.is_true ();
! 	      else
! 		eval_error ();
  	    }
- 	  else
- 	    eval_error ();
  	}
        else
! 	eval_error ();
      }
    else
      eval_error ();
  
!   return retval;
  }
  
  int
--- 123,206 ----
    delete lead_comm;
  }
  
+ 
+ // Compare two octave values, returning true if equal, false if not
+ // XXX FIXME XXX --- should be member or friend of octave_value class
+ static bool
+ equal (const octave_value& val, const octave_value& test)
+ {
+   // First make sure the types are comparable, returning false if not
+   int t1 = val.type_id ();
+   int t2 = test.type_id ();
+ 
+   binary_op_fcn f = octave_value_typeinfo::lookup_binary_op (octave_value::op_eq, t1, t2);
+ 
+   if (f == NULL)
+     return false; /* values not comparable */
+ 
+   // Next make sure the sizes are comparable, returning false if not
+   if (val.rows() != test.rows() || val.columns() != test.columns())
+     return false;
+ 
+   // Finally, do the comparison, returning an error if there is a problem
+   octave_value tmp = do_binary_op (octave_value::op_eq, val, test);
+   if (! error_state && tmp.is_defined ())
+     return tmp.is_true ();
+ 
+   ::error ("values not comparable");
+   return false;
+ }
+ 
  bool
  tree_switch_case::label_matches (const octave_value& val)
  {
    octave_value label_value = label->rvalue ();
  
!   if (! error_state && label_value.is_defined() )
      {
!       cout << "defined" << endl;
!       if (label_value.is_cell ())
  	{
! 	  cout << "in label_matches with cell array" << endl;
! 	  label_value.print(cout);
! 	  Cell cell(label_value.cell_value());
  
! 	  for (int i = 0; i < cell.rows(); i++)
  	    {
! 	      for (int j = 0; j < cell.columns(); j++)
! 		{
! 		  cout << "cell(" << i << "," << j << ")=" << endl;
! 		  cell(i,j).print(cout);
! 		  bool match = equal (val, cell(i,j));
! 		  
! 		  if (error_state)
! 		    {
! 		      eval_error();
! 		      return false;
! 		    }
! 		  else if (match)
! 		    return true;
! 		}
  	    }
  	}
        else
! 	{
! 	  cout << "not cell" << endl;
! 	  bool match = equal (val, label_value);
! 	  
! 	  if (error_state)
! 	    {
! 	      eval_error();
! 	      return false;
! 	    }
! 	  else
! 	    return match;
! 	}
      }
    else
      eval_error ();
  
!   return false;
  }
  
  int
