{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric  #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Safe  #-}

-- | Errors from dynamic loading of shared libraries for FFI.
module Cryptol.Backend.FFI.Error where

import           Control.DeepSeq
import           GHC.Generics

import           Cryptol.Utils.PP
import           Cryptol.ModuleSystem.Name

data FFILoadError
  = CantLoadFFISrc
    FilePath -- ^ Path to cryptol module
    String   -- ^ Error message
  | CantLoadFFIImpl
    String   -- ^ Function name
    String   -- ^ Error message
  | FFIDuplicates [Name]
  | FFIInFunctor  Name
  deriving (Int -> FFILoadError -> ShowS
[FFILoadError] -> ShowS
FFILoadError -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [FFILoadError] -> ShowS
$cshowList :: [FFILoadError] -> ShowS
show :: FFILoadError -> FilePath
$cshow :: FFILoadError -> FilePath
showsPrec :: Int -> FFILoadError -> ShowS
$cshowsPrec :: Int -> FFILoadError -> ShowS
Show, forall x. Rep FFILoadError x -> FFILoadError
forall x. FFILoadError -> Rep FFILoadError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FFILoadError x -> FFILoadError
$cfrom :: forall x. FFILoadError -> Rep FFILoadError x
Generic, FFILoadError -> ()
forall a. (a -> ()) -> NFData a
rnf :: FFILoadError -> ()
$crnf :: FFILoadError -> ()
NFData)

instance PP FFILoadError where
  ppPrec :: Int -> FFILoadError -> Doc
ppPrec Int
_ FFILoadError
e =
    case FFILoadError
e of
      CantLoadFFISrc FilePath
path FilePath
msg ->
        Doc -> Int -> Doc -> Doc
hang (Doc
"Could not load foreign source for module located at"
              Doc -> Doc -> Doc
<+> FilePath -> Doc
text FilePath
path Doc -> Doc -> Doc
<.> Doc
colon)
          Int
4 (FilePath -> Doc
text FilePath
msg)
      CantLoadFFIImpl FilePath
name FilePath
msg ->
        Doc -> Int -> Doc -> Doc
hang (Doc
"Could not load foreign implementation for binding"
              Doc -> Doc -> Doc
<+> FilePath -> Doc
text FilePath
name Doc -> Doc -> Doc
<.> Doc
colon)
          Int
4 (FilePath -> Doc
text FilePath
msg)
      FFIDuplicates [Name]
xs ->
        Doc -> Int -> Doc -> Doc
hang Doc
"Multiple foreign declarations with the same name:"
           Int
4 (Doc -> Doc
backticks (forall a. PP a => a -> Doc
pp (Name -> Ident
nameIdent (forall a. [a] -> a
head [Name]
xs))) Doc -> Doc -> Doc
<+>
                 Doc
"defined at" Doc -> Doc -> Doc
<+> Doc -> Doc
align ([Doc] -> Doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map (forall a. PP a => a -> Doc
pp forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Range
nameLoc) [Name]
xs)))
      FFIInFunctor Name
x ->
        Doc -> Int -> Doc -> Doc
hang (forall a. PP a => a -> Doc
pp (Name -> Range
nameLoc Name
x) Doc -> Doc -> Doc
<.> Doc
":")
          Int
4 Doc
"Foreign declaration" Doc -> Doc -> Doc
<+> Doc -> Doc
backticks (forall a. PP a => a -> Doc
pp (Name -> Ident
nameIdent Name
x)) Doc -> Doc -> Doc
<+>
                Doc
"may not appear in a parameterized module."