From 9bd17966b1ad8e8aa5645e927434004490b0c690 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 5 Aug 2009 02:57:11 +0000 Subject: [PATCH] Add support for using bash's built-in readline or equivalent for single-line input editing in eval.php etc, if the PHP readline extension is not available. This is handy when running on Mac OS X with Apple's default PHP installation... If bash cannot be found, will fall back to the fgets() we did before -- a horrible realm in which arrow keys and backspace don't work. Note that this isn't quite as good as full readline support, since we don't get to retain entry history. --- install-utils.inc | 92 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 5 deletions(-) diff --git a/install-utils.inc b/install-utils.inc index 0e3ebc0ef3..78a33b2c06 100644 --- a/install-utils.inc +++ b/install-utils.inc @@ -83,18 +83,100 @@ function readconsole( $prompt = '' ) { return readline( $prompt ); } else { if ( $isatty ) { - print $prompt; - } - if ( feof( STDIN ) ) { - return false; + $st = readlineEmulation( $prompt ); + } else { + if ( feof( STDIN ) ) { + $st = false; + } else { + $st = fgets(STDIN, 1024); + } } - $st = fgets(STDIN, 1024); if ($st === false) return false; $resp = trim( $st ); return $resp; } } +function findExecutable( $name ) { + $paths = explode( PATH_SEPARATOR, getenv( "PATH" ) ); + foreach( $paths as $path ) { + $full = $path . DIRECTORY_SEPARATOR . $name; + if( file_exists( $full ) ) { + if( wfIsWindows() || is_executable( $full ) ) { + return $full; + } + } + } + return false; +} + +function readlineEmulation( $prompt ) { + $bash = "xbash"; + if( !wfIsWindows() && findExecutable( $bash ) ) { + $retval = false; + $encPrompt = wfEscapeShellArg( $prompt ); + $command = "read -er -p $encPrompt && echo \"\$REPLY\""; + $encCommand = wfEscapeShellArg( $command ); + $line = wfShellExec( "$bash -c $encCommand", $retval ); + + if( $retval == 0 ) { + return $line; + } elseif( $retval == 127 ) { + // Couldn't execute bash even though we thought we saw it. + // Shell probably spit out an error message, sorry :( + // Fall through to fgets()... + } else { + // EOF/ctrl+D + return false; + } + } + + // Fallback... we'll have no editing controls, EWWW + if ( feof( STDIN ) ) { + return false; + } + print $prompt; + return fgets(STDIN, 1024); +} + +function readlineEmulationX() { + // Yes this is GODAWFUL. But it's better than nothing. + $chars = array(); + while( true ) { + if( feof( STDIN ) ) { + // ctrl+D? + echo "[eof]"; + break; + } + $inchar = fread( STDIN, 1 ); + + // Horrible hack... assume input is UTF-8 + $inbyte = ord( $inchar ); + if( $inbyte >= 0xf0 ) { + $remaining = 3; + } elseif( $inbyte >= 0xe0 ) { + $remaining = 2; + } elseif( $inbyte >= 0xc0 ) { + $remaining = 1; + } else { + $remaining = 0; + } + if( $remaining ) { + $inchar .= fread( STDIN, $remaining ); + } + + if( $inchar == "\n" ) { + // newline + echo "[newline]"; + break; + } + + $chars[] = $inchar; + echo "[char: $inchar]"; + } + return implode( '', $chars ); +} + # # Read and execute SQL commands from a file # -- 2.20.1