Open Journal Systems  3.3.0
Getopt.php
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4: */
21 require_once 'PEAR.php';
22 
33 {
34 
69  public static function getopt2($args, $short_options, $long_options = null, $skip_unknown = false)
70  {
71  return Console_Getopt::doGetopt(2, $args, $short_options, $long_options, $skip_unknown);
72  }
73 
86  public static function getopt($args, $short_options, $long_options = null, $skip_unknown = false)
87  {
88  return Console_Getopt::doGetopt(1, $args, $short_options, $long_options, $skip_unknown);
89  }
90 
102  public static function doGetopt($version, $args, $short_options, $long_options = null, $skip_unknown = false)
103  {
104  // in case you pass directly readPHPArgv() as the first arg
105  if (PEAR::isError($args)) {
106  return $args;
107  }
108 
109  if (empty($args)) {
110  return array(array(), array());
111  }
112 
113  $non_opts = $opts = array();
114 
115  settype($args, 'array');
116 
117  if ($long_options) {
118  sort($long_options);
119  }
120 
121  /*
122  * Preserve backwards compatibility with callers that relied on
123  * erroneous POSIX fix.
124  */
125  if ($version < 2) {
126  if (isset($args[0][0]) && $args[0][0] != '-') {
127  array_shift($args);
128  }
129  }
130 
131  for ($i = 0; $i < count($args); $i++) {
132  $arg = $args[$i];
133  /* The special element '--' means explicit end of
134  options. Treat the rest of the arguments as non-options
135  and end the loop. */
136  if ($arg == '--') {
137  $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
138  break;
139  }
140 
141  if ($arg[0] != '-' || (strlen($arg) > 1 && $arg[1] == '-' && !$long_options)) {
142  $non_opts = array_merge($non_opts, array_slice($args, $i));
143  break;
144  } elseif (strlen($arg) > 1 && $arg[1] == '-') {
145  $error = Console_Getopt::_parseLongOption(substr($arg, 2),
146  $long_options,
147  $opts,
148  $i,
149  $args,
150  $skip_unknown);
151  if (PEAR::isError($error)) {
152  return $error;
153  }
154  } elseif ($arg == '-') {
155  // - is stdin
156  $non_opts = array_merge($non_opts, array_slice($args, $i));
157  break;
158  } else {
159  $error = Console_Getopt::_parseShortOption(substr($arg, 1),
160  $short_options,
161  $opts,
162  $i,
163  $args,
164  $skip_unknown);
165  if (PEAR::isError($error)) {
166  return $error;
167  }
168  }
169  }
170 
171  return array($opts, $non_opts);
172  }
173 
186  protected static function _parseShortOption($arg, $short_options, &$opts, &$argIdx, $args, $skip_unknown)
187  {
188  for ($i = 0; $i < strlen($arg); $i++) {
189  $opt = $arg[$i];
190  $opt_arg = null;
191 
192  /* Try to find the short option in the specifier string. */
193  if (($spec = strstr($short_options, $opt)) === false || $arg[$i] == ':') {
194  if ($skip_unknown === true) {
195  break;
196  }
197 
198  $msg = "Console_Getopt: unrecognized option -- $opt";
199  return PEAR::raiseError($msg);
200  }
201 
202  if (strlen($spec) > 1 && $spec[1] == ':') {
203  if (strlen($spec) > 2 && $spec[2] == ':') {
204  if ($i + 1 < strlen($arg)) {
205  /* Option takes an optional argument. Use the remainder of
206  the arg string if there is anything left. */
207  $opts[] = array($opt, substr($arg, $i + 1));
208  break;
209  }
210  } else {
211  /* Option requires an argument. Use the remainder of the arg
212  string if there is anything left. */
213  if ($i + 1 < strlen($arg)) {
214  $opts[] = array($opt, substr($arg, $i + 1));
215  break;
216  } else if (isset($args[++$argIdx])) {
217  $opt_arg = $args[$argIdx];
218  /* Else use the next argument. */;
219  if (Console_Getopt::_isShortOpt($opt_arg)
220  || Console_Getopt::_isLongOpt($opt_arg)) {
221  $msg = "option requires an argument --$opt";
222  return PEAR::raiseError("Console_Getopt: " . $msg);
223  }
224  } else {
225  $msg = "option requires an argument --$opt";
226  return PEAR::raiseError("Console_Getopt: " . $msg);
227  }
228  }
229  }
230 
231  $opts[] = array($opt, $opt_arg);
232  }
233  }
234 
242  protected static function _isShortOpt($arg)
243  {
244  return strlen($arg) == 2 && $arg[0] == '-'
245  && preg_match('/[a-zA-Z]/', $arg[1]);
246  }
247 
255  protected static function _isLongOpt($arg)
256  {
257  return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' &&
258  preg_match('/[a-zA-Z]+$/', substr($arg, 2));
259  }
260 
272  protected static function _parseLongOption($arg, $long_options, &$opts, &$argIdx, $args, $skip_unknown)
273  {
274  @list($opt, $opt_arg) = explode('=', $arg, 2);
275 
276  $opt_len = strlen($opt);
277 
278  for ($i = 0; $i < count($long_options); $i++) {
279  $long_opt = $long_options[$i];
280  $opt_start = substr($long_opt, 0, $opt_len);
281 
282  $long_opt_name = str_replace('=', '', $long_opt);
283 
284  /* Option doesn't match. Go on to the next one. */
285  if ($long_opt_name != $opt) {
286  continue;
287  }
288 
289  $opt_rest = substr($long_opt, $opt_len);
290 
291  /* Check that the options uniquely matches one of the allowed
292  options. */
293  if ($i + 1 < count($long_options)) {
294  $next_option_rest = substr($long_options[$i + 1], $opt_len);
295  } else {
296  $next_option_rest = '';
297  }
298 
299  if ($opt_rest != '' && $opt[0] != '=' &&
300  $i + 1 < count($long_options) &&
301  $opt == substr($long_options[$i+1], 0, $opt_len) &&
302  $next_option_rest != '' &&
303  $next_option_rest[0] != '=') {
304 
305  $msg = "Console_Getopt: option --$opt is ambiguous";
306  return PEAR::raiseError($msg);
307  }
308 
309  if (substr($long_opt, -1) == '=') {
310  if (substr($long_opt, -2) != '==') {
311  /* Long option requires an argument.
312  Take the next argument if one wasn't specified. */;
313  if (!strlen($opt_arg)) {
314  if (!isset($args[++$argIdx])) {
315  $msg = "Console_Getopt: option requires an argument --$opt";
316  return PEAR::raiseError($msg);
317  }
318  $opt_arg = $args[$argIdx];
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 
349  public static function readPHPArgv()
350  {
351  global $argv;
352  if (!is_array($argv)) {
353  if (!@is_array($_SERVER['argv'])) {
354  if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
355  $msg = "Could not read cmd args (register_argc_argv=Off?)";
356  return PEAR::raiseError("Console_Getopt: " . $msg);
357  }
358  return $GLOBALS['HTTP_SERVER_VARS']['argv'];
359  }
360  return $_SERVER['argv'];
361  }
362  return $argv;
363  }
364 
365 }
Console_Getopt\_parseLongOption
static _parseLongOption($arg, $long_options, &$opts, &$argIdx, $args, $skip_unknown)
Definition: Getopt.php:272
Console_Getopt\_parseShortOption
static _parseShortOption($arg, $short_options, &$opts, &$argIdx, $args, $skip_unknown)
Definition: Getopt.php:186
Console_Getopt\doGetopt
static doGetopt($version, $args, $short_options, $long_options=null, $skip_unknown=false)
Definition: Getopt.php:102
PEAR\isError
static isError($data, $code=null)
Definition: PEAR.php:314
Console_Getopt
Console_Getopt\getopt
static getopt($args, $short_options, $long_options=null, $skip_unknown=false)
Definition: Getopt.php:86
$GLOBALS
$GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']
Definition: prependCoverageReport.php:17
Console_Getopt\readPHPArgv
static readPHPArgv()
Definition: Getopt.php:349
Console_Getopt\_isLongOpt
static _isLongOpt($arg)
Definition: Getopt.php:255
Console_Getopt\getopt2
static getopt2($args, $short_options, $long_options=null, $skip_unknown=false)
Definition: Getopt.php:69
Console_Getopt\_isShortOpt
static _isShortOpt($arg)
Definition: Getopt.php:242