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