1 ## Copyright (C) 2002 Etienne Grossmann <etienne@isr.ist.utl.pt>
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
17 ## @deftypefn{Function File} {@var{[op,nread]} = } read_options ( args, varargin )
19 ## The function read_options parses arguments to a function as,
20 ## [ops,nread] = read_options (args,...) - Read options
22 ## The input being @var{args} a list of options and values.
23 ## The options can be any of the following,
25 ## 'op0' , string : Space-separated names of opt taking no argument <''>
27 ## 'op1' , string : Space-separated names of opt taking one argument <''>
29 ## 'extra' , string : Name of nameless trailing arguments. <''>
31 ## 'default', struct : Struct holding default option values <none>
33 ## 'prefix' , int : If false, only accept whole opt names. Otherwise, <0>
34 ## recognize opt from first chars, and choose
35 ## shortest if many opts start alike.
37 ## 'nocase' , int : If set, ignore case in option names <0>
39 ## 'quiet' , int : Behavior when a non-string or unknown opt is met <0>
40 ## 0 - Produce an error
41 ## 1 - Return quietly (can be diagnosed by checking 'nread')
43 ## 'skipnan', int : Ignore NaNs if there is a default value.
44 ## Note : At least one of 'op0' or 'op1' should be specified.
46 ## The output variables are,
47 ## @var{ops} : struct : Struct whose key/values are option names/values
48 ## @var{nread} : int : Number of elements of args that were read
52 ## # Define options and defaults
53 ## op0 = "is_man is_plane flies"
54 ## default = struct ("is_man",1, "flies",0);
58 ## s = read_options (list (all_va_args), "op0",op0,"default",default)
60 ## # Create variables w/ same name as options
62 ## [is_man, is_plane, flies] = getfields (s,"is_man", "is_plane", "flies")
63 ## pre 2.1.39 function [op,nread] = read_options (args, ...)
67 function [op,nread] = read_options (args, varargin) ## pos 2.1.39
71 op = struct (); # Empty struct
73 skipnan = prefix = quiet = nocase = quiet = 0;
77 nargs = nargin-1; # nargin is now a function
78 if rem (nargs, 2), error ("odd number of optional args"); endif
83 if ! ischar (tmp = varargin{i}), error ("non-string option"); endif
85 if strcmp (tmp, "op0") , op0 = varargin{i}; i=i+1;
86 elseif strcmp (tmp, "op1") , op1 = varargin{i}; i=i+1;
87 elseif strcmp (tmp, "extra") , extra = varargin{i}; i=i+1;
88 elseif strcmp (tmp, "default"), op = varargin{i}; i=i+1;
89 elseif strcmp (tmp, "prefix") , prefix = varargin{i}; i=i+1;
90 elseif strcmp (tmp, "nocase") , nocase = varargin{i}; i=i+1;
91 elseif strcmp (tmp, "quiet") , quiet = varargin{i}; i=i+1;
92 elseif strcmp (tmp, "skipnan"), skipnan = varargin{i}; i=i+1;
93 elseif strcmp (tmp, "verbose"), verbose = varargin{i}; i=i+1;
95 error ("unknown option '%s' for option-reading function!",tmp);
99 if length (op0) + length (op1) < 3
100 error ("Either 'op0' or 'op1' should be specified");
104 if op0(1) != " ", op0 = [" ",op0]; endif
105 if op0(length(op0)) != " ", op0 = [op0," "]; endif
109 if op1(1) != " ", op1 = [" ",op1]; endif
110 if op1(length(op1)) != " ", op1 = [op1," "]; endif
114 lextra = lgrep (cellstr (strsplit (extra, " ")));
119 opts = [op0,op1]; # Join options
120 # Before iend : opts w/out arg. After, opts
121 iend = length (op0); # w/ arg
123 spi = find (opts == " ");
127 if nocase, opts = tolower (opts); endif
132 while nread < length (args)
134 oname = name = args{++nread};
135 if ! ischar (name) # Whoa! Option name is not a string
137 if !optread && length (lextra)
138 op.(lextra{1}) = args{nread};
139 lextra = lextra(2:length(lextra));
141 elseif quiet, nread--; return;
142 else error ("option name in pos %i is not a string",nread);
147 if nocase, name = tolower (name); endif
149 ii = findstr ([" ",name], opts);
151 if isempty (ii) # Whoa! Unknown option name
152 if quiet, nread--; return;
153 else error ("unknown option '%s'",oname);
158 if length (ii) > 1 # Ambiguous option name
160 fullen = zeros (1,length (ii)); # Full length of each optio
164 fullen(++j) = spi(find (spi > i,1))-i ;
165 tmp = [tmp,"', '",opts(i:i+fullen(j)-1)];
167 tmp = tmp(5:length(tmp));
169 if sum (fullen == min (fullen)) > 1 || ...
170 ((min (fullen) != length(name)) && ! prefix) ,
171 error ("ambiguous option '%s'. Could be '%s'",oname,tmp);
173 j = find (fullen == min (fullen), 1);
177 # Full name of option (w/ correct case)
179 fullname = opts_orig(ii:spi(find (spi > ii, 1))-1);
181 if verbose, printf ("read_options : found boolean '%s'\n",fullname); endif
184 if verbose, printf ("read_options : found '%s'\n",fullname); endif
185 if nread < length (args)
187 if verbose, printf ("read_options : size is %i x %i\n",size(tmp)); endif
188 if !isnumeric (tmp) || !all (isnan (tmp(:))) || ...
189 !isfield (op, fullname)
192 if verbose, printf ("read_options : ignoring nan\n"); endif
195 error ("options end before I can read value of option '%s'",oname);