Nenhuma Descrição

Terminal.php 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Console;
  11. class Terminal
  12. {
  13. private static $width;
  14. private static $height;
  15. /**
  16. * Gets the terminal width.
  17. *
  18. * @return int
  19. */
  20. public function getWidth()
  21. {
  22. if ($width = trim(getenv('COLUMNS'))) {
  23. return (int) $width;
  24. }
  25. if (null === self::$width) {
  26. self::initDimensions();
  27. }
  28. return self::$width ?: 80;
  29. }
  30. /**
  31. * Gets the terminal height.
  32. *
  33. * @return int
  34. */
  35. public function getHeight()
  36. {
  37. if ($height = trim(getenv('LINES'))) {
  38. return (int) $height;
  39. }
  40. if (null === self::$height) {
  41. self::initDimensions();
  42. }
  43. return self::$height ?: 50;
  44. }
  45. private static function initDimensions()
  46. {
  47. if ('\\' === DIRECTORY_SEPARATOR) {
  48. if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) {
  49. // extract [w, H] from "wxh (WxH)"
  50. // or [w, h] from "wxh"
  51. self::$width = (int) $matches[1];
  52. self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
  53. } elseif (null !== $dimensions = self::getConsoleMode()) {
  54. // extract [w, h] from "wxh"
  55. self::$width = (int) $dimensions[0];
  56. self::$height = (int) $dimensions[1];
  57. }
  58. } elseif ($sttyString = self::getSttyColumns()) {
  59. if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
  60. // extract [w, h] from "rows h; columns w;"
  61. self::$width = (int) $matches[2];
  62. self::$height = (int) $matches[1];
  63. } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
  64. // extract [w, h] from "; h rows; w columns"
  65. self::$width = (int) $matches[2];
  66. self::$height = (int) $matches[1];
  67. }
  68. }
  69. }
  70. /**
  71. * Runs and parses mode CON if it's available, suppressing any error output.
  72. *
  73. * @return int[]|null An array composed of the width and the height or null if it could not be parsed
  74. */
  75. private static function getConsoleMode()
  76. {
  77. if (!function_exists('proc_open')) {
  78. return;
  79. }
  80. $descriptorspec = array(
  81. 1 => array('pipe', 'w'),
  82. 2 => array('pipe', 'w'),
  83. );
  84. $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
  85. if (is_resource($process)) {
  86. $info = stream_get_contents($pipes[1]);
  87. fclose($pipes[1]);
  88. fclose($pipes[2]);
  89. proc_close($process);
  90. if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
  91. return array((int) $matches[2], (int) $matches[1]);
  92. }
  93. }
  94. }
  95. /**
  96. * Runs and parses stty -a if it's available, suppressing any error output.
  97. *
  98. * @return string|null
  99. */
  100. private static function getSttyColumns()
  101. {
  102. if (!function_exists('proc_open')) {
  103. return;
  104. }
  105. $descriptorspec = array(
  106. 1 => array('pipe', 'w'),
  107. 2 => array('pipe', 'w'),
  108. );
  109. $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
  110. if (is_resource($process)) {
  111. $info = stream_get_contents($pipes[1]);
  112. fclose($pipes[1]);
  113. fclose($pipes[2]);
  114. proc_close($process);
  115. return $info;
  116. }
  117. }
  118. }