summaryrefslogtreecommitdiff
path: root/src/server/PGFService.hs
diff options
context:
space:
mode:
authorkrasimir <krasimir@chalmers.se>2010-04-22 14:01:08 +0000
committerkrasimir <krasimir@chalmers.se>2010-04-22 14:01:08 +0000
commite3a279e457c8159c07db2db652dbe151afb51f36 (patch)
treec3cf73a14297d7c40288b7403f4d778282032a6b /src/server/PGFService.hs
parentba7467a550b83c942fbeb414667697337d3ca3a9 (diff)
now the PGF service communicates with Graphviz using UTF8 for the input and binary for the output
Diffstat (limited to 'src/server/PGFService.hs')
-rw-r--r--src/server/PGFService.hs45
1 files changed, 39 insertions, 6 deletions
diff --git a/src/server/PGFService.hs b/src/server/PGFService.hs
index 0ee7391e2..7a57bba81 100644
--- a/src/server/PGFService.hs
+++ b/src/server/PGFService.hs
@@ -9,8 +9,10 @@ import URLEncoding
import Network.FastCGI
import Text.JSON
import qualified Codec.Binary.UTF8.String as UTF8 (encodeString, decodeString)
+import qualified Data.ByteString.Lazy as BS
import Control.Concurrent
+import Control.Exception
import Control.Monad
import Data.Char
import Data.Function (on)
@@ -20,6 +22,8 @@ import Data.Maybe
import System.Directory
import System.FilePath
import System.Process
+import System.Exit
+import System.IO
logFile :: FilePath
logFile = "pgf-error.log"
@@ -206,16 +210,45 @@ doGrammar pgf macc = showJSON $ toJSObject
functions = [PGF.showCId fun | fun <- PGF.functions pgf]
doGraphvizAbstrTree pgf tree = do
- let dot = PGF.graphvizAbstractTree pgf (True,True) tree
- readProcess "dot" ["-T","png"] dot
+ pipeIt2graphviz $ PGF.graphvizAbstractTree pgf (True,True) tree
doGraphvizParseTree pgf lang tree = do
- let dot = PGF.graphvizParseTree pgf lang tree
- readProcess "dot" ["-T","png"] (UTF8.encodeString dot)
+ pipeIt2graphviz $ PGF.graphvizParseTree pgf lang tree
doGraphvizAlignment pgf tree = do
- let dot = PGF.graphvizAlignment pgf tree
- readProcess "dot" ["-T","png"] (UTF8.encodeString dot)
+ pipeIt2graphviz $ PGF.graphvizAlignment pgf tree
+
+pipeIt2graphviz :: String -> IO BS.ByteString
+pipeIt2graphviz code = do
+ (Just inh, Just outh, _, pid) <-
+ createProcess (proc "dot" ["-T","png"])
+ { std_in = CreatePipe,
+ std_out = CreatePipe,
+ std_err = Inherit }
+
+ hSetEncoding outh latin1
+ hSetEncoding inh utf8
+
+ -- fork off a thread to start consuming the output
+ output <- BS.hGetContents outh
+ outMVar <- newEmptyMVar
+ _ <- forkIO $ evaluate (BS.length output) >> putMVar outMVar ()
+
+ -- now write and flush any input
+ hPutStr inh code
+ hFlush inh
+ hClose inh -- done with stdin
+
+ -- wait on the output
+ takeMVar outMVar
+ hClose outh
+
+ -- wait on the process
+ ex <- waitForProcess pid
+
+ case ex of
+ ExitSuccess -> return output
+ ExitFailure r -> fail ("pipeIt2graphviz: (exit " ++ show r ++ ")")
doBrowse pgf id cssClass href =
case PGF.browse pgf id of