# HG changeset patch # User bill@denney.ws # Date 1206645250 14400 # Node ID 1ce6460aebdf14e29463e2192d2483d8935fc25b # Parent 76e7548add3f55c21c0c19211183346387678020 nargoutchk.m, validatestring.m, addtodate.m: new functions diff -r 76e7548add3f -r 1ce6460aebdf scripts/ChangeLog --- a/scripts/ChangeLog Thu Mar 27 15:00:18 2008 -0400 +++ b/scripts/ChangeLog Thu Mar 27 15:14:10 2008 -0400 @@ -1,5 +1,11 @@ 2008-03-27 Bill Denney + * strings/validatestring.m: New function. + * strings/Makefile.in (SOURCES): Add it to the list. + + * general/nargoutchk.m: New function. + * general/Makefile.in (SOURCES): Add it to the list. + * general/genvarname.m: New function. * general/Makefile.in (SOURCES): Add it to the list. diff -r 76e7548add3f -r 1ce6460aebdf scripts/general/Makefile.in --- a/scripts/general/Makefile.in Thu Mar 27 15:00:18 2008 -0400 +++ b/scripts/general/Makefile.in Thu Mar 27 15:14:10 2008 -0400 @@ -38,11 +38,12 @@ cart2sph.m cell2mat.m celldisp.m circshift.m common_size.m \ cplxpair.m cumtrapz.m deal.m del2.m diff.m flipdim.m fliplr.m \ flipud.m genvarname.m gradient.m idivide.m ind2sub.m int2str.m \ - interp1.m interp2.m interp3.m interpn.m interpft.m is_duplicate_entry.m \ - isa.m isdefinite.m isdir.m isequal.m isequalwithequalnans.m \ - isscalar.m issquare.m issymmetric.m isvector.m logical.m logspace.m \ - lookup.m mod.m nargchk.m nextpow2.m nthroot.m num2str.m perror.m \ - pol2cart.m polyarea.m postpad.m prepad.m quadl.m randperm.m rat.m rem.m \ + interp1.m interp2.m interp3.m interpn.m interpft.m \ + is_duplicate_entry.m isa.m isdefinite.m isdir.m isequal.m \ + isequalwithequalnans.m isscalar.m issquare.m issymmetric.m \ + isvector.m logical.m logspace.m lookup.m mod.m nargchk.m \ + nargoutchk.m nextpow2.m nthroot.m num2str.m perror.m pol2cart.m \ + polyarea.m postpad.m prepad.m quadl.m randperm.m rat.m rem.m \ repmat.m rot90.m rotdim.m shift.m shiftdim.m sortrows.m \ sph2cart.m strerror.m structfun.m sub2ind.m trapz.m tril.m triu.m diff -r 76e7548add3f -r 1ce6460aebdf scripts/general/nargchk.m --- a/scripts/general/nargchk.m Thu Mar 27 15:00:18 2008 -0400 +++ b/scripts/general/nargchk.m Thu Mar 27 15:14:10 2008 -0400 @@ -25,6 +25,7 @@ ## ## This is useful for checking to see that the number of arguments supplied ## to a function is within an acceptable range. +## @seealso{nargoutchk, error, nargin, nargout} ## @end deftypefn ## Author: jwe @@ -36,7 +37,7 @@ endif if (nargin_min > nargin_max) - error ("nargchk: nargin_min > nargin_max"); + error ("nargchk: nargin_min > nargin_max"); endif if (n < nargin_min) diff -r 76e7548add3f -r 1ce6460aebdf scripts/general/nargoutchk.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/general/nargoutchk.m Thu Mar 27 15:14:10 2008 -0400 @@ -0,0 +1,84 @@ +## Copyright (C) 2008 Bill Denney +## +## 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 3 of the License, 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, see +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{msgstr} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs}) +## @deftypefnx {Function File} {@var{msgstr} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs}, "string") +## @deftypefnx {Function File} {@var{msgstruct} =} nargoutchk (@var{minargs}, @var{maxargs}, @var{nargs}, "struct") +## Return an appropriate error message string (or structure) if the +## number of outputs requested is invalid. +## +## This is useful for checking to see that the number of arguments supplied +## to a function is within an acceptable range. +## @seealso{nargchk, error, nargout, nargin} +## @end deftypefn + +## Author: Bill Denney + +function msg = nargoutchk (mina, maxa, narg, outtype) + + if (nargin < 3 || nargin > 4) + print_usage (); + elseif (mina > maxa) + error ("nargoutchk: minargs must be <= maxargs"); + elseif (nargin == 3) + outtype = "string"; + elseif (! any (strcmpi (outtype, {"string" "struct"}))) + error ("nargoutchk: output type must be either string or struct"); + elseif (! (isscalar (mina) && isscalar (maxa) && isscalar (narg))) + error ("nargoutchk: mina, maxa, and narg must be scalars"); + endif + + msg = struct ("message", "", "identifier", ""); + if (narg < mina) + msg.message = "not enough output arguments"; + msg.identifier = "Octave:nargoutchk:not-enough-outputs"; + elseif (narg > maxa) + msg.message = "too many output arguments"; + msg.identifier = "Octave:nargoutchk:too-many-outputs"; + endif + + if (strcmpi (outtype, "string")) + msg = msg.message; + else + if (isempty (msg.message)) + msg = struct ([]); + endif + ## FIXME: remove the error below if error is modified to accept + ## struct inputs + error ("nargoutchk: error does not yet support struct inputs") + endif + +endfunction + +## Tests +%!shared stmin, stmax +%! stmin = struct ("message", "not enough output arguments", +%! "identifier", "Octave:nargoutchk:not-enough-outputs"); +%! stmax = struct ("message", "too many output arguments", +%! "identifier", "Octave:nargoutchk:too-many-outputs"); +%!assert (nargoutchk (0, 1, 0), "") +%!assert (nargoutchk (0, 1, 1), "") +%!assert (nargoutchk (1, 1, 0), "not enough output arguments") +%!assert (nargoutchk (0, 1, 2), "too many output arguments") +%!assert (nargoutchk (0, 1, 2, "string"), "too many output arguments") +## Struct outputs +#%!assert (nargoutchk (0, 1, 0, "struct"), struct([])) +#%!assert (nargoutchk (0, 1, 1, "struct"), struct([])) +#%!assert (nargoutchk (1, 1, 0, "struct"), stmin) +#%!assert (nargoutchk (0, 1, 2, "struct"), stmax) diff -r 76e7548add3f -r 1ce6460aebdf scripts/strings/Makefile.in --- a/scripts/strings/Makefile.in Thu Mar 27 15:00:18 2008 -0400 +++ b/scripts/strings/Makefile.in Thu Mar 27 15:14:10 2008 -0400 @@ -1,6 +1,6 @@ # Makefile for octave's scripts/strings directory # -# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007 +# Copyright (C) 1994, 1995, 1996, 1997, 2002, 2005, 2006, 2007, 2008 # John W. Eaton # # This file is part of Octave. @@ -38,7 +38,7 @@ lower.m mat2str.m regexptranslate.m rindex.m split.m str2double.m str2mat.m \ str2num.m strcat.m cstrcat.m strcmpi.m strfind.m strjust.m strmatch.m \ strncmpi.m strrep.m strtok.m strtrim.m strtrunc.m strvcat.m \ - substr.m upper.m + substr.m upper.m validatestring.m DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES)) diff -r 76e7548add3f -r 1ce6460aebdf scripts/strings/validatestring.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/strings/validatestring.m Thu Mar 27 15:14:10 2008 -0400 @@ -0,0 +1,143 @@ +## Copyright (C) 2008 Bill Denney +## +## 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 3 of the License, 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, see +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}) +## @deftypefnx {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}, @var{funname}) +## @deftypefnx {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}, @var{funname}, @var{varname}) +## @deftypefnx {Function File} {@var{validstr} =} validatestring (@dots{}, @var{position}) +## Verify that @var{str} is a string or substring of an element of +## @var{strarray}. +## +## @var{str} is a character string to be tested, and @var{strarray} is a +## cellstr of valid values. @var{validstr} will be the validated form +## of @var{str} where validation is defined as @var{str} being a member +## or substring of @var{validstr}. If @var{str} is a substring of +## @var{validstr} and there are multiple matches, the shortest match +## will be returned if all matches are substrings of each other, and an +## error will be raised if the matches are not substrings of each other. +## +## All comparisons are case insensitive. +## @seealso{strcmp, strcmpi} +## @end deftypefn + +## Author: Bill Denney + +function str = validatestring (str, strarray, varargin) + + if (nargin < 2 || nargin > 5) + print_usage (); + endif + + ## set the defaults + funname = ""; + varname = ""; + position = 0; + ## set the actual values + if (! isempty (varargin)) + if (isnumeric (varargin{end})) + position = varargin{end}; + varargin(end) = []; + endif + endif + funnameset = false; + varnameset = false; + for i = 1:numel (varargin) + if (ischar (varargin{i})) + if (varnameset) + error ("validatestring: invalid number of character inputs: %d", + numel (varargin)); + elseif (funnameset) + varname = varargin{i}; + varnameset = true; + else + funname = varargin{i}; + funnameset = true; + endif + endif + endfor + + ## Check the inputs + if (! ischar (str)) + error ("validatestring: str must be a character string") + elseif (rows (str) != 1) + error ("validatestring: str must have only one row") + elseif (! iscellstr (strarray)) + error ("validatestring: strarray must be a cellstr") + elseif (! ischar (funname)) + error ("validatestring: funname must be a character string") + elseif (! isempty (funname) && (rows (funname) != 1)) + error ("validatestring: funname must be exactly one row") + elseif (! ischar (varname)) + error ("validatestring: varname must be a character string") + elseif (! isempty (varname) && (rows (varname) != 1)) + error ("validatestring: varname must be exactly one row") + elseif (position < 0) + error ("validatestring: position must be >= 0") + endif + + ## make the part of the error that will use funname, varname, and + ## position + errstr = ""; + if (! isempty (funname)) + errstr = sprintf ("Function: %s ", funname); + endif + if (! isempty (varname)) + errstr = sprintf ("%sVariable: %s ", errstr, varname); + endif + if (position > 0) + errstr = sprintf ("%sArgument position %d ", errstr, position); + endif + if (! isempty (errstr)) + errstr(end:end+1) = ":\n"; + endif + + matches = strncmpi (str, strarray(:), numel (str)); + nmatches = sum (matches); + if (nmatches == 1) + str = strarray{matches}; + elseif (nmatches == 0) + error ("validatestring: %s%s does not match any of\n%s", errstr, str, + sprintf ("%s, ", strarray{:})(1:end-1)); + else + ## are the matches a substring of each other, if so, choose the + ## shortest. If not, raise an error. + match_idx = find (matches); + match_l = cellfun (@length, strarray(match_idx)); + longest_idx = find (match_l == max (match_l), 1); + shortest_idx = find (match_l == min (match_l), 1); + longest = strarray(match_idx)(longest_idx); + for i = 1:numel(match_idx) + currentmatch = strarray(match_idx(i)); + if (! strncmpi (longest, currentmatch, length(currentmatch))) + error ("validatestring: %smultiple unique matches were found for %s:\n%s", + errstr, sprintf ("%s, ", strarray(match_idx))(1:end-2)); + endif + endfor + str = strarray{shortest_idx}; + endif + +endfunction + +## Tests +%!shared strarray +%! strarray = {"octave" "Oct" "octopus" "octaves"}; +%!assert (validatestring ("octave", strarray), "octave") +%!assert (validatestring ("oct", strarray), "Oct") +%!assert (validatestring ("octave", strarray), "octave") +%!assert (validatestring ("octav", strarray), "octave")