Home > vbmeg > functions > tool_box > dmri_processor > functions > util > finputcheck.m

finputcheck

PURPOSE ^

finputcheck() - check Matlab function {'key','value'} input argument pairs

SYNOPSIS ^

function [g, varargnew] = finputcheck( vararg, fieldlist, callfunc, mode )

DESCRIPTION ^

 finputcheck() - check Matlab function {'key','value'} input argument pairs

 Usage: >> result = finputcheck( varargin, fieldlist );
        >> [result varargin] = finputcheck( varargin, fieldlist, ... 
                                                         callingfunc, mode );
 Input:
   varargin  - 'varargin' argument from a function call using 'key', 'value'
               argument pairs.
   fieldlist - A 3- to 5-column cell array, one row per 'key'. The first
               column contains the key string, the second its type, 
               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' 'int' { 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'}.
 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:
     g = finputcheck(varargin, ...
               { 'title'         'string'   []       ''; ...
                 'percent'       'real'     [0 1]    1 ; ...
                 'elecamp'       'integer'  [1:10]   [] });
 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

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 % finputcheck() - check Matlab function {'key','value'} input argument pairs
0002 %
0003 % Usage: >> result = finputcheck( varargin, fieldlist );
0004 %        >> [result varargin] = finputcheck( varargin, fieldlist, ...
0005 %                                                         callingfunc, mode );
0006 % Input:
0007 %   varargin  - 'varargin' argument from a function call using 'key', 'value'
0008 %               argument pairs.
0009 %   fieldlist - A 3- to 5-column cell array, one row per 'key'. The first
0010 %               column contains the key string, the second its type,
0011 %               the third the accepted value range, and the fourth the
0012 %               default value.  Allowed types are 'boolean', 'integer',
0013 %               'real', 'string', 'cell' or 'struct'.  For example:
0014 %                       {'key1' 'string' { 'string1' 'string2' } 'defaultval_key1'}
0015 %                       {'key2' 'int' { minint maxint } 'defaultval_key2'}
0016 %  callingfunc - Calling function name for error messages. {default: none}.
0017 %  mode        - ['ignore'|'error'] ignore keywords that are either not specified
0018 %                in the fieldlist cell array or generate an error.
0019 %                {default: 'error'}.
0020 % Outputs:
0021 %   result     - If no error, structure with 'key' as fields and 'value' as
0022 %                content. If error this output contain the string error.
0023 %   varargin   - residual varagin containing unrecognized input arguments.
0024 %                Requires mode 'ignore' above.
0025 %
0026 % Note: In case of error, a string is returned containing the error message
0027 %       instead of a structure.
0028 %
0029 % Example:
0030 %     g = finputcheck(varargin, ...
0031 %               { 'title'         'string'   []       ''; ...
0032 %                 'percent'       'real'     [0 1]    1 ; ...
0033 %                 'elecamp'       'integer'  [1:10]   [] });
0034 % Note:
0035 %   The 'title' argument should be a string. {no default value}
0036 %   The 'percent' argument should be a real number between 0 and 1. {default: 1}
0037 %   The 'elecamp' argument should be an integer between 1 and 10 (inclusive).
0038 %
0039 %   Now 'g.title' will contain the title arg (if any, else the default ''), etc.
0040 %
0041 % Author: Arnaud Delorme, CNL / Salk Institute, 10 July 2002
0042 
0043 %123456789012345678901234567890123456789012345678901234567890123456789012
0044 
0045 % Copyright (C) Arnaud Delorme, CNL / Salk Institute, 10 July 2002, arno@salk.edu
0046 %
0047 % This program is free software; you can redistribute it and/or modify
0048 % it under the terms of the GNU General Public License as published by
0049 % the Free Software Foundation; either version 2 of the License, or
0050 % (at your option) any later version.
0051 %
0052 % This program is distributed in the hope that it will be useful,
0053 % but WITHOUT ANY WARRANTY; without even the implied warranty of
0054 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0055 % GNU General Public License for more details.
0056 %
0057 % You should have received a copy of the GNU General Public License
0058 % along with this program; if not, write to the Free Software
0059 % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0060 
0061 % $Log: finputcheck.m,v $
0062 % Revision 1.23  2004/11/06 02:54:06  scott
0063 % a few further small edits to the help msg -sm
0064 %
0065 % Revision 1.22  2004/11/05 15:23:37  arno
0066 % ,sg
0067 %
0068 % Revision 1.21  2004/11/05 04:10:44  scott
0069 % help msg. -sm
0070 %
0071 % Revision 1.20  2004/06/09 16:30:42  arno
0072 % adding or if several types
0073 %
0074 % Revision 1.19  2003/10/29 16:35:57  arno
0075 % msg typo
0076 %
0077 % Revision 1.18  2003/07/30 23:53:58  arno
0078 % debug multiple return values
0079 %
0080 % Revision 1.17  2003/07/26 00:21:17  arno
0081 % allowing cell array for values
0082 %
0083 % Revision 1.16  2003/06/30 02:10:10  arno
0084 % strmatch exact
0085 %
0086 % Revision 1.15  2003/01/31 02:35:38  arno
0087 % debugging lowercase/upercase problem
0088 %
0089 % Revision 1.14  2002/11/20 01:05:44  arno
0090 % take into account duplicate parameters
0091 %
0092 % Revision 1.13  2002/11/18 17:15:18  arno
0093 % adding float arg (=real)
0094 %
0095 % Revision 1.12  2002/11/15 02:16:50  arno
0096 % header for web
0097 %
0098 % Revision 1.11  2002/09/30 15:29:23  arno
0099 % autorizing cell arrays for types
0100 %
0101 % Revision 1.10  2002/09/30 00:42:08  arno
0102 % debug input arguments
0103 %
0104 % Revision 1.9  2002/07/29 18:00:53  arno
0105 % debugging for NaN
0106 %
0107 % Revision 1.8  2002/07/29 17:24:22  arno
0108 % header
0109 %
0110 % Revision 1.7  2002/07/20 19:10:41  arno
0111 % debugging output
0112 %
0113 % Revision 1.6  2002/07/19 17:58:11  arno
0114 % returning non-matched 'key' 'val' arguments
0115 %
0116 % Revision 1.5  2002/07/19 17:46:53  arno
0117 % g empty if no varargin
0118 %
0119 % Revision 1.4  2002/07/19 16:27:14  arno
0120 % adding ignore mode
0121 %
0122 % Revision 1.3  2002/07/10 02:18:32  arno
0123 % header info
0124 %
0125 % Revision 1.2  2002/07/10 02:17:27  arno
0126 % debugging error message passing
0127 %
0128 % Revision 1.1  2002/07/10 01:03:19  arno
0129 % Initial revision
0130 %
0131 
0132 function [g, varargnew] = finputcheck( vararg, fieldlist, callfunc, mode )
0133 
0134     if nargin < 2
0135         help finputcheck;
0136         return;
0137     end;
0138     if nargin < 3
0139         callfunc = '';
0140     else 
0141         callfunc = [callfunc ' ' ];
0142     end;
0143     if nargin < 4
0144         mode = 'do not ignore';
0145     end;
0146     NAME = 1;
0147     TYPE = 2;
0148     VALS = 3;
0149     DEF  = 4;
0150     SIZE = 5;
0151     
0152     varargnew = {};
0153     % create structure
0154     % ----------------
0155     if ~isempty(vararg)
0156         vararg = removedup(vararg);
0157         for index=1:length(vararg)
0158             if iscell(vararg{index})
0159                 vararg{index} = {vararg{index}};
0160             end;
0161         end;
0162         try
0163             g = struct(vararg{:});
0164         catch
0165             g = [ callfunc 'error: bad ''key'', ''val'' sequence' ]; return;
0166         end;
0167     else 
0168         g = [];
0169     end;
0170     
0171     for index = 1:size(fieldlist,NAME)
0172         % check if present
0173         % ----------------
0174         if ~isfield(g, fieldlist{index, NAME})
0175             g = setfield( g, fieldlist{index, NAME}, fieldlist{index, DEF});
0176         end;
0177         tmpval = getfield( g, {1}, fieldlist{index, NAME});
0178         
0179         % check type
0180         % ----------
0181         if ~iscell( fieldlist{index, TYPE} )
0182             res = fieldtest( fieldlist{index, NAME},  fieldlist{index, TYPE}, ...
0183                            fieldlist{index, VALS}, tmpval, callfunc );
0184             if isstr(res), g = res; return; end;
0185         else 
0186             testres = 0;
0187             tmplist = fieldlist;
0188             for it = 1:length( fieldlist{index, TYPE} )
0189                 if ~iscell(fieldlist{index, VALS})
0190                      res{it} = fieldtest(  fieldlist{index, NAME},  fieldlist{index, TYPE}{it}, ...
0191                                            fieldlist{index, VALS}, tmpval, callfunc );
0192                 else res{it} = fieldtest(  fieldlist{index, NAME},  fieldlist{index, TYPE}{it}, ...
0193                                            fieldlist{index, VALS}{it}, tmpval, callfunc );
0194                 end;
0195                 if ~isstr(res{it}), testres = 1; end;
0196             end;
0197             if testres == 0,
0198                 g = res{1};
0199                 for tmpi = 2:length(res)
0200                     g = [ g 10 'or ' res{tmpi} ];
0201                 end;
0202                 return; 
0203             end;
0204         end;
0205     end;
0206     
0207     % check if fields are defined
0208     % ---------------------------
0209     allfields = fieldnames(g);
0210     for index=1:length(allfields)
0211         if isempty(strmatch(allfields{index}, fieldlist(:, 1)', 'exact'))
0212             if ~strcmpi(mode, 'ignore')
0213                 g = [ callfunc 'error: undefined argument ''' allfields{index} '''']; return;
0214             end;
0215             varargnew{end+1} = allfields{index};
0216             varargnew{end+1} = getfield(g, {1}, allfields{index});
0217         end;
0218     end;
0219 
0220 
0221 function g = fieldtest( fieldname, fieldtype, fieldval, tmpval, callfunc );
0222     NAME = 1;
0223     TYPE = 2;
0224     VALS = 3;
0225     DEF  = 4;
0226     SIZE = 5;
0227     g = [];
0228     
0229     switch fieldtype
0230      case { 'integer' 'real' 'boolean' 'float' }, 
0231       if ~isnumeric(tmpval)
0232           g = [ callfunc 'error: argument ''' fieldname ''' must be numeric' ]; return;
0233       end;
0234       if strcmpi(fieldtype, 'boolean')
0235           if tmpval ~=0 & tmpval ~= 1
0236               g = [ callfunc 'error: argument ''' fieldname ''' must be 0 or 1' ]; return;
0237           end;  
0238       else 
0239           if strcmpi(fieldtype, 'integer')
0240               if ~isempty(fieldval)
0241                   if (isnan(tmpval) & ~any(isnan(fieldval))) ...
0242                           & (~ismember(tmpval, fieldval))
0243                       g = [ callfunc 'error: wrong value for argument ''' fieldname '''' ]; return;
0244                   end;
0245               end;
0246           else % real or float
0247               if ~isempty(fieldval)
0248                   if tmpval < fieldval(1) | tmpval > fieldval(2)
0249                       g = [ callfunc 'error: value out of range for argument ''' fieldname '''' ]; return;
0250                   end;
0251               end;
0252           end;
0253       end;  
0254       
0255       
0256      case 'string'
0257       if ~isstr(tmpval)
0258           g = [ callfunc 'error: argument ''' fieldname ''' must be a string' ]; return;
0259       end;
0260       if ~isempty(fieldval)
0261           if isempty(strmatch(lower(tmpval), lower(fieldval), 'exact'))
0262               g = [ callfunc 'error: wrong value for argument ''' fieldname '''' ]; return;
0263           end;
0264       end;
0265 
0266       
0267      case 'cell'
0268       if ~iscell(tmpval)
0269           g = [ callfunc 'error: argument ''' fieldname ''' must be a cell array' ]; return;
0270       end;
0271       
0272       
0273      case 'struct'
0274       if ~isstruct(tmpval)
0275           g = [ callfunc 'error: argument ''' fieldname ''' must be a structure' ]; return;
0276       end;
0277       
0278       
0279      case '';
0280      otherwise, error([ 'finputcheck error: unrecognized type ''' fieldname '''' ]);
0281     end;
0282 
0283 % remove duplicates in the list of parameters
0284 % -------------------------------------------
0285 function cella = removedup(cella)
0286     [tmp indices] = unique(cella(1:2:end));
0287     if length(tmp) ~= length(cella)/2
0288         fprintf('Warning: duplicate ''key'', ''val'' parameter(s), keeping the last one(s)\n');
0289     end;
0290     cella = cella(sort(union(indices*2-1, indices*2)));

Generated on Mon 22-May-2023 06:53:56 by m2html © 2005