/tags/R2003-06-01/octave-forge/main/miscellaneous/read_options.m

# · Objective C · 183 lines · 158 code · 25 blank · 0 comment · 50 complexity · e3c8d382013806a90aa5a5561e0ee8ee MD5 · raw file

  1. ## Copyright (C) 2002 Etienne Grossmann. All rights reserved.
  2. ##
  3. ## This program is free software; you can redistribute it and/or modify it
  4. ## under the terms of the GNU General Public License as published by the
  5. ## Free Software Foundation; either version 2, or (at your option) any
  6. ## later version.
  7. ##
  8. ## This 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
  11. ## for more details.
  12. ## [ops,nread] = read_options (args,...) - Read options
  13. ##
  14. ## INPUT -------------
  15. ## args : list : Options and values
  16. ##
  17. ## OPTIONS -------
  18. ## 'op0' , string : Space-separated names of opt taking no argument <''>
  19. ## 'op1' , string : Space-separated names of opt taking one argument <''>
  20. ## 'default', struct : Struct holding default option values <none>
  21. ## 'prefix' , int : If false, only accept whole opt names. Otherwise, <0>
  22. ## recognize opt from first chars, and choose
  23. ## shortest if many opts start alike.
  24. ## 'nocase' , int : If set, ignore case in option names <0>
  25. ## 'quiet' , int : Behavior when a non-string or unknown opt is met <0>
  26. ## 0 - Produce an error
  27. ## 1 - Return quietly (can be diagnosed by checking 'nread')
  28. ## 'skipnan', int : Ignore NaNs if there is a default value.
  29. ## Note : At least one of 'op0' or 'op1' should be specified.
  30. ##
  31. ## OUTPUT ------------
  32. ## ops : struct : Struct whose key/values are option names/values
  33. ## nread : int : Number of elements of args that were read
  34. ##
  35. ## USAGE -------------
  36. ##
  37. ## # Define options and defaults
  38. ## op0 = "is_man is_plane flies"
  39. ## default = struct ("is_man",1, "flies",0);
  40. ##
  41. ## # Read the options
  42. ##
  43. ## s = read_options (list (all_va_args), "op0",op0,"default",default)
  44. ##
  45. ## # Create variables w/ same name as options
  46. ##
  47. ## [is_man, is_plane, flies] = getfield (s,"is_man", "is_plane", "flies")
  48. ## pre 2.1.39 function [op,nread] = read_options (args, ...)
  49. function [op,nread] = read_options (args, varargin) ## pos 2.1.39
  50. verbose = 0;
  51. op = setfield (); # Empty struct
  52. op0 = op1 = " ";
  53. skipnan = prefix = quiet = nocase = quiet = 0;
  54. nargin--;
  55. if rem (nargin, 2), error ("odd number of optional args"); end
  56. ## beginpos 2.1.39
  57. i=1;
  58. while i<nargin
  59. if ! isstr (tmp = nth (varargin,i++)), error ("non-string option"); end
  60. if strcmp (tmp, "op0") , op0 = nth (varargin, i++);
  61. elseif strcmp (tmp, "op1") , op1 = nth (varargin, i++);
  62. elseif strcmp (tmp, "default"), op = nth (varargin, i++);
  63. elseif strcmp (tmp, "prefix") , prefix = nth (varargin, i++);
  64. elseif strcmp (tmp, "nocase") , nocase = nth (varargin, i++);
  65. elseif strcmp (tmp, "quiet") , quiet = nth (varargin, i++);
  66. elseif strcmp (tmp, "skipnan"), skipnan = nth (varargin, i++);
  67. elseif strcmp (tmp, "verbose"), verbose = nth (varargin, i++);
  68. else
  69. error ("unknown option '%s' for option-reading function!",tmp);
  70. end
  71. end
  72. ## endpos 2.1.39
  73. ## beginpre 2.1.39
  74. # while nargin
  75. # nargin -= 2;
  76. # if ! isstr (tmp = va_arg ()), error ("non-string option"); end
  77. # if strcmp (tmp, "op0") , op0 = va_arg ();
  78. # elseif strcmp (tmp, "op1") , op1 = va_arg ();
  79. # elseif strcmp (tmp, "default"), op = va_arg ();
  80. # elseif strcmp (tmp, "prefix") , prefix = va_arg ();
  81. # elseif strcmp (tmp, "nocase") , nocase = va_arg ();
  82. # elseif strcmp (tmp, "quiet") , quiet = va_arg ();
  83. # else
  84. # error ("unknown option '%s' for option-reading function!",tmp);
  85. # end
  86. # end
  87. ## endpre 2.1.39
  88. if length (op0) + length (op1) < 3
  89. error ("Either 'op0' or 'op1' should be specified");
  90. end
  91. ###
  92. if length (op0)
  93. if op0(1) != " ", op0 = [" ",op0]; end;
  94. if op0(length(op0)) != " ", op0 = [op0," "]; end;
  95. end
  96. if length (op1)
  97. if op1(1) != " ", op1 = [" ",op1]; end;
  98. if op1(length(op1)) != " ", op1 = [op1," "]; end;
  99. end
  100. opts = [op0,op1]; # Join options
  101. # Before iend : opts w/out arg. After, opts
  102. iend = length (op0); # w/ arg
  103. spi = find (opts == " ");
  104. opts_orig = opts;
  105. if nocase, opts = tolower (opts); end
  106. nread = 0;
  107. while nread < length (args)
  108. oname = name = nth (args, ++nread);
  109. if ! isstr (name) # Whoa! Option name is not a string
  110. if quiet, nread--; return;
  111. else error ("option name in pos %i is not a string",nread);
  112. end
  113. end
  114. if nocase, name = tolower (name); end
  115. ii = findstr ([" ",name], opts);
  116. if isempty (ii) # Whoa! Unknown option name
  117. if quiet, nread--; return;
  118. else error ("unknown option '%s'",oname);
  119. end
  120. end
  121. ii++;
  122. if length (ii) > 1 # Ambiguous option name
  123. fullen = zeros (1,length (ii)); # Full length of each optio
  124. tmp = correct = "";
  125. j = 0;
  126. for i = ii
  127. fullen(++j) = spi(find (spi > i)(1))-i ;
  128. tmp = [tmp,"', '",opts(i:i+fullen(j)-1)];
  129. end
  130. tmp = tmp(5:length(tmp));
  131. if sum (fullen == min (fullen)) > 1 || \
  132. ((min (fullen) != length(name)) && ! prefix) ,
  133. error ("ambiguous option '%s'. Could be '%s'",oname,tmp);
  134. end
  135. j = find (fullen == min (fullen))(1);
  136. ii = ii(j);
  137. end
  138. # Full name of option (w/ correct case)
  139. fullname = opts_orig(ii:spi(find (spi > ii)(1))-1);
  140. if ii < iend
  141. if verbose, printf ("read_options : found boolean '%s'\n",fullname); end
  142. op = setfield (op, fullname, 1);
  143. else
  144. if verbose, printf ("read_options : found '%s'\n",fullname); end
  145. if nread < length (args)
  146. tmp = nth (args,++nread);
  147. if verbose, printf ("read_options : size is %i x %i\n",size(tmp)); end
  148. if !isnumeric (tmp) || !all (isnan (tmp(:))) || \
  149. !struct_contains (op, fullname)
  150. op = setfield (op, fullname, tmp);
  151. else
  152. if verbose, printf ("read_options : ignoring nan\n"); end
  153. end
  154. else
  155. error ("options end before I can read value of option '%s'",oname);
  156. end
  157. end
  158. end