annotate vendor/zendframework/zend-stdlib/src/Glob.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 7a779792577d
children
rev   line source
Chris@0 1 <?php
Chris@0 2 /**
Chris@0 3 * Zend Framework (http://framework.zend.com/)
Chris@0 4 *
Chris@0 5 * @link http://github.com/zendframework/zf2 for the canonical source repository
Chris@0 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
Chris@0 7 * @license http://framework.zend.com/license/new-bsd New BSD License
Chris@0 8 */
Chris@0 9
Chris@0 10 namespace Zend\Stdlib;
Chris@0 11
Chris@0 12 /**
Chris@0 13 * Wrapper for glob with fallback if GLOB_BRACE is not available.
Chris@0 14 */
Chris@0 15 abstract class Glob
Chris@0 16 {
Chris@0 17 /**#@+
Chris@0 18 * Glob constants.
Chris@0 19 */
Chris@0 20 const GLOB_MARK = 0x01;
Chris@0 21 const GLOB_NOSORT = 0x02;
Chris@0 22 const GLOB_NOCHECK = 0x04;
Chris@0 23 const GLOB_NOESCAPE = 0x08;
Chris@0 24 const GLOB_BRACE = 0x10;
Chris@0 25 const GLOB_ONLYDIR = 0x20;
Chris@0 26 const GLOB_ERR = 0x40;
Chris@0 27 /**#@-*/
Chris@0 28
Chris@0 29 /**
Chris@0 30 * Find pathnames matching a pattern.
Chris@0 31 *
Chris@0 32 * @see http://docs.php.net/glob
Chris@0 33 * @param string $pattern
Chris@0 34 * @param int $flags
Chris@0 35 * @param bool $forceFallback
Chris@0 36 * @return array
Chris@0 37 * @throws Exception\RuntimeException
Chris@0 38 */
Chris@0 39 public static function glob($pattern, $flags = 0, $forceFallback = false)
Chris@0 40 {
Chris@12 41 if (! defined('GLOB_BRACE') || $forceFallback) {
Chris@0 42 return static::fallbackGlob($pattern, $flags);
Chris@0 43 }
Chris@0 44
Chris@0 45 return static::systemGlob($pattern, $flags);
Chris@0 46 }
Chris@0 47
Chris@0 48 /**
Chris@0 49 * Use the glob function provided by the system.
Chris@0 50 *
Chris@0 51 * @param string $pattern
Chris@0 52 * @param int $flags
Chris@0 53 * @return array
Chris@0 54 * @throws Exception\RuntimeException
Chris@0 55 */
Chris@0 56 protected static function systemGlob($pattern, $flags)
Chris@0 57 {
Chris@0 58 if ($flags) {
Chris@0 59 $flagMap = [
Chris@0 60 self::GLOB_MARK => GLOB_MARK,
Chris@0 61 self::GLOB_NOSORT => GLOB_NOSORT,
Chris@0 62 self::GLOB_NOCHECK => GLOB_NOCHECK,
Chris@0 63 self::GLOB_NOESCAPE => GLOB_NOESCAPE,
Chris@0 64 self::GLOB_BRACE => defined('GLOB_BRACE') ? GLOB_BRACE : 0,
Chris@0 65 self::GLOB_ONLYDIR => GLOB_ONLYDIR,
Chris@0 66 self::GLOB_ERR => GLOB_ERR,
Chris@0 67 ];
Chris@0 68
Chris@0 69 $globFlags = 0;
Chris@0 70
Chris@0 71 foreach ($flagMap as $internalFlag => $globFlag) {
Chris@0 72 if ($flags & $internalFlag) {
Chris@0 73 $globFlags |= $globFlag;
Chris@0 74 }
Chris@0 75 }
Chris@0 76 } else {
Chris@0 77 $globFlags = 0;
Chris@0 78 }
Chris@0 79
Chris@0 80 ErrorHandler::start();
Chris@0 81 $res = glob($pattern, $globFlags);
Chris@0 82 $err = ErrorHandler::stop();
Chris@0 83 if ($res === false) {
Chris@0 84 throw new Exception\RuntimeException("glob('{$pattern}', {$globFlags}) failed", 0, $err);
Chris@0 85 }
Chris@0 86 return $res;
Chris@0 87 }
Chris@0 88
Chris@0 89 /**
Chris@0 90 * Expand braces manually, then use the system glob.
Chris@0 91 *
Chris@0 92 * @param string $pattern
Chris@0 93 * @param int $flags
Chris@0 94 * @return array
Chris@0 95 * @throws Exception\RuntimeException
Chris@0 96 */
Chris@0 97 protected static function fallbackGlob($pattern, $flags)
Chris@0 98 {
Chris@12 99 if (! $flags & self::GLOB_BRACE) {
Chris@0 100 return static::systemGlob($pattern, $flags);
Chris@0 101 }
Chris@0 102
Chris@0 103 $flags &= ~self::GLOB_BRACE;
Chris@0 104 $length = strlen($pattern);
Chris@0 105 $paths = [];
Chris@0 106
Chris@0 107 if ($flags & self::GLOB_NOESCAPE) {
Chris@0 108 $begin = strpos($pattern, '{');
Chris@0 109 } else {
Chris@0 110 $begin = 0;
Chris@0 111
Chris@0 112 while (true) {
Chris@0 113 if ($begin === $length) {
Chris@0 114 $begin = false;
Chris@0 115 break;
Chris@0 116 } elseif ($pattern[$begin] === '\\' && ($begin + 1) < $length) {
Chris@0 117 $begin++;
Chris@0 118 } elseif ($pattern[$begin] === '{') {
Chris@0 119 break;
Chris@0 120 }
Chris@0 121
Chris@0 122 $begin++;
Chris@0 123 }
Chris@0 124 }
Chris@0 125
Chris@0 126 if ($begin === false) {
Chris@0 127 return static::systemGlob($pattern, $flags);
Chris@0 128 }
Chris@0 129
Chris@0 130 $next = static::nextBraceSub($pattern, $begin + 1, $flags);
Chris@0 131
Chris@0 132 if ($next === null) {
Chris@0 133 return static::systemGlob($pattern, $flags);
Chris@0 134 }
Chris@0 135
Chris@0 136 $rest = $next;
Chris@0 137
Chris@0 138 while ($pattern[$rest] !== '}') {
Chris@0 139 $rest = static::nextBraceSub($pattern, $rest + 1, $flags);
Chris@0 140
Chris@0 141 if ($rest === null) {
Chris@0 142 return static::systemGlob($pattern, $flags);
Chris@0 143 }
Chris@0 144 }
Chris@0 145
Chris@0 146 $p = $begin + 1;
Chris@0 147
Chris@0 148 while (true) {
Chris@0 149 $subPattern = substr($pattern, 0, $begin)
Chris@0 150 . substr($pattern, $p, $next - $p)
Chris@0 151 . substr($pattern, $rest + 1);
Chris@0 152
Chris@0 153 $result = static::fallbackGlob($subPattern, $flags | self::GLOB_BRACE);
Chris@0 154
Chris@0 155 if ($result) {
Chris@0 156 $paths = array_merge($paths, $result);
Chris@0 157 }
Chris@0 158
Chris@0 159 if ($pattern[$next] === '}') {
Chris@0 160 break;
Chris@0 161 }
Chris@0 162
Chris@0 163 $p = $next + 1;
Chris@0 164 $next = static::nextBraceSub($pattern, $p, $flags);
Chris@0 165 }
Chris@0 166
Chris@0 167 return array_unique($paths);
Chris@0 168 }
Chris@0 169
Chris@0 170 /**
Chris@0 171 * Find the end of the sub-pattern in a brace expression.
Chris@0 172 *
Chris@0 173 * @param string $pattern
Chris@0 174 * @param int $begin
Chris@0 175 * @param int $flags
Chris@0 176 * @return int|null
Chris@0 177 */
Chris@0 178 protected static function nextBraceSub($pattern, $begin, $flags)
Chris@0 179 {
Chris@0 180 $length = strlen($pattern);
Chris@0 181 $depth = 0;
Chris@0 182 $current = $begin;
Chris@0 183
Chris@0 184 while ($current < $length) {
Chris@12 185 if (! $flags & self::GLOB_NOESCAPE && $pattern[$current] === '\\') {
Chris@0 186 if (++$current === $length) {
Chris@0 187 break;
Chris@0 188 }
Chris@0 189
Chris@0 190 $current++;
Chris@0 191 } else {
Chris@0 192 if (($pattern[$current] === '}' && $depth-- === 0) || ($pattern[$current] === ',' && $depth === 0)) {
Chris@0 193 break;
Chris@0 194 } elseif ($pattern[$current++] === '{') {
Chris@0 195 $depth++;
Chris@0 196 }
Chris@0 197 }
Chris@0 198 }
Chris@0 199
Chris@0 200 return ($current < $length ? $current : null);
Chris@0 201 }
Chris@0 202 }