{-# LANGUAGE OverloadedStrings, RankNTypes #-}
-- | A front-end to run Hpp with textual arguments as from a command
-- line invocation.
module Hpp.CmdLine (runWithArgs) where
import Control.Monad (unless)
import Control.Monad.Trans.Except (runExceptT)
import Data.String (fromString)
import Hpp
import Hpp.Config
import Hpp.Env (deleteKey, emptyEnv, insertPair)
import Hpp.StringSig (readLines, putStringy)
import Hpp.Types (Env, Error(..))
import System.Directory (doesFileExist, makeAbsolute)
import System.IO (openFile, IOMode(..), hClose, stdout)

-- | Break a string on an equals sign. For example, the string @x=y@
-- is broken into @[x,"=",y]@.
breakEqs :: String -> [String]
breakEqs :: String -> [String]
breakEqs = (String, String) -> [String]
aux ((String, String) -> [String])
-> (String -> (String, String)) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'=')
  where aux :: (String, String) -> [String]
aux (String
h,[]) = [String
h]
        aux (String
h,Char
'=':String
t) = [String
h,String
"=",String
t]
        aux (String, String)
_ = String -> [String]
forall a. HasCallStack => String -> a
error String
"breakEqs broke"

-- | If no space is included between a switch and its argument, break
-- it into two tokens to simplify parsing.
splitSwitches :: String -> [String]
splitSwitches :: String -> [String]
splitSwitches (Char
'-':Char
'I':t :: String
t@(Char
_:String
_)) = [String
"-I",String
t]
splitSwitches (Char
'-':Char
'D':t :: String
t@(Char
_:String
_)) = [String
"-D",String
t]
splitSwitches (Char
'-':Char
'U':t :: String
t@(Char
_:String
_)) = [String
"-U",String
t]
splitSwitches (Char
'-':Char
'o':t :: String
t@(Char
_:String
_)) = [String
"-o",String
t]
splitSwitches (Char
'-':Char
'i':Char
'n':Char
'c':Char
'l':Char
'u':Char
'd':Char
'e':t :: String
t@(Char
_:String
_)) = [String
"-include",String
t]
splitSwitches String
x = [String
x]

-- FIXME: Defining function macros probably doesn't work here.
parseArgs :: ConfigF Maybe -> [String]
          -> IO (Either Error (Env, [String], Config, Maybe FilePath))
parseArgs :: ConfigF Maybe
-> [String]
-> IO (Either Error (Env, [String], Config, Maybe String))
parseArgs ConfigF Maybe
cfg0 = Env
-> ([String] -> [String])
-> ConfigF Maybe
-> Maybe String
-> [String]
-> IO (Either Error (Env, [String], Config, Maybe String))
forall (m :: * -> *) c.
Monad m =>
Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
forall a. HashMap ByteString a
emptyEnv [String] -> [String]
forall a. a -> a
id ConfigF Maybe
cfg0 Maybe String
forall a. Maybe a
Nothing ([String]
 -> IO (Either Error (Env, [String], Config, Maybe String)))
-> ([String] -> [String])
-> [String]
-> IO (Either Error (Env, [String], Config, Maybe String))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> [String]) -> [String] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap String -> [String]
breakEqs
  where go :: Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out [] =
          case ConfigF Maybe -> Maybe Config
realizeConfig ConfigF Maybe
cfg of
            Just Config
cfg' -> Either Error (Env, c, Config, Maybe String)
-> m (Either Error (Env, c, Config, Maybe String))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Env, c, Config, Maybe String)
-> Either Error (Env, c, Config, Maybe String)
forall a b. b -> Either a b
Right (Env
env, [String] -> c
acc [], Config
cfg', Maybe String
out))
            Maybe Config
Nothing -> Either Error (Env, c, Config, Maybe String)
-> m (Either Error (Env, c, Config, Maybe String))
forall (m :: * -> *) a. Monad m => a -> m a
return (Error -> Either Error (Env, c, Config, Maybe String)
forall a b. a -> Either a b
Left Error
NoInputFile)
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"-D":String
name:String
"=":String
body:[String]
rst) =
          case ByteString -> ByteString -> Maybe (ByteString, Macro)
parseDefinition (String -> ByteString
forall a. IsString a => String -> a
fromString String
name) (String -> ByteString
forall a. IsString a => String -> a
fromString String
body) of
            Maybe (ByteString, Macro)
