Skip to content
This repository was archived by the owner on Dec 10, 2021. It is now read-only.

Commit ce9bf6f

Browse files
committed
Add "parseArgs"
Add "parseArgs" function, from WORMTRACK repo (rev e7b56ae).
0 parents  commit ce9bf6f

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed

parseArgs.m

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
function [argStruct] = parseArgs(args, defArgStruct, flagParamNames)
2+
% Helper function for parsing varargin.
3+
%
4+
% INPUT:
5+
% args = 'varargin' 1xN cell array
6+
% defArgStruct = struct with argument names and corresponding default
7+
% values.
8+
% flagParamNames = 1xM cell array with names of parameters that don't
9+
% require a value. If they appear in 'args', their value
10+
% will be set to 1. (Optional)
11+
%
12+
% OUTPUT:
13+
% argStruct = struct with parsed arguments/values. Flags are guaranteed to
14+
% get assigned either a true/false value by parseArgs.
15+
%
16+
% EXAMPLES:
17+
% >> argStruct = parseArgs(varargin, struct('param1', 0.1, 'otherParam', 'test'));
18+
19+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20+
%% Initialization
21+
22+
if nargin < 3
23+
flagParamNames = {};
24+
end
25+
26+
if ~(isscalar(defArgStruct) && isstruct(defArgStruct))
27+
error('PARSEARGS:InvalidDefArgStruct', 'Invalid default parameter specification: should be a single struct');
28+
end
29+
30+
% Create matrix of accepted parameter names
31+
validParamNames = fieldnames(defArgStruct);
32+
33+
for i = 1:length(flagParamNames)
34+
if ~isValidParamName(flagParamNames{i}, validParamNames)
35+
error('PARSEARGS:InvalidFlagParamName', 'Invalid flag parameter name "%s"', flagParamNames{i});
36+
end
37+
end
38+
39+
argStruct = defArgStruct;
40+
41+
42+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43+
%% Parse!
44+
45+
parseStates = struct('paramName', 1, 'paramValue', 2);
46+
curParseState = parseStates.paramName;
47+
curParamName = '';
48+
curArgIdx = 1;
49+
50+
while curArgIdx <= length(args)
51+
if curParseState == parseStates.paramName
52+
curParamName = parseParamName(args{curArgIdx}, validParamNames);
53+
if isempty(curParamName)
54+
error('PARSEARGS:InvalidArgument', 'Invalid argument "%s"', args{curArgIdx});
55+
end
56+
if isFlagParam(curParamName, flagParamNames)
57+
% Flag parameter!
58+
% Value might be explicitly specified...
59+
if length(args) > curArgIdx
60+
if islogical(args{curArgIdx+1}) || isnumeric(args{curArgIdx+1})
61+
% Flag value is explicitly specified
62+
if args{curArgIdx+1}
63+
argStruct.(curParamName) = true; % make sure we explicitly assign true/false
64+
else
65+
argStruct.(curParamName) = false;
66+
end
67+
68+
% --> paramName (skip 1 arg)
69+
curArgIdx = curArgIdx + 2;
70+
curParseState = parseStates.paramName;
71+
%^^^
72+
continue;
73+
end
74+
end
75+
76+
% Apparently, value was not explicitly specified: turn it on
77+
argStruct.(curParamName) = true;
78+
79+
% --> paramName
80+
curArgIdx = curArgIdx + 1;
81+
curParseState = parseStates.paramName;
82+
%^^^
83+
continue;
84+
else
85+
% Not a flag parameter
86+
% --> paramValue
87+
curArgIdx = curArgIdx + 1;
88+
curParseState = parseStates.paramValue;
89+
%^^^
90+
continue;
91+
end
92+
elseif curParseState == parseStates.paramValue
93+
% Save parameter value
94+
argStruct.(curParamName) = args{curArgIdx};
95+
96+
% --> paramName
97+
curArgIdx = curArgIdx + 1;
98+
curParseState = parseStates.paramName;
99+
%^^^
100+
continue;
101+
else
102+
error('Invalid parse state in parseArgs!');
103+
end
104+
end % while
105+
106+
% Are we missing anything?
107+
if curParseState == parseStates.paramValue
108+
error('PARSEARGS:MissingArgumentValue', 'Missing value for argument "%s"', curParamName);
109+
end
110+
111+
112+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113+
114+
function [valid] = isValidParamName(paramName, validParamNames)
115+
valid = ~isempty(parseParamName(paramName, validParamNames));
116+
end
117+
118+
function [parsedParamName] = parseParamName(paramName, validParamNames)
119+
parsedParamName = '';
120+
for j = 1:length(validParamNames)
121+
if strcmpi(paramName, validParamNames{j})
122+
parsedParamName = validParamNames{j};
123+
return
124+
end
125+
end
126+
end
127+
128+
function [isFlag] = isFlagParam(paramName, flagParamNames)
129+
isFlag = false;
130+
for j = 1:length(flagParamNames)
131+
if strcmpi(paramName, flagParamNames{j})
132+
isFlag = true;
133+
return
134+
end
135+
end
136+
end
137+
138+
end
139+

0 commit comments

Comments
 (0)