# HG changeset patch # User jwe # Date 1169577472 0 # Node ID ff5e6cf72bda1a17aa56ef369ea497eeeccb41e5 # Parent c507206c45bc3a78152193971c5d83e981ed8034 [project @ 2007-01-23 18:37:52 by jwe] diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,9 @@ +2007-01-23 Luis F. Ortiz + + * strings/strncmp.m: Delete. + + * strings/strncmpi.m: Use strncmp instead of calling strtrunc on args. + 2007-01-22 Bob Weigel * testfun/test.m: Check for all files in path, use first found. diff --git a/scripts/strings/strncmp.m b/scripts/strings/strncmp.m deleted file mode 100644 --- a/scripts/strings/strncmp.m +++ /dev/null @@ -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 diff --git a/scripts/strings/strncmpi.m b/scripts/strings/strncmpi.m --- a/scripts/strings/strncmpi.m +++ b/scripts/strings/strncmpi.m @@ -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 diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2007-01-23 Luis F. Ortiz + + * strfns.cc (Fstrncmp): New function. + 2007-01-17 John W. Eaton * help.cc (help_from_file, help_from_symbol_table, help_from_list): diff --git a/src/strfns.cc b/src/strfns.cc --- a/src/strfns.cc +++ b/src/strfns.cc @@ -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\