GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — v0.89-develop ( 2a64a1...dbf016 )
by Zordius
03:45
created

Parser::getBlockParams()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 9.4286
cc 2
eloc 5
nc 2
nop 1
crap 2
1
<?php
2
/*
3
4
Copyrights for code authored by Yahoo! Inc. is licensed under the following terms:
5
MIT License
6
Copyright (c) 2013-2015 Yahoo! Inc. All Rights Reserved.
7
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10
11
Origin: https://github.com/zordius/lightncandy
12
*/
13
14
/**
15
 * file to keep LightnCandy Parser
16
 *
17
 * @package    LightnCandy
18
 * @author     Zordius <[email protected]>
19
 */
20
21
namespace LightnCandy;
22
23
use \LightnCandy\Token;
24
use \LightnCandy\SafeString;
25
26
/**
27
 * LightnCandy Parser
28
 */
29
class Parser extends Token
30
{
31
    // Compile time error handling flags
32
    const BLOCKPARAM = 9999;
33
34
    /**
35
     * Get block params and fix the variable list
36
     *
37
     * @param array<boolean|integer|array> $vars parsed token
38
     *
39
     * @return array<string>|null Return list of block params or null
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|integer|array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
40
     *
41
     */
42 174
    public static function getBlockParams(&$vars) {
43 174
        if (isset($vars[static::BLOCKPARAM])) {
44 6
            $list = $vars[static::BLOCKPARAM];
45 6
            unset($vars[static::BLOCKPARAM]);
46 6
            return $list;
47
        }
48 169
    }
49
50
    /**
51
     * Return array presentation for an expression
52
     *
53
     * @param string $name variable name.
54
     * @param boolean $asis keep the name as is or not
55
     * @param boolean $quote add single quote or not
56
     *
57
     * @return array<integer|string> Return variable name array
58
     *
59
     */
60 86
    protected static function getLiteral($name, $asis, $quote = false) {
61 86
        return $asis ? array($name) : array(0, $quote ? "'$name'" : $name);
62
    }
63
64
    /**
65
     * Return array presentation for an expression
66
     *
67
     * @param string $v analyzed expression names.
68
     * @param array<string,array|string|integer> $context Current compile content.
69
     * @param boolean $asis keep the reference name
70
     *
71
     * @return array<integer,string> Return variable name array
72
     *
73
     * @expect array('this') when input 'this', array('flags' => array('advar' => 0, 'this' => 0)), false
74
     * @expect array() when input 'this', array('flags' => array('advar' => 0, 'this' => 1)), false
75
     * @expect array(1) when input '../', array('flags' => array('advar' => 0, 'this' => 1, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
76
     * @expect array(1) when input '../.', array('flags' => array('advar' => 0, 'this' => 1, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
77
     * @expect array(1) when input '../this', array('flags' => array('advar' => 0, 'this' => 1, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
78
     * @expect array(1, 'a') when input '../a', array('flags' => array('advar' => 0, 'this' => 1, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
79
     * @expect array(2, 'a', 'b') when input '../../a.b', array('flags' => array('advar' => 0, 'this' => 0, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
80
     * @expect array(2, '[a]', 'b') when input '../../[a].b', array('flags' => array('advar' => 0, 'this' => 0, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
81
     * @expect array(2, 'a', 'b') when input '../../[a].b', array('flags' => array('advar' => 1, 'this' => 0, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
82
     * @expect array('id') when input 'this.id', array('flags' => array('advar' => 1, 'this' => 1, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
83
     * @expect array(0, '\'a.b\'') when input '"a.b"', array('flags' => array('advar' => 1, 'this' => 0, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
84
     * @expect array(0, '123') when input '123', array('flags' => array('advar' => 1, 'this' => 0, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
85
     * @expect array(0, 'null') when input 'null', array('flags' => array('advar' => 1, 'this' => 0, 'parent' => 1), 'usedFeature' => array('parent' => 0)), false
86
     */
87 602
    protected static function getExpression($v, &$context, $asis) {
88
        // handle number
89 602
        if (is_numeric($v)) {
90 28
            return static::getLiteral(strval(1 * $v), $asis);
91
        }
92
93
        // handle double quoted string
94 598
        if (preg_match('/^"(.*)"$/', $v, $matched)) {
95 45
            return static::getLiteral(preg_replace('/([^\\\\])\\\\\\\\"/', '$1"', preg_replace('/^\\\\\\\\"/', '"', $matched[1])), $asis, true);
96
        }
97
98
        // handle single quoted string
99 592
        if (preg_match('/^\\\\\'(.*)\\\\\'$/', $v, $matched)) {
100 17
            return static::getLiteral($matched[1], $asis, true);
101
        }
102
103
        // handle boolean, null and undefined
104 589
        if (preg_match('/^(true|false|null|undefined)$/', $v)) {
105 23
            return static::getLiteral(($v === 'undefined') ? 'null' : $v, $asis);
106
        }
107
108 586
        $ret = array();
109 586
        $levels = 0;
110
111
        // handle ..
112 586
        if ($v === '..') {
113 6
            $v = '../';
114
        }
115
116
        // Trace to parent for ../ N times
117 586
        $v = preg_replace_callback('/\\.\\.\\//', function() use (&$levels) {
118 42
            $levels++;
119 42
            return '';
120 586
        }, trim($v));
121
122
        // remove ./ in path
123 586
        $v = preg_replace('/\\.\\//', '', $v);
124
125 586
        if ($levels) {
126 42
            $ret[] = $levels;
127 42
            if (!$context['flags']['parent']) {
128 4
                $context['error'][] = 'Do not support {{../var}}, you should do compile with LightnCandy::FLAG_PARENT flag';
129
            }
130 42
            $context['usedFeature']['parent'] ++;
131
        }
132
133 586
        if ($context['flags']['advar'] && preg_match('/\\]/', $v)) {
134 31
            preg_match_all(static::VARNAME_SEARCH, $v, $matchedall);
135
        } else {
136 561
            preg_match_all('/([^\\.\\/]+)/', $v, $matchedall);
137
        }
138
139 586
        foreach ($matchedall[1] as $m) {
140 579
            if ($context['flags']['advar'] && substr($m, 0, 1) === '[') {
141 25
                $ret[] = substr($m, 1, -1);
142 572
            } else if ((!$context['flags']['this'] || ($m !== 'this')) && ($m !== '.')) {
143 579
                $ret[] = $m;
144
            }
145
        }
146
147 586
        return $ret;
148
    }
149
150
    /**
151
     * Parse the token and return parsed result.
152
     *
153
     * @param array<string> $token preg_match results
154
     * @param array<string,array|string|integer> $context current compile context
155
     *
156
     * @return array<boolean|integer|array> Return parsed result
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<boolean|array<boolean|integer|array>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
157
     *
158
     * @expect array(false, array(array())) when input array(0,0,0,0,0,0,0,''), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 0, 'noesc' => 0), 'rawblock' => false)
159
     * @expect array(true, array(array())) when input array(0,0,0,'{{',0,'{',0,''), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 0, 'noesc' => 0), 'rawblock' => false)
160
     * @expect array(true, array(array())) when input array(0,0,0,0,0,0,0,''), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 0, 'noesc' => 1), 'rawblock' => false)
161
     * @expect array(false, array(array('a'))) when input array(0,0,0,0,0,0,0,'a'), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 0, 'noesc' => 0), 'rawblock' => false)
162
     * @expect array(false, array(array('a'), array('b'))) when input array(0,0,0,0,0,0,0,'a  b'), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 0, 'noesc' => 0), 'rawblock' => false)
163
     * @expect array(false, array(array('a'), array('"b'), array('c"'))) when input array(0,0,0,0,0,0,0,'a "b c"'), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 0, 'noesc' => 0), 'rawblock' => false)
164
     * @expect array(false, array(array('a'), array(0, '\'b c\''))) when input array(0,0,0,0,0,0,0,'a "b c"'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 0, 'noesc' => 0), 'rawblock' => false)
165
     * @expect array(false, array(array('a'), array('[b'), array('c]'))) when input array(0,0,0,0,0,0,0,'a [b c]'), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 0, 'noesc' => 0), 'rawblock' => false)
166
     * @expect array(false, array(array('a'), array('[b'), array('c]'))) when input array(0,0,0,0,0,0,0,'a [b c]'), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
167
     * @expect array(false, array(array('a'), array('b c'))) when input array(0,0,0,0,0,0,0,'a [b c]'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 0, 'noesc' => 0), 'rawblock' => false)
168
     * @expect array(false, array(array('a'), array('b c'))) when input array(0,0,0,0,0,0,0,'a [b c]'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
169
     * @expect array(false, array(array('a'), 'q' => array('b c'))) when input array(0,0,0,0,0,0,0,'a q=[b c]'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
170
     * @expect array(false, array(array('a'), array('q=[b c'))) when input array(0,0,0,0,0,0,0,'a [q=[b c]'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
171
     * @expect array(false, array(array('a'), 'q' => array('[b'), array('c]'))) when input array(0,0,0,0,0,0,0,'a q=[b c]'), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
172
     * @expect array(false, array(array('a'), 'q' => array('b'), array('c'))) when input array(0,0,0,0,0,0,0,'a [q]=b c'), array('flags' => array('advar' => 0, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
173
     * @expect array(false, array(array('a'), 'q' => array(0, '\'b c\''))) when input array(0,0,0,0,0,0,0,'a q="b c"'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
174
     * @expect array(false, array(array(-1, array(array('foo'), array('bar')), '(foo bar)'))) when input array(0,0,0,0,0,0,0,'(foo bar)'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0, 'exhlp' => 1, 'lambda' => 0), 'ops' => array('seperator' => ''), 'usedFeature' => array('subexp' => 0), 'rawblock' => false)
175
     * @expect array(false, array(array('foo'), array("'=='"), array('bar'))) when input array(0,0,0,0,0,0,0,"foo '==' bar"), array('flags' => array('advar' => 1, 'namev' => 1, 'noesc' => 0, 'this' => 0), 'rawblock' => false)
176
     * @expect array(false, array(array(-1, array(array('foo'), array('bar')), '( foo bar)'))) when input array(0,0,0,0,0,0,0,'( foo bar)'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0, 'exhlp' => 1, 'lambda' => 0), 'ops' => array('seperator' => ''), 'usedFeature' => array('subexp' => 0), 'rawblock' => false)
177
     * @expect array(false, array(array('a'), array(0, '\' b c\''))) when input array(0,0,0,0,0,0,0,'a " b c"'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 0, 'noesc' => 0), 'rawblock' => false)
178
     * @expect array(false, array(array('a'), 'q' => array(0, '\' b c\''))) when input array(0,0,0,0,0,0,0,'a q=" b c"'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
179
     * @expect array(false, array(array('foo'), array(0, "' =='"), array('bar'))) when input array(0,0,0,0,0,0,0,"foo \' ==\' bar"), array('flags' => array('advar' => 1, 'namev' => 1, 'noesc' => 0, 'this' => 0), 'rawblock' => false)
180
     * @expect array(false, array(array('a'), array(' b c'))) when input array(0,0,0,0,0,0,0,'a [ b c]'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
181
     * @expect array(false, array(array('a'), 'q' => array(0, "' d e'"))) when input array(0,0,0,0,0,0,0,"a q=\' d e\'"), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0), 'rawblock' => false)
182
     * @expect array(false, array('q' => array(-1, array(array('foo'), array('bar')), '( foo bar)'))) when input array(0,0,0,0,0,0,0,'q=( foo bar)'), array('flags' => array('advar' => 1, 'this' => 1, 'namev' => 1, 'noesc' => 0, 'exhlp' => 0, 'lambda' => 0), 'usedFeature' => array('subexp' => 0), 'ops' => array('seperator' => 0), 'rawblock' => false)
183
     */
184 608
    public static function parse(&$token, &$context) {
185 608
        $vars = static::analyze($token[static::POS_INNERTAG], $context);
186 608
        if ($token[static::POS_OP] === '>' && isset($vars[0])) {
187 69
            $fn = $vars[0];
188
        }
189
190 608
        $avars = static::advancedVariable($vars, $context, static::toString($token));
191
192 608
        if ($token[static::POS_OP] === '>' && isset($fn)) {
193 69
            $avars[0] = preg_match(SafeString::IS_SUBEXP_SEARCH, $fn) ? $avars[0] : array(preg_replace('/^("(.+)")|(\\[(.+)\\])$/', '$2$4', $fn));
194
        }
195
196 608
        return array(($token[static::POS_BEGINRAW] === '{') || ($token[static::POS_OP] === '&') || $context['flags']['noesc'] || $context['rawblock'], $avars);
197
    }
198
199
    /**
200
     * Parse a subexpression then return parsed result.
201
     *
202
     * @param string $expression the full string of a sub expression
203
     * @param array<string,array|string|integer> $context current compile context
204
     *
205
     * @return array<boolean|integer|array> Return parsed result
0 ignored issues
show
Documentation introduced by
Should the return type not be array<integer|array<bool...|integer|array>|string>?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
206
     */
207 40
    public static function subexpression($expression, &$context) {
208 40
        $context['usedFeature']['subexp']++;
209 40
        $vars = static::analyze(substr($expression, 1, -1), $context);
210 40
        $avars = static::advancedVariable($vars, $context, $expression);
211 40
        if (isset($avars[0][0]) && !$context['flags']['exhlp']) {
212 21
            if (!Validator::helper($context, $avars[0][0])) {
213 2
                $context['error'][] = "Can not find custom helper function defination {$avars[0][0]}() !";
214
            }
215
        }
216 40
        return array(-1, $avars, $expression);
217
    }
218
219
    /**
220
     * Check a parsed result is a subexpression or not
221
     *
222
     * @param array<string|integer|array> $var
223
     *
224
     * @return boolean return true when input is a subexpression
225
     */
226 366
    public static function isSubExp($var) {
227 366
        return is_array($var) && (count($var) === 3) && ($var[0] === -1) && is_string($var[2]);
228
    }
229
230
    /**
231
     * Analyze parsed token for advanved variables.
232
     *
233
     * @param array<boolean|integer|array> $vars parsed token
234
     * @param array<string,array|string|integer> $context current compile context
235
     * @param string $token original token
236
     *
237
     * @return array<boolean|integer|array> Return parsed result
238
     *
239
     */
240 607
    protected static function advancedVariable($vars, &$context, $token) {
241 607
        $ret = array();
242 607
        $i = 0;
243 607
        foreach ($vars as $idx => $var) {
244
            // handle (...)
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
245 601
            if (preg_match(SafeString::IS_SUBEXP_SEARCH, $var)) {
246 35
                $ret[$i] = static::subexpression($var, $context);
247 35
                $i++;
248 35
                continue;
249
            }
250
251
            // handle |...|
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
252 601
            if (preg_match(SafeString::IS_BLOCKPARAM_SEARCH, $var, $matched)) {
253 6
                $ret[static::BLOCKPARAM] = explode(' ', $matched[1]);
254 6
                continue;
255
            }
256
257 601
            if ($context['flags']['namev']) {
258 396
                if (preg_match('/^((\\[([^\\]]+)\\])|([^=^["\']+))=(.+)$/', $var, $m)) {
259 35
                    if (!$context['flags']['advar'] && $m[3]) {
260 1
                        $context['error'][] = "Wrong argument name as '[$m[3]]' in $token ! You should fix your template or compile with LightnCandy::FLAG_ADVARNAME flag.";
261
                    }
262 35
                    $idx = $m[3] ? $m[3] : $m[4];
263 35
                    $var = $m[5];
264
                    // handle foo=(...)
1 ignored issue
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
265 35
                    if (preg_match(SafeString::IS_SUBEXP_SEARCH, $var)) {
266 6
                        $ret[$idx] = static::subexpression($var, $context);
267 6
                        continue;
268
                    }
269
                }
270
            }
271
272 601
            if ($context['flags']['advar'] && !preg_match("/^(\"|\\\\')(.*)(\"|\\\\')$/", $var)) {
273
                    // foo]  Rule 1: no starting [ or [ not start from head
274 411
                if (preg_match('/^[^\\[\\.]+[\\]\\[]/', $var)
275
                    // [bar  Rule 2: no ending ] or ] not in the end
276 405
                    || preg_match('/[\\[\\]][^\\]\\.]+$/', $var)
277
                    // ]bar. Rule 3: middle ] not before .
278 403
                    || preg_match('/\\][^\\]\\[\\.]+\\./', $var)
279
                    // .foo[ Rule 4: middle [ not after .
280 411
                    || preg_match('/\\.[^\\]\\[\\.]+\\[/', preg_replace('/^(..\\/)+/', '', preg_replace('/\\[[^\\]]+\\]/', '[XXX]', $var)))
281
                ) {
282 12
                    $context['error'][] = "Wrong variable naming as '$var' in $token !";
283
                } else {
284 399
                    $name = preg_replace('/(\\[.+?\\])/', '', $var);
285
                    // Scan for invalid charactors which not be protected by [ ]
286
                    // now make ( and ) pass, later fix
287 399
                    if (preg_match('/[!"#%\'*+,;<=>{|}~]/', $name)) {
288 2
                        $context['error'][] = "Wrong variable naming as '$var' in $token ! You should wrap ! \" # % & ' * + , ; < = > { | } ~ into [ ]";
289
                    }
290
                }
291
            }
292
293 601
            $var = static::getExpression($var, $context, (count($vars) === 1) && ($idx === 0));
294
295 601
            if (is_string($idx)) {
296 30
                $ret[$idx] = $var;
297
            } else {
298 600
                $ret[$i] = $var;
299 601
                $i++;
300
            }
301
        }
302 607
        return $ret;
303
    }
304
305
    /**
306
     * Analyze a token string and return parsed result.
307
     *
308
     * @param string $token preg_match results
309
     * @param array<string,array|string|integer> $context current compile context
310
     *
311
     * @return array<boolean|integer|array> Return parsed result
312
     *
313
     */
314 607
    protected static function analyze($token, &$context) {
315 607
        $count = preg_match_all('/(\s*)([^\s]+)/', $token, $matchedall);
316
        // Parse arguments and deal with "..." or [...] or (...) or \'...\' or |...|
1 ignored issue
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
317 607
        if (($count > 0) && $context['flags']['advar']) {
318 424
            $vars = array();
319 424
            $prev = '';
320 424
            $expect = 0;
321 424
            $stack = 0;
322
323 424
            foreach ($matchedall[2] as $index => $t) {
324
                // continue from previous match when expect something
325 424
                if ($expect) {
326 49
                    $prev .= "{$matchedall[1][$index]}$t";
327 49
                    if (($stack > 0) && (substr($t, 0, 1) === '(')) {
328 10
                        $stack++;
329
                    }
330
                    // end an argument when end with expected charactor
331 49
                    if (substr($t, -1, 1) === $expect) {
332 49
                        if ($stack > 0) {
333 39
                            preg_match('/(\\)+)$/', $t, $matchedq);
334 39
                            $stack -= isset($matchedq[0]) ? strlen($matchedq[0]) : 1;
335 39
                            if ($stack > 0) {
336 4
                                continue;
337
                            }
338 39
                            if ($stack < 0) {
339 1
                                $context['error'][] = "Unexcepted ')' in expression '$token' !!";
340 1
                                break;
341
                            }
342
                        }
343 48
                        $vars[] = $prev;
344 48
                        $prev = '';
345 48
                        $expect = 0;
346
                    }
347 49
                    continue;
348
                }
349
350
                // continue to next match when begin with '(' without ending ')'
351 424
                if (preg_match('/^\([^\)]*$/', $t)) {
352 29
                    $prev = $t;
353 29
                    $expect = ')';
354 29
                    $stack=1;
355 29
                    continue;
356
                }
357
358
                // continue to next match when begin with '"' without ending '"'
359 424
                if (preg_match('/^"[^"]*$/', $t)) {
360 6
                    $prev = $t;
361 6
                    $expect = '"';
362 6
                    continue;
363
                }
364
365
                // continue to next match when begin with \' without ending '
366 423
                if (preg_match('/^\\\\\'[^\']*$/', $t)) {
367 6
                    $prev = $t;
368 6
                    $expect = '\'';
369 6
                    continue;
370
                }
371
372
                // continue to next match when '="' exists without ending '"'
373 422
                if (preg_match('/^[^"]*="[^"]*$/', $t)) {
374 2
                    $prev = $t;
375 2
                    $expect = '"';
376 2
                    continue;
377
                }
378
379
                // continue to next match when '[' exists without ending ']'
380 422
                if (preg_match('/^([^"\'].+)?\\[[^\\]]*$/', $t)) {
381 9
                    $prev = $t;
382 9
                    $expect = ']';
383 9
                    continue;
384
                }
385
386
                // continue to next match when =\' exists without ending '
387 414
                if (preg_match('/^[^\']*=\\\\\'[^\']*$/', $t)) {
388 1
                    $prev = $t;
389 1
                    $expect = '\'';
390 1
                    continue;
391
                }
392
393
                // continue to next match when =( exists without ending )
394 414
                if (preg_match('/.+\([^\)]*$/', $t)) {
395 5
                    $prev = $t;
396 5
                    $expect = ')';
397 5
                    $stack=1;
398 5
                    continue;
399
                }
400
401
                // continue to next match when 'as' without ending '|'
402 414
                if (($t === 'as') && (count($vars) > 0)) {
403 6
                    $prev = '';
404 6
                    $expect = '|';
405 6
                    $stack=1;
406 6
                    continue;
407
                }
408
409 414
                $vars[] = $t;
410
            }
411 424
            return $vars;
412
        }
413 206
        return ($count > 0) ? $matchedall[2] : explode(' ', $token);
414
    }
415
}
416
417