Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

parseargs.m 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. %parseargs [opts] = parseargs(arguments, pairs, singles, ignore_unknowns)
  2. %
  3. % Variable argument parsing-- supersedes parseargs_example. This
  4. % function is meant to be used in the context of other functions
  5. % which have variable arguments. Typically, the function using
  6. % variable argument parsing would be written with the following
  7. % header:
  8. %
  9. % function myfunction(args, ..., varargin)
  10. %
  11. % and would define the variables "pairs" and "singles" (in a
  12. % format described below), and would then include the line
  13. %
  14. % parseargs(varargin, pairs, singles);
  15. %
  16. % 'pairs' and 'singles' specify how the variable arguments should
  17. % be parsed; their format is decribed below. It is best
  18. % understood by looking at the example at the bottom of these help
  19. % comments.
  20. %
  21. % varargin can be of two forms:
  22. % 1) A cell array where odd entries are variable names and even entries are
  23. % the corresponding values
  24. % 2) A struct where the fieldnames are the variable names and the values of
  25. % the fields are the values (for pairs) or the existence of the field
  26. % triggers acts as a single.
  27. %
  28. % pairs can be of two forms:
  29. % 1) an n x 2 cell array where the first column are the variable names and
  30. % the 2nd column are the default values.
  31. % 2) A struct where the fieldnames are the variable names and the values of
  32. % the fields are the values.
  33. %
  34. % PARSEARGS DOES NOT RETURN ANY VALUES; INSTEAD, IT USES ASSIGNIN
  35. % COMMANDS TO CHANGE OR SET VALUES OF VARIABLES IN THE CALLING
  36. % FUNCTION'S SPACE.
  37. %
  38. %
  39. %
  40. % PARAMETERS:
  41. % -----------
  42. %
  43. % -arguments The varargin list, I.e. a row cell array.
  44. %
  45. % -pairs A cell array of all those arguments that are
  46. % specified by argument-value pairs. First column
  47. % of this cell array must indicate the variable
  48. % names; the second column must indicate
  49. % correponding default values.
  50. %
  51. % -singles A cell array of all those arguments that are
  52. % specified by a single flag. The first column must
  53. % indicate the flag; the second column must
  54. % indicate the corresponding variable name that
  55. % will be affected in the caller's workspace; the
  56. % third column must indicate the value that that
  57. % variable will take upon appearance of the flag;
  58. % and the fourth column must indicate a default
  59. % value for the variable.
  60. %
  61. %
  62. % Example:
  63. % --------
  64. %
  65. % In "pairs", the first column defines both the variable name and the
  66. % marker looked for in varargin, and the second column defines that
  67. % variable's default value:
  68. %
  69. % pairs = {'thingy' 20 ; ...
  70. % 'blob' 'that'};
  71. %
  72. % In "singles", the first column is the flag to be looked for in varargin,
  73. % the second column defines the variable name this flag affects, the third
  74. % column defines the value the variable will take if the flag was found, and
  75. % the last column defines the value the variable takes if the flag was NOT
  76. % found in varargin.
  77. %
  78. % singles = {'no_plot' 'plot_fg' '0' '1'; ...
  79. % {'plot' 'plot_fg' '1' '1'};
  80. %
  81. %
  82. % Now for the function call from the user function:
  83. %
  84. % parseargs({'blob', 'fuff!', 'no_plot'}, pairs, singles);
  85. %
  86. % This will set, in the caller space, thingy=20, blob='fuff!', and
  87. % plot_fg=0. Since default values are in the second column of "pairs"
  88. % and the fourth column of "singles", and in the call to
  89. % parseargs 'thingy' was not specified, 'thingy' takes on its
  90. % default value of 20.
  91. %
  92. % Note that the arguments to parseargs may be in any order-- the
  93. % only ordering restriction is that whatever immediately follows
  94. % pair names (e.g. 'blob') will be interpreted as the value to be
  95. % assigned to them (e.g. 'blob' takes on the value 'fuff!');
  96. %
  97. % If you never use singles, you can just call "parseargs(varargin, pairs)"
  98. % without the singles argument.
  99. %
  100. function [varargout] = parseargs(arguments, pairs, singles,ignore_unknowns)
  101. if nargin < 3, singles = {}; end;
  102. if nargin < 4, ignore_unknowns=false; end;
  103. % This assigns all the default values for pairs.
  104. if isstruct(pairs)
  105. out=pairs;
  106. fn=fieldnames(pairs);
  107. for fx=1:numel(fn)
  108. assignin('caller',fn{fx}, pairs.(fn{fx}));
  109. end
  110. pairs=fn;
  111. else
  112. for i=1:size(pairs,1),
  113. assignin('caller', pairs{i,1}, pairs{i,2});
  114. end;
  115. end
  116. % This assigns all the default values for singles.
  117. for i=1:size(singles,1),
  118. assignin('caller', singles{i,2}, singles{i,4});
  119. end;
  120. if isempty(singles), singles = {'', '', [], []}; nosingles=true; else nosingles=false; end;
  121. if isempty(pairs), pairs = {'', []}; nopairs=true; else nopairs=false; end;
  122. % Now we assign the value to those passed by arguments.
  123. if numel(arguments)==1 && isstruct(arguments{1})
  124. arguments=arguments{1};
  125. fn=fieldnames(arguments);
  126. for arg=1:numel(fn)
  127. switch fn{arg}
  128. case pairs(:,1)
  129. assignin('caller',fn{arg}, arguments.(fn{arg}));
  130. out.(fn{arg})=arguments.(fn{arg});
  131. case singles(:,1)
  132. u = find(strcmp(fn{arg}, singles(:,1)));
  133. out.(fn{arg})=singles(:,1);
  134. assignin('caller', singles{u,2}, singles{u,3});
  135. otherwise
  136. if ~ignore_unknowns
  137. fn{arg}
  138. mname = evalin('caller', 'mfilename');
  139. error([mname ' : Didn''t understand above parameter']);
  140. end
  141. end
  142. end
  143. else
  144. arg = 1; while arg <= length(arguments),
  145. switch arguments{arg},
  146. case pairs(:,1),
  147. if arg+1 <= length(arguments)
  148. assignin('caller', arguments{arg}, arguments{arg+1});
  149. arg = arg+1;
  150. end;
  151. case singles(:,1),
  152. u = find(strcmp(arguments{arg}, singles(:,1)));
  153. assignin('caller', singles{u,2}, singles{u,3});
  154. otherwise
  155. if ~ignore_unknowns
  156. arguments{arg}
  157. mname = evalin('caller', 'mfilename');
  158. error([mname ' : Didn''t understand above parameter']);
  159. else
  160. if nosingles
  161. arg=arg+1;
  162. elseif nopairs
  163. % don't increment args.
  164. else
  165. error('Cannot use ignore_unknown and a mix of singles and pairs')
  166. end
  167. end
  168. end;
  169. arg = arg+1; end;
  170. end
  171. if nargout>0
  172. varargout{1}=out;
  173. end
  174. return;