Hoa central
Parser.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Console;
38 
49 class Parser
50 {
57  protected $_longonly = false;
58 
64  protected $_parsed = null;
65 
66 
67 
159  public function parse($command)
160  {
161  unset($this->_parsed);
162  $this->_parsed = [
163  'input' => [],
164  'switch' => []
165  ];
166 
206  $regex = '#(?:(?<b>--?[^=\s]+)(?:(?:(=)|(\s))(?<!\\\)(?:("|\')|)(?<s>(?(3)[^-]|).*?)(?(4)(?<!\\\)\4|(?(2)(?<!\\\)\s|(?:(?:(?<!\\\)\s)|$))))?)|(?:(?<!\\\)(?:("|\')|)(?<i>.*?)(?(6)(?<!\\\)\6|(?:(?:(?<!\\\)\s)|$)))#Ssm';
207 
208  preg_match_all($regex, $command, $matches, PREG_SET_ORDER);
209 
210  for ($i = 0, $max = count($matches); $i < $max; ++$i) {
211  $match = $matches[$i];
212 
213  if (isset($match['i']) &&
214  ('0' === $match['i'] || !empty($match['i']))) {
215  $this->addInput($match);
216  } elseif (!isset($match['i']) && !isset($match['s'])) {
217  if (isset($matches[$i + 1])) {
218  $nextMatch = $matches[$i + 1];
219 
220  if (!empty($nextMatch['i']) &&
221  '=' === $nextMatch['i'][0]) {
222  ++$i;
223  $match[2] = '=';
224  $match[3] =
225  $match[4] = null;
226  $match['s'] =
227  $match[5] = substr($nextMatch[7], 1);
228 
229  $this->addValuedSwitch($match);
230 
231  continue;
232  }
233  }
234 
235  $this->addBoolSwitch($match);
236  } elseif (!isset($match['i']) && isset($match['s'])) {
237  $this->addValuedSwitch($match);
238  }
239  }
240 
241  return;
242  }
243 
250  protected function addInput(Array $input)
251  {
252  $handle = $input['i'];
253 
254  if (!empty($input[6])) {
255  $handle = str_replace('\\' . $input[6], $input[6], $handle);
256  } else {
257  $handle = str_replace('\\ ', ' ', $handle);
258  }
259 
260  $this->_parsed['input'][] = $handle;
261 
262  return;
263  }
264 
271  protected function addBoolSwitch(Array $switch)
272  {
273  $this->addSwitch($switch['b'], true);
274 
275  return;
276  }
277 
284  protected function addValuedSwitch(Array $switch)
285  {
286  $this->addSwitch($switch['b'], $switch['s'], $switch[4]);
287 
288  return;
289  }
290 
299  protected function addSwitch($name, $value, $escape = null)
300  {
301  if (substr($name, 0, 2) == '--') {
302  return $this->addSwitch(substr($name, 2), $value, $escape);
303  }
304 
305  if (substr($name, 0, 1) == '-') {
306  if (true === $this->getLongOnly()) {
307  return $this->addSwitch('-' . $name, $value, $escape);
308  }
309 
310  foreach (str_split(substr($name, 1)) as $foo => $switch) {
311  $this->addSwitch($switch, $value, $escape);
312  }
313 
314  return;
315  }
316 
317  if (null !== $escape) {
318  $escape = '' == $escape ? ' ' : $escape;
319 
320  if (is_string($value)) {
321  $value = str_replace('\\' . $escape, $escape, $value);
322  }
323  } elseif (is_string($value)) {
324  $value = str_replace('\\ ', ' ', $value);
325  }
326 
327  if (isset($this->_parsed['switch'][$name])) {
328  if (is_bool($this->_parsed['switch'][$name])) {
329  $value = !$this->_parsed['switch'][$name];
330  } else {
331  $value = [$this->_parsed['switch'][$name], $value];
332  }
333  }
334 
335  if (empty($name)) {
336  return $this->addInput([6 => null, 'i' => $value]);
337  }
338 
339  $this->_parsed['switch'][$name] = $value;
340 
341  return;
342  }
343 
351  public function transferSwitchToInput($name, &$value)
352  {
353  if (!isset($this->_parsed['switch'][$name])) {
354  return;
355  }
356 
357  $this->_parsed['input'][] = $this->_parsed['switch'][$name];
358  $value = true;
359  unset($this->_parsed['switch'][$name]);
360 
361  return;
362  }
363 
369  public function getInputs()
370  {
371  return $this->_parsed['input'];
372  }
373 
385  public function listInputs(
386  &$a,
387  &$b = null,
388  &$c = null,
389  &$d = null,
390  &$e = null,
391  &$f = null,
392  &$g = null,
393  &$h = null,
394  &$i = null,
395  &$j = null,
396  &$k = null,
397  &$l = null,
398  &$m = null,
399  &$n = null,
400  &$o = null,
401  &$p = null,
402  &$q = null,
403  &$r = null,
404  &$s = null,
405  &$t = null,
406  &$u = null,
407  &$v = null,
408  &$w = null,
409  &$x = null,
410  &$y = null,
411  &$z = null
412  ) {
413  $inputs = $this->getInputs();
414  $i = 'a';
415  $ii = -1;
416 
417  while (isset($inputs[++$ii]) && $i <= 'z') {
418  ${$i++} = $inputs[$ii];
419  }
420 
421  return;
422  }
423 
429  public function getSwitches()
430  {
431  return $this->_parsed['switch'];
432  }
433 
444  public function parseSpecialValue($value, Array $keywords = [])
445  {
446  $out = [];
447 
448  foreach (explode(',', $value) as $key => $subvalue) {
449  $subvalue = str_replace(
450  array_keys($keywords),
451  array_values($keywords),
452  $subvalue
453  );
454 
455  if (0 !== preg_match('#^(-?[0-9]+):(-?[0-9]+)$#', $subvalue, $matches)) {
456  if (0 > $matches[1] && 0 > $matches[2]) {
457  throw new Exception(
458  'Cannot give two negative numbers, given %s.',
459  0,
460  $subvalue
461  );
462  }
463 
464  array_shift($matches);
465  $max = max($matches);
466  $min = min($matches);
467 
468  if (0 > $max || 0 > $min) {
469  if (0 > $max - $min) {
470  throw new Exception(
471  'The difference between operands must be ' .
472  'positive.',
473  1
474  );
475  }
476 
477  $min = $max + $min;
478  }
479 
480  $out = array_merge(range($min, $max), $out);
481  } else {
482  $out[] = $subvalue;
483  }
484  }
485 
486  return $out;
487  }
488 
495  public function setLongOnly($longonly = false)
496  {
497  $old = $this->_longonly;
498  $this->_longonly = $longonly;
499 
500  return $old;
501  }
502 
508  public function getLongOnly()
509  {
510  return $this->_longonly;
511  }
512 }
setLongOnly($longonly=false)
Definition: Parser.php:495
addSwitch($name, $value, $escape=null)
Definition: Parser.php:299
listInputs(&$a, &$b=null, &$c=null, &$d=null, &$e=null, &$f=null, &$g=null, &$h=null, &$i=null, &$j=null, &$k=null, &$l=null, &$m=null, &$n=null, &$o=null, &$p=null, &$q=null, &$r=null, &$s=null, &$t=null, &$u=null, &$v=null, &$w=null, &$x=null, &$y=null, &$z=null)
Definition: Parser.php:385
addValuedSwitch(Array $switch)
Definition: Parser.php:284
addBoolSwitch(Array $switch)
Definition: Parser.php:271
parse($command)
Definition: Parser.php:159
transferSwitchToInput($name, &$value)
Definition: Parser.php:351
parseSpecialValue($value, Array $keywords=[])
Definition: Parser.php:444
addInput(Array $input)
Definition: Parser.php:250