public function parse($argc, array $argv)
{
for ($f = false, $p = 0, $i = 0; $i < $argc; ++$i) {
$o = $argv[$i];
if ($o[0] === "-" && strlen($o) > 2 && $o[1] !== "-") {
// multiple short opts, e.g. -vps
$argc += strlen($o) - 2;
array_splice($argv, $i, 1, array_map(function ($s) {
return "-{$s}";
}, str_split(substr($o, 1))));
$o = $argv[$i];
} elseif ($o[0] === "-" && strlen($o) > 2 && $o[1] === "-" && 0 < ($eq = strpos($o, "="))) {
// long opt with argument, e.g. --foo=bar
$argc++;
array_splice($argv, $i, 1, [substr($o, 0, $eq++), substr($o, $eq)]);
$o = $argv[$i];
} elseif ($o === "--") {
// only positional args following
$f = true;
continue;
}
if ($f || !isset($this->spec[$o])) {
if ($o[0] !== "-" && isset($this->spec["--{$p}"])) {
$this[$p] = $o;
if (!$this->optIsMulti($p)) {
++$p;
}
} else {
(yield sprintf("Unknown option %s", $o));
}
} elseif (!$this->optAcceptsArg($o)) {
$this[$o] = true;
} elseif ($i + 1 < $argc && !isset($this->spec[$argv[$i + 1]])) {
$this[$o] = $argv[++$i];
} elseif ($this->optRequiresArg($o)) {
(yield sprintf("Option --%s requires an argument", $this->optLongName($o)));
} else {
// OPTARG
$this[$o] = $this->optDefaultArg($o);
}
if ($this->optHalts($o)) {
return;
}
}
}