ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
Getopt.php
Go to the documentation of this file.
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4: */
24 require_once 'PEAR.php';
25 
36 {
37 
73  function getopt2($args, $short_options, $long_options = null, $skip_unknown = false)
74  {
75  return Console_Getopt::doGetopt(2, $args, $short_options, $long_options, $skip_unknown);
76  }
77 
90  function getopt($args, $short_options, $long_options = null, $skip_unknown = false)
91  {
92  return Console_Getopt::doGetopt(1, $args, $short_options, $long_options, $skip_unknown);
93  }
94 
106  function doGetopt($version, $args, $short_options, $long_options = null, $skip_unknown = false)
107  {
108  // in case you pass directly readPHPArgv() as the first arg
109  if (PEAR::isError($args)) {
110  return $args;
111  }
112 
113  if (empty($args)) {
114  return array(array(), array());
115  }
116 
117  $non_opts = $opts = array();
118 
119  settype($args, 'array');
120 
121  if ($long_options) {
122  sort($long_options);
123  }
124 
125  /*
126  * Preserve backwards compatibility with callers that relied on
127  * erroneous POSIX fix.
128  */
129  if ($version < 2) {
130  if (isset($args[0]{0}) && $args[0]{0} != '-') {
131  array_shift($args);
132  }
133  }
134 
135  reset($args);
136  while (list($i, $arg) = each($args)) {
137  /* The special element '--' means explicit end of
138  options. Treat the rest of the arguments as non-options
139  and end the loop. */
140  if ($arg == '--') {
141  $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
142  break;
143  }
144 
145  if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {
146  $non_opts = array_merge($non_opts, array_slice($args, $i));
147  break;
148  } elseif (strlen($arg) > 1 && $arg{1} == '-') {
149  $error = Console_Getopt::_parseLongOption(substr($arg, 2),
150  $long_options,
151  $opts,
152  $args,
153  $skip_unknown);
154  if (PEAR::isError($error)) {
155  return $error;
156  }
157  } elseif ($arg == '-') {
158  // - is stdin
159  $non_opts = array_merge($non_opts, array_slice($args, $i));
160  break;
161  } else {
162  $error = Console_Getopt::_parseShortOption(substr($arg, 1),
163  $short_options,
164  $opts,
165  $args,
166  $skip_unknown);
167  if (PEAR::isError($error)) {
168  return $error;
169  }
170  }
171  }
172 
173  return array($opts, $non_opts);
174  }
175 
188  function _parseShortOption($arg, $short_options, &$opts, &$args, $skip_unknown)
189  {
190  for ($i = 0; $i < strlen($arg); $i++) {
191  $opt = $arg{$i};
192  $opt_arg = null;
193 
194  /* Try to find the short option in the specifier string. */
195  if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') {
196  if ($skip_unknown === true) {
197  break;
198  }
199 
200  $msg = "Console_Getopt: unrecognized option -- $opt";
201  return PEAR::raiseError($msg);
202  }
203 
204  if (strlen($spec) > 1 && $spec{1} == ':') {
205  if (strlen($spec) > 2 && $spec{2} == ':') {
206  if ($i + 1 < strlen($arg)) {
207  /* Option takes an optional argument. Use the remainder of
208  the arg string if there is anything left. */
209  $opts[] = array($opt, substr($arg, $i + 1));
210  break;
211  }
212  } else {
213  /* Option requires an argument. Use the remainder of the arg
214  string if there is anything left. */
215  if ($i + 1 < strlen($arg)) {
216  $opts[] = array($opt, substr($arg, $i + 1));
217  break;
218  } else if (list(, $opt_arg) = each($args)) {
219  /* Else use the next argument. */;
220  if (Console_Getopt::_isShortOpt($opt_arg)
221  || Console_Getopt::_isLongOpt($opt_arg)) {
222  $msg = "option requires an argument --$opt";
223  return PEAR::raiseError("Console_Getopt:" . $msg);
224  }
225  } else {
226  $msg = "option requires an argument --$opt";
227  return PEAR::raiseError("Console_Getopt:" . $msg);
228  }
229  }
230  }
231 
232  $opts[] = array($opt, $opt_arg);
233  }
234  }
235 
244  function _isShortOpt($arg)
245  {
246  return strlen($arg) == 2 && $arg[0] == '-'
247  && preg_match('/[a-zA-Z]/', $arg[1]);
248  }
249 
258  function _isLongOpt($arg)
259  {
260  return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' &&
261  preg_match('/[a-zA-Z]+$/', substr($arg, 2));
262  }
263 
275  function _parseLongOption($arg, $long_options, &$opts, &$args, $skip_unknown)
276  {
277  @list($opt, $opt_arg) = explode('=', $arg, 2);
278 
279  $opt_len = strlen($opt);
280 
281  for ($i = 0; $i < count($long_options); $i++) {
282  $long_opt = $long_options[$i];
283  $opt_start = substr($long_opt, 0, $opt_len);
284 
285  $long_opt_name = str_replace('=', '', $long_opt);
286 
287  /* Option doesn't match. Go on to the next one. */
288  if ($long_opt_name != $opt) {
289  continue;
290  }
291 
292  $opt_rest = substr($long_opt, $opt_len);
293 
294  /* Check that the options uniquely matches one of the allowed
295  options. */
296  if ($i + 1 < count($long_options)) {
297  $next_option_rest = substr($long_options[$i + 1], $opt_len);
298  } else {
299  $next_option_rest = '';
300  }
301 
302  if ($opt_rest != '' && $opt{0} != '=' &&
303  $i + 1 < count($long_options) &&
304  $opt == substr($long_options[$i+1], 0, $opt_len) &&
305  $next_option_rest != '' &&
306  $next_option_rest{0} != '=') {
307 
308  $msg = "Console_Getopt: option --$opt is ambiguous";
309  return PEAR::raiseError($msg);
310  }
311 
312  if (substr($long_opt, -1) == '=') {
313  if (substr($long_opt, -2) != '==') {
314  /* Long option requires an argument.
315  Take the next argument if one wasn't specified. */;
316  if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {
317  $msg = "Console_Getopt: option requires an argument --$opt";
318  return PEAR::raiseError($msg);
319  }
320 
321  if (Console_Getopt::_isShortOpt($opt_arg)
322  || Console_Getopt::_isLongOpt($opt_arg)) {
323  $msg = "Console_Getopt: option requires an argument --$opt";
324  return PEAR::raiseError($msg);
325  }
326  }
327  } else if ($opt_arg) {
328  $msg = "Console_Getopt: option --$opt doesn't allow an argument";
329  return PEAR::raiseError($msg);
330  }
331 
332  $opts[] = array('--' . $opt, $opt_arg);
333  return;
334  }
335 
336  if ($skip_unknown === true) {
337  return;
338  }
339 
340  return PEAR::raiseError("Console_Getopt: unrecognized option --$opt");
341  }
342 
350  function readPHPArgv()
351  {
352  global $argv;
353  if (!is_array($argv)) {
354  if (!@is_array($_SERVER['argv'])) {
355  if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
356  $msg = "Could not read cmd args (register_argc_argv=Off?)";
357  return PEAR::raiseError("Console_Getopt: " . $msg);
358  }
359  return $GLOBALS['HTTP_SERVER_VARS']['argv'];
360  }
361  return $_SERVER['argv'];
362  }
363  return $argv;
364  }
365 
366 }