@@ -21,27 +21,43 @@ class Shell {
2121 /**
2222 * Returns the number of columns the current shell has for display.
2323 *
24+ * @param mixed $test For testing only.
25+ *
2426 * @return int The number of columns.
2527 * @todo Test on more systems.
2628 */
27- static public function columns () {
29+ static public function columns ( $ test = null ) {
2830 static $ columns ;
2931
32+ if ( null !== $ test ) {
33+ $ columns = null ;
34+ }
3035 if ( null === $ columns ) {
31- if (self ::is_windows () ) {
32- $ output = array ();
33- exec ('mode CON ' , $ output );
34- foreach ($ output as $ line ) {
35- if (preg_match ('/Columns:( )*([0-9]+)/ ' , $ line , $ matches )) {
36- $ columns = (int )$ matches [2 ];
37- break ;
36+ if ( function_exists ( 'exec ' ) ) {
37+ if ( self ::is_windows ( 'WIN ' === $ test ) ) {
38+ // Cater for shells such as Cygwin and Git bash where `mode CON` returns an incorrect value for columns.
39+ if ( ( $ shell = getenv ( 'SHELL ' ) ) && preg_match ( '/(?:bash|zsh)(?:.exe)?$/ ' , $ shell ) && getenv ( 'TERM ' ) ) {
40+ $ columns = (int ) exec ( 'tput cols ' );
41+ }
42+ if ( ! $ columns ) {
43+ $ return_var = -1 ;
44+ $ output = array ();
45+ exec ( 'mode CON ' , $ output , $ return_var );
46+ if ( 0 === $ return_var && $ output ) {
47+ // Look for second line ending in ": <number>" (searching for "Columns:" will fail on non-English locales).
48+ if ( preg_match ( '/:\s*[0-9]+\n[^:]+:\s*([0-9]+)\n/ ' , implode ( "\n" , $ output ), $ matches ) ) {
49+ $ columns = (int ) $ matches [1 ];
50+ }
51+ }
52+ }
53+ } else {
54+ if ( getenv ( 'TERM ' ) ) {
55+ $ columns = (int ) exec ( '/usr/bin/env tput cols ' );
3856 }
3957 }
40- } else if (!preg_match ('/(^|,)(\s*)?exec(\s*)?(,|$)/ ' , ini_get ('disable_functions ' ))) {
41- $ columns = (int ) exec ('/usr/bin/env tput cols ' );
4258 }
4359
44- if ( !$ columns ) {
60+ if ( ! $ columns ) {
4561 $ columns = 80 ; // default width of cmd window on Windows OS
4662 }
4763 }
0 commit comments