summaryrefslogtreecommitdiff
path: root/vendor/symfony/console/Terminal.php
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2024-08-13 23:45:21 +0200
committerpolo <ordipolo@gmx.fr>2024-08-13 23:45:21 +0200
commitbf6655a534a6775d30cafa67bd801276bda1d98d (patch)
treec6381e3f6c81c33eab72508f410b165ba05f7e9c /vendor/symfony/console/Terminal.php
parent94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff)
downloadAppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.zip
VERSION 0.2 doctrine ORM et entités
Diffstat (limited to 'vendor/symfony/console/Terminal.php')
-rw-r--r--vendor/symfony/console/Terminal.php228
1 files changed, 228 insertions, 0 deletions
diff --git a/vendor/symfony/console/Terminal.php b/vendor/symfony/console/Terminal.php
new file mode 100644
index 0000000..9eb16aa
--- /dev/null
+++ b/vendor/symfony/console/Terminal.php
@@ -0,0 +1,228 @@
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Console;
13
14use Symfony\Component\Console\Output\AnsiColorMode;
15
16class Terminal
17{
18 public const DEFAULT_COLOR_MODE = AnsiColorMode::Ansi4;
19
20 private static ?AnsiColorMode $colorMode = null;
21 private static ?int $width = null;
22 private static ?int $height = null;
23 private static ?bool $stty = null;
24
25 /**
26 * About Ansi color types: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
27 * For more information about true color support with terminals https://github.com/termstandard/colors/.
28 */
29 public static function getColorMode(): AnsiColorMode
30 {
31 // Use Cache from previous run (or user forced mode)
32 if (null !== self::$colorMode) {
33 return self::$colorMode;
34 }
35
36 // Try with $COLORTERM first
37 if (\is_string($colorterm = getenv('COLORTERM'))) {
38 $colorterm = strtolower($colorterm);
39
40 if (str_contains($colorterm, 'truecolor')) {
41 self::setColorMode(AnsiColorMode::Ansi24);
42
43 return self::$colorMode;
44 }
45
46 if (str_contains($colorterm, '256color')) {
47 self::setColorMode(AnsiColorMode::Ansi8);
48
49 return self::$colorMode;
50 }
51 }
52
53 // Try with $TERM
54 if (\is_string($term = getenv('TERM'))) {
55 $term = strtolower($term);
56
57 if (str_contains($term, 'truecolor')) {
58 self::setColorMode(AnsiColorMode::Ansi24);
59
60 return self::$colorMode;
61 }
62
63 if (str_contains($term, '256color')) {
64 self::setColorMode(AnsiColorMode::Ansi8);
65
66 return self::$colorMode;
67 }
68 }
69
70 self::setColorMode(self::DEFAULT_COLOR_MODE);
71
72 return self::$colorMode;
73 }
74
75 /**
76 * Force a terminal color mode rendering.
77 */
78 public static function setColorMode(?AnsiColorMode $colorMode): void
79 {
80 self::$colorMode = $colorMode;
81 }
82
83 /**
84 * Gets the terminal width.
85 */
86 public function getWidth(): int
87 {
88 $width = getenv('COLUMNS');
89 if (false !== $width) {
90 return (int) trim($width);
91 }
92
93 if (null === self::$width) {
94 self::initDimensions();
95 }
96
97 return self::$width ?: 80;
98 }
99
100 /**
101 * Gets the terminal height.
102 */
103 public function getHeight(): int
104 {
105 $height = getenv('LINES');
106 if (false !== $height) {
107 return (int) trim($height);
108 }
109
110 if (null === self::$height) {
111 self::initDimensions();
112 }
113
114 return self::$height ?: 50;
115 }
116
117 /**
118 * @internal
119 */
120 public static function hasSttyAvailable(): bool
121 {
122 if (null !== self::$stty) {
123 return self::$stty;
124 }
125
126 // skip check if shell_exec function is disabled
127 if (!\function_exists('shell_exec')) {
128 return false;
129 }
130
131 return self::$stty = (bool) shell_exec('stty 2> '.('\\' === \DIRECTORY_SEPARATOR ? 'NUL' : '/dev/null'));
132 }
133
134 private static function initDimensions(): void
135 {
136 if ('\\' === \DIRECTORY_SEPARATOR) {
137 $ansicon = getenv('ANSICON');
138 if (false !== $ansicon && preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim($ansicon), $matches)) {
139 // extract [w, H] from "wxh (WxH)"
140 // or [w, h] from "wxh"
141 self::$width = (int) $matches[1];
142 self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
143 } elseif (!sapi_windows_vt100_support(fopen('php://stdout', 'w')) && self::hasSttyAvailable()) {
144 // only use stty on Windows if the terminal does not support vt100 (e.g. Windows 7 + git-bash)
145 // testing for stty in a Windows 10 vt100-enabled console will implicitly disable vt100 support on STDOUT
146 self::initDimensionsUsingStty();
147 } elseif (null !== $dimensions = self::getConsoleMode()) {
148 // extract [w, h] from "wxh"
149 self::$width = (int) $dimensions[0];
150 self::$height = (int) $dimensions[1];
151 }
152 } else {
153 self::initDimensionsUsingStty();
154 }
155 }
156
157 /**
158 * Initializes dimensions using the output of an stty columns line.
159 */
160 private static function initDimensionsUsingStty(): void
161 {
162 if ($sttyString = self::getSttyColumns()) {
163 if (preg_match('/rows.(\d+);.columns.(\d+);/is', $sttyString, $matches)) {
164 // extract [w, h] from "rows h; columns w;"
165 self::$width = (int) $matches[2];
166 self::$height = (int) $matches[1];
167 } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/is', $sttyString, $matches)) {
168 // extract [w, h] from "; h rows; w columns"
169 self::$width = (int) $matches[2];
170 self::$height = (int) $matches[1];
171 }
172 }
173 }
174
175 /**
176 * Runs and parses mode CON if it's available, suppressing any error output.
177 *
178 * @return int[]|null An array composed of the width and the height or null if it could not be parsed
179 */
180 private static function getConsoleMode(): ?array
181 {
182 $info = self::readFromProcess('mode CON');
183
184 if (null === $info || !preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
185 return null;
186 }
187
188 return [(int) $matches[2], (int) $matches[1]];
189 }
190
191 /**
192 * Runs and parses stty -a if it's available, suppressing any error output.
193 */
194 private static function getSttyColumns(): ?string
195 {
196 return self::readFromProcess(['stty', '-a']);
197 }
198
199 private static function readFromProcess(string|array $command): ?string
200 {
201 if (!\function_exists('proc_open')) {
202 return null;
203 }
204
205 $descriptorspec = [
206 1 => ['pipe', 'w'],
207 2 => ['pipe', 'w'],
208 ];
209
210 $cp = \function_exists('sapi_windows_cp_set') ? sapi_windows_cp_get() : 0;
211
212 $process = proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
213 if (!\is_resource($process)) {
214 return null;
215 }
216
217 $info = stream_get_contents($pipes[1]);
218 fclose($pipes[1]);
219 fclose($pipes[2]);
220 proc_close($process);
221
222 if ($cp) {
223 sapi_windows_cp_set($cp);
224 }
225
226 return $info;
227 }
228}