Exemplo n.º 1
0
 /**
  * Parses command line options from an argv array into tokenized data
  *
  * This method processes options like -abc foo as if they were -a -b -c foo
  * This method also handles --foo=bar the same as -foo bar
  * 
  * @param mixed $argv_in        A numbered array of argv data like $_SERVER['argv']
  * @param ArgumentsSpec $arguments_spec The arguments specification
  *
  * @return array tokenized data
  */
 protected static function tokenizeArgvData($argv_in, ArgumentsSpec $arguments_spec)
 {
     $data_offset_count = 0;
     $usage = $arguments_spec->getUsage();
     $argv_tokens_out = array(array('type' => self::TOKEN_SELF, 'value' => $argv_in[0]));
     $token_offset = 1;
     $count = count($argv_in);
     while ($token_offset < $count) {
         $token_text = $argv_in[$token_offset];
         $tokens_read = 1;
         // build the switch key
         $key = false;
         $is_single_flag = false;
         if (substr($token_text, 0, 2) == '--') {
             $key = substr($token_text, 2);
         } else {
             if (substr($token_text, 0, 1) == '-') {
                 $key = substr($token_text, 1);
                 $is_single_flag = true;
             }
         }
         // build the data
         $data = null;
         if (strlen($key)) {
             // key exists
             // handle multiple flags on a single switch like -abc
             if ($is_single_flag and ($key_len = strlen($key)) > 1) {
                 for ($flag_offset = 0; $flag_offset < $key_len - 1; $flag_offset++) {
                     if (substr($key, $flag_offset + 1, 1) == '=') {
                         break;
                     }
                     $argv_tokens_out[] = array('type' => self::TOKEN_OPTION, 'key' => substr($key, $flag_offset, 1), 'value' => false);
                 }
                 $key = substr($key, $flag_offset);
             }
             // try to parse --foo=bar
             if (preg_match('/^(.+?)=(.+)$/', $key, $matches)) {
                 $key = $matches[1];
                 $data = $matches[2];
             } else {
                 if ($arguments_spec->optionExpectsValue($key)) {
                     // we are expecting a value, so read the next token as data
                     $next_token = isset($argv_in[$token_offset + 1]) ? $argv_in[$token_offset + 1] : null;
                     if ($next_token !== null and substr($next_token, 0, 1) != '-') {
                         $data = $next_token;
                         // this is the only situation in which we read ahead another token
                         ++$tokens_read;
                     } else {
                         // did not find data for this switch even though we were expecting it
                         $data = false;
                     }
                 } else {
                     // no value expected
                     $data = false;
                 }
             }
         } else {
             // no key
             $data = $token_text;
         }
         if (strlen($key)) {
             $argv_tokens_out[] = array('type' => self::TOKEN_OPTION, 'key' => $key, 'value' => $data);
         } else {
             $argv_tokens_out[] = array('type' => self::TOKEN_DATA, 'offset' => $data_offset_count, 'key' => isset($usage['named_args_spec'][$data_offset_count]) ? $usage['named_args_spec'][$data_offset_count]['name'] : null, 'value' => $data);
             ++$data_offset_count;
         }
         $token_offset += $tokens_read;
     }
     return $argv_tokens_out;
 }
Exemplo n.º 2
0
 /**
  * validates if the arguments are valid according to the spec
  * 
  * @param ArgumentsSpec $arguments_spec The arguments specification
  * @param array         $parsed_args    data parsed by the ArgumentsParser
  *
  * @return bool true if the arguments are valid according to the spec
  */
 protected function validate(ArgumentsSpec $arguments_spec, $parsed_args)
 {
     $is_valid = true;
     // check for missing required items or argument values
     foreach ($arguments_spec as $option_spec) {
         $value_specified = (isset($option_spec['short']) and strlen($option_spec['short']) and isset($parsed_args['options'][$option_spec['short']]) and strlen($parsed_args['options'][$option_spec['short']]) or isset($option_spec['long']) and strlen($option_spec['long']) and isset($parsed_args['options'][$option_spec['long']]) and strlen($parsed_args['options'][$option_spec['long']]));
         if ($option_spec['required']) {
             if (!$value_specified) {
                 // required, but not found
                 $is_valid = false;
                 $this->errors[] = "Required value for argument " . $this->longOptionName($option_spec) . " not found.";
             }
         } else {
             if (strlen($option_spec['value_name'])) {
                 if (!$value_specified) {
                     $switch_was_sepcified = (isset($parsed_args['options'][$option_spec['short']]) and isset($parsed_args['options'][$option_spec['short']]) or isset($parsed_args['options'][$option_spec['long']]) and isset($parsed_args['options'][$option_spec['long']]));
                     if ($switch_was_sepcified) {
                         // not required, but a value name is specified and none was given
                         $is_valid = false;
                         $this->errors[] = "No value was specified for argument " . $this->longOptionName($option_spec) . ".";
                     }
                 }
             }
         }
     }
     // find extra argument values that are not defined
     foreach ($parsed_args['options'] as $option_name => $value) {
         $resolved_option_name = $arguments_spec->normalizeOptionName($option_name);
         if ($resolved_option_name === null) {
             $is_valid = false;
             $this->errors[] = "Unknown option " . $option_name . ".";
         }
     }
     // data
     $usage_data = $arguments_spec->getUsage();
     // find required arguments
     foreach ($usage_data['named_args_spec'] as $offset => $named_arg_spec) {
         if ($named_arg_spec['required'] and !isset($parsed_args['numbered_data'][$offset])) {
             $is_valid = false;
             $this->errors[] = "No value for <" . $named_arg_spec['name'] . "> was provided.";
         }
     }
     // find extra arguments
     $expected_values_count = count($usage_data['named_args_spec']);
     if (($data_count = count($parsed_args['numbered_data'])) > $expected_values_count) {
         $extra_count = $data_count - $expected_values_count;
         $is_valid = false;
         $this->errors[] = "Found {$extra_count} unexpected value" . ($extra_count == 1 ? '' : 's') . ".";
     }
     return $is_valid;
 }
Exemplo n.º 3
0
 /**
  * builds argument values by long option name
  * 
  * @param ArgumentsSpec $arguments_spec The arguments specification
  * @param array         $parsed_args    data parsed by the ArgumentsParser
  *
  * @return array argument values by long option name
  */
 protected function extractAllLongOpts(ArgumentsSpec $arguments_spec, $parsed_args)
 {
     $long_opts = array();
     foreach ($parsed_args['options'] as $option_name => $value) {
         if ($long_option_name = $arguments_spec->normalizeOptionName($option_name)) {
             $long_opts[$long_option_name] = $value;
         }
     }
     return $long_opts;
 }