changeset 6250:ff5e6cf72bda

[project @ 2007-01-23 18:37:52 by jwe]
author jwe
date Tue, 23 Jan 2007 18:37:52 +0000
parents c507206c45bc
children 27f85707054a
files scripts/ChangeLog scripts/strings/strncmp.m scripts/strings/strncmpi.m src/ChangeLog src/strfns.cc
diffstat 5 files changed, 322 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Mon Jan 22 20:00:06 2007 +0000
+++ b/scripts/ChangeLog	Tue Jan 23 18:37:52 2007 +0000
@@ -1,3 +1,9 @@
+2007-01-23  Luis F. Ortiz  <lortiz@interactivesupercomputing.com>
+
+	* strings/strncmp.m: Delete.
+
+	* strings/strncmpi.m: Use strncmp instead of calling strtrunc on args.
+
 2007-01-22  Bob Weigel <rweigel@gmu.edu>
 
 	* testfun/test.m: Check for all files in path, use first found.
--- a/scripts/strings/strncmp.m	Mon Jan 22 20:00:06 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-## Copyright (C) 1996, 1997 John W. Eaton
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, write to the Free
-## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-## 02110-1301, USA.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} strncmp (@var{s1}, @var{s2}, @var{n})
-## Return 1 if the first @var{n} characters of character strings @var{s1}
-## and @var{s2} are the same, and 0 otherwise.
-##
-## If either @var{s1} or @var{s2} is a cell array of strings, then an array
-## of the same size is returned, containing the values described above for
-## every member of the cell array. The other argument may also be a cell
-## array of strings (of the same size or with only one element), char matrix
-## or character string.
-##
-## @strong{Caution:} For compatibility with @sc{Matlab}, Octave's strncmp
-## function returns 1 if the character strings are equal, and 0 otherwise.
-## This is just the opposite of the corresponding C library function.
-## @seealso{strcmp, strcmpi, strncmpi}
-## @end deftypefn
-
-function retval = strncmp (s1, s2, n)
-
-  if (nargin == 3)
-    retval = strcmp (strtrunc (s1, n), strtrunc (s2, n));
-  else
-    print_usage ();
-  endif
-
-endfunction
--- a/scripts/strings/strncmpi.m	Mon Jan 22 20:00:06 2007 +0000
+++ b/scripts/strings/strncmpi.m	Tue Jan 23 18:37:52 2007 +0000
@@ -39,7 +39,7 @@
   if (nargin == 3)
     ## Note that we don't use tolower here because we need to be able to
     ## handle cell arrays of strings.
-    retval = strcmp (lower (strtrunc (s1, n)), lower (strtrunc (s2, n)));
+    retval = strncmp (lower (s1), lower (s2), n);
   else
     print_usage ();
   endif
--- a/src/ChangeLog	Mon Jan 22 20:00:06 2007 +0000
+++ b/src/ChangeLog	Tue Jan 23 18:37:52 2007 +0000
@@ -1,3 +1,7 @@
+2007-01-23  Luis F. Ortiz  <lortiz@interactivesupercomputing.com>
+
+	* strfns.cc (Fstrncmp): New function.
+
 2007-01-17  John W. Eaton  <jwe@octave.org>
 
 	* help.cc (help_from_file, help_from_symbol_table, help_from_list):
--- a/src/strfns.cc	Mon Jan 22 20:00:06 2007 +0000
+++ b/src/strfns.cc	Tue Jan 23 18:37:52 2007 +0000
@@ -238,10 +238,12 @@
 	      std::string s = r == 0 ? std::string () : str[0];
 
 	      for (int i = 0; i < cell.length (); i++)
-		if (cell(i).is_string ())
-		  output(i) = (cell(i).string_value () == s);
-		else
-		  output(i) = false;
+		{
+		  if (cell(i).is_string ())
+		    output(i) = (cell(i).string_value () == s);
+		  else
+		    output(i) = false;
+		}
 
 	      retval = output;
 	    }
