summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2006-06-16 17:49:06 +0200
committerAndreas Gohr <andi@splitbrain.org>2006-06-16 17:49:06 +0200
commit63cb5853ff174b45e697ea0818816060805503aa (patch)
treeba3f541e18cca2976be0216c3b767099675d2454 /inc
parent11e384f72d646266f90cc7ff18c59dea58fd30c7 (diff)
downloadrpg-63cb5853ff174b45e697ea0818816060805503aa.tar.gz
rpg-63cb5853ff174b45e697ea0818816060805503aa.tar.bz2
aspell fix #836
darcs-hash:20060616154906-7ad00-6ace887070a70fda5f898f241aebb639230b53d8.gz
Diffstat (limited to 'inc')
-rw-r--r--inc/aspell.php168
-rw-r--r--inc/common.php15
2 files changed, 123 insertions, 60 deletions
diff --git a/inc/aspell.php b/inc/aspell.php
index 0cf519b43..8c033e2c8 100644
--- a/inc/aspell.php
+++ b/inc/aspell.php
@@ -163,75 +163,123 @@ class Aspell{
* @link http://aspell.sf.net/man-html/Through-A-Pipe.html
*/
function runAspell($text,&$out,&$err,$specials=null){
- $this->_prepareArgs();
if(empty($text)) return true;
- //prepare file descriptors
- $descspec = array(
- 0 => array('pipe', 'r'), // stdin is a pipe that the child will read from
- 1 => array('pipe', 'w'), // stdout is a pipe that the child will write to
- 2 => array('pipe', 'w') // stderr is a file to write to
- );
-
- $process = proc_open(ASPELL_BIN.' -a'.$this->args, $descspec, $pipes);
- $terse = 1; // terse mode active
- if ($process) {
- // write specials if given
- if(is_array($specials)){
- foreach($specials as $s){
- if ($s == '!') $terse = 0;
- fwrite($pipes[0],"$s\n");
- }
+ $terse = true;
+
+ // prepare arguments
+ $this->_prepareArgs();
+ $command = ASPELL_BIN.' -a'.$this->args;
+ $stdin = '';
+
+ // prepare specials
+ if(is_array($specials)){
+ foreach($specials as $s){
+ if ($s == '!') $terse = false;
+ $stdin .= "$s\n";
}
+ }
- // prepare text for Aspell and handle it over
- $string = "^".str_replace("\n", "\n^",$text);
- fwrite($pipes[0],$string); // send text to Aspell
- fclose($pipes[0]);
+ // prepare text
+ $stdin .= "^".str_replace("\n", "\n^",$text);
- // read Aspells response from stdin
- while (!feof($pipes[1])) {
- $out .= fread($pipes[1], 8192);
- }
- fclose($pipes[1]);
-
- // Aspell has a bug that can't be autodetected because both versions
- // might produce the same output but under different conditions. So
- // we check Aspells version number here to divide broken and working
- // versions of Aspell.
- $tmp = array();
- preg_match('/^\@.*Aspell (\d+)\.(\d+).(\d+)/',$out,$tmp);
- $this->version = $tmp[1]*100 + $tmp[2]*10 + $tmp[3];
-
- if ($this->version <= 603) // version 0.60.3
- $r = $terse ? "\n*\n\$1" : "\n\$1"; // replacement for broken Aspell
- else
- $r = $terse ? "\n*\n" : "\n"; // replacement for good Aspell
-
- // lines starting with a '?' are no realy misspelled words and some
- // Aspell versions doesn't produce usable output anyway so we filter
- // them out here.
- $out = preg_replace('/\n\? [^\n\&\*]*([\n]?)/',$r, $out);
-
- // read stderr
- while (!feof($pipes[2])) {
- $err .= fread($pipes[2], 8192);
+ // run aspell through the pipe
+ $rc = $this->execPipe($command,$stdin,$out,$err);
+ if(is_null($rc)){
+ $err = "Could not run Aspell '".ASPELL_BIN."'";
+ return false;
+ }
+
+ // Aspell has a bug that can't be autodetected because both versions
+ // might produce the same output but under different conditions. So
+ // we check Aspells version number here to divide broken and working
+ // versions of Aspell.
+ $tmp = array();
+ preg_match('/^\@.*Aspell (\d+)\.(\d+).(\d+)/',$out,$tmp);
+ $this->version = $tmp[1]*100 + $tmp[2]*10 + $tmp[3];
+
+ if ($this->version <= 603) // version 0.60.3
+ $r = $terse ? "\n*\n\$1" : "\n\$1"; // replacement for broken Aspell
+ else
+ $r = $terse ? "\n*\n" : "\n"; // replacement for good Aspell
+
+ // lines starting with a '?' are no realy misspelled words and some
+ // Aspell versions doesn't produce usable output anyway so we filter
+ // them out here.
+ $out = preg_replace('/\n\? [^\n\&\*]*([\n]?)/',$r, $out);
+
+ if ($err){
+ //something went wrong
+ $err = "Aspell returned an error(".ASPELL_BIN." exitcode: $rc ):\n".$err;
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * Runs the given command with the given input on STDIN
+ *
+ * STDOUT and STDERR are written to the given vars, the command's
+ * exit code is returned. If the pip couldn't be opened null is returned
+ *
+ * @author <richard at 2006 dot atterer dot net>
+ * @link http://www.php.net/manual/en/function.proc-open.php#64116
+ */
+ function execPipe($command,$stdin,&$stdout,&$stderr){
+ $descriptorSpec = array(0 => array("pipe", "r"),
+ 1 => array('pipe', 'w'),
+ 2 => array('pipe', 'w'));
+ $process = proc_open($command, $descriptorSpec, $pipes);
+ if(!$process) return null;
+
+ $txOff = 0;
+ $txLen = strlen($stdin);
+ $stdoutDone = FALSE;
+ $stderrDone = FALSE;
+
+ stream_set_blocking($pipes[0], 0); // Make stdin/stdout/stderr non-blocking
+ stream_set_blocking($pipes[1], 0);
+ stream_set_blocking($pipes[2], 0);
+
+ if ($txLen == 0) fclose($pipes[0]);
+ while (TRUE) {
+ $rx = array(); // The program's stdout/stderr
+ if (!$stdoutDone) $rx[] = $pipes[1];
+ if (!$stderrDone) $rx[] = $pipes[2];
+ $tx = array(); // The program's stdin
+ if ($txOff < $txLen) $tx[] = $pipes[0];
+ stream_select($rx, $tx, $ex = NULL, NULL, NULL); // Block til r/w possible
+
+ if (!empty($tx)) {
+ $txRet = fwrite($pipes[0], substr($stdin, $txOff, 8192));
+ if ($txRet !== FALSE) $txOff += $txRet;
+ if ($txOff >= $txLen) fclose($pipes[0]);
}
- fclose($pipes[2]);
-
- // close process
- $rc = proc_close($process);
- if ($err){
- //something went wrong
- $err = "Aspell returned an error(".ASPELL_BIN." exitcode: $rc ):\n".$err;
- return false;
+
+ foreach ($rx as $r) {
+ if ($r == $pipes[1]) {
+ $stdout .= fread($pipes[1], 8192);
+ if (feof($pipes[1])) {
+ fclose($pipes[1]);
+ $stdoutDone = TRUE;
+ }
+ } else if ($r == $pipes[2]) {
+ $stderr .= fread($pipes[2], 8192);
+ if (feof($pipes[2])) {
+ fclose($pipes[2]);
+ $stderrDone = TRUE;
+ }
+ }
}
- return true;
+ if (!is_resource($process)) break;
+ if ($txOff >= $txLen && $stdoutDone && $stderrDone) break;
}
- //opening failed
- $err = "Could not run Aspell '".ASPELL_BIN."'";
- return false;
+ return proc_close($process);
}
+
+
+
/**
* Checks a single word for correctness
*
diff --git a/inc/common.php b/inc/common.php
index 975c70098..e47b4e7a3 100644
--- a/inc/common.php
+++ b/inc/common.php
@@ -695,6 +695,21 @@ function dbg($msg,$hidden=false){
}
/**
+ * Print info to a log file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function dbglog($msg){
+ global $conf;
+ $file = $conf['cachedir'].'/debug.log';
+ $fh = fopen($file,'a');
+ if($fh){
+ fwrite($fh,date('H:i:s ').$_SERVER['REMOTE_ADDR'].': '.$msg."\n");
+ fclose($fh);
+ }
+}
+
+/**
* Add's an entry to the changelog
*
* @author Andreas Gohr <andi@splitbrain.org>