changeset 7658:1ce6460aebdf

nargoutchk.m, validatestring.m, addtodate.m: new functions
author bill@denney.ws
date Thu, 27 Mar 2008 15:14:10 -0400
parents 76e7548add3f
children 4ab2488ab2b4
files scripts/ChangeLog scripts/general/Makefile.in scripts/general/nargchk.m scripts/general/nargoutchk.m scripts/strings/Makefile.in scripts/strings/validatestring.m
diffstat 6 files changed, 243 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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  <bill@denney.ws>
 
+	* 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.
 
--- 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
 
--- 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)
--- /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
+## <http://www.gnu.org/licenses/>.
+
+## -*- 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 <bill@denney.ws>
+
+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)
--- 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))
 
--- /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
+## <http://www.gnu.org/licenses/>.
+
+## -*- 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 <bill@denney.ws>
+
+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")