Nothing -> Either Error (Env, c, Config, Maybe String)
-> m (Either Error (Env, c, Config, Maybe String))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error (Env, c, Config, Maybe String)
 -> m (Either Error (Env, c, Config, Maybe String)))
-> (Error -> Either Error (Env, c, Config, Maybe String))
-> Error
-> m (Either Error (Env, c, Config, Maybe String))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Error -> Either Error (Env, c, Config, Maybe String)
forall a b. a -> Either a b
Left (Error -> m (Either Error (Env, c, Config, Maybe String)))
-> Error -> m (Either Error (Env, c, Config, Maybe String))
forall a b. (a -> b) -> a -> b
$ LineNum -> Error
BadMacroDefinition LineNum
0
            Just (ByteString, Macro)
def -> Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go ((ByteString, Macro) -> Env -> Env
forall a.
(ByteString, a) -> HashMap ByteString a -> HashMap ByteString a
insertPair (ByteString, Macro)
def Env
env) [String] -> c
acc ConfigF Maybe
cfg Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"-D":String
name:[String]
rst) =
          case ByteString -> ByteString -> Maybe (ByteString, Macro)
parseDefinition (String -> ByteString
forall a. IsString a => String -> a
fromString String
name) ByteString
"1" of
            Maybe (ByteString, Macro)
Nothing -> Either Error (Env, c, Config, Maybe String)
-> m (Either Error (Env, c, Config, Maybe String))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error (Env, c, Config, Maybe String)
 -> m (Either Error (Env, c, Config, Maybe String)))
-> (Error -> Either Error (Env, c, Config, Maybe String))
-> Error
-> m (Either Error (Env, c, Config, Maybe String))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Error -> Either Error (Env, c, Config, Maybe String)
forall a b. a -> Either a b
Left (Error -> m (Either Error (Env, c, Config, Maybe String)))
-> Error -> m (Either Error (Env, c, Config, Maybe String))
forall a b. (a -> b) -> a -> b
$ LineNum -> Error
BadMacroDefinition LineNum
0
            Just (ByteString, Macro)
def -> Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go ((ByteString, Macro) -> Env -> Env
forall a.
(ByteString, a) -> HashMap ByteString a -> HashMap ByteString a
insertPair (ByteString, Macro)
def Env
env) [String] -> c
acc ConfigF Maybe
cfg Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"-U":String
name:[String]
rst) =
          Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go (ByteString -> Env -> Env
forall a.
ByteString -> HashMap ByteString a -> HashMap ByteString a
deleteKey (String -> ByteString
forall a. IsString a => String -> a
fromString String
name) Env
env) [String] -> c
acc ConfigF Maybe
cfg Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"-I":String
dir:[String]
rst) =
          let cfg' :: ConfigF Maybe
cfg' = ConfigF Maybe
cfg { includePathsF :: Maybe [String]
includePathsF = ([String] -> [String]) -> Maybe [String] -> Maybe [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++[String
dir]) (ConfigF Maybe -> Maybe [String]
forall (f :: * -> *). ConfigF f -> f [String]
includePathsF ConfigF Maybe
cfg) }
          in Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc ConfigF Maybe
cfg' Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"-include":String
file:[String]
rst) =
          let ln :: String
ln = String
"#include \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
file String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\""
          in Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env ([String] -> c
acc ([String] -> c) -> ([String] -> [String]) -> [String] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
lnString -> [String] -> [String]
forall a. a -> [a] -> [a]
:)) ConfigF Maybe
cfg Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"-P":[String]
rst) =
          let cfg' :: ConfigF Maybe
cfg' = ConfigF Maybe
cfg { inhibitLinemarkersF :: Maybe Bool
inhibitLinemarkersF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True }
          in Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc ConfigF Maybe
cfg' Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"--cpp":[String]
rst) =
          let cfg' :: ConfigF Maybe
cfg' = ConfigF Maybe
cfg { spliceLongLinesF :: Maybe Bool
spliceLongLinesF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True
                         , eraseCCommentsF :: Maybe Bool
eraseCCommentsF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True
                         , inhibitLinemarkersF :: Maybe Bool
inhibitLinemarkersF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
                         , replaceTrigraphsF :: Maybe Bool
replaceTrigraphsF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True }
              defs :: [String]
defs = ([String] -> [String]) -> [[String]] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String
"-D"String -> [String] -> [String]
forall a. a -> [a] -> [a]
:)
                       [ [String
"__STDC__"]
                         -- __STDC_VERSION__ is only defined in C94 and later
                       , [String
"__STDC_VERSION__",String
"=",String
"199409L"] ]
                       -- , ["_POSIX_C_SOURCE","=","200112L"] ]
          in Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc ConfigF Maybe
