public function parse(array $argv)
{
$result = new OptionResult();
list($argv, $extra) = $this->preprocessingArguments($argv);
foreach ($this->specs as $opt) {
if ($opt->defaultValue !== null) {
$opt->setValue($opt->defaultValue);
$result->set($opt->getId(), $opt);
}
}
$len = count($argv);
// some people might still pass only the option names here.
$first = new Argument($argv[0]);
if ($first->isOption()) {
throw new Exception('parse(argv) expects the first argument to be the program name.');
}
for ($i = 1; $i < $len; ++$i) {
$arg = new Argument($argv[$i]);
// if looks like not an option, push it to argument list.
// TODO: we might want to support argument with preceding dash (?)
if (!$arg->isOption()) {
$result->addArgument($arg);
continue;
}
// if the option is with extra flags,
// split the string, and insert into the argv array
if ($arg->withExtraFlagOptions()) {
$extra = $arg->extractExtraFlagOptions();
array_splice($argv, $i + 1, 0, $extra);
$argv[$i] = $arg->arg;
// update argument to current argv list.
$len = count($argv);
// update argv list length
}
$next = null;
if ($i + 1 < count($argv)) {
$next = new Argument($argv[$i + 1]);
}
$spec = $this->specs->get($arg->getOptionName());
if (!$spec) {
throw new InvalidOptionException('Invalid option: ' . $arg);
}
// This if expr might be unnecessary, becase we have default mode - flag
// if ($spec->isRequired() || $spec->isMultiple() || $spec->isOptional() || $spec->isFlag()) {
$i += $this->consumeOptionToken($spec, $arg, $next);
$result->set($spec->getId(), $spec);
}
return $result;
}