File indexing completed on 2024-12-22 05:36:32
0001 <?php 0002 /** 0003 * Zend_Console_Getopt is a class to parse options for command-line 0004 * applications. 0005 * 0006 * LICENSE 0007 * 0008 * This source file is subject to the new BSD license that is bundled 0009 * with this package in the file LICENSE.txt. 0010 * It is also available through the world-wide-web at this URL: 0011 * http://framework.zend.com/license/new-bsd 0012 * If you did not receive a copy of the license and are unable to 0013 * obtain it through the world-wide-web, please send an email 0014 * to license@zend.com so we can send you a copy immediately. 0015 * 0016 * @category Zend 0017 * @package Zend_Console_Getopt 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * Zend_Console_Getopt is a class to parse options for command-line 0025 * applications. 0026 * 0027 * Terminology: 0028 * Argument: an element of the argv array. This may be part of an option, 0029 * or it may be a non-option command-line argument. 0030 * Flag: the letter or word set off by a '-' or '--'. Example: in '--output filename', 0031 * '--output' is the flag. 0032 * Parameter: the additional argument that is associated with the option. 0033 * Example: in '--output filename', the 'filename' is the parameter. 0034 * Option: the combination of a flag and its parameter, if any. 0035 * Example: in '--output filename', the whole thing is the option. 0036 * 0037 * The following features are supported: 0038 * 0039 * - Short flags like '-a'. Short flags are preceded by a single 0040 * dash. Short flags may be clustered e.g. '-abc', which is the 0041 * same as '-a' '-b' '-c'. 0042 * - Long flags like '--verbose'. Long flags are preceded by a 0043 * double dash. Long flags may not be clustered. 0044 * - Options may have a parameter, e.g. '--output filename'. 0045 * - Parameters for long flags may also be set off with an equals sign, 0046 * e.g. '--output=filename'. 0047 * - Parameters for long flags may be checked as string, word, or integer. 0048 * - Automatic generation of a helpful usage message. 0049 * - Signal end of options with '--'; subsequent arguments are treated 0050 * as non-option arguments, even if they begin with '-'. 0051 * - Raise exception Zend_Console_Getopt_Exception in several cases 0052 * when invalid flags or parameters are given. Usage message is 0053 * returned in the exception object. 0054 * 0055 * The format for specifying options uses a PHP associative array. 0056 * The key is has the format of a list of pipe-separated flag names, 0057 * followed by an optional '=' to indicate a required parameter or 0058 * '-' to indicate an optional parameter. Following that, the type 0059 * of parameter may be specified as 's' for string, 'w' for word, 0060 * or 'i' for integer. 0061 * 0062 * Examples: 0063 * - 'user|username|u=s' this means '--user' or '--username' or '-u' 0064 * are synonyms, and the option requires a string parameter. 0065 * - 'p=i' this means '-p' requires an integer parameter. No synonyms. 0066 * - 'verbose|v-i' this means '--verbose' or '-v' are synonyms, and 0067 * they take an optional integer parameter. 0068 * - 'help|h' this means '--help' or '-h' are synonyms, and 0069 * they take no parameter. 0070 * 0071 * The values in the associative array are strings that are used as 0072 * brief descriptions of the options when printing a usage message. 0073 * 0074 * The simpler format for specifying options used by PHP's getopt() 0075 * function is also supported. This is similar to GNU getopt and shell 0076 * getopt format. 0077 * 0078 * Example: 'abc:' means options '-a', '-b', and '-c' 0079 * are legal, and the latter requires a string parameter. 0080 * 0081 * @category Zend 0082 * @package Zend_Console_Getopt 0083 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0084 * @license http://framework.zend.com/license/new-bsd New BSD License 0085 * @version Release: @package_version@ 0086 * @since Class available since Release 0.6.0 0087 * 0088 * @todo Handle params with multiple values, e.g. --colors=red,green,blue 0089 * Set value of parameter to the array of values. Allow user to specify 0090 * the separator with Zend_Console_Getopt::CONFIG_PARAMETER_SEPARATOR. 0091 * If this config value is null or empty string, do not split values 0092 * into arrays. Default separator is comma (','). 0093 * 0094 * @todo Handle params with multiple values specified with separate options 0095 * e.g. --colors red --colors green --colors blue should give one 0096 * option with an array(red, green, blue). 0097 * Enable with Zend_Console_Getopt::CONFIG_CUMULATIVE_PARAMETERS. 0098 * Default is that subsequent options overwrite the parameter value. 0099 * 0100 * @todo Handle flags occurring multiple times, e.g. -v -v -v 0101 * Set value of the option's parameter to the integer count of instances 0102 * instead of a boolean. 0103 * Enable with Zend_Console_Getopt::CONFIG_CUMULATIVE_FLAGS. 0104 * Default is that the value is simply boolean true regardless of 0105 * how many instances of the flag appear. 0106 * 0107 * @todo Handle flags that implicitly print usage message, e.g. --help 0108 * 0109 * @todo Handle freeform options, e.g. --set-variable 0110 * Enable with Zend_Console_Getopt::CONFIG_FREEFORM_FLAGS 0111 * All flag-like syntax is recognized, no flag generates an exception. 0112 * 0113 * @todo Handle numeric options, e.g. -1, -2, -3, -1000 0114 * Enable with Zend_Console_Getopt::CONFIG_NUMERIC_FLAGS 0115 * The rule must specify a named flag and the '#' symbol as the 0116 * parameter type. e.g., 'lines=#' 0117 * 0118 * @todo Enable user to specify header and footer content in the help message. 0119 * 0120 * @todo Feature request to handle option interdependencies. 0121 * e.g. if -b is specified, -a must be specified or else the 0122 * usage is invalid. 0123 * 0124 * @todo Feature request to implement callbacks. 0125 * e.g. if -a is specified, run function 'handleOptionA'(). 0126 */ 0127 class Zend_Console_Getopt 0128 { 0129 0130 /** 0131 * The options for a given application can be in multiple formats. 0132 * modeGnu is for traditional 'ab:c:' style getopt format. 0133 * modeZend is for a more structured format. 0134 */ 0135 const MODE_ZEND = 'zend'; 0136 const MODE_GNU = 'gnu'; 0137 0138 /** 0139 * Constant tokens for various symbols used in the mode_zend 0140 * rule format. 0141 */ 0142 const PARAM_REQUIRED = '='; 0143 const PARAM_OPTIONAL = '-'; 0144 const TYPE_STRING = 's'; 0145 const TYPE_WORD = 'w'; 0146 const TYPE_INTEGER = 'i'; 0147 0148 /** 0149 * These are constants for optional behavior of this class. 0150 * ruleMode is either 'zend' or 'gnu' or a user-defined mode. 0151 * dashDash is true if '--' signifies the end of command-line options. 0152 * ignoreCase is true if '--opt' and '--OPT' are implicitly synonyms. 0153 * parseAll is true if all options on the command line should be parsed, regardless of 0154 * whether an argument appears before them. 0155 */ 0156 const CONFIG_RULEMODE = 'ruleMode'; 0157 const CONFIG_DASHDASH = 'dashDash'; 0158 const CONFIG_IGNORECASE = 'ignoreCase'; 0159 const CONFIG_PARSEALL = 'parseAll'; 0160 0161 /** 0162 * Defaults for getopt configuration are: 0163 * ruleMode is 'zend' format, 0164 * dashDash (--) token is enabled, 0165 * ignoreCase is not enabled, 0166 * parseAll is enabled. 0167 */ 0168 protected $_getoptConfig = array( 0169 self::CONFIG_RULEMODE => self::MODE_ZEND, 0170 self::CONFIG_DASHDASH => true, 0171 self::CONFIG_IGNORECASE => false, 0172 self::CONFIG_PARSEALL => true, 0173 ); 0174 0175 /** 0176 * Stores the command-line arguments for the calling application. 0177 * 0178 * @var array 0179 */ 0180 protected $_argv = array(); 0181 0182 /** 0183 * Stores the name of the calling application. 0184 * 0185 * @var string 0186 */ 0187 protected $_progname = ''; 0188 0189 /** 0190 * Stores the list of legal options for this application. 0191 * 0192 * @var array 0193 */ 0194 protected $_rules = array(); 0195 0196 /** 0197 * Stores alternate spellings of legal options. 0198 * 0199 * @var array 0200 */ 0201 protected $_ruleMap = array(); 0202 0203 /** 0204 * Stores options given by the user in the current invocation 0205 * of the application, as well as parameters given in options. 0206 * 0207 * @var array 0208 */ 0209 protected $_options = array(); 0210 0211 /** 0212 * Stores the command-line arguments other than options. 0213 * 0214 * @var array 0215 */ 0216 protected $_remainingArgs = array(); 0217 0218 /** 0219 * State of the options: parsed or not yet parsed? 0220 * 0221 * @var boolean 0222 */ 0223 protected $_parsed = false; 0224 0225 /** 0226 * The constructor takes one to three parameters. 0227 * 0228 * The first parameter is $rules, which may be a string for 0229 * gnu-style format, or a structured array for Zend-style format. 0230 * 0231 * The second parameter is $argv, and it is optional. If not 0232 * specified, $argv is inferred from the global argv. 0233 * 0234 * The third parameter is an array of configuration parameters 0235 * to control the behavior of this instance of Getopt; it is optional. 0236 * 0237 * @param array $rules 0238 * @param array $argv 0239 * @param array $getoptConfig 0240 * @return void 0241 */ 0242 public function __construct($rules, $argv = null, $getoptConfig = array()) 0243 { 0244 if (!isset($_SERVER['argv'])) { 0245 // require_once 'Zend/Console/Getopt/Exception.php'; 0246 if (ini_get('register_argc_argv') == false) { 0247 throw new Zend_Console_Getopt_Exception( 0248 "argv is not available, because ini option 'register_argc_argv' is set Off" 0249 ); 0250 } else { 0251 throw new Zend_Console_Getopt_Exception( 0252 '$_SERVER["argv"] is not set, but Zend_Console_Getopt cannot work without this information.' 0253 ); 0254 } 0255 } 0256 0257 $this->_progname = $_SERVER['argv'][0]; 0258 $this->setOptions($getoptConfig); 0259 $this->addRules($rules); 0260 if (!is_array($argv)) { 0261 $argv = array_slice($_SERVER['argv'], 1); 0262 } 0263 if (isset($argv)) { 0264 $this->addArguments((array)$argv); 0265 } 0266 } 0267 0268 /** 0269 * Return the state of the option seen on the command line of the 0270 * current application invocation. This function returns true, or the 0271 * parameter to the option, if any. If the option was not given, 0272 * this function returns null. 0273 * 0274 * The magic __get method works in the context of naming the option 0275 * as a virtual member of this class. 0276 * 0277 * @param string $key 0278 * @return string 0279 */ 0280 public function __get($key) 0281 { 0282 return $this->getOption($key); 0283 } 0284 0285 /** 0286 * Test whether a given option has been seen. 0287 * 0288 * @param string $key 0289 * @return boolean 0290 */ 0291 public function __isset($key) 0292 { 0293 $this->parse(); 0294 if (isset($this->_ruleMap[$key])) { 0295 $key = $this->_ruleMap[$key]; 0296 return isset($this->_options[$key]); 0297 } 0298 return false; 0299 } 0300 0301 /** 0302 * Set the value for a given option. 0303 * 0304 * @param string $key 0305 * @param string $value 0306 * @return void 0307 */ 0308 public function __set($key, $value) 0309 { 0310 $this->parse(); 0311 if (isset($this->_ruleMap[$key])) { 0312 $key = $this->_ruleMap[$key]; 0313 $this->_options[$key] = $value; 0314 } 0315 } 0316 0317 /** 0318 * Return the current set of options and parameters seen as a string. 0319 * 0320 * @return string 0321 */ 0322 public function __toString() 0323 { 0324 return $this->toString(); 0325 } 0326 0327 /** 0328 * Unset an option. 0329 * 0330 * @param string $key 0331 * @return void 0332 */ 0333 public function __unset($key) 0334 { 0335 $this->parse(); 0336 if (isset($this->_ruleMap[$key])) { 0337 $key = $this->_ruleMap[$key]; 0338 unset($this->_options[$key]); 0339 } 0340 } 0341 0342 /** 0343 * Define additional command-line arguments. 0344 * These are appended to those defined when the constructor was called. 0345 * 0346 * @param array $argv 0347 * @throws Zend_Console_Getopt_Exception When not given an array as parameter 0348 * @return Zend_Console_Getopt Provides a fluent interface 0349 */ 0350 public function addArguments($argv) 0351 { 0352 if(!is_array($argv)) { 0353 // require_once 'Zend/Console/Getopt/Exception.php'; 0354 throw new Zend_Console_Getopt_Exception( 0355 "Parameter #1 to addArguments should be an array"); 0356 } 0357 $this->_argv = array_merge($this->_argv, $argv); 0358 $this->_parsed = false; 0359 return $this; 0360 } 0361 0362 /** 0363 * Define full set of command-line arguments. 0364 * These replace any currently defined. 0365 * 0366 * @param array $argv 0367 * @throws Zend_Console_Getopt_Exception When not given an array as parameter 0368 * @return Zend_Console_Getopt Provides a fluent interface 0369 */ 0370 public function setArguments($argv) 0371 { 0372 if(!is_array($argv)) { 0373 // require_once 'Zend/Console/Getopt/Exception.php'; 0374 throw new Zend_Console_Getopt_Exception( 0375 "Parameter #1 to setArguments should be an array"); 0376 } 0377 $this->_argv = $argv; 0378 $this->_parsed = false; 0379 return $this; 0380 } 0381 0382 /** 0383 * Define multiple configuration options from an associative array. 0384 * These are not program options, but properties to configure 0385 * the behavior of Zend_Console_Getopt. 0386 * 0387 * @param array $getoptConfig 0388 * @return Zend_Console_Getopt Provides a fluent interface 0389 */ 0390 public function setOptions($getoptConfig) 0391 { 0392 if (isset($getoptConfig)) { 0393 foreach ($getoptConfig as $key => $value) { 0394 $this->setOption($key, $value); 0395 } 0396 } 0397 return $this; 0398 } 0399 0400 /** 0401 * Define one configuration option as a key/value pair. 0402 * These are not program options, but properties to configure 0403 * the behavior of Zend_Console_Getopt. 0404 * 0405 * @param string $configKey 0406 * @param string $configValue 0407 * @return Zend_Console_Getopt Provides a fluent interface 0408 */ 0409 public function setOption($configKey, $configValue) 0410 { 0411 if ($configKey !== null) { 0412 $this->_getoptConfig[$configKey] = $configValue; 0413 } 0414 return $this; 0415 } 0416 0417 /** 0418 * Define additional option rules. 0419 * These are appended to the rules defined when the constructor was called. 0420 * 0421 * @param array $rules 0422 * @return Zend_Console_Getopt Provides a fluent interface 0423 */ 0424 public function addRules($rules) 0425 { 0426 $ruleMode = $this->_getoptConfig['ruleMode']; 0427 switch ($this->_getoptConfig['ruleMode']) { 0428 case self::MODE_ZEND: 0429 if (is_array($rules)) { 0430 $this->_addRulesModeZend($rules); 0431 break; 0432 } 0433 // intentional fallthrough 0434 case self::MODE_GNU: 0435 $this->_addRulesModeGnu($rules); 0436 break; 0437 default: 0438 /** 0439 * Call addRulesModeFoo() for ruleMode 'foo'. 0440 * The developer should subclass Getopt and 0441 * provide this method. 0442 */ 0443 $method = '_addRulesMode' . ucfirst($ruleMode); 0444 $this->$method($rules); 0445 } 0446 $this->_parsed = false; 0447 return $this; 0448 } 0449 0450 /** 0451 * Return the current set of options and parameters seen as a string. 0452 * 0453 * @return string 0454 */ 0455 public function toString() 0456 { 0457 $this->parse(); 0458 $s = array(); 0459 foreach ($this->_options as $flag => $value) { 0460 $s[] = $flag . '=' . ($value === true ? 'true' : $value); 0461 } 0462 return implode(' ', $s); 0463 } 0464 0465 /** 0466 * Return the current set of options and parameters seen 0467 * as an array of canonical options and parameters. 0468 * 0469 * Clusters have been expanded, and option aliases 0470 * have been mapped to their primary option names. 0471 * 0472 * @return array 0473 */ 0474 public function toArray() 0475 { 0476 $this->parse(); 0477 $s = array(); 0478 foreach ($this->_options as $flag => $value) { 0479 $s[] = $flag; 0480 if ($value !== true) { 0481 $s[] = $value; 0482 } 0483 } 0484 return $s; 0485 } 0486 0487 /** 0488 * Return the current set of options and parameters seen in Json format. 0489 * 0490 * @return string 0491 */ 0492 public function toJson() 0493 { 0494 $this->parse(); 0495 $j = array(); 0496 foreach ($this->_options as $flag => $value) { 0497 $j['options'][] = array( 0498 'option' => array( 0499 'flag' => $flag, 0500 'parameter' => $value 0501 ) 0502 ); 0503 } 0504 0505 /** 0506 * @see Zend_Json 0507 */ 0508 // require_once 'Zend/Json.php'; 0509 $json = Zend_Json::encode($j); 0510 0511 return $json; 0512 } 0513 0514 /** 0515 * Return the current set of options and parameters seen in XML format. 0516 * 0517 * @return string 0518 */ 0519 public function toXml() 0520 { 0521 $this->parse(); 0522 $doc = new DomDocument('1.0', 'utf-8'); 0523 $optionsNode = $doc->createElement('options'); 0524 $doc->appendChild($optionsNode); 0525 foreach ($this->_options as $flag => $value) { 0526 $optionNode = $doc->createElement('option'); 0527 $optionNode->setAttribute('flag', utf8_encode($flag)); 0528 if ($value !== true) { 0529 $optionNode->setAttribute('parameter', utf8_encode($value)); 0530 } 0531 $optionsNode->appendChild($optionNode); 0532 } 0533 $xml = $doc->saveXML(); 0534 return $xml; 0535 } 0536 0537 /** 0538 * Return a list of options that have been seen in the current argv. 0539 * 0540 * @return array 0541 */ 0542 public function getOptions() 0543 { 0544 $this->parse(); 0545 return array_keys($this->_options); 0546 } 0547 0548 /** 0549 * Return the state of the option seen on the command line of the 0550 * current application invocation. 0551 * 0552 * This function returns true, or the parameter value to the option, if any. 0553 * If the option was not given, this function returns null. 0554 * 0555 * @param string $flag 0556 * @return mixed 0557 */ 0558 public function getOption($flag) 0559 { 0560 $this->parse(); 0561 if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { 0562 $flag = strtolower($flag); 0563 } 0564 if (isset($this->_ruleMap[$flag])) { 0565 $flag = $this->_ruleMap[$flag]; 0566 if (isset($this->_options[$flag])) { 0567 return $this->_options[$flag]; 0568 } 0569 } 0570 return null; 0571 } 0572 0573 /** 0574 * Return the arguments from the command-line following all options found. 0575 * 0576 * @return array 0577 */ 0578 public function getRemainingArgs() 0579 { 0580 $this->parse(); 0581 return $this->_remainingArgs; 0582 } 0583 0584 /** 0585 * Return a useful option reference, formatted for display in an 0586 * error message. 0587 * 0588 * Note that this usage information is provided in most Exceptions 0589 * generated by this class. 0590 * 0591 * @return string 0592 */ 0593 public function getUsageMessage() 0594 { 0595 $usage = "Usage: {$this->_progname} [ options ]\n"; 0596 $maxLen = 20; 0597 $lines = array(); 0598 foreach ($this->_rules as $rule) { 0599 $flags = array(); 0600 if (is_array($rule['alias'])) { 0601 foreach ($rule['alias'] as $flag) { 0602 $flags[] = (strlen($flag) == 1 ? '-' : '--') . $flag; 0603 } 0604 } 0605 $linepart['name'] = implode('|', $flags); 0606 if (isset($rule['param']) && $rule['param'] != 'none') { 0607 $linepart['name'] .= ' '; 0608 switch ($rule['param']) { 0609 case 'optional': 0610 $linepart['name'] .= "[ <{$rule['paramType']}> ]"; 0611 break; 0612 case 'required': 0613 $linepart['name'] .= "<{$rule['paramType']}>"; 0614 break; 0615 } 0616 } 0617 if (strlen($linepart['name']) > $maxLen) { 0618 $maxLen = strlen($linepart['name']); 0619 } 0620 $linepart['help'] = ''; 0621 if (isset($rule['help'])) { 0622 $linepart['help'] .= $rule['help']; 0623 } 0624 $lines[] = $linepart; 0625 } 0626 foreach ($lines as $linepart) { 0627 $usage .= sprintf("%s %s\n", 0628 str_pad($linepart['name'], $maxLen), 0629 $linepart['help']); 0630 } 0631 return $usage; 0632 } 0633 0634 /** 0635 * Define aliases for options. 0636 * 0637 * The parameter $aliasMap is an associative array 0638 * mapping option name (short or long) to an alias. 0639 * 0640 * @param array $aliasMap 0641 * @throws Zend_Console_Getopt_Exception 0642 * @return Zend_Console_Getopt Provides a fluent interface 0643 */ 0644 public function setAliases($aliasMap) 0645 { 0646 foreach ($aliasMap as $flag => $alias) 0647 { 0648 if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { 0649 $flag = strtolower($flag); 0650 $alias = strtolower($alias); 0651 } 0652 if (!isset($this->_ruleMap[$flag])) { 0653 continue; 0654 } 0655 $flag = $this->_ruleMap[$flag]; 0656 if (isset($this->_rules[$alias]) || isset($this->_ruleMap[$alias])) { 0657 $o = (strlen($alias) == 1 ? '-' : '--') . $alias; 0658 // require_once 'Zend/Console/Getopt/Exception.php'; 0659 throw new Zend_Console_Getopt_Exception( 0660 "Option \"$o\" is being defined more than once."); 0661 } 0662 $this->_rules[$flag]['alias'][] = $alias; 0663 $this->_ruleMap[$alias] = $flag; 0664 } 0665 return $this; 0666 } 0667 0668 /** 0669 * Define help messages for options. 0670 * 0671 * The parameter $help_map is an associative array 0672 * mapping option name (short or long) to the help string. 0673 * 0674 * @param array $helpMap 0675 * @return Zend_Console_Getopt Provides a fluent interface 0676 */ 0677 public function setHelp($helpMap) 0678 { 0679 foreach ($helpMap as $flag => $help) 0680 { 0681 if (!isset($this->_ruleMap[$flag])) { 0682 continue; 0683 } 0684 $flag = $this->_ruleMap[$flag]; 0685 $this->_rules[$flag]['help'] = $help; 0686 } 0687 return $this; 0688 } 0689 0690 /** 0691 * Parse command-line arguments and find both long and short 0692 * options. 0693 * 0694 * Also find option parameters, and remaining arguments after 0695 * all options have been parsed. 0696 * 0697 * @return Zend_Console_Getopt|null Provides a fluent interface 0698 */ 0699 public function parse() 0700 { 0701 if ($this->_parsed === true) { 0702 return; 0703 } 0704 $argv = $this->_argv; 0705 $this->_options = array(); 0706 $this->_remainingArgs = array(); 0707 while (count($argv) > 0) { 0708 if ($argv[0] == '--') { 0709 array_shift($argv); 0710 if ($this->_getoptConfig[self::CONFIG_DASHDASH]) { 0711 $this->_remainingArgs = array_merge($this->_remainingArgs, $argv); 0712 break; 0713 } 0714 } 0715 if (substr($argv[0], 0, 2) == '--') { 0716 $this->_parseLongOption($argv); 0717 } else if (substr($argv[0], 0, 1) == '-' && ('-' != $argv[0] || count($argv) >1)) { 0718 $this->_parseShortOptionCluster($argv); 0719 } else if($this->_getoptConfig[self::CONFIG_PARSEALL]) { 0720 $this->_remainingArgs[] = array_shift($argv); 0721 } else { 0722 /* 0723 * We should put all other arguments in _remainingArgs and stop parsing 0724 * since CONFIG_PARSEALL is false. 0725 */ 0726 $this->_remainingArgs = array_merge($this->_remainingArgs, $argv); 0727 break; 0728 } 0729 } 0730 $this->_parsed = true; 0731 return $this; 0732 } 0733 0734 /** 0735 * @throws Zend_Console_Getopt_Exception 0736 */ 0737 public function checkRequiredArguments() 0738 { 0739 foreach ($this->_rules as $name => $rule) { 0740 if ($rule['param'] === 'required') { 0741 $defined = false; 0742 foreach ($rule['alias'] as $alias) { 0743 $defined = $defined === true ? true : array_key_exists($alias, $this->_options); 0744 } 0745 if ($defined === false) { 0746 // require_once 'Zend/Console/Getopt/Exception.php'; 0747 throw new Zend_Console_Getopt_Exception( 0748 'Option "$alias" requires a parameter.', 0749 $this->getUsageMessage() 0750 ); 0751 } 0752 } 0753 } 0754 } 0755 0756 /** 0757 * Parse command-line arguments for a single long option. 0758 * A long option is preceded by a double '--' character. 0759 * Long options may not be clustered. 0760 * 0761 * @param mixed &$argv 0762 * @return void 0763 */ 0764 protected function _parseLongOption(&$argv) 0765 { 0766 $optionWithParam = ltrim(array_shift($argv), '-'); 0767 $l = explode('=', $optionWithParam, 2); 0768 $flag = array_shift($l); 0769 $param = array_shift($l); 0770 if (isset($param)) { 0771 array_unshift($argv, $param); 0772 } 0773 $this->_parseSingleOption($flag, $argv); 0774 } 0775 0776 /** 0777 * Parse command-line arguments for short options. 0778 * Short options are those preceded by a single '-' character. 0779 * Short options may be clustered. 0780 * 0781 * @param mixed &$argv 0782 * @return void 0783 */ 0784 protected function _parseShortOptionCluster(&$argv) 0785 { 0786 $flagCluster = ltrim(array_shift($argv), '-'); 0787 foreach (str_split($flagCluster) as $flag) { 0788 $this->_parseSingleOption($flag, $argv); 0789 } 0790 } 0791 0792 /** 0793 * Parse command-line arguments for a single option. 0794 * 0795 * @param string $flag 0796 * @param mixed $argv 0797 * @throws Zend_Console_Getopt_Exception 0798 * @return void 0799 */ 0800 protected function _parseSingleOption($flag, &$argv) 0801 { 0802 if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { 0803 $flag = strtolower($flag); 0804 } 0805 if (!isset($this->_ruleMap[$flag])) { 0806 // require_once 'Zend/Console/Getopt/Exception.php'; 0807 throw new Zend_Console_Getopt_Exception( 0808 "Option \"$flag\" is not recognized.", 0809 $this->getUsageMessage()); 0810 } 0811 $realFlag = $this->_ruleMap[$flag]; 0812 switch ($this->_rules[$realFlag]['param']) { 0813 case 'required': 0814 if (count($argv) > 0 && substr($argv[0], 0, 1) != '-') { 0815 $param = array_shift($argv); 0816 $this->_checkParameterType($realFlag, $param); 0817 } else { 0818 // require_once 'Zend/Console/Getopt/Exception.php'; 0819 throw new Zend_Console_Getopt_Exception( 0820 "Option \"$flag\" requires a parameter.", 0821 $this->getUsageMessage()); 0822 } 0823 break; 0824 case 'optional': 0825 if (count($argv) > 0 && substr($argv[0], 0, 1) != '-') { 0826 $param = array_shift($argv); 0827 $this->_checkParameterType($realFlag, $param); 0828 } else { 0829 $param = true; 0830 } 0831 break; 0832 default: 0833 $param = true; 0834 } 0835 $this->_options[$realFlag] = $param; 0836 } 0837 0838 /** 0839 * Return true if the parameter is in a valid format for 0840 * the option $flag. 0841 * Throw an exception in most other cases. 0842 * 0843 * @param string $flag 0844 * @param string $param 0845 * @throws Zend_Console_Getopt_Exception 0846 * @return bool 0847 */ 0848 protected function _checkParameterType($flag, $param) 0849 { 0850 $type = 'string'; 0851 if (isset($this->_rules[$flag]['paramType'])) { 0852 $type = $this->_rules[$flag]['paramType']; 0853 } 0854 switch ($type) { 0855 case 'word': 0856 if (preg_match('/\W/', $param)) { 0857 // require_once 'Zend/Console/Getopt/Exception.php'; 0858 throw new Zend_Console_Getopt_Exception( 0859 "Option \"$flag\" requires a single-word parameter, but was given \"$param\".", 0860 $this->getUsageMessage()); 0861 } 0862 break; 0863 case 'integer': 0864 if (preg_match('/\D/', $param)) { 0865 // require_once 'Zend/Console/Getopt/Exception.php'; 0866 throw new Zend_Console_Getopt_Exception( 0867 "Option \"$flag\" requires an integer parameter, but was given \"$param\".", 0868 $this->getUsageMessage()); 0869 } 0870 break; 0871 case 'string': 0872 default: 0873 break; 0874 } 0875 return true; 0876 } 0877 0878 /** 0879 * Define legal options using the gnu-style format. 0880 * 0881 * @param string $rules 0882 * @return void 0883 */ 0884 protected function _addRulesModeGnu($rules) 0885 { 0886 $ruleArray = array(); 0887 0888 /** 0889 * Options may be single alphanumeric characters. 0890 * Options may have a ':' which indicates a required string parameter. 0891 * No long options or option aliases are supported in GNU style. 0892 */ 0893 preg_match_all('/([a-zA-Z0-9]:?)/', $rules, $ruleArray); 0894 foreach ($ruleArray[1] as $rule) { 0895 $r = array(); 0896 $flag = substr($rule, 0, 1); 0897 if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { 0898 $flag = strtolower($flag); 0899 } 0900 $r['alias'][] = $flag; 0901 if (substr($rule, 1, 1) == ':') { 0902 $r['param'] = 'required'; 0903 $r['paramType'] = 'string'; 0904 } else { 0905 $r['param'] = 'none'; 0906 } 0907 $this->_rules[$flag] = $r; 0908 $this->_ruleMap[$flag] = $flag; 0909 } 0910 } 0911 0912 /** 0913 * Define legal options using the Zend-style format. 0914 * 0915 * @param array $rules 0916 * @throws Zend_Console_Getopt_Exception 0917 * @return void 0918 */ 0919 protected function _addRulesModeZend($rules) 0920 { 0921 foreach ($rules as $ruleCode => $helpMessage) 0922 { 0923 // this may have to translate the long parm type if there 0924 // are any complaints that =string will not work (even though that use 0925 // case is not documented) 0926 if (in_array(substr($ruleCode, -2, 1), array('-', '='))) { 0927 $flagList = substr($ruleCode, 0, -2); 0928 $delimiter = substr($ruleCode, -2, 1); 0929 $paramType = substr($ruleCode, -1); 0930 } else { 0931 $flagList = $ruleCode; 0932 $delimiter = $paramType = null; 0933 } 0934 if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { 0935 $flagList = strtolower($flagList); 0936 } 0937 $flags = explode('|', $flagList); 0938 $rule = array(); 0939 $mainFlag = $flags[0]; 0940 foreach ($flags as $flag) { 0941 if (empty($flag)) { 0942 // require_once 'Zend/Console/Getopt/Exception.php'; 0943 throw new Zend_Console_Getopt_Exception( 0944 "Blank flag not allowed in rule \"$ruleCode\"."); 0945 } 0946 if (strlen($flag) == 1) { 0947 if (isset($this->_ruleMap[$flag])) { 0948 // require_once 'Zend/Console/Getopt/Exception.php'; 0949 throw new Zend_Console_Getopt_Exception( 0950 "Option \"-$flag\" is being defined more than once."); 0951 } 0952 $this->_ruleMap[$flag] = $mainFlag; 0953 $rule['alias'][] = $flag; 0954 } else { 0955 if (isset($this->_rules[$flag]) || isset($this->_ruleMap[$flag])) { 0956 // require_once 'Zend/Console/Getopt/Exception.php'; 0957 throw new Zend_Console_Getopt_Exception( 0958 "Option \"--$flag\" is being defined more than once."); 0959 } 0960 $this->_ruleMap[$flag] = $mainFlag; 0961 $rule['alias'][] = $flag; 0962 } 0963 } 0964 if (isset($delimiter)) { 0965 switch ($delimiter) { 0966 case self::PARAM_REQUIRED: 0967 $rule['param'] = 'required'; 0968 break; 0969 case self::PARAM_OPTIONAL: 0970 default: 0971 $rule['param'] = 'optional'; 0972 } 0973 switch (substr($paramType, 0, 1)) { 0974 case self::TYPE_WORD: 0975 $rule['paramType'] = 'word'; 0976 break; 0977 case self::TYPE_INTEGER: 0978 $rule['paramType'] = 'integer'; 0979 break; 0980 case self::TYPE_STRING: 0981 default: 0982 $rule['paramType'] = 'string'; 0983 } 0984 } else { 0985 $rule['param'] = 'none'; 0986 } 0987 $rule['help'] = $helpMessage; 0988 $this->_rules[$mainFlag] = $rule; 0989 } 0990 } 0991 0992 }