cfg' Maybe String
out ([String]
defs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
rst)
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"--fline-splice":[String]
rst) =
          Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc (ConfigF Maybe
cfg { spliceLongLinesF :: Maybe Bool
spliceLongLinesF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True }) Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"--ferase-comments":[String]
rst) =
          Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc (ConfigF Maybe
cfg { eraseCCommentsF :: Maybe Bool
eraseCCommentsF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True }) Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"--freplace-trigraphs":[String]
rst) =
          Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc (ConfigF Maybe
cfg { replaceTrigraphsF :: Maybe Bool
replaceTrigraphsF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True }) Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"--only-macros":[String]
rst) =
          Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc (ConfigF Maybe
cfg { replaceTrigraphsF :: Maybe Bool
replaceTrigraphsF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
                          , spliceLongLinesF :: Maybe Bool
spliceLongLinesF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
                          , eraseCCommentsF :: Maybe Bool
eraseCCommentsF = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False }) Maybe String
out [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
_ (String
"-o":String
file:[String]
rst) =
          Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc ConfigF Maybe
cfg (String -> Maybe String
forall a. a -> Maybe a
Just String
file) [String]
rst
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"-x":String
_lang:[String]
rst) =
          Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out [String]
rst -- We ignore source language specification
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"-traditional":[String]
rst) =
          Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out [String]
rst -- Ignore the "-traditional" flag
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out (String
"-Werror":[String]
rst) =
          Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
out [String]
rst -- Ignore the "-Werror" flag
        go Env
env [String] -> c
acc ConfigF Maybe
cfg Maybe String
Nothing (String
file:[String]
rst) =
          case ConfigF Maybe -> Maybe String
forall (f :: * -> *). ConfigF f -> f String
curFileNameF ConfigF Maybe
cfg of
            Maybe String
Nothing -> Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc (ConfigF Maybe
cfg { curFileNameF :: Maybe String
curFileNameF = String -> Maybe String
forall a. a -> Maybe a
Just String
file }) Maybe String
forall a. Maybe a
Nothing [String]
rst
            Just String
_ -> Env
-> ([String] -> c)
-> ConfigF Maybe
-> Maybe String
-> [String]
-> m (Either Error (Env, c, Config, Maybe String))
go Env
env [String] -> c
acc ConfigF Maybe
cfg (String -> Maybe String
forall a. a -> Maybe a
Just String
file) [String]
rst
        go Env
_ [String] -> c
_ ConfigF Maybe
_ (Just String
_) [String]
_ =
          Either Error (Env, c, Config, Maybe String)
-> m (Either Error (Env, c, Config, Maybe String))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error (Env, c, Config, Maybe String)
 -> m (Either Error (Env, c, Config, Maybe String)))
-> (Error -> Either Error (Env, c, Config, Maybe String))
-> Error
-> m (Either Error (Env, c, Config, Maybe String))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Error -> Either Error (Env, c, Config, Maybe String)
forall a b. a -> Either a b
Left (Error -> m (Either Error (Env, c, Config, Maybe String)))
-> Error -> m (Either Error (Env, c, Config, Maybe String))
forall a b. (a -> b) -> a -> b
$ String -> Error
BadCommandLine String
"Multiple output files given"

-- | Run Hpp with the given commandline arguments.
runWithArgs :: [String] -> IO (Maybe Error)
runWithArgs :: [String] -> IO (Maybe Error)
runWithArgs [String]
args =
  do ConfigF Maybe
cfgNow <- IO (ConfigF Maybe)
defaultConfigFNow
     let args' :: [String]
args' = (String -> [String]) -> [String] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap String -> [String]
splitSwitches [String]
args
     (Env
env,[String]
lns,Config
cfg,Maybe String
outPath) <- (Either Error (Env, [String], Config, Maybe String)
 -> (Env, [String], Config, Maybe String))
-> IO (Either Error (Env, [String], Config, Maybe String))
-> IO (Env, [String], Config, Maybe String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Error -> (Env, [String], Config, Maybe String))
-> ((Env, [String], Config, Maybe String)
    -> (Env, [String], Config, Maybe String))
