forked from milleratotago/ExtractNameVal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExtractNameVal.m
106 lines (91 loc) · 3.92 KB
/
ExtractNameVal.m
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
function [x, ArgList, PosOfArg] = ExtractNameVal(xName,xDefaultVal,ArgList,CaseSensitive,varargin)
% Process a single name/value pair within an argument list. The order of parameters is irrelevant.
%
% Set the parameter "x" to its value specified within an argument list of name-value pairs
% or else to its default value (if its name does not appear in the argument list).
%
% Note that xName can be a cell array if you want to allow synonyms for the name, e.g. {'Label', 'Labels'}
%
% Also return the shortened argument list "ArgList" after removing (xName,xValue)
% if they were present.
%
% The optional varargin is a string or cell array of strings used in assertions to check x.
% For example, 'x>0' would check that x was a positive number.
% For example, 'isa(x,''function_handle'')' would check that x was a function (note double quotes because isa requires a string descriptor).
%
% PosOfArg is the position in the output ArgList of the next argument following the (last) named argument pair.
% Example of usage to process a function's varargin's:
%
% function myfunction(parm1, parm2, varargin)
%
% % set Option1 to value specified in varargin or to default 1 (case insensitive):
% [Option1, varargin] = ExtractNameVal('Option1',1,varargin,false);
% % The following would be equivalent but would accept either Option1 or Option01 as the parameter name:
% % [Option1, varargin] = ExtractNameVal({'Option1', 'Option01'},1,varargin,false);
%
% % set Option2 to value specified in varargin or to default 10 (case insensitive):
% % also check to make sure the value of Option2 is positive.
% % note that the parameter list is now ArgList rather than myfunction's original varargin;
% % this is so we can check at the end whether all name-value pairs have been processed.
% [Option2, varargin] = ExtractNameVal('Option2',10,ArgList,false,'x>0');
%
% % Bomb if myfunction's varargin had any unprocessed parameters.
% assert(numel(varargin)==0,'Unprocessed parameters!');
%
% ... processing for myfunction
%
% end % myfunction
%
% TIP:
% To require that a parameter is specified, give a default value that
% does NOT satisfy the assertion, such as:
% [Option2, varargin] = ExtractNameVal('Option2',-10,ArgList,false,'x>0');
% This is useful when a second "required" parameter must be specified
% whenever a certain first "optional" parameter is specified.
%
% MODIFICATION NEEDED: It was a bad idea for ExtractNameVal to check for a
% required parameter by testing an assertion. In some use cases, I only
% want to check the assertion if the parameter is actually specified.
% It would be better to have a separate ExtractNameVal parameter to indicate
% whether the named input parameter is required.
x = xDefaultVal;
[xName, NSynonyms] = EnsureCell(xName);
NamePos = [];
for iPos=1:NSynonyms
if CaseSensitive
tempNamePos = find(strcmp(xName{iPos},ArgList));
else
tempNamePos = find(strcmpi(xName{iPos},ArgList));
end
NamePos = [NamePos tempNamePos];
end
NamePos = sort(NamePos);
NFound = numel(NamePos);
if NFound > 0
UsePos = 1; % Just use the first instance if the option is specified more than once.
x = ArgList{NamePos(UsePos)+1}; % Use the last value if the option was specified more than once.
% Remove the option's name and values from the argument list.
for iFnd = UsePos:-1:1
jPos = NamePos(iFnd);
ArgList(jPos+1) = [];
ArgList(jPos) = [];
end
PosOfArg = NamePos(1);
else
PosOfArg = NaN;
end
%if NFound > 1
% warning(['Parameter ' xName{1} ' specified more than once; only using the first value.']);
%end
% Check the assertions indicated by the varargin arguments, if any:
assertions = varargin;
if numel(assertions) == 0
return;
end
if ~iscell(assertions)
assertions = {assertions};
end
for iAssert=1:numel(assertions)
assert(eval(assertions{iAssert}),['Parameter ' xName{1} ' failed assertion ' assertions{iAssert}]);
end
end