changeset 19581:f054112912df

Change strfind to return empty array for empty pattern for compatibility (bug #43649). * NEWS: Announce change. * strfind.cc (Fstrfind): Add note to docstring about change. Return Matrix () if pattern is empty.
author Rik <rik@octave.org>
date Fri, 05 Dec 2014 22:17:09 -0800
parents 3b4d6780d6b8
children 52ae096f038b
files NEWS libinterp/corefcn/strfind.cc
diffstat 2 files changed, 36 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS
+++ b/NEWS
@@ -39,6 +39,17 @@
     limit from above is taken.  This criteria is consistent with several other
     numerical analysis software packages.
 
+ ** strfind changes when using empty pattern ("") for Matlab compatibility
+
+    strfind now returns an empty array when the pattern itself is empty.
+    In previous versions of Octave, strfind matched at every character
+    location when the pattern was empty.
+
+      NEW
+      strfind ("abc", "") => []
+      OLD
+      strfind ("abc", "") => [1, 2, 3, 4]
+
  ** Integer formats used in the printf family of functions now work for
     64-bit integers and are more compatible with Matlab when printing
     non-integer values.  Now instead of truncating, Octave will switch
--- a/libinterp/corefcn/strfind.cc
+++ b/libinterp/corefcn/strfind.cc
@@ -157,7 +157,8 @@
 starting index of every such occurrence in the vector @var{idx}.\n\
 \n\
 If there is no such occurrence, or if @var{pattern} is longer\n\
-than @var{str}, then @var{idx} is the empty array @code{[]}.\n\
+than @var{str}, or if @var{pattern} itself is empty, then @var{idx} is the\n\
+empty array @code{[]}.\n\
 The optional argument @qcode{\"overlaps\"} determines whether the pattern\n\
 can match at every position in @var{str} (true), or only for unique\n\
 occurrences of the complete pattern (false).  The default is true.\n\
@@ -220,10 +221,14 @@
           qs_preprocess (needle, table);
 
           if (argstr.is_string ())
-            retval = octave_value (qs_search (needle,
-                                              argstr.char_array_value (),
-                                              table, overlaps),
-                                   true, true);
+            if (argpat.is_empty ())
+              // Return a null matrix for null pattern for MW compatibility
+              retval = Matrix ();
+            else
+              retval = octave_value (qs_search (needle,
+                                                argstr.char_array_value (),
+                                                table, overlaps),
+                                     true, true);
           else if (argstr.is_cell ())
             {
               const Cell argsc = argstr.cell_value ();
@@ -234,11 +239,15 @@
                 {
                   octave_value argse = argsc(i);
                   if (argse.is_string ())
-                    retc(i)
-                      = octave_value (qs_search (needle,
-                                                 argse.char_array_value (),
-                                                 table, overlaps),
-                                      true, true);
+                    {
+                      if (argpat.is_empty ())
+                        retc(i) = Matrix ();
+                      else
+                        retc(i) = octave_value (qs_search (needle,
+                                                     argse.char_array_value (),
+                                                     table, overlaps),
+                                                true, true);
+                    }
                   else
                     {
                       error ("strfind: each element of CELLSTR must be a string");
@@ -267,11 +276,16 @@
 %!assert (strfind ("abababa", "aba", "overlaps", false), [1, 5])
 %!assert (strfind ({"abababa", "bla", "bla"}, "a"), {[1, 3, 5, 7], 3, 3})
 %!assert (strfind ("Linux _is_ user-friendly. It just isn't ignorant-friendly or idiot-friendly.", "friendly"), [17, 50, 68])
+%!assert (strfind ("abc", ""), [])
+%!assert (strfind ("abc", {"", "b", ""}), {[], 2, []})
+%!assert (strfind ({"abc", "def"}, ""), {[], []})
 
 %!error strfind ()
 %!error strfind ("foo", "bar", 1)
+%!error <unknown option: foobar> strfind ("foo", 100, "foobar", 1)
+%!error <each element of CELLSTR must be a string> strfind ({"A", 1}, "foo")
+%!error <first argument must be a string> strfind (100, "foo")
 %!error <PATTERN must be a string> strfind ("foo", 100)
-%!error <first argument must be a string> strfind (100, "foo")
 */
 
 static Array<char>