-
Notifications
You must be signed in to change notification settings - Fork 2
/
process_options.m
132 lines (125 loc) · 4.42 KB
/
process_options.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
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
% PROCESS_OPTIONS - Processes options passed to a Matlab function.
% This function provides a simple means of
% parsing attribute-value options. Each option is
% named by a unique string and is given a default
% value.
%
% Usage: [var1, var2, ..., varn[, unused]] = ...
% process_options(args, ...
% str1, def1, str2, def2, ..., strn, defn)
%
% Arguments:
% args - a cell array of input arguments, such
% as that provided by VARARGIN. Its contents
% should alternate between strings and
% values.
% str1, ..., strn - Strings that are associated with a
% particular variable
% def1, ..., defn - Default values returned if no option
% is supplied
%
% Returns:
% var1, ..., varn - values to be assigned to variables
% unused - an optional cell array of those
% string-value pairs that were unused;
% if this is not supplied, then a
% warning will be issued for each
% option in args that lacked a match.
%
% Examples:
%
% Suppose we wish to define a Matlab function 'func' that has
% required parameters x and y, and optional arguments 'u' and 'v'.
% With the definition
%
% function y = func(x, y, varargin)
%
% [u, v] = process_options(varargin, 'u', 0, 'v', 1);
%
% calling func(0, 1, 'v', 2) will assign 0 to x, 1 to y, 0 to u, and 2
% to v. The parameter names are insensitive to case; calling
% func(0, 1, 'V', 2) has the same effect. The function call
%
% func(0, 1, 'u', 5, 'z', 2);
%
% will result in u having the value 5 and v having value 1, but
% will issue a warning that the 'z' option has not been used. On
% the other hand, if func is defined as
%
% function y = func(x, y, varargin)
%
% [u, v, unused_args] = process_options(varargin, 'u', 0, 'v', 1);
%
% then the call func(0, 1, 'u', 5, 'z', 2) will yield no warning,
% and unused_args will have the value {'z', 2}. This behaviour is
% useful for functions with options that invoke other functions
% with options; all options can be passed to the outer function and
% its unprocessed arguments can be passed to the inner function.
% Copyright (C) 2002 Mark A. Paskin
%
% 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 2 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, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
% USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [varargout] = process_options(args, varargin)
% Check the number of input arguments
n = length(varargin);
if (mod(n, 2))
error('Each option must be a string/value pair.');
end
% Check the number of supplied output arguments
if (nargout < (n / 2))
error('Insufficient number of output arguments given');
elseif (nargout == (n / 2))
warn = 1;
nout = n / 2;
else
warn = 0;
nout = n / 2 + 1;
end
% Set outputs to be defaults
varargout = cell(1, nout);
for i=2:2:n
varargout{i/2} = varargin{i};
end
% Now process all arguments
nunused = 0;
for i=1:2:length(args)
found = 0;
for j=1:2:n
if strcmpi(args{i}, varargin{j})
varargout{(j + 1)/2} = args{i + 1};
found = 1;
break;
end
end
if (~found)
if (warn)
warning(sprintf('Option ''%s'' not used.', args{i}));
args{i}
else
nunused = nunused + 1;
unused{2 * nunused - 1} = args{i};
unused{2 * nunused} = args{i + 1};
end
end
end
% Assign the unused arguments
if (~warn)
if (nunused)
varargout{nout} = unused;
else
varargout{nout} = cell(0);
end
end