Merge branch 'MDL-32509' of git://github.com/danpoltawski/moodle
[moodle.git] / lib / simpletestlib / arguments.php
blob89e7f9de6ef276651c834c97a9e6d3fb39998cf7
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 */
9 /**
10 * Parses the command line arguments.
11 * @package SimpleTest
12 * @subpackage UnitTester
14 class SimpleArguments {
15 private $all = array();
17 /**
18 * Parses the command line arguments. The usual formats
19 * are supported:
20 * -f value
21 * -f=value
22 * --flag=value
23 * --flag value
24 * -f (true)
25 * --flag (true)
26 * @param array $arguments Normally the PHP $argv.
28 function __construct($arguments) {
29 array_shift($arguments);
30 while (count($arguments) > 0) {
31 list($key, $value) = $this->parseArgument($arguments);
32 $this->assign($key, $value);
36 /**
37 * Sets the value in the argments object. If multiple
38 * values are added under the same key, the key will
39 * give an array value in the order they were added.
40 * @param string $key The variable to assign to.
41 * @param string value The value that would norally
42 * be colected on the command line.
44 function assign($key, $value) {
45 if ($this->$key === false) {
46 $this->all[$key] = $value;
47 } elseif (! is_array($this->$key)) {
48 $this->all[$key] = array($this->$key, $value);
49 } else {
50 $this->all[$key][] = $value;
54 /**
55 * Extracts the next key and value from the argument list.
56 * @param array $arguments The remaining arguments to be parsed.
57 * The argument list will be reduced.
58 * @return array Two item array of key and value.
59 * If no value can be found it will
60 * have the value true assigned instead.
62 private function parseArgument(&$arguments) {
63 $argument = array_shift($arguments);
64 if (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 } elseif (preg_match('/^--(\w+)=(.+)$/', $argument, $matches)) {
69 return array($matches[1], $matches[2]);
70 } elseif (preg_match('/^--(\w+)$/', $argument, $matches)) {
71 return array($matches[1], $this->nextNonFlagElseTrue($arguments));
75 /**
76 * Attempts to use the next argument as a value. It
77 * won't use what it thinks is a flag.
78 * @param array $arguments Remaining arguments to be parsed.
79 * This variable is modified if there
80 * is a value to be extracted.
81 * @return string/boolean The next value unless it's a flag.
83 private function nextNonFlagElseTrue(&$arguments) {
84 return $this->valueIsNext($arguments) ? array_shift($arguments) : true;
87 /**
88 * Test to see if the next available argument is a valid value.
89 * If it starts with "-" or "--" it's a flag and doesn't count.
90 * @param array $arguments Remaining arguments to be parsed.
91 * Not affected by this call.
92 * boolean True if valid value.
94 function valueIsNext($arguments) {
95 return isset($arguments[0]) && ! $this->isFlag($arguments[0]);
98 /**
99 * It's a flag if it starts with "-" or "--".
100 * @param string $argument Value to be tested.
101 * @return boolean True if it's a flag.
103 function isFlag($argument) {
104 return strncmp($argument, '-', 1) == 0;
108 * The arguments are available as individual member
109 * variables on the object.
110 * @param string $key Argument name.
111 * @return string/array/boolean Either false for no value,
112 * the value as a string or
113 * a list of multiple values if
114 * the flag had been specified more
115 * than once.
117 function __get($key) {
118 if (isset($this->all[$key])) {
119 return $this->all[$key];
121 return false;
125 * The entire argument set as a hash.
126 * @return hash Each argument and it's value(s).
128 function all() {
129 return $this->all;
134 * Renders the help for the command line arguments.
135 * @package SimpleTest
136 * @subpackage UnitTester
138 class SimpleHelp {
139 private $overview;
140 private $flag_sets = array();
141 private $explanations = array();
144 * Sets up the top level explanation for the program.
145 * @param string $overview Summary of program.
147 function __construct($overview = '') {
148 $this->overview = $overview;
152 * Adds the explanation for a group of flags that all
153 * have the same function.
154 * @param string/array $flags Flag and alternates. Don't
155 * worry about leading dashes
156 * as these are inserted automatically.
157 * @param string $explanation What that flag group does.
159 function explainFlag($flags, $explanation) {
160 $flags = is_array($flags) ? $flags : array($flags);
161 $this->flag_sets[] = $flags;
162 $this->explanations[] = $explanation;
166 * Generates the help text.
167 * @returns string The complete formatted text.
169 function render() {
170 $tab_stop = $this->longestFlag($this->flag_sets) + 4;
171 $text = $this->overview . "\n";
172 for ($i = 0; $i < count($this->flag_sets); $i++) {
173 $text .= $this->renderFlagSet($this->flag_sets[$i], $this->explanations[$i], $tab_stop);
175 return $this->noDuplicateNewLines($text);
179 * Works out the longest flag for formatting purposes.
180 * @param array $flag_sets The internal flag set list.
182 private function longestFlag($flag_sets) {
183 $longest = 0;
184 foreach ($flag_sets as $flags) {
185 foreach ($flags as $flag) {
186 $longest = max($longest, strlen($this->renderFlag($flag)));
189 return $longest;
193 * Generates the text for a single flag and it's alternate flags.
194 * @returns string Help text for that flag group.
196 private function renderFlagSet($flags, $explanation, $tab_stop) {
197 $flag = array_shift($flags);
198 $text = str_pad($this->renderFlag($flag), $tab_stop, ' ') . $explanation . "\n";
199 foreach ($flags as $flag) {
200 $text .= ' ' . $this->renderFlag($flag) . "\n";
202 return $text;
206 * Generates the flag name including leading dashes.
207 * @param string $flag Just the name.
208 * @returns Fag with apropriate dashes.
210 private function renderFlag($flag) {
211 return (strlen($flag) == 1 ? '-' : '--') . $flag;
215 * Converts multiple new lines into a single new line.
216 * Just there to trap accidental duplicate new lines.
217 * @param string $text Text to clean up.
218 * @returns string Text with no blank lines.
220 private function noDuplicateNewLines($text) {
221 return preg_replace('/(\n+)/', "\n", $text);