module Futhark.CLI.Datacmp (main) where
import Control.Exception
import Data.ByteString.Lazy.Char8 qualified as BS
import Futhark.Data.Compare
import Futhark.Data.Reader
import Futhark.Util.Options
import System.Exit
import System.IO
readFileSafely :: String -> IO (Either String BS.ByteString)
readFileSafely :: String -> IO (Either String ByteString)
readFileSafely String
filepath =
(forall a b. b -> Either a b
Right forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO ByteString
BS.readFile String
filepath) forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch` forall {f :: * -> *} {b}.
Applicative f =>
IOError -> f (Either String b)
couldNotRead
where
couldNotRead :: IOError -> f (Either String b)
couldNotRead IOError
e = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show (IOError
e :: IOError)
main :: String -> [String] -> IO ()
main :: String -> [String] -> IO ()
main = forall cfg.
cfg
-> [FunOptDescr cfg]
-> String
-> ([String] -> cfg -> Maybe (IO ()))
-> String
-> [String]
-> IO ()
mainWithOptions () [] String
"<file> <file>" [String] -> () -> Maybe (IO ())
f
where
f :: [String] -> () -> Maybe (IO ())
f [String
file_a, String
file_b] () = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ do
Either String ByteString
file_contents_a_maybe <- String -> IO (Either String ByteString)
readFileSafely String
file_a
Either String ByteString
file_contents_b_maybe <- String -> IO (Either String ByteString)
readFileSafely String
file_b
case (Either String ByteString
file_contents_a_maybe, Either String ByteString
file_contents_b_maybe) of
(Left String
err_msg, Either String ByteString
_) -> do
Handle -> String -> IO ()
hPutStrLn Handle
stderr String
err_msg
forall a. IO a
exitFailure
(Either String ByteString
_, Left String
err_msg) -> do
Handle -> String -> IO ()
hPutStrLn Handle
stderr String
err_msg
forall a. IO a
exitFailure
(Right ByteString
contents_a, Right ByteString
contents_b) -> do
let vs_a_maybe :: Maybe [Value]
vs_a_maybe = ByteString -> Maybe [Value]
readValues ByteString
contents_a
let vs_b_maybe :: Maybe [Value]
vs_b_maybe = ByteString -> Maybe [Value]
readValues ByteString
contents_b
case (Maybe [Value]
vs_a_maybe, Maybe [Value]
vs_b_maybe) of
(Maybe [Value]
Nothing, Maybe [Value]
_) -> do
Handle -> String -> IO ()
hPutStrLn Handle
stderr forall a b. (a -> b) -> a -> b
$ String
"Error reading values from " forall a. [a] -> [a] -> [a]
++ String
file_a
forall a. IO a
exitFailure
(Maybe [Value]
_, Maybe [Value]
Nothing) -> do
Handle -> String -> IO ()
hPutStrLn Handle
stderr forall a b. (a -> b) -> a -> b
$ String
"Error reading values from " forall a. [a] -> [a] -> [a]
++ String
file_b
forall a. IO a
exitFailure
(Just [Value]
vs_a, Just [Value]
vs_b) ->
case Tolerance -> [Value] -> [Value] -> [Mismatch]
compareSeveralValues (Double -> Tolerance
Tolerance Double
0.002) [Value]
vs_a [Value]
vs_b of
[] -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
[Mismatch]
es -> do
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. Show a => a -> IO ()
print [Mismatch]
es
forall a. ExitCode -> IO a
exitWith forall a b. (a -> b) -> a -> b
$ Int -> ExitCode
ExitFailure Int
2
f [String]
_ ()
_ =
forall a. Maybe a
Nothing