changeset 13320:9da8fbd17b92

strchr.m: Tune switching between algorithms. Add error messages to input validation. * strchr.m: Switch to mask creation via indexing above 4 CHARS. Tell user what went wrong when input validation fails.
author Rik <octave@nomad.inbox5.com>
date Tue, 11 Oct 2011 13:18:40 -0700
parents eb0ce6ffefb0
children 5ea207067ee5
files scripts/strings/strchr.m
diffstat 1 files changed, 26 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/strings/strchr.m
+++ b/scripts/strings/strchr.m
@@ -20,8 +20,9 @@
 ## @deftypefn  {Function File} {@var{idx} =} strchr (@var{str}, @var{chars})
 ## @deftypefnx {Function File} {@var{idx} =} strchr (@var{str}, @var{chars}, @var{n})
 ## @deftypefnx {Function File} {@var{idx} =} strchr (@var{str}, @var{chars}, @var{n}, @var{direction})
+## @deftypefnx {Function File} {[@var{i}, @var{j}] =} strchr (@dots{})
 ## Search for the string @var{str} for occurrences of characters from
-## the set @var{chars}.  The return value, as well as the @var{n} and
+## the set @var{chars}.  The return value(s), as well as the @var{n} and
 ## @var{direction} arguments behave identically as in @code{find}.
 ##
 ## This will be faster than using regexp in most cases.
@@ -30,12 +31,18 @@
 ## @end deftypefn
 
 function varargout = strchr (str, chars, varargin)
-  if (nargin < 2 || ! ischar (str) || ! ischar (chars))
+
+  if (nargin < 2)
     print_usage ();
+  elseif (! ischar (str))
+    error ("strchr: STR argument must be a string or string array");
+  elseif (! ischar (chars))
+    error ("strchr: CHARS argument must be a string");
   endif
+
   if (isempty (chars))
     mask = false (size (str));
-  elseif (length (chars) <= 6)
+  elseif (length (chars) <= 4)
     ## With a few characters, it pays off to build the mask incrementally.
     ## We do it via a for loop to save memory.
     mask = str == chars(1);
@@ -43,22 +50,31 @@
       mask |= str == chars(i);
     endfor
   else
-    ## Index the str into a mask of valid values.  This is slower than
-    ## it could be because of the +1 issue.
-    f = false (1, 256);
+    ## Index the str into a mask of valid values.
+    ## This is slower than it could be because of the +1 issue.
+    f = false (256, 1);
     f(uint8(chars)+1) = true;
     ## Default goes via double -- unnecessarily long.
     si = uint32 (str);
-    ## in-place
+    ## in-place is faster than str+1
     ++si;
     mask = reshape (f(si), size (str));
   endif
+
   varargout = cell (1, nargout);
   varargout{1} = [];
   [varargout{:}] = find (mask, varargin{:});
+
 endfunction
 
-%!assert(strchr("Octave is the best software",""),zeros(1,0))
-%!assert(strchr("Octave is the best software","best"),[3, 6, 9, 11, 13, 15, 16, 17, 18, 20, 23, 27])
-%!assert(strchr("Octave is the best software","software"),[3, 4, 6, 9, 11, 13, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27])
+
+%!assert (strchr ("Octave is the best software", ""), zeros (1,0))
+%!assert (strchr ("Octave is the best software", "best"), [3, 6, 9, 11, 13, 15, 16, 17, 18, 20, 23, 27])
+%!assert (strchr ("Octave is the best software", "software"), [3, 4, 6, 9, 11, 13, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27])
 
+%% Test input validation
+%!error strchr ()
+%!error strchr (1)
+%!error <STR argument must be a string> strchr (1, "aeiou")
+%!error <CHARS argument must be a string> strchr ("aeiou", 1)
+