arguments.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. /**
  3. * base include file for SimpleTest
  4. * @package SimpleTest
  5. * @subpackage UnitTester
  6. * @version $Id: dumper.php 1909 2009-07-29 15:58:11Z dgheath $
  7. */
  8. /**
  9. * Parses the command line arguments.
  10. * @package SimpleTest
  11. * @subpackage UnitTester
  12. */
  13. class SimpleArguments {
  14. private $all = array();
  15. /**
  16. * Parses the command line arguments. The usual formats
  17. * are supported:
  18. * -f value
  19. * -f=value
  20. * --flag=value
  21. * --flag value
  22. * -f (true)
  23. * --flag (true)
  24. * @param array $arguments Normally the PHP $argv.
  25. */
  26. function __construct($arguments) {
  27. array_shift($arguments);
  28. while (count($arguments) > 0) {
  29. list($key, $value) = $this->parseArgument($arguments);
  30. $this->assign($key, $value);
  31. }
  32. }
  33. /**
  34. * Sets the value in the argments object. If multiple
  35. * values are added under the same key, the key will
  36. * give an array value in the order they were added.
  37. * @param string $key The variable to assign to.
  38. * @param string value The value that would norally
  39. * be colected on the command line.
  40. */
  41. function assign($key, $value) {
  42. if ($this->$key === false) {
  43. $this->all[$key] = $value;
  44. } elseif (! is_array($this->$key)) {
  45. $this->all[$key] = array($this->$key, $value);
  46. } else {
  47. $this->all[$key][] = $value;
  48. }
  49. }
  50. /**
  51. * Extracts the next key and value from the argument list.
  52. * @param array $arguments The remaining arguments to be parsed.
  53. * The argument list will be reduced.
  54. * @return array Two item array of key and value.
  55. * If no value can be found it will
  56. * have the value true assigned instead.
  57. */
  58. private function parseArgument(&$arguments) {
  59. $argument = array_shift($arguments);
  60. if (preg_match('/^-(\w)=(.+)$/', $argument, $matches)) {
  61. return array($matches[1], $matches[2]);
  62. } elseif (preg_match('/^-(\w)$/', $argument, $matches)) {
  63. return array($matches[1], $this->nextNonFlagElseTrue($arguments));
  64. } elseif (preg_match('/^--(\w+)=(.+)$/', $argument, $matches)) {
  65. return array($matches[1], $matches[2]);
  66. } elseif (preg_match('/^--(\w+)$/', $argument, $matches)) {
  67. return array($matches[1], $this->nextNonFlagElseTrue($arguments));
  68. }
  69. }
  70. /**
  71. * Attempts to use the next argument as a value. It
  72. * won't use what it thinks is a flag.
  73. * @param array $arguments Remaining arguments to be parsed.
  74. * This variable is modified if there
  75. * is a value to be extracted.
  76. * @return string/boolean The next value unless it's a flag.
  77. */
  78. private function nextNonFlagElseTrue(&$arguments) {
  79. return $this->valueIsNext($arguments) ? array_shift($arguments) : true;
  80. }
  81. /**
  82. * Test to see if the next available argument is a valid value.
  83. * If it starts with "-" or "--" it's a flag and doesn't count.
  84. * @param array $arguments Remaining arguments to be parsed.
  85. * Not affected by this call.
  86. * boolean True if valid value.
  87. */
  88. function valueIsNext($arguments) {
  89. return isset($arguments[0]) && ! $this->isFlag($arguments[0]);
  90. }
  91. /**
  92. * It's a flag if it starts with "-" or "--".
  93. * @param string $argument Value to be tested.
  94. * @return boolean True if it's a flag.
  95. */
  96. function isFlag($argument) {
  97. return strncmp($argument, '-', 1) == 0;
  98. }
  99. /**
  100. * The arguments are available as individual member
  101. * variables on the object.
  102. * @param string $key Argument name.
  103. * @return string/array/boolean Either false for no value,
  104. * the value as a string or
  105. * a list of multiple values if
  106. * the flag had been specified more
  107. * than once.
  108. */
  109. function __get($key) {
  110. if (isset($this->all[$key])) {
  111. return $this->all[$key];
  112. }
  113. return false;
  114. }
  115. /**
  116. * The entire argument set as a hash.
  117. * @return hash Each argument and it's value(s).
  118. */
  119. function all() {
  120. return $this->all;
  121. }
  122. }
  123. /**
  124. * Renders the help for the command line arguments.
  125. * @package SimpleTest
  126. * @subpackage UnitTester
  127. */
  128. class SimpleHelp {
  129. private $overview;
  130. private $flag_sets = array();
  131. private $explanations = array();
  132. /**
  133. * Sets up the top level explanation for the program.
  134. * @param string $overview Summary of program.
  135. */
  136. function __construct($overview = '') {
  137. $this->overview = $overview;
  138. }
  139. /**
  140. * Adds the explanation for a group of flags that all
  141. * have the same function.
  142. * @param string/array $flags Flag and alternates. Don't
  143. * worry about leading dashes
  144. * as these are inserted automatically.
  145. * @param string $explanation What that flag group does.
  146. */
  147. function explainFlag($flags, $explanation) {
  148. $flags = is_array($flags) ? $flags : array($flags);
  149. $this->flag_sets[] = $flags;
  150. $this->explanations[] = $explanation;
  151. }
  152. /**
  153. * Generates the help text.
  154. * @returns string The complete formatted text.
  155. */
  156. function render() {
  157. $tab_stop = $this->longestFlag($this->flag_sets) + 4;
  158. $text = $this->overview . "\n";
  159. for ($i = 0; $i < count($this->flag_sets); $i++) {
  160. $text .= $this->renderFlagSet($this->flag_sets[$i], $this->explanations[$i], $tab_stop);
  161. }
  162. return $this->noDuplicateNewLines($text);
  163. }
  164. /**
  165. * Works out the longest flag for formatting purposes.
  166. * @param array $flag_sets The internal flag set list.
  167. */
  168. private function longestFlag($flag_sets) {
  169. $longest = 0;
  170. foreach ($flag_sets as $flags) {
  171. foreach ($flags as $flag) {
  172. $longest = max($longest, strlen($this->renderFlag($flag)));
  173. }
  174. }
  175. return $longest;
  176. }
  177. /**
  178. * Generates the text for a single flag and it's alternate flags.
  179. * @returns string Help text for that flag group.
  180. */
  181. private function renderFlagSet($flags, $explanation, $tab_stop) {
  182. $flag = array_shift($flags);
  183. $text = str_pad($this->renderFlag($flag), $tab_stop, ' ') . $explanation . "\n";
  184. foreach ($flags as $flag) {
  185. $text .= ' ' . $this->renderFlag($flag) . "\n";
  186. }
  187. return $text;
  188. }
  189. /**
  190. * Generates the flag name including leading dashes.
  191. * @param string $flag Just the name.
  192. * @returns Fag with apropriate dashes.
  193. */
  194. private function renderFlag($flag) {
  195. return (strlen($flag) == 1 ? '-' : '--') . $flag;
  196. }
  197. /**
  198. * Converts multiple new lines into a single new line.
  199. * Just there to trap accidental duplicate new lines.
  200. * @param string $text Text to clean up.
  201. * @returns string Text with no blank lines.
  202. */
  203. private function noDuplicateNewLines($text) {
  204. return preg_replace('/(\n+)/', "\n", $text);
  205. }
  206. }
  207. ?>