1 %
finputcheck() - check Matlab
function {
'key',
'value'} input argument pairs
3 % Usage: >> result =
finputcheck( varargin, fieldlist );
4 % >> [result varargin] =
finputcheck( varargin, fieldlist, ...
5 % callingfunc, mode, verbose );
7 % varargin - Cell array
'varargin' argument from a
function call
using 'key',
8 %
'value' argument pairs. See Matlab
function 'varargin'.
9 % May also be a structure such as
struct(varargin{:})
10 % fieldlist - A 4-column cell array, one row per
'key'. The first
11 % column contains the key
string, the second its type(s),
12 % the third the accepted value range, and the fourth the
13 %
default value. Allowed types are
'boolean',
'integer',
14 %
'real',
'string',
'cell' or
'struct'. For example,
15 % {
'key1' 'string' {
'string1' 'string2' }
'defaultval_key1'}
16 % {
'key2' {
'real' 'integer'} { minint maxint }
'defaultval_key2'}
17 % callingfunc - Calling
function name
for error messages. {
default: none}.
18 % mode - [
'ignore'|
'error'] ignore keywords that are either not specified
19 % in the fieldlist cell array or generate an error.
21 % verbose - [
'verbose',
'quiet'] print information. Default:
'verbose'.
24 % result - If no error, structure with
'key' as fields and
'value' as
25 % content. If error
this output contain the
string error.
26 % varargin - residual varagin containing unrecognized input arguments.
27 % Requires mode
'ignore' above.
29 % Note: In
case of error, a
string is returned containing the error message
30 % instead of a structure.
32 % Example (insert the following at the beginning of your
function):
34 % {
'title' 'string' []
''; ...
35 %
'percent' 'real' [0 1] 1 ; ...
36 %
'elecamp' 'integer' [1:10] [] });
42 % The
'title' argument should be a
string. {no
default value}
43 % The
'percent' argument should be a real number between 0 and 1. {
default: 1}
44 % The
'elecamp' argument should be an integer between 1 and 10 (inclusive).
46 % Now
'g.title' will contain the title arg (
if any,
else the
default ''), etc.
48 % Author: Arnaud Delorme, CNL / Salk Institute, 10 July 2002
50 % Copyright (C) Arnaud Delorme, CNL / Salk Institute, 10 July 2002, arno@salk.edu
52 % This program is free software; you can redistribute it and/or modify
53 % it under the terms of the GNU General Public License as published by
54 % the Free Software Foundation; either version 2 of the License, or
55 % (at your option) any later version.
57 % This program is distributed in the hope that it will be useful,
58 % but WITHOUT ANY WARRANTY; without even the implied warranty of
59 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60 % GNU General Public License
for more details.
62 % You should have received a copy of the GNU General Public License
63 % along with
this program;
if not, write to the Free Software
64 % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
66 function [g, varargnew] =
finputcheck( vararg, fieldlist, callfunc, mode, verbose )
75 callfunc = [callfunc
' ' ];
78 mode =
'do not ignore';
96 for index=1:length(vararg)
97 if iscell(vararg{index})
98 vararg{index} = {vararg{index}};
102 g =
struct(vararg{:});
106 g =
struct(vararg{:});
108 g = [ callfunc
'error: bad ''key'', ''val'' sequence' ];
return;
116 for index = 1:size(fieldlist,NAME)
119 if ~isfield(g, fieldlist{index, NAME})
120 g = setfield( g, fieldlist{index, NAME}, fieldlist{index, DEF});
122 tmpval = getfield( g, {1}, fieldlist{index, NAME});
126 if ~iscell( fieldlist{index, TYPE} )
127 res =
fieldtest( fieldlist{index, NAME}, fieldlist{index, TYPE}, ...
128 fieldlist{index, VALS}, tmpval, callfunc );
129 if isstr(res), g = res;
return; end;
133 for it = 1:length( fieldlist{index, TYPE} )
134 if ~iscell(fieldlist{index, VALS})
135 res{it} =
fieldtest( fieldlist{index, NAME}, fieldlist{index, TYPE}{it}, ...
136 fieldlist{index, VALS}, tmpval, callfunc );
137 else res{it} =
fieldtest( fieldlist{index, NAME}, fieldlist{index, TYPE}{it}, ...
138 fieldlist{index, VALS}{it}, tmpval, callfunc );
140 if ~isstr(res{it}), testres = 1; end;
144 for tmpi = 2:length(res)
145 g = [ g 10
'or ' res{tmpi} ];
152 % check
if fields are defined
153 % ---------------------------
154 allfields = fieldnames(g);
155 for index=1:length(allfields)
156 if isempty(strmatch(allfields{index}, fieldlist(:, 1)
', 'exact
'))
157 if ~strcmpi(mode, 'ignore
')
158 g = [ callfunc 'error: undefined argument
''' allfields{index}
'''']; return;
160 varargnew{end+1} = allfields{index};
161 varargnew{end+1} = getfield(g, {1}, allfields{index});
166 function g = fieldtest( fieldname, fieldtype, fieldval, tmpval, callfunc );
175 case { 'integer
' 'real
' 'boolean' 'float' },
176 if ~isnumeric(tmpval) && ~islogical(tmpval)
177 g = [ callfunc 'error: argument
''' fieldname
''' must be numeric
' ]; return;
179 if strcmpi(fieldtype, 'boolean')
180 if tmpval ~=0 && tmpval ~= 1
181 g = [ callfunc 'error: argument
''' fieldname
''' must be 0 or 1
' ]; return;
184 if strcmpi(fieldtype, 'integer
')
185 if ~isempty(fieldval)
186 if (any(isnan(tmpval(:))) && ~any(isnan(fieldval))) ...
187 && (~ismember(tmpval, fieldval))
188 g = [ callfunc 'error: wrong value
for argument
''' fieldname
'''' ]; return;
192 if ~isempty(fieldval) && ~isempty(tmpval)
193 if any(tmpval < fieldval(1)) || any(tmpval > fieldval(2))
194 g = [ callfunc 'error: value out of range
for argument
''' fieldname
'''' ]; return;
203 g = [ callfunc 'error: argument
''' fieldname
''' must be a
string' ]; return;
205 if ~isempty(fieldval)
206 if isempty(strmatch(lower(tmpval), lower(fieldval), 'exact
'))
207 g = [ callfunc 'error: wrong value
for argument
''' fieldname
'''' ]; return;
214 g = [ callfunc 'error: argument
''' fieldname
''' must be a cell array
' ]; return;
220 g = [ callfunc 'error: argument
''' fieldname
''' must be a structure
' ]; return;
225 otherwise, error([ 'finputcheck error: unrecognized type
''' fieldname
'''' ]);
228 % remove duplicates in the list of parameters
229 % -------------------------------------------
230 function cella = removedup(cella, verbose)
231 % make sure if all the values passed to unique() are strings, if not, exist
233 [tmp indices] = unique(cella(1:2:end));
234 if length(tmp) ~= length(cella)/2
235 myfprintf(verbose,'Note: duplicate
''key
'',
''val
'' parameter(s), keeping the last one(s)\n
');
237 cella = cella(sort(union(indices*2-1, indices*2)));
239 % some elements of cella were not string
240 % error('some
''key
'' values are not
string.
');
243 function myfprintf(verbose, varargin)
245 if strcmpi(verbose, 'verbose
')
246 fprintf(varargin{:});