Skip to content

Commit 2ebf40b

Browse files
committed
Add ArgvParser, StringIterator
Shamelessly stolen from http://stackoverflow.com/a/18229461
1 parent bcea1da commit 2ebf40b

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

src/App/Utility/ArgvParser.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
namespace App\Utility;
4+
5+
// stolen from http://stackoverflow.com/a/18229461
6+
class ArgvParser extends StringIterator
7+
{
8+
const TOKEN_DOUBLE_QUOTE = '"';
9+
const TOKEN_SINGLE_QUOTE = "'";
10+
const TOKEN_SPACE = ' ';
11+
const TOKEN_ESCAPE = '\\';
12+
13+
public function parse()
14+
{
15+
$this->rewind();
16+
17+
$args = [];
18+
19+
while ($this->valid()) {
20+
switch ($this->current()) {
21+
case self::TOKEN_DOUBLE_QUOTE:
22+
case self::TOKEN_SINGLE_QUOTE:
23+
$args[] = $this->QUOTED($this->current());
24+
break;
25+
26+
case self::TOKEN_SPACE:
27+
$this->next();
28+
break;
29+
30+
default:
31+
$args[] = $this->UNQUOTED();
32+
}
33+
}
34+
35+
return $args;
36+
}
37+
38+
private function QUOTED($enclosure)
39+
{
40+
$this->next();
41+
$result = '';
42+
43+
while ($this->valid()) {
44+
if ($this->current() == self::TOKEN_ESCAPE) {
45+
$this->next();
46+
if ($this->valid() && $this->current() == $enclosure) {
47+
$result .= $enclosure;
48+
} elseif ($this->valid()) {
49+
$result .= self::TOKEN_ESCAPE;
50+
if ($this->current() != self::TOKEN_ESCAPE) {
51+
$result .= $this->current();
52+
}
53+
}
54+
} elseif ($this->current() == $enclosure) {
55+
$this->next();
56+
break;
57+
} else {
58+
$result .= $this->current();
59+
}
60+
$this->next();
61+
}
62+
63+
return $result;
64+
}
65+
66+
private function UNQUOTED()
67+
{
68+
$result = '';
69+
70+
while ($this->valid()) {
71+
if ($this->current() == self::TOKEN_SPACE) {
72+
$this->next();
73+
break;
74+
} else {
75+
$result .= $this->current();
76+
}
77+
$this->next();
78+
}
79+
80+
return $result;
81+
}
82+
83+
public static function parseString($input)
84+
{
85+
$parser = new self($input);
86+
87+
return $parser->parse();
88+
}
89+
}

src/App/Utility/StringIterator.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace App\Utility;
4+
5+
class StringIterator implements \Iterator
6+
{
7+
private $string;
8+
9+
private $current;
10+
11+
public function __construct($string)
12+
{
13+
$this->string = $string;
14+
}
15+
16+
public function current()
17+
{
18+
return $this->string[$this->current];
19+
}
20+
21+
public function next()
22+
{
23+
++$this->current;
24+
}
25+
26+
public function key()
27+
{
28+
return $this->current;
29+
}
30+
31+
public function valid()
32+
{
33+
return $this->current < strlen($this->string);
34+
}
35+
36+
public function rewind()
37+
{
38+
$this->current = 0;
39+
}
40+
}

0 commit comments

Comments
 (0)