/usr/share/octave/packages/general-1.3.4/@inputParser/inputParser.m is in octave-general 1.3.4-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | ## Copyright (C) 2011-2012 Carnë Draug <carandraug+dev@gmail.com>
##
## This program 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.
##
## This program 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
## this program; if not, see <http://www.gnu.org/licenses/>.
## -*- texinfo -*-
## @deftypefn {Function File} {@var{parser} =} inputParser ()
## Create object @var{parser} of the inputParser class.
##
## This class is designed to allow easy parsing of function arguments. This class
## supports four types of arguments:
##
## @enumerate
## @item mandatory (see @command{@@inputParser/addRequired});
## @item optional (see @command{@@inputParser/addOptional});
## @item named (see @command{@@inputParser/addParamValue});
## @item switch (see @command{@@inputParser/addSwitch}).
## @end enumerate
##
## After defining the function API with this methods, the supplied arguments can
## be parsed with the @command{@@inputParser/parse} method and the parsing results
## accessed with the @command{Results} accessor.
##
## @deftypefnx {Accessor method} parser.Parameters
## Return list of parameters name already defined.
##
## @deftypefnx {Accessor method} parser.Results
## Return structure with argument names as fieldnames and corresponding values.
##
## @deftypefnx {Accessor method} parser.Unmatched
## Return structure similar to @command{Results} for unmatched parameters. See
## the @command{KeepUnmatched} property.
##
## @deftypefnx {Accessor method} parser.UsingDefaults
## Return cell array with the names of arguments that are using default values.
##
## @deftypefnx {Class property} parser.CaseSensitive = @var{boolean}
## Set whether matching of argument names should be case sensitive. Defaults to false.
##
## @deftypefnx {Class property} parser.FunctionName = @var{name}
## Set function name to be used on error messages. Defauls to empty string.
##
## @deftypefnx {Class property} parser.KeepUnmatched = @var{boolean}
## Set whether an error should be given for non-defined arguments. Defaults to
## false. If set to true, the extra arguments can be accessed through
## @code{Unmatched} after the @code{parse} method. Note that since @command{Switch}
## and @command{ParamValue} arguments can be mixed, it is not possible to know
## the unmatched type. If argument is found unmatched it is assumed to be of the
## @command{ParamValue} type and it is expected to be followed by a value.
##
## @deftypefnx {Class property} parser.StructExpand = @var{boolean}
## Set whether a structure can be passed to the function instead of parameter
## value pairs. Defaults to true. Not implemented yet.
##
## The following example shows how to use this class:
##
## @example
## @group
## function check (varargin)
## p = inputParser (); # create object
## p.FunctionName = "check"; # set function name
## p = p.addRequired ("pack", @@ischar); # create mandatory argument
##
## p = p.addOptional ("path", pwd(), @@ischar); # create optional argument
##
## ## one can create a function handle to anonymous functions for validators
## val_mat = @@(x) isvector (x) && all (x <= 1) && all (x >= 0);
## p = p.addOptional ("mat", [0 0], val_mat);
##
## ## create two ParamValue type of arguments
## val_type = @@(x) ischar (x) && any (strcmp (x, @{"linear", "quadratic"@}));
## p = p.addParamValue ("type", "linear", val_type);
## val_verb = @@(x) ischar (x) && any (strcmp (x, @{"low", "medium", "high"@}));
## p = p.addParamValue ("tolerance", "low", val_verb);
##
## ## create a switch type of argument
## p = p.addSwitch ("verbose");
##
## p = p.parse (varargin@{:@});
##
## ## the rest of the function can access the input by accessing p.Results
## ## for example, to access the value of tolerance, use p.Results.tolerance
## endfunction
##
## check ("mech"); # valid, will use defaults for other arguments
## check (); # error since at least one argument is mandatory
## check (1); # error since !ischar
## check ("mech", "~/dev"); # valid, will use defaults for other arguments
##
## check ("mech", "~/dev", [0 1 0 0], "type", "linear"); # valid
##
## ## the following is also valid. Note how the Switch type of argument can be
## ## mixed into or before the ParamValue (but still after Optional)
## check ("mech", "~/dev", [0 1 0 0], "verbose", "tolerance", "high");
##
## ## the following returns an error since not all optional arguments, `path' and
## ## `mat', were given before the named argument `type'.
## check ("mech", "~/dev", "type", "linear");
## @end group
## @end example
##
## @emph{Note 1}: a function can have any mixture of the four API types but they
## must appear in a specific order. @command{Required} arguments must be the very
## first which can be followed by @command{Optional} arguments. Only the
## @command{ParamValue} and @command{Switch} arguments can be mixed together but
## must be at the end.
##
## @emph{Note 2}: if both @command{Optional} and @command{ParamValue} arguments
## are mixed in a function API, once a string Optional argument fails to validate
## against, it will be considered the end of @command{Optional} arguments and the
## first key for a @command{ParamValue} and @command{Switch} arguments.
##
## @seealso{@@inputParser/addOptional, @@inputParser/addSwitch,
## @@inputParser/addParamValue, @@inputParser/addRequired,
## @@inputParser/createCopy, @@inputParser/parse}
## @end deftypefn
function inPar = inputParser
if (nargin != 0)
print_usage;
endif
inPar = struct;
## these are not to be accessed by users. Each will have a field whose names
## are the argnames which will also be a struct with fieldnames 'validator'
## and 'default'
inPar.ParamValue = struct;
inPar.Optional = struct;
inPar.Required = struct;
inPar.Switch = struct;
## this will be filled when the methodd parse is used and will be a struct whose
## fieldnames are the argnames that return their value
inPar.Results = struct;
## an 1xN cell array with argnames. It is read only by the user and its order
## showws the order that they were added to the object (which is the order they
## will be expected)
inPar.Parameters = {};
inPar.CaseSensitive = false;
inPar.FunctionName = ''; # name of the function for the error message
inPar.KeepUnmatched = false;
inPar.StructExpand = true;
inPar.Unmatched = struct;
inPar.UsingDefaults = {};
inPar = class (inPar, 'inputParser');
endfunction
%!shared p, out
%! p = inputParser;
%! p = p.addRequired ("req1", @(x) ischar (x));
%! p = p.addOptional ("op1", "val", @(x) ischar (x) && any (strcmp (x, {"val", "foo"})));
%! p = p.addOptional ("op2", 78, @(x) (x) > 50);
%! p = p.addSwitch ("verbose");
%! p = p.addParamValue ("line", "tree", @(x) ischar (x) && any (strcmp (x, {"tree", "circle"})));
%! ## check normal use, only required are given
%! out = p.parse ("file");
%!assert ({out.Results.req1, out.Results.op1, out.Results.op2, out.Results.verbose, out.Results.line},
%! {"file" , "val" , 78 , false , "tree"});
%!assert (out.UsingDefaults, {"op1", "op2", "verbose", "line"});
%! ## check normal use, but give values different than defaults
%! out = p.parse ("file", "foo", 80, "line", "circle", "verbose");
%!assert ({out.Results.req1, out.Results.op1, out.Results.op2, out.Results.verbose, out.Results.line},
%! {"file" , "foo" , 80 , true , "circle"});
%! ## check optional is skipped and considered ParamValue if unvalidated string
%! out = p.parse ("file", "line", "circle");
%!assert ({out.Results.req1, out.Results.op1, out.Results.op2, out.Results.verbose, out.Results.line},
%! {"file" , "val" , 78 , false , "circle"});
%! ## check case insensitivity
%! out = p.parse ("file", "foo", 80, "LiNE", "circle", "vERbOSe");
%!assert ({out.Results.req1, out.Results.op1, out.Results.op2, out.Results.verbose, out.Results.line},
%! {"file" , "foo" , 80 , true , "circle"});
%! ## check KeepUnmatched
%! p.KeepUnmatched = true;
%! out = p.parse ("file", "foo", 80, "line", "circle", "verbose", "extra", 50);
%!assert (out.Unmatched.extra, 50)
%! ## check error when missing required
%!error(p.parse())
%! ## check error when given required do not validate
%!error(p.parse(50))
%! ## check error when given optional do not validate
%!error(p.parse("file", "no-val"))
%! ## check error when given ParamValue do not validate
%!error(p.parse("file", "foo", 51, "line", "round"))
## check alternative method (obj), ...) API
%!shared p, out
%! p = inputParser;
%! p = addRequired (p, "req1", @(x) ischar (x));
%! p = addOptional (p, "op1", "val", @(x) ischar (x) && any (strcmp (x, {"val", "foo"})));
%! p = addOptional (p, "op2", 78, @(x) (x) > 50);
%! p = addSwitch (p, "verbose");
%! p = addParamValue (p, "line", "tree", @(x) ischar (x) && any (strcmp (x, {"tree", "circle"})));
%! ## check normal use, only required are given
%! out = parse (p, "file");
%!assert ({out.Results.req1, out.Results.op1, out.Results.op2, out.Results.verbose, out.Results.line},
%! {"file" , "val" , 78 , false , "tree"});
%!assert (out.UsingDefaults, {"op1", "op2", "verbose", "line"});
%! ## check normal use, but give values different than defaults
%! out = parse (p, "file", "foo", 80, "line", "circle", "verbose");
%!assert ({out.Results.req1, out.Results.op1, out.Results.op2, out.Results.verbose, out.Results.line},
%! {"file" , "foo" , 80 , true , "circle"});
## if we were matlab compatible...
%!shared p, out
%! p = inputParser;
%! p = p.addOptional ("op1", "val");
%! p = p.addParamValue ("line", "tree");
%!xtest assert (getfield (p.parse("line", "circle"), "Results"), struct ("op1", "val", "line", "circle"));
|