-> Either Error (Env, [String], Config, Maybe String)
-> (Env, [String], Config, Maybe String)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> (Env, [String], Config, Maybe String)
forall a. HasCallStack => String -> a
error (String -> (Env, [String], Config, Maybe String))
-> (Error -> String)
-> Error
-> (Env, [String], Config, Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Error -> String
forall a. Show a => a -> String
show) (Env, [String], Config, Maybe String)
-> (Env, [String], Config, Maybe String)
forall a. a -> a
id)
                                   (ConfigF Maybe
-> [String]
-> IO (Either Error (Env, [String], Config, Maybe String))
parseArgs ConfigF Maybe
cfgNow [String]
args')
     Bool
exists <- String -> IO Bool
doesFileExist (Config -> String
curFileName Config
cfg)
     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
exists (IO () -> IO ()) -> (String -> IO ()) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
forall a. HasCallStack => String -> a
error (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
       String
"Couldn't open input file: "String -> String -> String
forall a. [a] -> [a] -> [a]
++Config -> String
curFileName Config
cfg
     let fileName :: String
fileName = Config -> String
curFileName Config
cfg
         cfg' :: Config
cfg' = Config
cfg { curFileNameF :: Identity String
curFileNameF = String -> Identity String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
fileName }
     ([ByteString] -> IO ()
snk, IO ()
closeSnk) <- case Maybe String
outPath of
                          Maybe String
Nothing -> ([ByteString] -> IO (), IO ()) -> IO ([ByteString] -> IO (), IO ())
forall (m :: * -> *) a. Monad m => a -> m a
return ( (ByteString -> IO ()) -> [ByteString] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Handle -> ByteString -> IO ()
forall s. Stringy s => Handle -> s -> IO ()
putStringy Handle
stdout)
                                            , () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return () )
                          Just String
f ->
                            do Handle
h <- String -> IO String
makeAbsolute String
f IO String -> (String -> IO Handle) -> IO Handle
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                                    (String -> IOMode -> IO Handle) -> IOMode -> String -> IO Handle
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> IOMode -> IO Handle
openFile IOMode
WriteMode
                               ([ByteString] -> IO (), IO ()) -> IO ([ByteString] -> IO (), IO ())
forall (m :: * -> *) a. Monad m => a -> m a
return ( \[ByteString]
os -> (ByteString -> IO ()) -> [ByteString] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Handle -> ByteString -> IO ()
forall s. Stringy s => Handle -> s -> IO ()
putStringy Handle
h) [ByteString]
os
                                      , Handle -> IO ()
hClose Handle
h )
     Either Error ([String], HppState)
result <- String -> IO [ByteString]
forall s. Stringy s => String -> IO [s]
readLines String
fileName
           IO [ByteString]
-> ([ByteString] -> IO (Either Error ([String], HppState)))
-> IO (Either Error ([String], HppState))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ExceptT Error IO ([String], HppState)
-> IO (Either Error ([String], HppState))
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT
               (ExceptT Error IO ([String], HppState)
 -> IO (Either Error ([String], HppState)))
-> ([ByteString] -> ExceptT Error IO ([String], HppState))
-> [ByteString]
-> IO (Either Error ([String], HppState))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HppState
-> ([ByteString] -> IO ())
-> HppT IO ()
-> ExceptT Error IO ([String], HppState)
forall (m :: * -> *) a.
MonadIO m =>
HppState
-> ([ByteString] -> m ())
-> HppT m a
-> ExceptT Error m ([String], HppState)
streamHpp (Config -> Env -> HppState
initHppState Config
cfg' Env
env) [ByteString] -> IO ()
snk
               (HppT IO () -> ExceptT Error IO ([String], HppState))
-> ([ByteString] -> HppT IO ())
-> [ByteString]
-> ExceptT Error IO ([String], HppState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> HppT IO ()
forall (m :: * -> *). Monad m => [ByteString] -> HppT m ()
preprocess
               ([ByteString] -> HppT IO ())
-> ([ByteString] -> [ByteString]) -> [ByteString] -> HppT IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String -> ByteString) -> [String] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map String -> ByteString
forall a. IsString a => String -> a
fromString [String]
lns [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++)
     IO ()
closeSnk
     case Either Error ([String], HppState)
result of
       Left Error
err -> Maybe Error -> IO (Maybe Error)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Error -> IO (Maybe Error))
-> Maybe Error -> IO (Maybe Error)
forall a b. (a -> b) -> a -> b
$ Error -> Maybe Error
forall a. a -> Maybe a
Just Error
err
       Either Error ([String], HppState)
_ -> Maybe Error -> IO (Maybe Error)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Error
forall a. Maybe a
Nothing