Completed
Pull Request — master (#1105)
by Tim
42:55
created

Arguments::split()   D

Complexity

Conditions 25
Paths 25

Size

Total Lines 107
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 25
eloc 59
nc 25
nop 1
dl 0
loc 107
rs 4.1666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * AppserverIo\Appserver\Core\Commands\Helper\ConfigurationHelper
5
 *
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2016 Christian Lück
9
 *
10
 * Permission is hereby granted, free of charge, to any person obtaining a copy
11
 * of this software and associated documentation files (the "Software"), to deal
12
 * in the Software without restriction, including without limitation the rights
13
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
 * copies of the Software, and to permit persons to whom the Software is furnished
15
 * to do so, subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be included in all
18
 * copies or substantial portions of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
 * THE SOFTWARE.
27
 */
28
29
namespace AppserverIo\Appserver\Core\Commands\Helper;
30
31
/**
32
 * The doctrine migrations command implementation.
33
 */
34
class Arguments
35
{
36
37
    /**
38
     * Splits the given command line string into an array of command arguments.
39
     *
40
     * @param string $command The command line string
41
     *
42
     * @return array Array of command line argument strings
43
     * @throws \RuntimeException Is thrown, if the arguments has not been quoted as expected
44
     */
45
    public static function split($command)
46
    {
47
48
        // whitespace characters count as argument separators
49
        static $ws = array(
50
            ' ',
51
            "\r",
52
            "\n",
53
            "\t",
54
            "\v",
55
        );
56
57
        $i = 0;
58
        $args = array();
59
60
        while (true) {
61
            // skip all whitespace characters
62
            for (; isset($command[$i]) && in_array($command[$i], $ws); ++$i) {
63
            }
64
65
            // command string ended
66
            if (!isset($command[$i])) {
67
                break;
68
            }
69
70
            $inQuote = null;
71
            $quotePosition = 0;
72
            $argument = '';
73
            $part = '';
74
75
            // read a single argument
76
            for (; isset($command[$i]); ++$i) {
77
                $c = $command[$i];
78
79
                if ($inQuote === "'") {
80
                    // we're within a 'single quoted' string
81
                    if ($c === '\\' && isset($command[$i + 1]) && ($command[$i + 1] === "'" || $command[$i + 1] === '\\')) {
82
                        // escaped single quote or backslash ends up as char in argument
83
                        $part .= $command[++$i];
84
                        continue;
85
                    } elseif ($c === "'") {
86
                        // single quote ends
87
                        $inQuote = null;
88
                        $argument .= $part;
89
                        $part = '';
90
                        continue;
91
                    }
92
                } else {
93
                    // we're not within any quotes or within a "double quoted" string
94
                    if ($c === '\\' && isset($command[$i + 1])) {
95
                        if ($command[$i + 1] === 'u') {
96
                            // this looks like a unicode escape sequence
97
                            // use JSON parser to interpret this
98
                            $c = json_decode('"' . substr($command, $i, 6) . '"');
99
                            if ($c !== null) {
100
                                // on success => use interpreted and skip sequence
101
                                $argument .= stripcslashes($part) . $c;
102
                                $part = '';
103
                                $i += 5;
104
                                continue;
105
                            }
106
                        }
107
108
                        // escaped characters will be interpreted when part is complete
109
                        $part .= $command[$i] . $command[$i + 1];
110
                        ++$i;
111
                        continue;
112
                    } elseif ($inQuote === '"' && $c === '"') {
113
                        // double quote ends
114
                        $inQuote = null;
115
116
                        // previous double quoted part should be interpreted
117
                        $argument .= stripcslashes($part);
118
                        $part = '';
119
                        continue;
120
                    } elseif ($inQuote === null && ($c === '"' || $c === "'")) {
121
                        // start of quotes found
122
                        $inQuote = $c;
123
                        $quotePosition = $i;
124
125
                        // previous unquoted part should be interpreted
126
                        $argument .= stripcslashes($part);
127
                        $part = '';
128
                        continue;
129
                    } elseif ($inQuote === null && in_array($c, $ws)) {
130
                        // whitespace character terminates unquoted argument
131
                        break;
132
                    }
133
                }
134
135
                $part .= $c;
136
            }
137
138
            // end of argument reached. Still in quotes is a parse error.
139
            if ($inQuote !== null) {
140
                throw new UnclosedQuotesException($inQuote, $quotePosition);
141
            }
142
143
            // add remaining part to current argument
144
            if ($part !== '') {
145
                $argument .= stripcslashes($part);
146
            }
147
148
            $args []= $argument;
149
        }
150
151
        return $args;
152
    }
153
}
154