Mercurial > forge
changeset 9916:b3e680ea42ec octave-forge
@inputParser/addSwitch: implemented addSwitch method
author | carandraug |
---|---|
date | Fri, 30 Mar 2012 00:08:36 +0000 |
parents | 17258f439dc3 |
children | 884f4e76fe41 |
files | main/general/inst/@inputParser/addOptional.m main/general/inst/@inputParser/addParamValue.m main/general/inst/@inputParser/addRequired.m main/general/inst/@inputParser/addSwitch.m main/general/inst/@inputParser/createCopy.m main/general/inst/@inputParser/inputParser.m main/general/inst/@inputParser/parse.m main/general/inst/@inputParser/subsref.m |
diffstat | 8 files changed, 84 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/main/general/inst/@inputParser/addOptional.m Thu Mar 29 22:55:39 2012 +0000 +++ b/main/general/inst/@inputParser/addOptional.m Fri Mar 30 00:08:36 2012 +0000 @@ -34,7 +34,7 @@ ## @emph{Note}: if @command{ParamValue} arguments are also specified, all @command{Optional} ## arguments will have to be specified before. ## -## @seealso{inputParser, @@inputParser/addParamValue +## @seealso{inputParser, @@inputParser/addParamValue, @@inputParser/addSwitch, ## @@inputParser/addParamValue, @@inputParser/addRequired, @@inputParser/parse} ## @end deftypefn
--- a/main/general/inst/@inputParser/addParamValue.m Thu Mar 29 22:55:39 2012 +0000 +++ b/main/general/inst/@inputParser/addParamValue.m Fri Mar 30 00:08:36 2012 +0000 @@ -29,7 +29,7 @@ ## for the parameter with name @var{argname}. Alternatively, a function name ## can be used. ## -## @seealso{inputParser, @@inputParser/addOptional, +## @seealso{inputParser, @@inputParser/addOptional, @@inputParser/addSwitch, ## @@inputParser/addParamValue, @@inputParser/addRequired, @@inputParser/parse} ## @end deftypefn
--- a/main/general/inst/@inputParser/addRequired.m Thu Mar 29 22:55:39 2012 +0000 +++ b/main/general/inst/@inputParser/addRequired.m Fri Mar 30 00:08:36 2012 +0000 @@ -37,7 +37,7 @@ ## it must be the first (see @command{@@inputParser}). ## ## @seealso{inputParser, @@inputParser/addOptional, @@inputParser/addParamValue -## @@inputParser/addParamValue, @@inputParser/parse} +## @@inputParser/addParamValue, @@inputParser/addSwitch, @@inputParser/parse} ## @end deftypefn function inPar = addRequired (inPar, name, val)
--- a/main/general/inst/@inputParser/addSwitch.m Thu Mar 29 22:55:39 2012 +0000 +++ b/main/general/inst/@inputParser/addSwitch.m Fri Mar 30 00:08:36 2012 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2011 Carnë Draug <carandraug+dev@gmail.com> +## 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 @@ -14,11 +14,35 @@ ## this program; if not, see <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {@var{parser} =} addSwitch (@var{parser}, @var{argname}, @var{default}) -## @deftypefnx {Function File} {@var{parser} =} @var{parser}.addSwitch (@var{argname}, @var{default}) -## Not implemented yet +## @deftypefn {Function File} {@var{parser} =} addSwitch (@var{parser}, @var{argname}) +## @deftypefnx {Function File} {@var{parser} =} @var{parser}.addSwitch (@var{argname}) +## Add new switch type of argument to the object @var{parser} of inputParser class. +## +## This method belongs to the inputParser class and implements a switch +## arguments type of API. +## +## @var{argname} must be a string with the name of the new argument. Arguments +## of this type can be specified at the end, after @code{Required} and @code{Optional}, +## and mixed between the @code{ParamValue}. They default to false. If one of the +## arguments supplied is a string like @var{argname}, then after parsing the value +## of @var{parse}.Results.@var{argname} will be true. +## +## See @command{help @@inputParser} for examples. +## +## @seealso{inputParser, @@inputParser/addOptional, @@inputParser/addParamValue +## @@inputParser/addParamValue, @@inputParser/addRequired, @@inputParser/parse} ## @end deftypefn -function inPar = addSwitch (inPar, name, def) +function inPar = addSwitch (inPar, name) + + ## check @inputParser/subsref for the actual code + if (nargin == 2) + inPar = subsref (inPar, substruct( + '.' , 'addParamValue', + '()', {name} + )); + else + print_usage; + endif endfunction
--- a/main/general/inst/@inputParser/createCopy.m Thu Mar 29 22:55:39 2012 +0000 +++ b/main/general/inst/@inputParser/createCopy.m Fri Mar 30 00:08:36 2012 +0000 @@ -19,7 +19,7 @@ ## class. ## ## @seealso{inputParser, @@inputParser/addOptional, @@inputParser/addParamValue -## @@inputParser/addParamValue, @@inputParser/addRequired, +## @@inputParser/addParamValue, @@inputParser/addRequired, @@inputParser/addSwitch, ## @@inputParser/parse} ## @end deftypefn
--- a/main/general/inst/@inputParser/inputParser.m Thu Mar 29 22:55:39 2012 +0000 +++ b/main/general/inst/@inputParser/inputParser.m Fri Mar 30 00:08:36 2012 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2011 Carnë Draug <carandraug+dev@gmail.com> +## 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 @@ -24,7 +24,7 @@ ## @item mandatory (see @command{@@inputParser/addRequired}); ## @item optional (see @command{@@inputParser/addOptional}); ## @item named (see @command{@@inputParser/addParamValue}); -## @item switch (not implemented yet). +## @item switch (see @command{@@inputParser/addSwitch}). ## @end enumerate ## ## After defining the function API with this methods, the supplied arguments can @@ -53,7 +53,10 @@ ## @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. +## @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 @@ -77,13 +80,16 @@ ## ## 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, @{"silent", "verbose", "debug"@}); -## p = p.addParamValue ("verbosity", "silent", @@val_verb)'; +## 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 (pack, path, mat, varargin@{:@}); ## ## ## the rest of the function can access the input by accessing p.Results -## ## for example, to access the value of verbosity, use p.Results.verbosity +## ## for example, to access the value of tolerance, use p.Results.tolerance ## endfunction ## ## check ("mech"); # valid, will use defaults for other arguments @@ -93,6 +99,10 @@ ## ## 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"); @@ -107,7 +117,8 @@ ## ## @emph{Note 2}: if both @command{Optional} and @command{ParamValue} arguments ## are mixed in a function API, the user will have to specify @emph{all} -## @command{Optional} arguments before the @command{ParamValue} arguments. +## @command{Optional} arguments before the @command{ParamValue} and +## @command{Switch}arguments. ## ## @seealso{@@inputParser/addOptional, @@inputParser/addSwitch, ## @@inputParser/addParamValue, @@inputParser/addRequired, @@ -128,6 +139,7 @@ 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
--- a/main/general/inst/@inputParser/parse.m Thu Mar 29 22:55:39 2012 +0000 +++ b/main/general/inst/@inputParser/parse.m Fri Mar 30 00:08:36 2012 +0000 @@ -23,7 +23,7 @@ ## accessor. See @command{help inputParser} for a more complete description. ## ## @seealso{inputParser, @@inputParser/addOptional, @@inputParser/addParamValue -## @@inputParser/addParamValue, @@inputParser/addRequired} +## @@inputParser/addParamValue, @@inputParser/addRequired, @@inputParser/addSwitch} ## @end deftypefn function inPar = parse (inPar, varargin)
--- a/main/general/inst/@inputParser/subsref.m Thu Mar 29 22:55:39 2012 +0000 +++ b/main/general/inst/@inputParser/subsref.m Fri Mar 30 00:08:36 2012 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2011 Carnë Draug <carandraug+dev@gmail.com> +## 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 @@ -38,7 +38,7 @@ inPar = parse_args (inPar, idx); case 'Unmatched' case 'UsingDefaults' - case {'addOptional', 'addParamValue', 'addRequired'} + case {'addOptional', 'addParamValue', 'addRequired', 'addSwitch'} inPar = check_methods (inPar, idx); otherwise error ("invalid index for reference of class %s", class (inPar) ); @@ -109,39 +109,47 @@ inPar.Results.(name) = value; endfor - ## only ParamValue can be after Optional so their number must be even - if ( rem (numel (args), 2) ) - error("%sodd number of Parameter/Values arguments", inPar.FunctionName); - endif - ## loop a maximum #times of the number of ParamValue, taking pairs of keys and ## values out 'args'. We no longer expect an order so we need the index in ## 'copy' to remove it from there. Once ran out of 'args', move their name ## into usingDefaults, place their default values into 'Results', and break - for i = 1 : numel (fieldnames (inPar.ParamValue)) + for i = 1 : (numel (fieldnames (inPar.ParamValue)) + numel (fieldnames (inPar.Switch))) if ( !numel (args) ) ## loops the number of times left in 'copy' since these are the last type for n = 1 : numel (inPar.copy) [name, inPar.copy] = pop (inPar.copy); inPar.UsingDefaults = push (inPar.UsingDefaults, name); - inPar.Results.(name) = inPar.ParamValue.(name).default; + if (isfield (inPar.ParamValue, name)) + inPar.Results.(name) = inPar.ParamValue.(name).default; + else + inPar.Results.(name) = inPar.Switch.(name).default; + endif endfor break endif - [key, args] = pop (args); - [value, args] = pop (args); + [key, args] = pop (args); if ( !ischar (key) ) - error("%sParameter names must be strings", inPar.FunctionName); + error("%sParameter/Switch names must be strings", inPar.FunctionName); endif if (inPar.CaseSensitive) index = find( strcmp(inPar.copy, key)); else index = find( strcmpi(inPar.copy, key)); endif + ## we can't use isfield here to support case insensitive + if (any (strcmpi (fieldnames (inPar.Switch), key))) + value = true; + method = "Switch"; + else + ## then it must be a ParamValue, pop its value + [value, args] = pop (args); + method = "ParamValue"; + endif + ## index == 0 means no match so either return error or move them into 'Unmatched' if ( index != 0 ) [name, inPar.copy] = pop (inPar.copy, index); - if ( !feval (inPar.ParamValue.(name).validator, value) ) + if ( !feval (inPar.(method).(name).validator, value)) error("%sinvalid value for parameter '%s'", inPar.FunctionName, key); endif ## we use the name popped from 'copy' instead of the key from 'args' in case @@ -188,7 +196,7 @@ ## a validator is optional but that complicates handling all the parsing with ## few functions and conditions. If not specified @() true will always return ## true. Simply using true is not enough because if the argument is zero it - ## return false and it it's too large, takes up memory + ## return false and if it's too large, takes up memory switch method case {'addOptional', 'addParamValue'} if ( numel (args) == 1 ) @@ -208,6 +216,9 @@ print_usage(func); endif def = false; + case {'addSwitch'} + val = def_val; + def = false; otherwise error ("invalid index for reference of class %s", class (inPar) ); endswitch @@ -238,13 +249,14 @@ endif ## because the order arguments are specified are the order they are expected, - ## can't have ParamValue before Optional, and Optional before Required + ## can't have ParamValue/Switch before Optional, and Optional before Required n_optional = numel (fieldnames (inPar.Optional)); n_params = numel (fieldnames (inPar.ParamValue)); - if ( strcmp (method, 'Required') && ( n_optional || n_params ) ) - error ("Can't specify 'Required' arguments after Optional or ParamValue"); - elseif ( strcmp (method, 'Optional') && n_params ) - error ("Can't specify 'Required' arguments after Optional or ParamValue"); + n_switch = numel (fieldnames (inPar.Switch)); + if ( strcmp (method, 'Required') && ( n_optional || n_params || n_switch) ) + error ("Can't specify 'Required' arguments after Optional, ParamValue or Switch"); + elseif ( strcmp (method, 'Optional') && ( n_params || n_switch) ) + error ("Can't specify 'Optional' arguments after ParamValue or Switch"); endif ## even if CaseSensitive is turned on, we still shouldn't have two args with