public function parse(array $args = NULL)
{
if ($args === NULL) {
$args = isset($_SERVER['argv']) ? array_slice($_SERVER['argv'], 1) : [];
}
$params = [];
reset($this->positional);
$i = 0;
while ($i < count($args)) {
$arg = $args[$i++];
if ($arg[0] !== '-') {
if (!current($this->positional)) {
throw new \Exception("Unexpected parameter {$arg}.");
}
$name = current($this->positional);
$this->checkArg($this->options[$name], $arg);
if (empty($this->options[$name][self::REPEATABLE])) {
$params[$name] = $arg;
next($this->positional);
} else {
$params[$name][] = $arg;
}
continue;
}
list($name, $arg) = strpos($arg, '=') ? explode('=', $arg, 2) : [$arg, TRUE];
if (isset($this->aliases[$name])) {
$name = $this->aliases[$name];
} elseif (!isset($this->options[$name])) {
throw new \Exception("Unknown option {$name}.");
}
$opt = $this->options[$name];
if ($arg !== TRUE && empty($opt[self::ARGUMENT])) {
throw new \Exception("Option {$name} has not argument.");
} elseif ($arg === TRUE && !empty($opt[self::ARGUMENT])) {
if (isset($args[$i]) && $args[$i][0] !== '-') {
$arg = $args[$i++];
} elseif (empty($opt[self::OPTIONAL])) {
throw new \Exception("Option {$name} requires argument.");
}
}
if (!empty($opt[self::ENUM]) && !in_array($arg, $opt[self::ENUM], TRUE) && !($opt[self::OPTIONAL] && $arg === TRUE)) {
throw new \Exception("Value of option {$name} must be " . implode(', or ', $opt[self::ENUM]) . ".");
}
$this->checkArg($opt, $arg);
if (empty($opt[self::REPEATABLE])) {
$params[$name] = $arg;
} else {
$params[$name][] = $arg;
}
}
foreach ($this->options as $name => $opt) {
if (isset($params[$name])) {
continue;
} elseif (isset($opt[self::VALUE])) {
$params[$name] = $opt[self::VALUE];
} elseif ($name[0] !== '-' && empty($opt[self::OPTIONAL])) {
throw new \Exception("Missing required argument <{$name}>.");
} else {
$params[$name] = NULL;
}
if (!empty($opt[self::REPEATABLE])) {
$params[$name] = (array) $params[$name];
}
}
return $params;
}