PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/app/sitesearch/lib/Zend/Console/Getopt.php

https://github.com/cbrunet/sitellite
PHP | 904 lines | 462 code | 45 blank | 397 comment | 69 complexity | 20574b6ec7fcb97c2a34544bc7e5dd9c MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0, GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Zend_Console_Getopt is a class to parse options for command-line
  4. * applications.
  5. *
  6. * LICENSE
  7. *
  8. * This source file is subject to the new BSD license that is bundled
  9. * with this package in the file LICENSE.txt.
  10. * It is also available through the world-wide-web at this URL:
  11. * http://framework.zend.com/license/new-bsd
  12. * If you did not receive a copy of the license and are unable to
  13. * obtain it through the world-wide-web, please send an email
  14. * to license@zend.com so we can send you a copy immediately.
  15. *
  16. * @category Zend
  17. * @package Zend_Console_Getopt
  18. * @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @version $Id: Getopt.php,v 1.1.1.1 2007/08/12 09:24:16 lux Exp $
  20. * @license http://framework.zend.com/license/new-bsd New BSD License
  21. */
  22. /** Zend_Console_Getopt_Exception */
  23. require_once 'Zend/Console/Getopt/Exception.php';
  24. /**
  25. * Zend_Console_Getopt is a class to parse options for command-line
  26. * applications.
  27. *
  28. * Terminology:
  29. * Argument: an element of the argv array. This may be part of an option,
  30. * or it may be a non-option command-line argument.
  31. * Flag: the letter or word set off by a '-' or '--'. Example: in '--output filename',
  32. * '--output' is the flag.
  33. * Parameter: the additional argument that is associated with the option.
  34. * Example: in '--output filename', the 'filename' is the parameter.
  35. * Option: the combination of a flag and its parameter, if any.
  36. * Example: in '--output filename', the whole thing is the option.
  37. *
  38. * The following features are supported:
  39. *
  40. * - Short flags like '-a'. Short flags are preceded by a single
  41. * dash. Short flags may be clustered e.g. '-abc', which is the
  42. * same as '-a' '-b' '-c'.
  43. * - Long flags like '--verbose'. Long flags are preceded by a
  44. * double dash. Long flags may not be clustered.
  45. * - Options may have a parameter, e.g. '--output filename'.
  46. * - Parameters for long flags may also be set off with an equals sign,
  47. * e.g. '--output=filename'.
  48. * - Parameters for long flags may be checked as string, word, or integer.
  49. * - Automatic generation of a helpful usage message.
  50. * - Signal end of options with '--'; subsequent arguments are treated
  51. * as non-option arguments, even if they begin with '-'.
  52. * - Raise exception Zend_Console_Getopt_Exception in several cases
  53. * when invalid flags or parameters are given. Usage message is
  54. * returned in the exception object.
  55. *
  56. * The format for specifying options uses a PHP associative array.
  57. * The key is has the format of a list of pipe-separated flag names,
  58. * followed by an optional '=' to indicate a required parameter or
  59. * '-' to indicate an optional parameter. Following that, the type
  60. * of parameter may be specified as 's' for string, 'w' for word,
  61. * or 'i' for integer.
  62. *
  63. * Examples:
  64. * - 'user|username|u=s' this means '--user' or '--username' or '-u'
  65. * are synonyms, and the option requires a string parameter.
  66. * - 'p=i' this means '-p' requires an integer parameter. No synonyms.
  67. * - 'verbose|v-i' this means '--verbose' or '-v' are synonyms, and
  68. * they take an optional integer parameter.
  69. * - 'help|h' this means '--help' or '-h' are synonyms, and
  70. * they take no parameter.
  71. *
  72. * The values in the associative array are strings that are used as
  73. * brief descriptions of the options when printing a usage message.
  74. *
  75. * The simpler format for specifying options used by PHP's getopt()
  76. * function is also supported. This is similar to GNU getopt and shell
  77. * getopt format.
  78. *
  79. * Example: 'abc:' means options '-a', '-b', and '-c'
  80. * are legal, and the latter requires a string parameter.
  81. *
  82. * @category Zend
  83. * @package Zend_Console_Getopt
  84. * @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
  85. * @license http://framework.zend.com/license/new-bsd New BSD License
  86. * @version Release: @package_version@
  87. * @since Class available since Release 0.6.0
  88. *
  89. * @todo: Handle params with multiple values, e.g. --colors=red,green,blue
  90. * Set value of parameter to the array of values. Allow user to specify
  91. * the separator with Zend_Console_Getopt::CONFIG_PARAMETER_SEPARATOR.
  92. * If this config value is null or empty string, do not split values
  93. * into arrays. Default separator is comma (',').
  94. *
  95. * @todo: Handle params with multiple values specified with separate options
  96. * e.g. --colors red --colors green --colors blue should give one
  97. * option with an array(red, green, blue).
  98. * Enable with Zend_Console_Getopt::CONFIG_CUMULATIVE_PARAMETERS.
  99. * Default is that subsequent options overwrite the parameter value.
  100. *
  101. * @todo: Handle flags occurring multiple times, e.g. -v -v -v
  102. * Set value of the option's parameter to the integer count of instances
  103. * instead of a boolean.
  104. * Enable with Zend_Console_Getopt::CONFIG_CUMULATIVE_FLAGS.
  105. * Default is that the value is simply boolean true regardless of
  106. * how many instances of the flag appear.
  107. *
  108. * @todo: Handle flags that implicitly print usage message, e.g. --help
  109. *
  110. * @todo: Handle freeform options, e.g. --set-variable
  111. * Enable with Zend_Console_Getopt::CONFIG_FREEFORM_FLAGS
  112. * All flag-like syntax is recognized, no flag generates an exception.
  113. *
  114. * @todo: Handle numeric options, e.g. -1, -2, -3, -1000
  115. * Enable with Zend_Console_Getopt::CONFIG_NUMERIC_FLAGS
  116. * The rule must specify a named flag and the '#' symbol as the
  117. * parameter type. e.g., 'lines=#'
  118. *
  119. * @todo: Enable user to specify header and footer content in the help message.
  120. *
  121. * @todo: Feature request to handle option interdependencies.
  122. * e.g. if -b is specified, -a must be specified or else the
  123. * usage is invalid.
  124. *
  125. * @todo: Feature request to implement callbacks.
  126. * e.g. if -a is specified, run function 'handleOptionA'().
  127. */
  128. class Zend_Console_Getopt
  129. {
  130. /**
  131. * The options for a given application can be in multiple formats.
  132. * modeGnu is for traditional 'ab:c:' style getopt format.
  133. * modeZend is for a more structured format.
  134. */
  135. const MODE_ZEND = 'zend';
  136. const MODE_GNU = 'gnu';
  137. /**
  138. * Constant tokens for various symbols used in the mode_zend
  139. * rule format.
  140. */
  141. const PARAM_REQUIRED = '=';
  142. const PARAM_OPTIONAL = '-';
  143. const TYPE_STRING = 's';
  144. const TYPE_WORD = 'w';
  145. const TYPE_INTEGER = 'i';
  146. /**
  147. * These are constants for optional behavior of this class.
  148. * ruleMode is either 'zend' or 'gnu' or a user-defined mode.
  149. * dashDash is true if '--' signifies the end of command-line options.
  150. * ignoreCase is true if '--opt' and '--OPT' are implicitly synonyms.
  151. */
  152. const CONFIG_RULEMODE = 'ruleMode';
  153. const CONFIG_DASHDASH = 'dashDash';
  154. const CONFIG_IGNORECASE = 'ignoreCase';
  155. /**
  156. * Defaults for getopt configuration are:
  157. * ruleMode is 'zend' format,
  158. * dashDash (--) token is enabled,
  159. * ignoreCase is not enabled.
  160. */
  161. protected $_getoptConfig = array(
  162. self::CONFIG_RULEMODE => self::MODE_ZEND,
  163. self::CONFIG_DASHDASH => true,
  164. self::CONFIG_IGNORECASE => false
  165. );
  166. /**
  167. * Stores the command-line arguments for the calling applicaion.
  168. */
  169. protected $_argv = array();
  170. /**
  171. * Stores the name of the calling applicaion.
  172. */
  173. protected $_progname = '';
  174. /**
  175. * Stores the list of legal options for this application.
  176. */
  177. protected $_rules = array();
  178. /**
  179. * Stores alternate spellings of legal options.
  180. */
  181. protected $_ruleMap = array();
  182. /**
  183. * Stores options given by the user in the current invocation
  184. * of the application, as well as parameters given in options.
  185. */
  186. protected $_options = array();
  187. /**
  188. * Stores the command-line arguments other than options.
  189. */
  190. protected $_remainingArgs = array();
  191. /**
  192. * State of the options: parsed or not yet parsed?
  193. */
  194. protected $_parsed = false;
  195. /**
  196. * The constructor takes one to three parameters.
  197. *
  198. * The first parameter is $rules, which may be a string for
  199. * gnu-style format, or a structured array for Zend-style format.
  200. *
  201. * The second parameter is $argv, and it is optional. If not
  202. * specified, $argv is inferred from the global argv.
  203. *
  204. * The third parameter is an array of configuration parameters
  205. * to control the behavior of this instance of Getopt; it is optional.
  206. *
  207. * @param array $rules
  208. * @param array $argv
  209. * @param array $getoptConfig
  210. * @return Zend_Console_Getopt
  211. */
  212. public function __construct($rules, $argv = null, $getoptConfig = array())
  213. {
  214. $this->_progname = $_SERVER['argv'][0];
  215. $this->setOptions($getoptConfig);
  216. $this->addRules($rules);
  217. if (!is_array($argv)) {
  218. $argv = array_slice($_SERVER['argv'], 1);
  219. }
  220. if (isset($argv)) {
  221. $this->addArguments((array)$argv);
  222. }
  223. }
  224. /**
  225. * Return the state of the option seen on the command line of the
  226. * current application invocation. This function returns true, or the
  227. * parameter to the option, if any. If the option was not given,
  228. * this function returns null.
  229. *
  230. * The magic __get method works in the context of naming the option
  231. * as a virtual member of this class.
  232. *
  233. * @param string $key
  234. * @return string
  235. */
  236. protected function __get($key)
  237. {
  238. return $this->getOption($key);
  239. }
  240. /**
  241. * Test whether a given option has been seen.
  242. *
  243. * @param string $key
  244. * @return bool
  245. */
  246. protected function __isset($key)
  247. {
  248. $this->parse();
  249. if (isset($this->_ruleMap[$key])) {
  250. $key = $this->_ruleMap[$key];
  251. return isset($this->_options[$key]);
  252. }
  253. return false;
  254. }
  255. /**
  256. * Set the value for a given option.
  257. *
  258. * @param string $key
  259. * @param string $value
  260. * @return void
  261. */
  262. protected function __set($key, $value)
  263. {
  264. $this->parse();
  265. if (isset($this->_ruleMap[$key])) {
  266. $key = $this->_ruleMap[$key];
  267. $this->_options[$key] = $value;
  268. }
  269. }
  270. /**
  271. * Return the current set of options and parameters seen as a string.
  272. *
  273. * @return string
  274. */
  275. public function __toString()
  276. {
  277. return $this->toString();
  278. }
  279. /**
  280. * Unset an option.
  281. *
  282. * @param string $key
  283. * @return void
  284. */
  285. public function __unset($key)
  286. {
  287. $this->parse();
  288. if (isset($this->_ruleMap[$key])) {
  289. $key = $this->_ruleMap[$key];
  290. unset($this->_options[$key]);
  291. }
  292. }
  293. /**
  294. * Define additional command-line arguments.
  295. * These are appended to those defined when the constructor was called.
  296. *
  297. * @param array $argv
  298. * @return Zend_Console_Getopt
  299. */
  300. public function addArguments($argv)
  301. {
  302. $this->_argv = array_merge($this->_argv, $argv);
  303. $this->_parsed = false;
  304. return $this;
  305. }
  306. /**
  307. * Define full set of command-line arguments.
  308. * These replace any currently defined.
  309. *
  310. * @param array $argv
  311. * @return Zend_Console_Getopt
  312. */
  313. public function setArguments($argv)
  314. {
  315. $this->_argv = $argv;
  316. $this->_parsed = false;
  317. return $this;
  318. }
  319. /**
  320. * Define multiple configuration options from an associative array.
  321. * These are not program options, but properties to configure
  322. * the behavior of Zend_Console_Getopt.
  323. *
  324. * @param array $getoptConfig
  325. * @return Zend_Console_Getopt
  326. */
  327. public function setOptions($getoptConfig)
  328. {
  329. if (isset($getoptConfig)) {
  330. foreach ($getoptConfig as $key => $value) {
  331. $this->setOption($key, $value);
  332. }
  333. }
  334. return $this;
  335. }
  336. /**
  337. * Define one configuration option as a key/value pair.
  338. * These are not program options, but properties to configure
  339. * the behavior of Zend_Console_Getopt.
  340. *
  341. * @param string $configKey
  342. * @param string $configValue
  343. * @return Zend_Console_Getopt
  344. */
  345. public function setOption($configKey, $configValue)
  346. {
  347. if ($configKey !== null) {
  348. $this->_getoptConfig[$configKey] = $configValue;
  349. }
  350. return $this;
  351. }
  352. /**
  353. * Define additional option rules.
  354. * These are appended to the rules defined when the constructor was called.
  355. *
  356. * @param array $rules
  357. * @return Zend_Console_Getopt
  358. */
  359. public function addRules($rules)
  360. {
  361. $ruleMode = $this->_getoptConfig['ruleMode'];
  362. switch ($this->_getoptConfig['ruleMode']) {
  363. case self::MODE_ZEND:
  364. if (is_array($rules)) {
  365. $this->_addRulesModeZend($rules);
  366. break;
  367. }
  368. $this->_getoptConfig['ruleMode'] = self::MODE_GNU;
  369. // intentional fallthrough
  370. case self::MODE_GNU:
  371. $this->_addRulesModeGnu($rules);
  372. break;
  373. default:
  374. /**
  375. * Call addRulesModeFoo() for ruleMode 'foo'.
  376. * The developer should subclass Getopt and
  377. * provide this method.
  378. */
  379. $method = '_addRulesMode' . ucfirst($ruleMode);
  380. $this->$method($rules);
  381. }
  382. $this->_parsed = false;
  383. return $this;
  384. }
  385. /**
  386. * Return the current set of options and parameters seen as a string.
  387. *
  388. * @return string
  389. */
  390. public function toString()
  391. {
  392. $this->parse();
  393. $s = array();
  394. foreach ($this->_options as $flag => $value) {
  395. $s[] = $flag . '=' . ($value === true ? 'true' : $value);
  396. }
  397. return implode(' ', $s);
  398. }
  399. /**
  400. * Return the current set of options and parameters seen
  401. * as an array of canonical options and parameters.
  402. *
  403. * Clusters have been expanded, and option aliases
  404. * have been mapped to their primary option names.
  405. *
  406. * @return array
  407. */
  408. public function toArray()
  409. {
  410. $this->parse();
  411. $s = array();
  412. foreach ($this->_options as $flag => $value) {
  413. $s[] = $flag;
  414. if ($value !== true) {
  415. $s[] = $value;
  416. }
  417. }
  418. return $s;
  419. }
  420. /**
  421. * Return the current set of options and parameters seen in Json format.
  422. *
  423. * @return string
  424. */
  425. public function toJson()
  426. {
  427. $this->parse();
  428. $j = array();
  429. foreach ($this->_options as $flag => $value) {
  430. $j['options'][] = array(
  431. 'option' => array(
  432. 'flag' => $flag,
  433. 'parameter' => $value
  434. )
  435. );
  436. }
  437. require_once 'Zend/Json.php';
  438. $json = Zend_Json::encode($j);
  439. return $json;
  440. }
  441. /**
  442. * Return the current set of options and parameters seen in XML format.
  443. *
  444. * @return string
  445. */
  446. public function toXml()
  447. {
  448. $this->parse();
  449. $doc = new DomDocument('1.0', 'utf-8');
  450. $optionsNode = $doc->createElement('options');
  451. $doc->appendChild($optionsNode);
  452. foreach ($this->_options as $flag => $value) {
  453. $optionNode = $doc->createElement('option');
  454. $optionNode->setAttribute('flag', utf8_encode($flag));
  455. if ($value !== true) {
  456. $optionNode->setAttribute('parameter', utf8_encode($value));
  457. }
  458. $optionsNode->appendChild($optionNode);
  459. }
  460. $xml = $doc->saveXML();
  461. return $xml;
  462. }
  463. /**
  464. * Return a list of options that have been seen in the current argv.
  465. *
  466. * @return array
  467. */
  468. public function getOptions()
  469. {
  470. $this->parse();
  471. return array_keys($this->_options);
  472. }
  473. /**
  474. * Return the state of the option seen on the command line of the
  475. * current application invocation.
  476. *
  477. * This function returns true, or the parameter value to the option, if any.
  478. * If the option was not given, this function returns false.
  479. *
  480. * @param string $key
  481. * @return mixed
  482. */
  483. public function getOption($flag)
  484. {
  485. $this->parse();
  486. if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) {
  487. $flag = strtolower($flag);
  488. }
  489. if (isset($this->_ruleMap[$flag])) {
  490. $flag = $this->_ruleMap[$flag];
  491. if (isset($this->_options[$flag])) {
  492. return $this->_options[$flag];
  493. }
  494. }
  495. return null;
  496. }
  497. /**
  498. * Return the arguments from the command-line following all options found.
  499. *
  500. * @return array
  501. */
  502. public function getRemainingArgs()
  503. {
  504. $this->parse();
  505. return $this->_remainingArgs;
  506. }
  507. /**
  508. * Return a useful option reference, formatted for display in an
  509. * error message.
  510. *
  511. * Note that this usage information is provided in most Exceptions
  512. * generated by this class.
  513. *
  514. * @return string
  515. */
  516. public function getUsageMessage()
  517. {
  518. $usage = "Usage: {$this->_progname} [ options ]\n";
  519. $maxLen = 20;
  520. foreach ($this->_rules as $rule) {
  521. $flags = array();
  522. if (is_array($rule['alias'])) {
  523. foreach ($rule['alias'] as $flag) {
  524. $flags[] = (strlen($flag) == 1 ? '-' : '--') . $flag;
  525. }
  526. }
  527. $linepart['name'] = implode('|', $flags);
  528. if (isset($rule['param']) && $rule['param'] != 'none') {
  529. $linepart['name'] .= ' ';
  530. switch ($rule['param']) {
  531. case 'optional':
  532. $linepart['name'] .= "[ <{$rule['paramType']}> ]";
  533. break;
  534. case 'required':
  535. $linepart['name'] .= "<{$rule['paramType']}>";
  536. break;
  537. }
  538. }
  539. if (strlen($linepart['name']) > $maxLen) {
  540. $maxLen = strlen($linepart['name']);
  541. }
  542. $linepart['help'] = '';
  543. if (isset($rule['help'])) {
  544. $linepart['help'] .= $rule['help'];
  545. }
  546. $lines[] = $linepart;
  547. }
  548. foreach ($lines as $linepart) {
  549. $usage .= sprintf("%s %s\n",
  550. str_pad($linepart['name'], $maxLen),
  551. $linepart['help']);
  552. }
  553. return $usage;
  554. }
  555. /**
  556. * Define aliases for options.
  557. *
  558. * The parameter $aliasMap is an associative array
  559. * mapping option name (short or long) to an alias.
  560. *
  561. * @param array $aliasMap
  562. * @return Zend_Console_Getopt
  563. * @throws Zend_Console_Getopt_Exception
  564. */
  565. public function setAliases($aliasMap)
  566. {
  567. foreach ($aliasMap as $flag => $alias)
  568. {
  569. if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) {
  570. $flag = strtolower($flag);
  571. $alias = strtolower($alias);
  572. }
  573. if (!isset($this->_ruleMap[$flag])) {
  574. continue;
  575. }
  576. $flag = $this->_ruleMap[$flag];
  577. if (isset($this->_rules[$alias]) || isset($this->_ruleMap[$alias])) {
  578. $o = (strlen($alias) == 1 ? '-' : '--') . $alias;
  579. throw new Zend_Console_Getopt_Exception(
  580. "Option \"$o\" is being defined more than once.");
  581. }
  582. $this->_rules[$flag]['alias'][] = $alias;
  583. $this->_ruleMap[$alias] = $flag;
  584. }
  585. return $this;
  586. }
  587. /**
  588. * Define help messages for options.
  589. *
  590. * The parameter $help_map is an associative array
  591. * mapping option name (short or long) to the help string.
  592. *
  593. * @param array $helpMap
  594. * @return Zend_Console_Getopt
  595. */
  596. public function setHelp($helpMap)
  597. {
  598. foreach ($helpMap as $flag => $help)
  599. {
  600. if (!isset($this->_ruleMap[$flag])) {
  601. continue;
  602. }
  603. $flag = $this->_ruleMap[$flag];
  604. $this->_rules[$flag]['help'] = $help;
  605. }
  606. return $this;
  607. }
  608. /**
  609. * Parse command-line arguments and find both long and short
  610. * options.
  611. *
  612. * Also find option parameters, and remaining arguments after
  613. * all options have been parsed.
  614. *
  615. * @return Zend_Console_Getopt
  616. */
  617. public function parse()
  618. {
  619. if ($this->_parsed === true) {
  620. return;
  621. }
  622. $argv = $this->_argv;
  623. $this->_options = array();
  624. $this->_remainingArgs = array();
  625. while (count($argv) > 0) {
  626. if ($argv[0] == '--') {
  627. array_shift($argv);
  628. if ($this->_getoptConfig[self::CONFIG_DASHDASH]) {
  629. $this->_remainingArgs = array_merge($this->_remainingArgs, $argv);
  630. break;
  631. }
  632. }
  633. if (substr($argv[0], 0, 2) == '--') {
  634. $this->_parseLongOption($argv);
  635. } else if (substr($argv[0], 0, 1) == '-') {
  636. $this->_parseShortOptionCluster($argv);
  637. } else {
  638. $this->_remainingArgs[] = array_shift($argv);
  639. }
  640. }
  641. $this->_parsed = true;
  642. return $this;
  643. }
  644. /**
  645. * Parse command-line arguments for a single long option.
  646. * A long option is preceded by a double '--' character.
  647. * Long options may not be clustered.
  648. *
  649. * @param mixed &$argv
  650. * @return void
  651. */
  652. protected function _parseLongOption(&$argv)
  653. {
  654. $optionWithParam = ltrim(array_shift($argv), '-');
  655. $l = explode('=', $optionWithParam);
  656. $flag = array_shift($l);
  657. $param = array_shift($l);
  658. if (isset($param)) {
  659. array_unshift($argv, $param);
  660. }
  661. $this->_parseSingleOption($flag, $argv);
  662. }
  663. /**
  664. * Parse command-line arguments for short options.
  665. * Short options are those preceded by a single '-' character.
  666. * Short options may be clustered.
  667. *
  668. * @param mixed &$argv
  669. * @return void
  670. */
  671. protected function _parseShortOptionCluster(&$argv)
  672. {
  673. $flagCluster = ltrim(array_shift($argv), '-');
  674. foreach (str_split($flagCluster) as $flag) {
  675. $this->_parseSingleOption($flag, $argv);
  676. }
  677. }
  678. /**
  679. * Parse command-line arguments for a single option.
  680. *
  681. * @param string $flag
  682. * @param mixed $argv
  683. * @return void
  684. */
  685. protected function _parseSingleOption($flag, &$argv)
  686. {
  687. if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) {
  688. $flag = strtolower($flag);
  689. }
  690. if (!isset($this->_ruleMap[$flag])) {
  691. throw new Zend_Console_Getopt_Exception(
  692. "Option \"$flag\" is not recognized.",
  693. $this->getUsageMessage());
  694. }
  695. $realFlag = $this->_ruleMap[$flag];
  696. switch ($this->_rules[$realFlag]['param']) {
  697. case 'required':
  698. if (count($argv) > 0) {
  699. $param = array_shift($argv);
  700. $this->_checkParameterType($realFlag, $param);
  701. } else {
  702. throw new Zend_Console_Getopt_Exception(
  703. "Option \"$flag\" requires a parameter.",
  704. $this->getUsageMessage());
  705. }
  706. break;
  707. case 'optional':
  708. if (count($argv) > 0 && substr($argv[0], 0, 1) != '-') {
  709. $param = array_shift($argv);
  710. $this->_checkParameterType($realFlag, $param);
  711. } else {
  712. $param = true;
  713. }
  714. break;
  715. default:
  716. $param = true;
  717. }
  718. $this->_options[$realFlag] = $param;
  719. }
  720. /**
  721. * Return true if the parameter is in a valid format for
  722. * the option $flag.
  723. * Throw an exception in most other cases.
  724. *
  725. * @param string $flag
  726. * @param string $param
  727. * @return bool
  728. * @throws Zend_Console_Getopt_Exception
  729. */
  730. protected function _checkParameterType($flag, $param)
  731. {
  732. $type = 'string';
  733. if (isset($this->_rules[$flag]['paramType'])) {
  734. $type = $this->_rules[$flag]['paramType'];
  735. }
  736. switch ($type) {
  737. case 'word':
  738. if (preg_match('/\W/', $param)) {
  739. throw new Zend_Console_Getopt_Exception(
  740. "Option \"$flag\" requires a single-word parameter, but was given \"$param\".",
  741. $this->getUsageMessage());
  742. }
  743. break;
  744. case 'integer':
  745. if (preg_match('/\D/', $param)) {
  746. throw new Zend_Console_Getopt_Exception(
  747. "Option \"$flag\" requires an integer parameter, but was given \"$param\".",
  748. $this->getUsageMessage());
  749. }
  750. break;
  751. case 'string':
  752. default:
  753. break;
  754. }
  755. return true;
  756. }
  757. /**
  758. * Define legal options using the gnu-style format.
  759. *
  760. * @param string $rules
  761. * @return void
  762. */
  763. protected function _addRulesModeGnu($rules)
  764. {
  765. $ruleArray = array();
  766. /**
  767. * Options may be single alphanumeric characters.
  768. * Options may have a ':' which indicates a required string parameter.
  769. * No long options or option aliases are supported in GNU style.
  770. */
  771. preg_match_all('/([a-zA-Z0-9]:?)/', $rules, $ruleArray);
  772. foreach ($ruleArray[1] as $rule) {
  773. $r = array();
  774. $flag = substr($rule, 0, 1);
  775. if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) {
  776. $flag = strtolower($flag);
  777. }
  778. $r['alias'][] = $flag;
  779. if (substr($rule, 1, 1) == ':') {
  780. $r['param'] = 'required';
  781. $r['paramType'] = 'string';
  782. } else {
  783. $r['param'] = 'none';
  784. }
  785. $this->_rules[$flag] = $r;
  786. $this->_ruleMap[$flag] = $flag;
  787. }
  788. }
  789. /**
  790. * Define legal options using the Zend-style format.
  791. *
  792. * @param array $rules
  793. * @return void
  794. * @throws Zend_Console_Getopt_Exception
  795. */
  796. protected function _addRulesModeZend($rules)
  797. {
  798. foreach ($rules as $ruleCode => $helpMessage)
  799. {
  800. $tokens = preg_split('/([=-])/',
  801. $ruleCode, 2, PREG_SPLIT_DELIM_CAPTURE);
  802. $flagList = array_shift($tokens);
  803. $delimiter = array_shift($tokens);
  804. $paramType = array_shift($tokens);
  805. if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) {
  806. $flagList = strtolower($flagList);
  807. }
  808. $flags = explode('|', $flagList);
  809. $rule = array();
  810. $mainFlag = $flags[0];
  811. foreach ($flags as $flag) {
  812. if (empty($flag)) {
  813. throw new Zend_Console_Getopt_Exception(
  814. "Blank flag not allowed in rule \"$ruleCode\".");
  815. }
  816. if (strlen($flag) == 1) {
  817. if (isset($this->_ruleMap[$flag])) {
  818. throw new Zend_Console_Getopt_Exception(
  819. "Option \"-$flag\" is being defined more than once.");
  820. }
  821. $this->_ruleMap[$flag] = $mainFlag;
  822. $rule['alias'][] = $flag;
  823. } else {
  824. if (isset($this->_rules[$flag]) || isset($this->_ruleMap[$flag])) {
  825. throw new Zend_Console_Getopt_Exception(
  826. "Option \"--$flag\" is being defined more than once.");
  827. }
  828. $this->_ruleMap[$flag] = $mainFlag;
  829. $rule['alias'][] = $flag;
  830. }
  831. }
  832. if (isset($delimiter)) {
  833. switch ($delimiter) {
  834. case self::PARAM_REQUIRED:
  835. $rule['param'] = 'required';
  836. break;
  837. case self::PARAM_OPTIONAL:
  838. default:
  839. $rule['param'] = 'optional';
  840. }
  841. switch (substr($paramType, 0, 1)) {
  842. case self::TYPE_WORD:
  843. $rule['paramType'] = 'word';
  844. break;
  845. case self::TYPE_INTEGER:
  846. $rule['paramType'] = 'integer';
  847. break;
  848. case self::TYPE_STRING:
  849. default:
  850. $rule['paramType'] = 'string';
  851. }
  852. } else {
  853. $rule['param'] = 'none';
  854. }
  855. $rule['help'] = $helpMessage;
  856. $this->_rules[$mainFlag] = $rule;
  857. }
  858. }
  859. }