123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- % finputcheck() - check Matlab function {'key','value'} input argument pairs
- %
- % Usage: >> result = finputcheck( varargin, fieldlist );
- % >> [result varargin] = finputcheck( varargin, fieldlist, ...
- % callingfunc, mode, verbose );
- % Input:
- % varargin - Cell array 'varargin' argument from a function call using 'key',
- % 'value' argument pairs. See Matlab function 'varargin'
- % fieldlist - A 4-column cell array, one row per 'key'. The first
- % column contains the key string, the second its type(s),
- % the third the accepted value range, and the fourth the
- % default value. Allowed types are 'boolean', 'integer',
- % 'real', 'string', 'cell' or 'struct'. For example,
- % {'key1' 'string' { 'string1' 'string2' } 'defaultval_key1'}
- % {'key2' {'real' 'integer'} { minint maxint } 'defaultval_key2'}
- % callingfunc - Calling function name for error messages. {default: none}.
- % mode - ['ignore'|'error'] ignore keywords that are either not specified
- % in the fieldlist cell array or generate an error.
- % {default: 'error'}.
- % verbose - ['verbose', 'quiet'] print information. Default: 'verbose'.
- %
- % Outputs:
- % result - If no error, structure with 'key' as fields and 'value' as
- % content. If error this output contain the string error.
- % varargin - residual varagin containing unrecognized input arguments.
- % Requires mode 'ignore' above.
- %
- % Note: In case of error, a string is returned containing the error message
- % instead of a structure.
- %
- % Example (insert the following at the beginning of your function):
- % result = finputcheck(varargin, ...
- % { 'title' 'string' [] ''; ...
- % 'percent' 'real' [0 1] 1 ; ...
- % 'elecamp' 'integer' [1:10] [] });
- % if isstr(result)
- % error(result);
- % end
- %
- % Note:
- % The 'title' argument should be a string. {no default value}
- % The 'percent' argument should be a real number between 0 and 1. {default: 1}
- % The 'elecamp' argument should be an integer between 1 and 10 (inclusive).
- %
- % Now 'g.title' will contain the title arg (if any, else the default ''), etc.
- %
- % Author: Arnaud Delorme, CNL / Salk Institute, 10 July 2002
- % Copyright (C) Arnaud Delorme, CNL / Salk Institute, 10 July 2002, arno@salk.edu
- %
- % 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 [g, varargnew] = cm_eeg_finputcheck_20140226( vararg, fieldlist, callfunc, mode, verbose )
- if nargin < 2
- help finputcheck;
- return;
- end;
- if nargin < 3
- callfunc = '';
- else
- callfunc = [callfunc ' ' ];
- end;
- if nargin < 4
- mode = 'do not ignore';
- end;
- if nargin < 5
- verbose = 'verbose';
- end;
- NAME = 1;
- TYPE = 2;
- VALS = 3;
- DEF = 4;
- SIZE = 5;
-
- varargnew = {};
- % create structure
- % ----------------
- if ~isempty(vararg)
- for index=1:length(vararg)
- if iscell(vararg{index})
- vararg{index} = {vararg{index}};
- end;
- end;
- try
- g = struct(vararg{:});
- catch
- vararg = removedup(vararg, verbose);
- try
- g = struct(vararg{:});
- catch
- g = [ callfunc 'error: bad ''key'', ''val'' sequence' ]; return;
- end;
- end;
- else
- g = [];
- end;
-
- for index = 1:size(fieldlist,NAME)
- % check if present
- % ----------------
- if ~isfield(g, fieldlist{index, NAME})
- g = setfield( g, fieldlist{index, NAME}, fieldlist{index, DEF});
- end;
- tmpval = getfield( g, {1}, fieldlist{index, NAME});
-
- % check type
- % ----------
- if ~iscell( fieldlist{index, TYPE} )
- res = fieldtest( fieldlist{index, NAME}, fieldlist{index, TYPE}, ...
- fieldlist{index, VALS}, tmpval, callfunc );
- if isstr(res), g = res; return; end;
- else
- testres = 0;
- tmplist = fieldlist;
- for it = 1:length( fieldlist{index, TYPE} )
- if ~iscell(fieldlist{index, VALS})
- res{it} = fieldtest( fieldlist{index, NAME}, fieldlist{index, TYPE}{it}, ...
- fieldlist{index, VALS}, tmpval, callfunc );
- else res{it} = fieldtest( fieldlist{index, NAME}, fieldlist{index, TYPE}{it}, ...
- fieldlist{index, VALS}{it}, tmpval, callfunc );
- end;
- if ~isstr(res{it}), testres = 1; end;
- end;
- if testres == 0,
- g = res{1};
- for tmpi = 2:length(res)
- g = [ g 10 'or ' res{tmpi} ];
- end;
- return;
- end;
- end;
- end;
-
- % check if fields are defined
- % ---------------------------
- allfields = fieldnames(g);
- for index=1:length(allfields)
- if isempty(strmatch(allfields{index}, fieldlist(:, 1)', 'exact'))
- if ~strcmpi(mode, 'ignore')
- g = [ callfunc 'error: undefined argument ''' allfields{index} '''']; return;
- end;
- varargnew{end+1} = allfields{index};
- varargnew{end+1} = getfield(g, {1}, allfields{index});
- end;
- end;
- function g = fieldtest( fieldname, fieldtype, fieldval, tmpval, callfunc );
- NAME = 1;
- TYPE = 2;
- VALS = 3;
- DEF = 4;
- SIZE = 5;
- g = [];
-
- switch fieldtype
- case { 'integer' 'real' 'boolean' 'float' },
- if ~isnumeric(tmpval) && ~islogical(tmpval)
- g = [ callfunc 'error: argument ''' fieldname ''' must be numeric' ]; return;
- end;
- if strcmpi(fieldtype, 'boolean')
- if tmpval ~=0 && tmpval ~= 1
- g = [ callfunc 'error: argument ''' fieldname ''' must be 0 or 1' ]; return;
- end;
- else
- if strcmpi(fieldtype, 'integer')
- if ~isempty(fieldval)
- if (any(isnan(tmpval(:))) && ~any(isnan(fieldval))) ...
- && (~ismember(tmpval, fieldval))
- g = [ callfunc 'error: wrong value for argument ''' fieldname '''' ]; return;
- end;
- end;
- else % real or float
- if ~isempty(fieldval) && ~isempty(tmpval)
- if any(tmpval < fieldval(1)) || any(tmpval > fieldval(2))
- g = [ callfunc 'error: value out of range for argument ''' fieldname '''' ]; return;
- end;
- end;
- end;
- end;
-
-
- case 'string'
- if ~isstr(tmpval)
- g = [ callfunc 'error: argument ''' fieldname ''' must be a string' ]; return;
- end;
- if ~isempty(fieldval)
- if isempty(strmatch(lower(tmpval), lower(fieldval), 'exact'))
- g = [ callfunc 'error: wrong value for argument ''' fieldname '''' ]; return;
- end;
- end;
-
- case 'cell'
- if ~iscell(tmpval)
- g = [ callfunc 'error: argument ''' fieldname ''' must be a cell array' ]; return;
- end;
-
-
- case 'struct'
- if ~isstruct(tmpval)
- g = [ callfunc 'error: argument ''' fieldname ''' must be a structure' ]; return;
- end;
-
-
- case '';
- otherwise, error([ 'finputcheck error: unrecognized type ''' fieldname '''' ]);
- end;
- % remove duplicates in the list of parameters
- % -------------------------------------------
- function cella = removedup(cella, verbose)
- % make sure if all the values passed to unique() are strings, if not, exist
- %try
- [tmp indices] = unique(cella(1:2:end));
- if length(tmp) ~= length(cella)/2
- myfprintf(verbose,'Note: duplicate ''key'', ''val'' parameter(s), keeping the last one(s)\n');
- end;
- cella = cella(sort(union(indices*2-1, indices*2)));
- %catch
- % some elements of cella were not string
- % error('some ''key'' values are not string.');
- %end;
- function myfprintf(verbose, varargin)
- if strcmpi(verbose, 'verbose')
- fprintf(varargin{:});
- end;
|