# HG changeset patch # User Jaroslav Hajek # Date 1263283422 -3600 # Node ID 76df75b10c800b5a81482695920c1bb65703b2da # Parent 82d47b70642404151336dba0669cbacfddb4f4de allow more cells in strfind/strrep + supply a general mechanism diff -r 82d47b706424 -r 76df75b10c80 src/ChangeLog --- a/src/ChangeLog Mon Jan 11 22:38:08 2010 -0800 +++ b/src/ChangeLog Tue Jan 12 09:03:42 2010 +0100 @@ -1,3 +1,12 @@ +2010-01-12 Jaroslav Hajek + + * oct-obj.cc (octave_value_list::any_cell): New method. + * oct-obj.h: Declare it. + * utils.cc (do_simple_cellfun): New overloaded function. + * utils.h: Declare it. + * DLD-FUNCTIONS/strfind.cc (Fstrfind): Call it here. + (Fstrrep): Also here. + 2010-01-11 Rik * Makefile.am: Update DOCSTRINGS rules to avoid simple_move_if_change_rule diff -r 82d47b706424 -r 76df75b10c80 src/DLD-FUNCTIONS/strfind.cc --- a/src/DLD-FUNCTIONS/strfind.cc Mon Jan 11 22:38:08 2010 -0800 +++ b/src/DLD-FUNCTIONS/strfind.cc Tue Jan 12 09:03:42 2010 +0100 @@ -151,10 +151,10 @@ if (nargin == 2) { - octave_value argstr = args(0), argp = args(1); - if (argp.is_string ()) + octave_value argstr = args(0), argpat = args(1); + if (argpat.is_string ()) { - Array needle = argp.char_array_value (); + Array needle = argpat.char_array_value (); OCTAVE_LOCAL_BUFFER (octave_idx_type, table, UCHAR_MAX); qs_preprocess (needle, table); @@ -185,8 +185,10 @@ else error ("strfind: first argument must be a string or cell array of strings"); } + else if (argpat.is_cell ()) + retval = do_simple_cellfun (Fstrfind, "strfind", args); else - error ("strfind: pattern must be a string"); + error ("strfind: pattern must be a string or cell array of strings"); } else print_usage (); @@ -269,11 +271,11 @@ if (nargin == 3) { - octave_value argstr = args(0), argp = args(1), argr = args(2); - if (argp.is_string () && argr.is_string ()) + octave_value argstr = args(0), argpat = args(1), argrep = args(2); + if (argpat.is_string () && argrep.is_string ()) { - const Array pat = argp.char_array_value (); - const Array rep = argr.char_array_value (); + const Array pat = argpat.char_array_value (); + const Array rep = argrep.char_array_value (); OCTAVE_LOCAL_BUFFER (octave_idx_type, table, UCHAR_MAX); qs_preprocess (pat, table); @@ -303,8 +305,10 @@ else error ("strrep: first argument must be a string or cell array of strings"); } + else if (argpat.is_cell () || argrep.is_cell ()) + retval = do_simple_cellfun (Fstrrep, "strrep", args); else - error ("strrep: 2rd and 3rd arguments must be strings"); + error ("strrep: x and y arguments must be strings or cell arrays of strings"); } else print_usage (); diff -r 82d47b706424 -r 76df75b10c80 src/oct-obj.cc --- a/src/oct-obj.cc Mon Jan 11 22:38:08 2010 -0800 +++ b/src/oct-obj.cc Tue Jan 12 09:03:42 2010 +0100 @@ -188,6 +188,19 @@ } bool +octave_value_list::any_cell (void) const +{ + bool retval = false; + octave_idx_type n = length (); + + for (octave_idx_type i = 0; i < n; i++) + if (retval = elem (i).is_cell ()) + break; + + return retval; +} + +bool octave_value_list::has_magic_colon (void) const { octave_idx_type n = length (); diff -r 82d47b706424 -r 76df75b10c80 src/oct-obj.h --- a/src/oct-obj.h Mon Jan 11 22:38:08 2010 -0800 +++ b/src/oct-obj.h Tue Jan 12 09:03:42 2010 +0100 @@ -137,6 +137,8 @@ bool all_scalars (void) const; + bool any_cell (void) const; + bool has_magic_colon (void) const; string_vector make_argv (const std::string& = std::string()) const; diff -r 82d47b706424 -r 76df75b10c80 src/utils.cc --- a/src/utils.cc Mon Jan 11 22:38:08 2010 -0800 +++ b/src/utils.cc Tue Jan 12 09:03:42 2010 +0100 @@ -1397,6 +1397,98 @@ return retval; } +octave_value_list +do_simple_cellfun (octave_value_list (*fun) (const octave_value_list&, int), + const char *fun_name, const octave_value_list& args, + int nargout) +{ + octave_value_list new_args = args, retval; + int nargin = args.length (); + OCTAVE_LOCAL_BUFFER (bool, iscell, nargin); + OCTAVE_LOCAL_BUFFER (Cell, cells, nargin); + OCTAVE_LOCAL_BUFFER (Cell, rcells, nargout); + + const Cell *ccells = cells; + + octave_idx_type numel = 1; + dim_vector dims (1, 1); + + for (int i = 0; i < nargin; i++) + { + octave_value arg = new_args(i); + iscell[i] = arg.is_cell (); + if (iscell[i]) + { + cells[i] = arg.cell_value (); + octave_idx_type n = ccells[i].numel (); + if (n == 1) + { + iscell[i] = false; + new_args(i) = ccells[i](0); + } + else if (numel == 1) + { + numel = n; + dims = ccells[i].dims (); + } + else if (dims != ccells[i].dims ()) + { + error ("%s: cell arguments must have matching sizes", fun_name); + break; + } + } + } + + if (! error_state) + { + for (int i = 0; i < nargout; i++) + rcells[i].clear (dims); + + for (octave_idx_type j = 0; j < numel; j++) + { + for (int i = 0; i < nargin; i++) + if (iscell[i]) + new_args(i) = ccells[i](j); + + OCTAVE_QUIT; + + const octave_value_list tmp = fun (new_args, nargout); + + if (tmp.length () < nargout) + { + error ("%s: do_simple_cellfun: internal error", fun_name); + break; + } + else + { + for (int i = 0; i < nargout; i++) + rcells[i](j) = tmp(i); + } + } + } + + if (! error_state) + { + retval.resize (nargout); + for (int i = 0; i < nargout; i++) + retval(i) = rcells[i]; + } + + return retval; +} + +octave_value +do_simple_cellfun (octave_value_list (*fun) (const octave_value_list&, int), + const char *fun_name, const octave_value_list& args) +{ + octave_value retval; + const octave_value_list tmp = do_simple_cellfun (fun, fun_name, args, 1); + if (tmp.length () > 0) + retval = tmp(0); + + return retval; +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff -r 82d47b706424 -r 76df75b10c80 src/utils.h --- a/src/utils.h Mon Jan 11 22:38:08 2010 -0800 +++ b/src/utils.h Tue Jan 12 09:03:42 2010 +0100 @@ -126,6 +126,16 @@ extern "C" OCTINTERP_API int octave_raw_vsnprintf (char *buf, size_t n, const char *fmt, va_list args); +extern OCTINTERP_API +octave_value_list +do_simple_cellfun (octave_value_list (*fun) (const octave_value_list&, int), + const char *fun_name, const octave_value_list& args, + int nargout); + +extern OCTINTERP_API +octave_value +do_simple_cellfun (octave_value_list (*fun) (const octave_value_list&, int), + const char *fun_name, const octave_value_list& args); #endif /*