@@ -278,10 +280,12 @@
 		  if (cell.length () == r)
 		    {
 		      for (int i = 0; i < r; i++)
-			if (cell(i).is_string ())
-			  output(i) = (str[i] == cell(i).string_value ());
-			else
-			  output(i) = false;
+			{
+			  if (cell(i).is_string ())
+			    output(i) = (str[i] == cell(i).string_value ());
+			  else
+			    output(i) = false;
+			}
 
 		      retval = output;
 		    }
@@ -419,6 +423,305 @@
 %!assert (all (strcmp (y, {'foo'}) == [false; false]));
 */
 
+DEFUN (strncmp, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Function File} {} strncmp (@var{s1}, @var{s2}, @var{n})\n\
+Return 1 if the first @var{n} characters of strings @var{s1} and @var{s2} are the same,\n\
+and 0 otherwise.\n\
+\n\
+@example\n\
+@group\n\
+strncmp (\"abce\", \"abcd\", 3)\n\
+     @result{} 1\n\
+@end group\n\
+@end example\n\
+\n\
+If either @var{s1} or @var{s2} is a cell array of strings, then an array\n\
+of the same size is returned, containing the values described above for\n\
+every member of the cell array. The other argument may also be a cell\n\
+array of strings (of the same size or with only one element), char matrix\n\
+or character string.\n\
+\n\
+@example\n\
+@group\n\
+strncmp (\"abce\", {\"abcd\", \"bca\", \"abc\"}, 3)\n\
+     @result{} [1, 0, 1]\n\
+@end group\n\
+@end example\n\
+\n\
+@strong{Caution:} For compatibility with @sc{Matlab}, Octave's strncmp\n\
+function returns 1 if the character strings are equal, and 0 otherwise.\n\
+This is just the opposite of the corresponding C library function.\n\
+@seealso{strncmpi, strcmp, strcmpi}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 3)
+    {
+      bool s1_string = args(0).is_string ();
+      bool s1_cell = args(0).is_cell ();
+      bool s2_string = args(1).is_string ();
+      bool s2_cell = args(1).is_cell ();
+
+      // Match only first n strings.
+      int  n = args(2).int_value ();
+
+      if (n <= 0)
+	{
+	  error ("strncmp: N must be greater than 0");
+	  return retval;
+	}
+
+      if (s1_string && s2_string)
+	{
+	  // The only restriction here is that each string has equal or 
+	  // greater than n characters
+
+	  const dim_vector dv1 = args(0).dims ();
+	  const dim_vector dv2 = args(1).dims ();
+
+	  if (dv1.numel () >= n && dv2.numel () >= n)
+	    {
+	      // Follow Matlab in the sense that the first n characters of 
+	      // the two strings (in column major order) need to be the same.
+	      charNDArray s1 = args(0).char_array_value ();
+	      charNDArray s2 = args(1).char_array_value ();
+	      
+	      for (int i = 0; i < n; i++)
+		{
+		  if (s1(i) != s2(i))
+		    {
+		      retval = false;
+		      return retval;
+		    }
+		}
+
+	      retval = true;
+	    }
+	  else
+	    retval = false;
+	}
+      else if ((s1_string && s2_cell) || (s1_cell && s2_string))
+	{
+	  string_vector str;
+	  Cell cell;
+	  int r, c;
+
+	  if (s1_string)
+	    {
+	      str = args(0).all_strings ();
+	      r = args(0).rows ();
+	      c = args(0).columns ();
+	      cell = args(1).cell_value ();
+	    }
+	  else
+	    {
+	      str = args(1).all_strings ();
+	      r = args(1).rows ();
+	      c = args(1).columns ();
+	      cell = args(0).cell_value ();
+	    }
+
+	  if (r == 1)
+	    {
+	      // Broadcast the string.
+
+	      boolNDArray output (cell.dimensions);
+
+	      if (c < n)
+		{
+		  for (int i = 0; i < cell.length (); i++)
+		    output(i) = false;
+		}
+	      else
+		{
+		  for (int i = 0; i < cell.length (); i++)
+		    {
+		      if (cell(i).is_string ())
+			{
+			  const std::string str2 = cell(i).string_value ();
+
+			  if (str2.length() >= n) 
+			    {
+			      if (str2.compare (0, n, str[0], 0, n) == 0)
+				output(i) = true;
+			      else
+				output(i) = false;
+			    }
+			  else
+			    output(i) = false;
+			}
+		    }
+		}
+
+	      retval = output;
+	    }
+	  else if (r > 1)
+	    {
+	      if (cell.length () == 1)
+		{
+		  // Broadcast the cell.
+
+		  const dim_vector dv (r, 1);
+		  boolNDArray output (dv);
+
+		  if (cell(0).is_string () && c >= n)
+		    {
+		      const std::string str2 = cell(0).string_value ();
+		      
+		      if (str2.length () >= n)
+			{
+			  for (int i = 0; i < r; i++)
+			    {
+			      if (str[i].compare (0, n, str2, 0, n) == 0)
+				output(i) = true;
+			      else
+				output(i) = false;
+			    }
+			}
+		      else
+			{
+			  for (int i = 0; i < r; i++)
+			    output(i) = false;
+			}
+		    }
+		  else
+		    {
+		      for (int i = 0; i < r; i++)
+			output(i) = false;
+		    }
+
+		  retval = output;
+		}
+	      else
+		{
+		  // Must match in all dimensions.
+
+		  boolNDArray output (cell.dimensions);
+
+		  if (cell.numel () == r)
+		    {
+		      for (int i = 0; i < r; i++)
+			{
+			  output(i) = false;
+
+			  if (cell(i).is_string () && c >= n)
+			    {
+			      std::string str2 = cell(i).string_value ();
+
+			      if (str2.length () >= n
+				  && str2.compare (0, n, str[i], 0, n) == 0)
+				output(i) = true;
+			    }
+			}
+
+		      retval = output;
+		    }
+		  else
+		    {
+		      error ("strncmp: the number of rows of the string matrix must match the number of elements in the cell");
+		      return retval;
+		    }
+		}
+	    }
+	}
+      else if (s1_cell && s2_cell)
+	{
+	  Cell cell1;
+	  Cell cell2;
+
+	  int r1 = args(0).numel ();
+	  int r2;
+
+	  if (r1 == 1)
+	    {
+	      // Make the singleton cell2.
+
+	      cell1 = args(1).cell_value ();
+	      cell2 = args(0).cell_value ();
+	      r1 = cell1.length ();
+	      r2 = 1;
+	    }
+	  else
+	    {
+	      cell1 = args(0).cell_value ();
+	      cell2 = args(1).cell_value ();
+	      r2 = cell2.length ();
+	    }
+
+	  const dim_vector size1 = cell1.dimensions;
+	  const dim_vector size2 = cell2.dimensions;
+
+	  boolNDArray output (size1);
+
+	  if (r2 == 1)
+	    {
+	      // Broadcast cell2.
+
+	      if (! cell2(0).is_string ())
+		{
+		  for (int i = 0; i < r1; i++)
+		    output(i) = false;
+		}
+	      else
+		{
+		  const std::string str2 = cell2(0).string_value ();
+
+		  for (int i = 0; i < r1; i++)
+		    {
+		      if (cell1(i).is_string ())
+			{
+			  const std::string str1 = cell1(i).string_value ();
+
+			  if (str1.length () >= n && str2.length () >= n
+			      && str1.compare (0, n, str2, 0, n) == 0)
+			    output(i) = true;
+			  else
+			    output(i) = false;
+			}
+		      else
+			output(i) = false;
+		    }
+		}
+	    }
+	  else
+	    {
+	      if (size1 != size2)
+		{
+		  error ("strncmp: nonconformant cell arrays");
+		  return retval;
+		}
+
+	      for (int i = 0; i < r1; i++)
+		{
+		  if (cell1(i).is_string () && cell2(i).is_string ())
+		    {
+		      const std::string str1 = cell1(i).string_value ();
+		      const std::string str2 = cell2(i).string_value ();
+
+		      if (str1.length () >= n && str2.length () >= n
+			  && str1.compare (0, n, str2, 0, n) == 0)
+			output(i) = true;
+		      else
+			output(i) = false;
+		    }
+		  else
+		    output(i) = false;
+		}
+	    }
+
+	  retval = output;
+	}
+      else
+	retval = false;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
 DEFUN (list_in_columns, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} list_in_columns (@var{arg}, @var{width})\n\