changeset 27315:86c5dd1283b6

Add support for "ForceCellOutput" option to strfind (bug #56699). * strfind.cc (Fstrfind): Add new calling form to documentation. Add explanation of new "ForceCellOutput" option. Add example showing its use to docstring. Decode third input and if ForceCellOutput option is true, then call Cell() to return a cell object on output of internal strfind routine. Add BIST tests for new option.
author Guillaume Flandin <guillaume.offline@gmail.com>
date Mon, 05 Aug 2019 08:51:40 -0700
parents c3b66eff89fd
children 22265a75be74
files libinterp/corefcn/strfind.cc
diffstat 1 files changed, 32 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/strfind.cc	Mon Aug 05 08:28:24 2019 -0700
+++ b/libinterp/corefcn/strfind.cc	Mon Aug 05 08:51:40 2019 -0700
@@ -151,6 +151,7 @@
 @deftypefn  {} {@var{idx} =} strfind (@var{str}, @var{pattern})
 @deftypefnx {} {@var{idx} =} strfind (@var{cellstr}, @var{pattern})
 @deftypefnx {} {@var{idx} =} strfind (@dots{}, "overlaps", @var{val})
+@deftypefnx {} {@var{idx} =} strfind (@dots{}, "forcecelloutput", @var{val})
 Search for @var{pattern} in the string @var{str} and return the starting
 index of every such occurrence in the vector @var{idx}.
 
@@ -165,6 +166,9 @@
 If a cell array of strings @var{cellstr} is specified then @var{idx} is a
 cell array of vectors, as specified above.
 
+The optional argument @qcode{"forcecelloutput"} forces @var{idx} to be
+returned as a cell array of vectors.  The default is false.
+
 Examples:
 
 @example
@@ -185,6 +189,14 @@
           [1,2] = [](1x0)
           [1,3] = [](1x0)
         @}
+
+strfind ("abababa", "aba", "forcecelloutput", true)
+     @result{}
+        @{
+          [1,1] =
+
+             1   3   5
+        @}
 @end group
 @end example
 @seealso{regexp, regexpi, find}
@@ -196,15 +208,19 @@
     print_usage ();
 
   bool overlaps = true;
+  bool forcecelloutput = false;
   if (nargin == 4)
     {
       if (! args(2).is_string () || ! args(3).is_scalar_type ())
         error ("strfind: invalid optional arguments");
 
       std::string opt = args(2).string_value ();
+      std::transform (opt.begin (), opt.end (), opt.begin (), tolower);
 
       if (opt == "overlaps")
         overlaps = args(3).bool_value ();
+      else if (opt == "forcecelloutput")
+        forcecelloutput = args(3).bool_value ();
       else
         error ("strfind: unknown option: %s", opt.c_str ());
     }
@@ -221,14 +237,18 @@
       qs_preprocess (needle, table);
 
       if (argstr.is_string ())
-        if (argpat.isempty ())
-          // 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);
+        {
+          if (argpat.isempty ())
+            // 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);
+          if (forcecelloutput)
+            retval = Cell (retval);
+        }
       else if (argstr.iscell ())
         {
           const Cell argsc = argstr.cell_value ();
@@ -266,7 +286,11 @@
 /*
 %!assert (strfind ("abababa", "aba"), [1, 3, 5])
 %!assert (strfind ("abababa", "aba", "overlaps", false), [1, 5])
+%!assert (strfind ("abababa", "aba", "forcecelloutput", false), [1, 3, 5])
+%!assert (strfind ("abababa", "aba", "forcecelloutput", true), {[1, 3, 5]})
 %!assert (strfind ({"abababa", "bla", "bla"}, "a"), {[1, 3, 5, 7], 3, 3})
+%!assert (strfind ({"abababa", "bla", "bla"}, "a", "forcecelloutput", false), {[1, 3, 5, 7], 3, 3})
+%!assert (strfind ({"abababa", "bla", "bla"}, "a", "forcecelloutput", true), {[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, []})