matthiasm@8: % PROCESS_OPTIONS - Processes options passed to a Matlab function. matthiasm@8: % This function provides a simple means of matthiasm@8: % parsing attribute-value options. Each option is matthiasm@8: % named by a unique string and is given a default matthiasm@8: % value. matthiasm@8: % matthiasm@8: % Usage: [var1, var2, ..., varn[, unused]] = ... matthiasm@8: % process_options(args, ... matthiasm@8: % str1, def1, str2, def2, ..., strn, defn) matthiasm@8: % matthiasm@8: % Arguments: matthiasm@8: % args - a cell array of input arguments, such matthiasm@8: % as that provided by VARARGIN. Its contents matthiasm@8: % should alternate between strings and matthiasm@8: % values. matthiasm@8: % str1, ..., strn - Strings that are associated with a matthiasm@8: % particular variable matthiasm@8: % def1, ..., defn - Default values returned if no option matthiasm@8: % is supplied matthiasm@8: % matthiasm@8: % Returns: matthiasm@8: % var1, ..., varn - values to be assigned to variables matthiasm@8: % unused - an optional cell array of those matthiasm@8: % string-value pairs that were unused; matthiasm@8: % if this is not supplied, then a matthiasm@8: % warning will be issued for each matthiasm@8: % option in args that lacked a match. matthiasm@8: % matthiasm@8: % Examples: matthiasm@8: % matthiasm@8: % Suppose we wish to define a Matlab function 'func' that has matthiasm@8: % required parameters x and y, and optional arguments 'u' and 'v'. matthiasm@8: % With the definition matthiasm@8: % matthiasm@8: % function y = func(x, y, varargin) matthiasm@8: % matthiasm@8: % [u, v] = process_options(varargin, 'u', 0, 'v', 1); matthiasm@8: % matthiasm@8: % calling func(0, 1, 'v', 2) will assign 0 to x, 1 to y, 0 to u, and 2 matthiasm@8: % to v. The parameter names are insensitive to case; calling matthiasm@8: % func(0, 1, 'V', 2) has the same effect. The function call matthiasm@8: % matthiasm@8: % func(0, 1, 'u', 5, 'z', 2); matthiasm@8: % matthiasm@8: % will result in u having the value 5 and v having value 1, but matthiasm@8: % will issue a warning that the 'z' option has not been used. On matthiasm@8: % the other hand, if func is defined as matthiasm@8: % matthiasm@8: % function y = func(x, y, varargin) matthiasm@8: % matthiasm@8: % [u, v, unused_args] = process_options(varargin, 'u', 0, 'v', 1); matthiasm@8: % matthiasm@8: % then the call func(0, 1, 'u', 5, 'z', 2) will yield no warning, matthiasm@8: % and unused_args will have the value {'z', 2}. This behaviour is matthiasm@8: % useful for functions with options that invoke other functions matthiasm@8: % with options; all options can be passed to the outer function and matthiasm@8: % its unprocessed arguments can be passed to the inner function. matthiasm@8: matthiasm@8: % Copyright (C) 2002 Mark A. Paskin matthiasm@8: % matthiasm@8: % This program is free software; you can redistribute it and/or modify matthiasm@8: % it under the terms of the GNU General Public License as published by matthiasm@8: % the Free Software Foundation; either version 2 of the License, or matthiasm@8: % (at your option) any later version. matthiasm@8: % matthiasm@8: % This program is distributed in the hope that it will be useful, but matthiasm@8: % WITHOUT ANY WARRANTY; without even the implied warranty of matthiasm@8: % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU matthiasm@8: % General Public License for more details. matthiasm@8: % matthiasm@8: % You should have received a copy of the GNU General Public License matthiasm@8: % along with this program; if not, write to the Free Software matthiasm@8: % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 matthiasm@8: % USA. matthiasm@8: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% matthiasm@8: matthiasm@8: function [varargout] = process_options(args, varargin) matthiasm@8: matthiasm@8: % Check the number of input arguments matthiasm@8: n = length(varargin); matthiasm@8: if (mod(n, 2)) matthiasm@8: error('Each option must be a string/value pair.'); matthiasm@8: end matthiasm@8: matthiasm@8: % Check the number of supplied output arguments matthiasm@8: if (nargout < (n / 2)) matthiasm@8: error('Insufficient number of output arguments given'); matthiasm@8: elseif (nargout == (n / 2)) matthiasm@8: warn = 1; matthiasm@8: nout = n / 2; matthiasm@8: else matthiasm@8: warn = 0; matthiasm@8: nout = n / 2 + 1; matthiasm@8: end matthiasm@8: matthiasm@8: % Set outputs to be defaults matthiasm@8: varargout = cell(1, nout); matthiasm@8: for i=2:2:n matthiasm@8: varargout{i/2} = varargin{i}; matthiasm@8: end matthiasm@8: matthiasm@8: % Now process all arguments matthiasm@8: nunused = 0; matthiasm@8: for i=1:2:length(args) matthiasm@8: found = 0; matthiasm@8: for j=1:2:n matthiasm@8: if strcmpi(args{i}, varargin{j}) matthiasm@8: varargout{(j + 1)/2} = args{i + 1}; matthiasm@8: found = 1; matthiasm@8: break; matthiasm@8: end matthiasm@8: end matthiasm@8: if (~found) matthiasm@8: if (warn) matthiasm@8: warning(sprintf('Option ''%s'' not used.', args{i})); matthiasm@8: args{i} matthiasm@8: else matthiasm@8: nunused = nunused + 1; matthiasm@8: unused{2 * nunused - 1} = args{i}; matthiasm@8: unused{2 * nunused} = args{i + 1}; matthiasm@8: end matthiasm@8: end matthiasm@8: end matthiasm@8: matthiasm@8: % Assign the unused arguments matthiasm@8: if (~warn) matthiasm@8: if (nunused) matthiasm@8: varargout{nout} = unused; matthiasm@8: else matthiasm@8: varargout{nout} = cell(0); matthiasm@8: end matthiasm@8: end