X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=octave_packages%2Fm%2Fstrings%2Fvalidatestring.m;fp=octave_packages%2Fm%2Fstrings%2Fvalidatestring.m;h=08877c062ebdbd62a7df19c763964d54e9978d30;hb=1c0469ada9531828709108a4882a751d2816994a;hp=0000000000000000000000000000000000000000;hpb=63de9f36673d49121015e3695f2c336ea92bc278;p=CreaPhase.git diff --git a/octave_packages/m/strings/validatestring.m b/octave_packages/m/strings/validatestring.m new file mode 100644 index 0000000..08877c0 --- /dev/null +++ b/octave_packages/m/strings/validatestring.m @@ -0,0 +1,163 @@ +## Copyright (C) 2008-2012 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{funcname}) +## @deftypefnx {Function File} {@var{validstr} =} validatestring (@var{str}, @var{strarray}, @var{funcname}, @var{varname}) +## @deftypefnx {Function File} {@var{validstr} =} validatestring (@dots{}, @var{position}) +## Verify that @var{str} is an element, or substring of an element, in +## @var{strarray}. +## +## When @var{str} is a character string to be tested, and @var{strarray} is a +## cellstr of valid values, then @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}. This is useful for both verifying +## and expanding short options, such as "r", to their longer forms, such as +## "red". 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. Otherwise, an error will be raised because the +## expansion of @var{str} is ambiguous. All comparisons are case insensitive. +## +## The additional inputs @var{funcname}, @var{varname}, and @var{position} +## are optional and will make any generated validation error message more +## specific. +## +## Examples: +## @c Set example in small font to prevent overfull line +## +## @smallexample +## @group +## validatestring ("r", @{"red", "green", "blue"@}) +## @result{} "red" +## +## validatestring ("b", @{"red", "green", "blue", "black"@}) +## @result{} error: validatestring: multiple unique matches were found for 'b': +## blue, black +## @end group +## @end smallexample +## +## @seealso{strcmp, strcmpi} +## @end deftypefn + +## Author: Bill Denney + +function str = validatestring (str, strarray, varargin) + + if (nargin < 2 || nargin > 5) + print_usage (); + endif + + position = 0; + ## Process input arguments + if (! isempty (varargin) && isnumeric (varargin{end})) + position = varargin{end}; + varargin(end) = []; + endif + + funcname = varname = ""; + char_idx = cellfun ("isclass", varargin, "char"); + n_chararg = sum (char_idx); + if (n_chararg > 2) + error ("validatestring: invalid number of character inputs (3)"); + elseif (n_chararg == 2) + [funcname, varname] = deal (varargin{char_idx}); + elseif (n_chararg == 1) + funcname = varargin{char_idx}; + endif + + ## Check the inputs + if (! ischar (str)) + error ("validatestring: STR must be a character string"); + elseif (! isrow (str)) + error ("validatestring: STR must be a single row vector"); + elseif (! iscellstr (strarray)) + error ("validatestring: STRARRAY must be a cellstr"); + elseif (! isempty (funcname) && ! isrow (funcname)) + error ("validatestring: FUNCNAME must be a single row vector"); + elseif (! isempty (varname) && ! isrow (varname)) + error ("validatestring: VARNAME must be a single row vector"); + elseif (position < 0) + error ("validatestring: POSITION must be >= 0"); + endif + + ## Make static part of error string that uses funcname, varname, and position + errstr = ""; + if (! isempty (funcname)) + errstr = sprintf ("Function: %s ", funcname); + 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 == 0) + error ("validatestring: %s'%s' does not match any of\n%s", errstr, str, + sprintf ("%s, ", strarray{:})(1:end-2)); + elseif (nmatches == 1) + str = strarray{matches}; + else + ## Are the matches substrings of each other? + ## If true, choose the shortest. If not, raise an error. + match_idx = find (matches); + match_len = cellfun ("length", strarray(match_idx)); + [min_len, min_idx] = min (match_len); + short_str = strarray{match_idx(min_idx)}; + submatch = strncmpi (short_str, strarray(match_idx), min_len); + if (all (submatch)) + str = short_str; + else + error ("validatestring: %smultiple unique matches were found for '%s':\n%s", + errstr, str, sprintf ("%s, ", strarray{match_idx})(1:end-2)); + endif + endif + +endfunction + + +%!shared strarray +%! strarray = {"octave" "Oct" "octopus" "octaves"}; +%!assert (validatestring ("octave", strarray), "octave") +%!assert (validatestring ("oct", strarray), "Oct") +%!assert (validatestring ("octa", strarray), "octave") +%! strarray = {"abc1" "def" "abc2"}; +%!assert (validatestring ("d", strarray), "def") +%!error <'xyz' does not match any> validatestring ("xyz", strarray) +%!error validatestring ("xyz", strarray, "DUMMY_TEST") +%!error validatestring ("xyz", strarray, "DUMMY_TEST", "DUMMY_VAR") +%!error validatestring ("xyz", strarray, "DUMMY_TEST", "DUMMY_VAR", 5) +%!error validatestring ("abc", strarray) + +%% Test input validation +%!error validatestring ("xyz") +%!error validatestring ("xyz", {"xyz"}, "3", "4", 5, 6) +%!error validatestring ("xyz", {"xyz"}, "3", "4", "5") +%!error validatestring (1, {"xyz"}, "3", "4", 5) +%!error validatestring ("xyz".', {"xyz"}, "3", "4", 5) +%!error validatestring ("xyz", "xyz", "3", "4", 5) +%!error validatestring ("xyz", {"xyz"}, "33".', "4", 5) +%!error validatestring ("xyz", {"xyz"}, "3", "44".', 5) +%!error validatestring ("xyz", {"xyz"}, "3", "4", -5) +