PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.12.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.12.1
5.12.1 5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / vendor / mustangostang / spyc / Spyc.php
matomo / app / vendor / mustangostang / spyc Last commit date
examples 2 years ago php4 2 years ago COPYING 6 years ago README.md 6 years ago Spyc.php 2 years ago spyc.yaml 6 years ago
Spyc.php
1257 lines
1 <?php
2
3 namespace {
4 /**
5 * Spyc -- A Simple PHP YAML Class
6 * @version 0.6.2
7 * @author Vlad Andersen <vlad.andersen@gmail.com>
8 * @author Chris Wanstrath <chris@ozmm.org>
9 * @link https://github.com/mustangostang/spyc/
10 * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen
11 * @license http://www.opensource.org/licenses/mit-license.php MIT License
12 * @package Spyc
13 */
14 if (!\function_exists('spyc_load')) {
15 /**
16 * Parses YAML to array.
17 * @param string $string YAML string.
18 * @return array
19 */
20 function spyc_load($string)
21 {
22 return \Spyc::YAMLLoadString($string);
23 }
24 }
25 if (!\function_exists('spyc_load_file')) {
26 /**
27 * Parses YAML to array.
28 * @param string $file Path to YAML file.
29 * @return array
30 */
31 function spyc_load_file($file)
32 {
33 return \Spyc::YAMLLoad($file);
34 }
35 }
36 if (!\function_exists('spyc_dump')) {
37 /**
38 * Dumps array to YAML.
39 * @param array $data Array.
40 * @return string
41 */
42 function spyc_dump($data)
43 {
44 return \Spyc::YAMLDump($data, \false, \false, \true);
45 }
46 }
47 if (!\class_exists('Spyc')) {
48 /**
49 * The Simple PHP YAML Class.
50 *
51 * This class can be used to read a YAML file and convert its contents
52 * into a PHP array. It currently supports a very limited subsection of
53 * the YAML spec.
54 *
55 * Usage:
56 * <code>
57 * $Spyc = new Spyc;
58 * $array = $Spyc->load($file);
59 * </code>
60 * or:
61 * <code>
62 * $array = Spyc::YAMLLoad($file);
63 * </code>
64 * or:
65 * <code>
66 * $array = spyc_load_file($file);
67 * </code>
68 * @package Spyc
69 */
70 class Spyc
71 {
72 // SETTINGS
73 const REMPTY = "\x00\x00\x00\x00\x00";
74 /**
75 * Setting this to true will force YAMLDump to enclose any string value in
76 * quotes. False by default.
77 *
78 * @var bool
79 */
80 public $setting_dump_force_quotes = \false;
81 /**
82 * Setting this to true will forse YAMLLoad to use syck_load function when
83 * possible. False by default.
84 * @var bool
85 */
86 public $setting_use_syck_is_possible = \false;
87 /**
88 * Setting this to true will forse YAMLLoad to use syck_load function when
89 * possible. False by default.
90 * @var bool
91 */
92 public $setting_empty_hash_as_object = \false;
93 /**#@+
94 * @access private
95 * @var mixed
96 */
97 private $_dumpIndent;
98 private $_dumpWordWrap;
99 private $_containsGroupAnchor = \false;
100 private $_containsGroupAlias = \false;
101 private $path;
102 private $result;
103 private $LiteralPlaceHolder = '___YAML_Literal_Block___';
104 private $SavedGroups = array();
105 private $indent;
106 /**
107 * Path modifier that should be applied after adding current element.
108 * @var array
109 */
110 private $delayedPath = array();
111 /**#@+
112 * @access public
113 * @var mixed
114 */
115 public $_nodeId;
116 /**
117 * Load a valid YAML string to Spyc.
118 * @param string $input
119 * @return array
120 */
121 public function load($input)
122 {
123 return $this->_loadString($input);
124 }
125 /**
126 * Load a valid YAML file to Spyc.
127 * @param string $file
128 * @return array
129 */
130 public function loadFile($file)
131 {
132 return $this->_load($file);
133 }
134 /**
135 * Load YAML into a PHP array statically
136 *
137 * The load method, when supplied with a YAML stream (string or file),
138 * will do its best to convert YAML in a file into a PHP array. Pretty
139 * simple.
140 * Usage:
141 * <code>
142 * $array = Spyc::YAMLLoad('lucky.yaml');
143 * print_r($array);
144 * </code>
145 * @access public
146 * @return array
147 * @param string $input Path of YAML file or string containing YAML
148 * @param array set options
149 */
150 public static function YAMLLoad($input, $options = [])
151 {
152 $Spyc = new \Spyc();
153 foreach ($options as $key => $value) {
154 if (\property_exists($Spyc, $key)) {
155 $Spyc->{$key} = $value;
156 }
157 }
158 return $Spyc->_load($input);
159 }
160 /**
161 * Load a string of YAML into a PHP array statically
162 *
163 * The load method, when supplied with a YAML string, will do its best
164 * to convert YAML in a string into a PHP array. Pretty simple.
165 *
166 * Note: use this function if you don't want files from the file system
167 * loaded and processed as YAML. This is of interest to people concerned
168 * about security whose input is from a string.
169 *
170 * Usage:
171 * <code>
172 * $array = Spyc::YAMLLoadString("---\n0: hello world\n");
173 * print_r($array);
174 * </code>
175 * @access public
176 * @return array
177 * @param string $input String containing YAML
178 * @param array set options
179 */
180 public static function YAMLLoadString($input, $options = [])
181 {
182 $Spyc = new \Spyc();
183 foreach ($options as $key => $value) {
184 if (\property_exists($Spyc, $key)) {
185 $Spyc->{$key} = $value;
186 }
187 }
188 return $Spyc->_loadString($input);
189 }
190 /**
191 * Dump YAML from PHP array statically
192 *
193 * The dump method, when supplied with an array, will do its best
194 * to convert the array into friendly YAML. Pretty simple. Feel free to
195 * save the returned string as nothing.yaml and pass it around.
196 *
197 * Oh, and you can decide how big the indent is and what the wordwrap
198 * for folding is. Pretty cool -- just pass in 'false' for either if
199 * you want to use the default.
200 *
201 * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
202 * you can turn off wordwrap by passing in 0.
203 *
204 * @access public
205 * @return string
206 * @param array|\stdClass $array PHP array
207 * @param int $indent Pass in false to use the default, which is 2
208 * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
209 * @param bool $no_opening_dashes Do not start YAML file with "---\n"
210 */
211 public static function YAMLDump($array, $indent = \false, $wordwrap = \false, $no_opening_dashes = \false)
212 {
213 $spyc = new \Spyc();
214 return $spyc->dump($array, $indent, $wordwrap, $no_opening_dashes);
215 }
216 /**
217 * Dump PHP array to YAML
218 *
219 * The dump method, when supplied with an array, will do its best
220 * to convert the array into friendly YAML. Pretty simple. Feel free to
221 * save the returned string as tasteful.yaml and pass it around.
222 *
223 * Oh, and you can decide how big the indent is and what the wordwrap
224 * for folding is. Pretty cool -- just pass in 'false' for either if
225 * you want to use the default.
226 *
227 * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
228 * you can turn off wordwrap by passing in 0.
229 *
230 * @access public
231 * @return string
232 * @param array $array PHP array
233 * @param int $indent Pass in false to use the default, which is 2
234 * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
235 */
236 public function dump($array, $indent = \false, $wordwrap = \false, $no_opening_dashes = \false)
237 {
238 // Dumps to some very clean YAML. We'll have to add some more features
239 // and options soon. And better support for folding.
240 // New features and options.
241 if ($indent === \false or !\is_numeric($indent)) {
242 $this->_dumpIndent = 2;
243 } else {
244 $this->_dumpIndent = $indent;
245 }
246 if ($wordwrap === \false or !\is_numeric($wordwrap)) {
247 $this->_dumpWordWrap = 40;
248 } else {
249 $this->_dumpWordWrap = $wordwrap;
250 }
251 // New YAML document
252 $string = "";
253 if (!$no_opening_dashes) {
254 $string = "---\n";
255 }
256 // Start at the base of the array and move through it.
257 if ($array) {
258 $array = (array) $array;
259 $previous_key = -1;
260 foreach ($array as $key => $value) {
261 if (!isset($first_key)) {
262 $first_key = $key;
263 }
264 $string .= $this->_yamlize($key, $value, 0, $previous_key, $first_key, $array);
265 $previous_key = $key;
266 }
267 }
268 return $string;
269 }
270 /**
271 * Attempts to convert a key / value array item to YAML
272 * @access private
273 * @return string
274 * @param $key The name of the key
275 * @param $value The value of the item
276 * @param $indent The indent of the current node
277 */
278 private function _yamlize($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null)
279 {
280 if (\is_object($value)) {
281 $value = (array) $value;
282 }
283 if (\is_array($value)) {
284 if (empty($value)) {
285 return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array);
286 }
287 // It has children. What to do?
288 // Make it the right kind of item
289 $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array);
290 // Add the indent
291 $indent += $this->_dumpIndent;
292 // Yamlize the array
293 $string .= $this->_yamlizeArray($value, $indent);
294 } elseif (!\is_array($value)) {
295 // It doesn't have children. Yip.
296 $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array);
297 }
298 return $string;
299 }
300 /**
301 * Attempts to convert an array to YAML
302 * @access private
303 * @return string
304 * @param $array The array you want to convert
305 * @param $indent The indent of the current level
306 */
307 private function _yamlizeArray($array, $indent)
308 {
309 if (\is_array($array)) {
310 $string = '';
311 $previous_key = -1;
312 foreach ($array as $key => $value) {
313 if (!isset($first_key)) {
314 $first_key = $key;
315 }
316 $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array);
317 $previous_key = $key;
318 }
319 return $string;
320 } else {
321 return \false;
322 }
323 }
324 /**
325 * Returns YAML from a key and a value
326 * @access private
327 * @return string
328 * @param $key The name of the key
329 * @param $value The value of the item
330 * @param $indent The indent of the current node
331 */
332 private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null)
333 {
334 // do some folding here, for blocks
335 if (\is_string($value) && (\strpos($value, "\n") !== \false || \strpos($value, ": ") !== \false || \strpos($value, "- ") !== \false || \strpos($value, "*") !== \false || \strpos($value, "#") !== \false || \strpos($value, "<") !== \false || \strpos($value, ">") !== \false || \strpos($value, '%') !== \false || \strpos($value, ' ') !== \false || \strpos($value, "[") !== \false || \strpos($value, "]") !== \false || \strpos($value, "{") !== \false || \strpos($value, "}") !== \false || \strpos($value, "&") !== \false || \strpos($value, "'") !== \false || \strpos($value, "!") === 0 || \substr($value, -1, 1) == ':')) {
336 $value = $this->_doLiteralBlock($value, $indent);
337 } else {
338 $value = $this->_doFolding($value, $indent);
339 }
340 if ($value === array()) {
341 $value = '[ ]';
342 }
343 if ($value === "") {
344 $value = '""';
345 }
346 if (self::isTranslationWord($value)) {
347 $value = $this->_doLiteralBlock($value, $indent);
348 }
349 if (\trim($value) != $value) {
350 $value = $this->_doLiteralBlock($value, $indent);
351 }
352 if (\is_bool($value)) {
353 $value = $value ? "true" : "false";
354 }
355 if ($value === null) {
356 $value = 'null';
357 }
358 if ($value === "'" . self::REMPTY . "'") {
359 $value = null;
360 }
361 $spaces = \str_repeat(' ', $indent);
362 //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {
363 if (\is_array($source_array) && \array_keys($source_array) === \range(0, \count($source_array) - 1)) {
364 // It's a sequence
365 $string = $spaces . '- ' . $value . "\n";
366 } else {
367 // if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"');
368 // It's mapped
369 if (\strpos($key, ":") !== \false || \strpos($key, "#") !== \false) {
370 $key = '"' . $key . '"';
371 }
372 $string = \rtrim($spaces . $key . ': ' . $value) . "\n";
373 }
374 return $string;
375 }
376 /**
377 * Creates a literal block for dumping
378 * @access private
379 * @return string
380 * @param $value
381 * @param $indent int The value of the indent
382 */
383 private function _doLiteralBlock($value, $indent)
384 {
385 if ($value === "\n") {
386 return '\\n';
387 }
388 if (\strpos($value, "\n") === \false && \strpos($value, "'") === \false) {
389 return \sprintf("'%s'", $value);
390 }
391 if (\strpos($value, "\n") === \false && \strpos($value, '"') === \false) {
392 return \sprintf('"%s"', $value);
393 }
394 $exploded = \explode("\n", $value);
395 $newValue = '|';
396 if (isset($exploded[0]) && ($exploded[0] == "|" || $exploded[0] == "|-" || $exploded[0] == ">")) {
397 $newValue = $exploded[0];
398 unset($exploded[0]);
399 }
400 $indent += $this->_dumpIndent;
401 $spaces = \str_repeat(' ', $indent);
402 foreach ($exploded as $line) {
403 $line = \trim($line);
404 if (\strpos($line, '"') === 0 && \strrpos($line, '"') == \strlen($line) - 1 || \strpos($line, "'") === 0 && \strrpos($line, "'") == \strlen($line) - 1) {
405 $line = \substr($line, 1, -1);
406 }
407 $newValue .= "\n" . $spaces . $line;
408 }
409 return $newValue;
410 }
411 /**
412 * Folds a string of text, if necessary
413 * @access private
414 * @return string
415 * @param $value The string you wish to fold
416 */
417 private function _doFolding($value, $indent)
418 {
419 // Don't do anything if wordwrap is set to 0
420 if ($this->_dumpWordWrap !== 0 && \is_string($value) && \strlen($value) > $this->_dumpWordWrap) {
421 $indent += $this->_dumpIndent;
422 $indent = \str_repeat(' ', $indent);
423 $wrapped = \wordwrap($value, $this->_dumpWordWrap, "\n{$indent}");
424 $value = ">\n" . $indent . $wrapped;
425 } else {
426 if ($this->setting_dump_force_quotes && \is_string($value) && $value !== self::REMPTY) {
427 $value = '"' . $value . '"';
428 }
429 if (\is_numeric($value) && \is_string($value)) {
430 $value = '"' . $value . '"';
431 }
432 }
433 return $value;
434 }
435 private function isTrueWord($value)
436 {
437 $words = self::getTranslations(array('true', 'on', 'yes', 'y'));
438 return \in_array($value, $words, \true);
439 }
440 private function isFalseWord($value)
441 {
442 $words = self::getTranslations(array('false', 'off', 'no', 'n'));
443 return \in_array($value, $words, \true);
444 }
445 private function isNullWord($value)
446 {
447 $words = self::getTranslations(array('null', '~'));
448 return \in_array($value, $words, \true);
449 }
450 private function isTranslationWord($value)
451 {
452 return self::isTrueWord($value) || self::isFalseWord($value) || self::isNullWord($value);
453 }
454 /**
455 * Coerce a string into a native type
456 * Reference: http://yaml.org/type/bool.html
457 * TODO: Use only words from the YAML spec.
458 * @access private
459 * @param $value The value to coerce
460 */
461 private function coerceValue(&$value)
462 {
463 if (self::isTrueWord($value)) {
464 $value = \true;
465 } else {
466 if (self::isFalseWord($value)) {
467 $value = \false;
468 } else {
469 if (self::isNullWord($value)) {
470 $value = null;
471 }
472 }
473 }
474 }
475 /**
476 * Given a set of words, perform the appropriate translations on them to
477 * match the YAML 1.1 specification for type coercing.
478 * @param $words The words to translate
479 * @access private
480 */
481 private static function getTranslations(array $words)
482 {
483 $result = array();
484 foreach ($words as $i) {
485 $result = \array_merge($result, array(\ucfirst($i), \strtoupper($i), \strtolower($i)));
486 }
487 return $result;
488 }
489 // LOADING FUNCTIONS
490 private function _load($input)
491 {
492 $Source = $this->loadFromSource($input);
493 return $this->loadWithSource($Source);
494 }
495 private function _loadString($input)
496 {
497 $Source = $this->loadFromString($input);
498 return $this->loadWithSource($Source);
499 }
500 private function loadWithSource($Source)
501 {
502 if (empty($Source)) {
503 return array();
504 }
505 if ($this->setting_use_syck_is_possible && \function_exists('syck_load')) {
506 $array = \syck_load(\implode("\n", $Source));
507 return \is_array($array) ? $array : array();
508 }
509 $this->path = array();
510 $this->result = array();
511 $cnt = \count($Source);
512 for ($i = 0; $i < $cnt; $i++) {
513 $line = $Source[$i];
514 $this->indent = \strlen($line) - \strlen(\ltrim($line));
515 $tempPath = $this->getParentPathByIndent($this->indent);
516 $line = self::stripIndent($line, $this->indent);
517 if (self::isComment($line)) {
518 continue;
519 }
520 if (self::isEmpty($line)) {
521 continue;
522 }
523 $this->path = $tempPath;
524 $literalBlockStyle = self::startsLiteralBlock($line);
525 if ($literalBlockStyle) {
526 $line = \rtrim($line, $literalBlockStyle . " \n");
527 $literalBlock = '';
528 $line .= ' ' . $this->LiteralPlaceHolder;
529 $literal_block_indent = \strlen($Source[$i + 1]) - \strlen(\ltrim($Source[$i + 1]));
530 while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) {
531 $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent);
532 }
533 $i--;
534 }
535 // Strip out comments
536 if (\strpos($line, '#')) {
537 $line = \preg_replace('/\\s*#([^"\']+)$/', '', $line);
538 }
539 while (++$i < $cnt && self::greedilyNeedNextLine($line)) {
540 $line = \rtrim($line, " \n\t\r") . ' ' . \ltrim($Source[$i], " \t");
541 }
542 $i--;
543 $lineArray = $this->_parseLine($line);
544 if ($literalBlockStyle) {
545 $lineArray = $this->revertLiteralPlaceHolder($lineArray, $literalBlock);
546 }
547 $this->addArray($lineArray, $this->indent);
548 foreach ($this->delayedPath as $indent => $delayedPath) {
549 $this->path[$indent] = $delayedPath;
550 }
551 $this->delayedPath = array();
552 }
553 return $this->result;
554 }
555 private function loadFromSource($input)
556 {
557 if (!empty($input) && \strpos($input, "\n") === \false && \file_exists($input)) {
558 $input = \file_get_contents($input);
559 }
560 return $this->loadFromString($input);
561 }
562 private function loadFromString($input)
563 {
564 $lines = \explode("\n", $input);
565 foreach ($lines as $k => $_) {
566 $lines[$k] = \rtrim($_, "\r");
567 }
568 return $lines;
569 }
570 /**
571 * Parses YAML code and returns an array for a node
572 * @access private
573 * @return array
574 * @param string $line A line from the YAML file
575 */
576 private function _parseLine($line)
577 {
578 if (!$line) {
579 return array();
580 }
581 $line = \trim($line);
582 if (!$line) {
583 return array();
584 }
585 $array = array();
586 $group = $this->nodeContainsGroup($line);
587 if ($group) {
588 $this->addGroup($line, $group);
589 $line = $this->stripGroup($line, $group);
590 }
591 if ($this->startsMappedSequence($line)) {
592 return $this->returnMappedSequence($line);
593 }
594 if ($this->startsMappedValue($line)) {
595 return $this->returnMappedValue($line);
596 }
597 if ($this->isArrayElement($line)) {
598 return $this->returnArrayElement($line);
599 }
600 if ($this->isPlainArray($line)) {
601 return $this->returnPlainArray($line);
602 }
603 return $this->returnKeyValuePair($line);
604 }
605 /**
606 * Finds the type of the passed value, returns the value as the new type.
607 * @access private
608 * @param string $value
609 * @return mixed
610 */
611 private function _toType($value)
612 {
613 if ($value === '') {
614 return "";
615 }
616 if ($this->setting_empty_hash_as_object && $value === '{}') {
617 return new \stdClass();
618 }
619 $first_character = $value[0];
620 $last_character = \substr($value, -1, 1);
621 $is_quoted = \false;
622 do {
623 if (!$value) {
624 break;
625 }
626 if ($first_character != '"' && $first_character != "'") {
627 break;
628 }
629 if ($last_character != '"' && $last_character != "'") {
630 break;
631 }
632 $is_quoted = \true;
633 } while (0);
634 if ($is_quoted) {
635 $value = \str_replace('\\n', "\n", $value);
636 if ($first_character == "'") {
637 return \strtr(\substr($value, 1, -1), array('\'\'' => '\'', '\\\'' => '\''));
638 }
639 return \strtr(\substr($value, 1, -1), array('\\"' => '"', '\\\'' => '\''));
640 }
641 if (\strpos($value, ' #') !== \false && !$is_quoted) {
642 $value = \preg_replace('/\\s+#(.+)$/', '', $value);
643 }
644 if ($first_character == '[' && $last_character == ']') {
645 // Take out strings sequences and mappings
646 $innerValue = \trim(\substr($value, 1, -1));
647 if ($innerValue === '') {
648 return array();
649 }
650 $explode = $this->_inlineEscape($innerValue);
651 // Propagate value array
652 $value = array();
653 foreach ($explode as $v) {
654 $value[] = $this->_toType($v);
655 }
656 return $value;
657 }
658 if (\strpos($value, ': ') !== \false && $first_character != '{') {
659 $array = \explode(': ', $value);
660 $key = \trim($array[0]);
661 \array_shift($array);
662 $value = \trim(\implode(': ', $array));
663 $value = $this->_toType($value);
664 return array($key => $value);
665 }
666 if ($first_character == '{' && $last_character == '}') {
667 $innerValue = \trim(\substr($value, 1, -1));
668 if ($innerValue === '') {
669 return array();
670 }
671 // Inline Mapping
672 // Take out strings sequences and mappings
673 $explode = $this->_inlineEscape($innerValue);
674 // Propagate value array
675 $array = array();
676 foreach ($explode as $v) {
677 $SubArr = $this->_toType($v);
678 if (empty($SubArr)) {
679 continue;
680 }
681 if (\is_array($SubArr)) {
682 $array[\key($SubArr)] = $SubArr[\key($SubArr)];
683 continue;
684 }
685 $array[] = $SubArr;
686 }
687 return $array;
688 }
689 if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') {
690 return null;
691 }
692 if (\is_numeric($value) && \preg_match('/^(-|)[1-9]+[0-9]*$/', $value)) {
693 $intvalue = (int) $value;
694 if ($intvalue != \PHP_INT_MAX && $intvalue != ~\PHP_INT_MAX) {
695 $value = $intvalue;
696 }
697 return $value;
698 }
699 if (\is_string($value) && \preg_match('/^0[xX][0-9a-fA-F]+$/', $value)) {
700 // Hexadecimal value.
701 return \hexdec($value);
702 }
703 $this->coerceValue($value);
704 if (\is_numeric($value)) {
705 if ($value === '0') {
706 return 0;
707 }
708 if (\rtrim($value, 0) === $value) {
709 $value = (float) $value;
710 }
711 return $value;
712 }
713 return $value;
714 }
715 /**
716 * Used in inlines to check for more inlines or quoted strings
717 * @access private
718 * @return array
719 */
720 private function _inlineEscape($inline)
721 {
722 // There's gotta be a cleaner way to do this...
723 // While pure sequences seem to be nesting just fine,
724 // pure mappings and mappings with sequences inside can't go very
725 // deep. This needs to be fixed.
726 $seqs = array();
727 $maps = array();
728 $saved_strings = array();
729 $saved_empties = array();
730 // Check for empty strings
731 $regex = '/("")|(\'\')/';
732 if (\preg_match_all($regex, $inline, $strings)) {
733 $saved_empties = $strings[0];
734 $inline = \preg_replace($regex, 'YAMLEmpty', $inline);
735 }
736 unset($regex);
737 // Check for strings
738 $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
739 if (\preg_match_all($regex, $inline, $strings)) {
740 $saved_strings = $strings[0];
741 $inline = \preg_replace($regex, 'YAMLString', $inline);
742 }
743 unset($regex);
744 // echo $inline;
745 $i = 0;
746 do {
747 // Check for sequences
748 while (\preg_match('/\\[([^{}\\[\\]]+)\\]/U', $inline, $matchseqs)) {
749 $seqs[] = $matchseqs[0];
750 $inline = \preg_replace('/\\[([^{}\\[\\]]+)\\]/U', 'YAMLSeq' . (\count($seqs) - 1) . 's', $inline, 1);
751 }
752 // Check for mappings
753 while (\preg_match('/{([^\\[\\]{}]+)}/U', $inline, $matchmaps)) {
754 $maps[] = $matchmaps[0];
755 $inline = \preg_replace('/{([^\\[\\]{}]+)}/U', 'YAMLMap' . (\count($maps) - 1) . 's', $inline, 1);
756 }
757 if ($i++ >= 10) {
758 break;
759 }
760 } while (\strpos($inline, '[') !== \false || \strpos($inline, '{') !== \false);
761 $explode = \explode(',', $inline);
762 $explode = \array_map('trim', $explode);
763 $stringi = 0;
764 $i = 0;
765 while (1) {
766 // Re-add the sequences
767 if (!empty($seqs)) {
768 foreach ($explode as $key => $value) {
769 if (\strpos($value, 'YAMLSeq') !== \false) {
770 foreach ($seqs as $seqk => $seq) {
771 $explode[$key] = \str_replace('YAMLSeq' . $seqk . 's', $seq, $value);
772 $value = $explode[$key];
773 }
774 }
775 }
776 }
777 // Re-add the mappings
778 if (!empty($maps)) {
779 foreach ($explode as $key => $value) {
780 if (\strpos($value, 'YAMLMap') !== \false) {
781 foreach ($maps as $mapk => $map) {
782 $explode[$key] = \str_replace('YAMLMap' . $mapk . 's', $map, $value);
783 $value = $explode[$key];
784 }
785 }
786 }
787 }
788 // Re-add the strings
789 if (!empty($saved_strings)) {
790 foreach ($explode as $key => $value) {
791 while (\strpos($value, 'YAMLString') !== \false) {
792 $explode[$key] = \preg_replace('/YAMLString/', $saved_strings[$stringi], $value, 1);
793 unset($saved_strings[$stringi]);
794 ++$stringi;
795 $value = $explode[$key];
796 }
797 }
798 }
799 // Re-add the empties
800 if (!empty($saved_empties)) {
801 foreach ($explode as $key => $value) {
802 while (\strpos($value, 'YAMLEmpty') !== \false) {
803 $explode[$key] = \preg_replace('/YAMLEmpty/', '', $value, 1);
804 $value = $explode[$key];
805 }
806 }
807 }
808 $finished = \true;
809 foreach ($explode as $key => $value) {
810 if (\strpos($value, 'YAMLSeq') !== \false) {
811 $finished = \false;
812 break;
813 }
814 if (\strpos($value, 'YAMLMap') !== \false) {
815 $finished = \false;
816 break;
817 }
818 if (\strpos($value, 'YAMLString') !== \false) {
819 $finished = \false;
820 break;
821 }
822 if (\strpos($value, 'YAMLEmpty') !== \false) {
823 $finished = \false;
824 break;
825 }
826 }
827 if ($finished) {
828 break;
829 }
830 $i++;
831 if ($i > 10) {
832 break;
833 }
834 // Prevent infinite loops.
835 }
836 return $explode;
837 }
838 private function literalBlockContinues($line, $lineIndent)
839 {
840 if (!\trim($line)) {
841 return \true;
842 }
843 if (\strlen($line) - \strlen(\ltrim($line)) > $lineIndent) {
844 return \true;
845 }
846 return \false;
847 }
848 private function referenceContentsByAlias($alias)
849 {
850 do {
851 if (!isset($this->SavedGroups[$alias])) {
852 echo "Bad group name: {$alias}.";
853 break;
854 }
855 $groupPath = $this->SavedGroups[$alias];
856 $value = $this->result;
857 foreach ($groupPath as $k) {
858 $value = $value[$k];
859 }
860 } while (\false);
861 return $value;
862 }
863 private function addArrayInline($array, $indent)
864 {
865 $CommonGroupPath = $this->path;
866 if (empty($array)) {
867 return \false;
868 }
869 foreach ($array as $k => $_) {
870 $this->addArray(array($k => $_), $indent);
871 $this->path = $CommonGroupPath;
872 }
873 return \true;
874 }
875 private function addArray($incoming_data, $incoming_indent)
876 {
877 // print_r ($incoming_data);
878 if (\count($incoming_data) > 1) {
879 return $this->addArrayInline($incoming_data, $incoming_indent);
880 }
881 $key = \key($incoming_data);
882 $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null;
883 if ($key === '__!YAMLZero') {
884 $key = '0';
885 }
886 if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) {
887 // Shortcut for root-level values.
888 if ($key || $key === '' || $key === '0') {
889 $this->result[$key] = $value;
890 } else {
891 $this->result[] = $value;
892 \end($this->result);
893 $key = \key($this->result);
894 }
895 $this->path[$incoming_indent] = $key;
896 return;
897 }
898 $history = array();
899 // Unfolding inner array tree.
900 $history[] = $_arr = $this->result;
901 foreach ($this->path as $k) {
902 $history[] = $_arr = $_arr[$k];
903 }
904 if ($this->_containsGroupAlias) {
905 $value = $this->referenceContentsByAlias($this->_containsGroupAlias);
906 $this->_containsGroupAlias = \false;
907 }
908 // Adding string or numeric key to the innermost level or $this->arr.
909 if (\is_string($key) && $key == '<<') {
910 if (!\is_array($_arr)) {
911 $_arr = array();
912 }
913 $_arr = \array_merge($_arr, $value);
914 } else {
915 if ($key || $key === '' || $key === '0') {
916 if (!\is_array($_arr)) {
917 $_arr = array($key => $value);
918 } else {
919 $_arr[$key] = $value;
920 }
921 } else {
922 if (!\is_array($_arr)) {
923 $_arr = array($value);
924 $key = 0;
925 } else {
926 $_arr[] = $value;
927 \end($_arr);
928 $key = \key($_arr);
929 }
930 }
931 }
932 $reverse_path = \array_reverse($this->path);
933 $reverse_history = \array_reverse($history);
934 $reverse_history[0] = $_arr;
935 $cnt = \count($reverse_history) - 1;
936 for ($i = 0; $i < $cnt; $i++) {
937 $reverse_history[$i + 1][$reverse_path[$i]] = $reverse_history[$i];
938 }
939 $this->result = $reverse_history[$cnt];
940 $this->path[$incoming_indent] = $key;
941 if ($this->_containsGroupAnchor) {
942 $this->SavedGroups[$this->_containsGroupAnchor] = $this->path;
943 if (\is_array($value)) {
944 $k = \key($value);
945 if (!\is_int($k)) {
946 $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k;
947 }
948 }
949 $this->_containsGroupAnchor = \false;
950 }
951 }
952 private static function startsLiteralBlock($line)
953 {
954 $lastChar = \substr(\trim($line), -1);
955 if ($lastChar != '>' && $lastChar != '|') {
956 return \false;
957 }
958 if ($lastChar == '|') {
959 return $lastChar;
960 }
961 // HTML tags should not be counted as literal blocks.
962 if (\preg_match('#<.*?>$#', $line)) {
963 return \false;
964 }
965 return $lastChar;
966 }
967 private static function greedilyNeedNextLine($line)
968 {
969 $line = \trim($line);
970 if (!\strlen($line)) {
971 return \false;
972 }
973 if (\substr($line, -1, 1) == ']') {
974 return \false;
975 }
976 if ($line[0] == '[') {
977 return \true;
978 }
979 if (\preg_match('#^[^:]+?:\\s*\\[#', $line)) {
980 return \true;
981 }
982 return \false;
983 }
984 private function addLiteralLine($literalBlock, $line, $literalBlockStyle, $indent = -1)
985 {
986 $line = self::stripIndent($line, $indent);
987 if ($literalBlockStyle !== '|') {
988 $line = self::stripIndent($line);
989 }
990 $line = \rtrim($line, "\r\n\t ") . "\n";
991 if ($literalBlockStyle == '|') {
992 return $literalBlock . $line;
993 }
994 if (\strlen($line) == 0) {
995 return \rtrim($literalBlock, ' ') . "\n";
996 }
997 if ($line == "\n" && $literalBlockStyle == '>') {
998 return \rtrim($literalBlock, " \t") . "\n";
999 }
1000 if ($line != "\n") {
1001 $line = \trim($line, "\r\n ") . " ";
1002 }
1003 return $literalBlock . $line;
1004 }
1005 function revertLiteralPlaceHolder($lineArray, $literalBlock)
1006 {
1007 foreach ($lineArray as $k => $_) {
1008 if (\is_array($_)) {
1009 $lineArray[$k] = $this->revertLiteralPlaceHolder($_, $literalBlock);
1010 } else {
1011 if (\substr($_, -1 * \strlen($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder) {
1012 $lineArray[$k] = \rtrim($literalBlock, " \r\n");
1013 }
1014 }
1015 }
1016 return $lineArray;
1017 }
1018 private static function stripIndent($line, $indent = -1)
1019 {
1020 if ($indent == -1) {
1021 $indent = \strlen($line) - \strlen(\ltrim($line));
1022 }
1023 return \substr($line, $indent);
1024 }
1025 private function getParentPathByIndent($indent)
1026 {
1027 if ($indent == 0) {
1028 return array();
1029 }
1030 $linePath = $this->path;
1031 do {
1032 \end($linePath);
1033 $lastIndentInParentPath = \key($linePath);
1034 if ($indent <= $lastIndentInParentPath) {
1035 \array_pop($linePath);
1036 }
1037 } while ($indent <= $lastIndentInParentPath);
1038 return $linePath;
1039 }
1040 private function clearBiggerPathValues($indent)
1041 {
1042 if ($indent == 0) {
1043 $this->path = array();
1044 }
1045 if (empty($this->path)) {
1046 return \true;
1047 }
1048 foreach ($this->path as $k => $_) {
1049 if ($k > $indent) {
1050 unset($this->path[$k]);
1051 }
1052 }
1053 return \true;
1054 }
1055 private static function isComment($line)
1056 {
1057 if (!$line) {
1058 return \false;
1059 }
1060 if ($line[0] == '#') {
1061 return \true;
1062 }
1063 if (\trim($line, " \r\n\t") == '---') {
1064 return \true;
1065 }
1066 return \false;
1067 }
1068 private static function isEmpty($line)
1069 {
1070 return \trim($line) === '';
1071 }
1072 private function isArrayElement($line)
1073 {
1074 if (!$line || !\is_scalar($line)) {
1075 return \false;
1076 }
1077 if (\substr($line, 0, 2) != '- ') {
1078 return \false;
1079 }
1080 if (\strlen($line) > 3) {
1081 if (\substr($line, 0, 3) == '---') {
1082 return \false;
1083 }
1084 }
1085 return \true;
1086 }
1087 private function isHashElement($line)
1088 {
1089 return \strpos($line, ':');
1090 }
1091 private function isLiteral($line)
1092 {
1093 if ($this->isArrayElement($line)) {
1094 return \false;
1095 }
1096 if ($this->isHashElement($line)) {
1097 return \false;
1098 }
1099 return \true;
1100 }
1101 private static function unquote($value)
1102 {
1103 if (!$value) {
1104 return $value;
1105 }
1106 if (!\is_string($value)) {
1107 return $value;
1108 }
1109 if ($value[0] == '\'') {
1110 return \trim($value, '\'');
1111 }
1112 if ($value[0] == '"') {
1113 return \trim($value, '"');
1114 }
1115 return $value;
1116 }
1117 private function startsMappedSequence($line)
1118 {
1119 return \substr($line, 0, 2) == '- ' && \substr($line, -1, 1) == ':';
1120 }
1121 private function returnMappedSequence($line)
1122 {
1123 $array = array();
1124 $key = self::unquote(\trim(\substr($line, 1, -1)));
1125 $array[$key] = array();
1126 $this->delayedPath = array(\strpos($line, $key) + $this->indent => $key);
1127 return array($array);
1128 }
1129 private function checkKeysInValue($value)
1130 {
1131 if (\strchr('[{"\'', $value[0]) === \false) {
1132 if (\strchr($value, ': ') !== \false) {
1133 throw new \Exception('Too many keys: ' . $value);
1134 }
1135 }
1136 }
1137 private function returnMappedValue($line)
1138 {
1139 $this->checkKeysInValue($line);
1140 $array = array();
1141 $key = self::unquote(\trim(\substr($line, 0, -1)));
1142 $array[$key] = '';
1143 return $array;
1144 }
1145 private function startsMappedValue($line)
1146 {
1147 return \substr($line, -1, 1) == ':';
1148 }
1149 private function isPlainArray($line)
1150 {
1151 return $line[0] == '[' && \substr($line, -1, 1) == ']';
1152 }
1153 private function returnPlainArray($line)
1154 {
1155 return $this->_toType($line);
1156 }
1157 private function returnKeyValuePair($line)
1158 {
1159 $array = array();
1160 $key = '';
1161 if (\strpos($line, ': ')) {
1162 // It's a key/value pair most likely
1163 // If the key is in double quotes pull it out
1164 if (($line[0] == '"' || $line[0] == "'") && \preg_match('/^(["\'](.*)["\'](\\s)*:)/', $line, $matches)) {
1165 $value = \trim(\str_replace($matches[1], '', $line));
1166 $key = $matches[2];
1167 } else {
1168 // Do some guesswork as to the key and the value
1169 $explode = \explode(': ', $line);
1170 $key = \trim(\array_shift($explode));
1171 $value = \trim(\implode(': ', $explode));
1172 $this->checkKeysInValue($value);
1173 }
1174 // Set the type of the value. Int, string, etc
1175 $value = $this->_toType($value);
1176 if ($key === '0') {
1177 $key = '__!YAMLZero';
1178 }
1179 $array[$key] = $value;
1180 } else {
1181 $array = array($line);
1182 }
1183 return $array;
1184 }
1185 private function returnArrayElement($line)
1186 {
1187 if (\strlen($line) <= 1) {
1188 return array(array());
1189 }
1190 // Weird %)
1191 $array = array();
1192 $value = \trim(\substr($line, 1));
1193 $value = $this->_toType($value);
1194 if ($this->isArrayElement($value)) {
1195 $value = $this->returnArrayElement($value);
1196 }
1197 $array[] = $value;
1198 return $array;
1199 }
1200 private function nodeContainsGroup($line)
1201 {
1202 $symbolsForReference = 'A-z0-9_\\-';
1203 if (\strpos($line, '&') === \false && \strpos($line, '*') === \false) {
1204 return \false;
1205 }
1206 // Please die fast ;-)
1207 if ($line[0] == '&' && \preg_match('/^(&[' . $symbolsForReference . ']+)/', $line, $matches)) {
1208 return $matches[1];
1209 }
1210 if ($line[0] == '*' && \preg_match('/^(\\*[' . $symbolsForReference . ']+)/', $line, $matches)) {
1211 return $matches[1];
1212 }
1213 if (\preg_match('/(&[' . $symbolsForReference . ']+)$/', $line, $matches)) {
1214 return $matches[1];
1215 }
1216 if (\preg_match('/(\\*[' . $symbolsForReference . ']+$)/', $line, $matches)) {
1217 return $matches[1];
1218 }
1219 if (\preg_match('#^\\s*<<\\s*:\\s*(\\*[^\\s]+).*$#', $line, $matches)) {
1220 return $matches[1];
1221 }
1222 return \false;
1223 }
1224 private function addGroup($line, $group)
1225 {
1226 if ($group[0] == '&') {
1227 $this->_containsGroupAnchor = \substr($group, 1);
1228 }
1229 if ($group[0] == '*') {
1230 $this->_containsGroupAlias = \substr($group, 1);
1231 }
1232 //print_r ($this->path);
1233 }
1234 private function stripGroup($line, $group)
1235 {
1236 $line = \trim(\str_replace($group, '', $line));
1237 return $line;
1238 }
1239 }
1240 }
1241 // Enable use of Spyc from command line
1242 // The syntax is the following: php Spyc.php spyc.yaml
1243 do {
1244 if (\PHP_SAPI != 'cli') {
1245 break;
1246 }
1247 if (empty($_SERVER['argc']) || $_SERVER['argc'] < 2) {
1248 break;
1249 }
1250 if (empty($_SERVER['PHP_SELF']) || \FALSE === \strpos($_SERVER['PHP_SELF'], 'Spyc.php')) {
1251 break;
1252 }
1253 $file = $argv[1];
1254 echo \json_encode(\spyc_load_file($file));
1255 } while (0);
1256 }
1257