@@ -9,6 +9,7 @@ module Data.Terminfo.Parse ( module Data.Terminfo.Parse
99 )
1010 where
1111
12+import Control.Applicative ( Applicative(..), pure, (<*>) )
1213import Control.Monad ( liftM )
1314import Control.Monad.Trans
1415import Control.Parallel.Strategies
@@ -17,11 +18,14 @@ import Data.Array.Unboxed
1718import Data.Monoid
1819import Data.Word
1920
21+import Foreign.Marshal.Array
22+import Foreign.Ptr
23+
2024import Text.ParserCombinators.Parsec
2125
2226type BytesLength = Word8
2327type BytesOffset = Word8
24−type CapBytes = UArray Word8 Word8
28+type CapBytes = ( Ptr Word8, Word )
2529
2630data CapExpression = CapExpression
2731 { cap_ops :: !CapOps
@@ -67,7 +71,11 @@ data ParamOp =
6771 IncFirstTwo
6872 deriving ( Show )
6973
70−parse_cap_expression :: MonadIO m => String -> m ( Either ParseError CapExpression )
74+parse_cap_expression :: ( Applicative m
75+ , MonadIO m
76+ )
77+ => String
78+ -> m ( Either ParseError CapExpression )
7179parse_cap_expression cap_string =
7280 let v = runParser cap_expression_parser
7381 initial_build_state
@@ -75,21 +83,20 @@ parse_cap_expression cap_string =
7583 cap_string
7684 in case v of
7785 Left e -> return $ Left e
78− Right build_results ->
79− return
80− $! Right
81− $! ( CapExpression
82− { cap_ops = out_cap_ops build_results
83− -- The cap bytes are the lower 8 bits of the input string's characters.
84− -- \todo Verify the input string actually contains an 8bit byte per character.
85− , cap_bytes = listArray (0, toEnum $ length cap_string - 1)
86− $ map (toEnum . fromEnum) cap_string
87− , source_string = cap_string
88− , param_count = out_param_count build_results
89− , param_ops = out_param_ops build_results
90− }
91− `using` rdeepseq
92− )
86+ Right build_results -> pure Right <*> construct_cap_expression cap_string build_results
87+
88+construct_cap_expression cap_string build_results = do
89+ byte_array <- liftIO $ newArray (map ( toEnum . fromEnum ) cap_string )
90+ let expr = CapExpression
91+ { cap_ops = out_cap_ops build_results
92+ -- The cap bytes are the lower 8 bits of the input string's characters.
93+ -- \todo Verify the input string actually contains an 8bit byte per character.
94+ , cap_bytes = ( byte_array, toEnum $! length cap_string )
95+ , source_string = cap_string
96+ , param_count = out_param_count build_results
97+ , param_ops = out_param_ops build_results
98+ }
99+ return $! expr `using` rdeepseq
93100
94101type CapParser a = GenParser Char BuildState a
95102