module Bindings.Bfd.Exception where
import Control.Exception
import Data.Typeable
import Foreign.C
import Foreign.Ptr
import Bindings.Bfd.Target
type FunctionName = String
type FormatName = String
type ErrorMsg = String
data BfdException = NoError FunctionName FilePath TargetName
| SystemCall FunctionName FilePath TargetName ErrorMsg
| InvalidTarget FunctionName FilePath TargetName
| WrongFormat
| WrongObjectFormat
| InvalidOperation
| NoMemory
| NoSymbols
| NoArmap
| NoMoreArchivedFiles
| MalformedArchive
| FileNotRecognized FunctionName FormatName
| FileAmbiguouslyRecognized
| NoContents
| NonrepresentableSection
| NoDebugSection
| BadValue
| FileTruncated
| FileTooBig
| OnInput
| InvalidErrorCode
deriving (Typeable)
instance Show BfdException where
show (NoError fn fp tn ) = fp ++ ": " ++ fn ++ ": '" ++ tn ++ "': no error (report this as a bug)"
show (SystemCall fn fp tn msg) = fp ++ ": " ++ fn ++ ": '" ++ tn ++ "': system call (" ++ msg ++ ")"
show (InvalidTarget fn fp tn ) = fp ++ ": " ++ fn ++ ": '" ++ tn ++ "': invalid target"
show (WrongFormat ) = "3"
show (WrongObjectFormat ) = "4"
show (InvalidOperation ) = "5"
show (NoMemory ) = "6"
show (NoSymbols ) = "7"
show (NoArmap ) = "8"
show (NoMoreArchivedFiles ) = "9"
show (MalformedArchive ) = "10"
show (FileNotRecognized fn ff ) = ff ++ ": " ++ fn ++ ": " ++ "file format not recognized"
show (FileAmbiguouslyRecognized ) = "12"
show (NoContents ) = "13"
show (NonrepresentableSection ) = "14"
show (NoDebugSection ) = "15"
show (BadValue ) = "16"
show (FileTruncated ) = "17"
show (FileTooBig ) = "18"
show (OnInput ) = "19"
show (InvalidErrorCode ) = "20"
instance Exception BfdException where
throwExceptionIfNull
:: FunctionName
-> FilePath
-> TargetName
-> IO (Ptr a)
-> IO (Ptr a)
throwExceptionIfNull fn fp tn f =
do
res <- f
if res == nullPtr
then throwException fn fp tn
else return res
throwExceptionIfFalse
:: FunctionName
-> FormatName
-> IO Bool
-> IO Bool
throwExceptionIfFalse fn ff f =
do
res <- f
if res == False
then throwException fn ff ""
else return res
throwException
:: String
-> String
-> String
-> IO a
throwException s1 s2 s3 =
do
errNum <- c_bfd_get_error
errMsg <- peekCString (c_bfd_errmsg errNum)
let
e =
case errNum of
0 -> NoError s1 s2 s3
1 -> SystemCall s1 s2 s3 errMsg
2 -> InvalidTarget s1 s2 s3
3 -> WrongFormat
4 -> WrongObjectFormat
5 -> InvalidOperation
6 -> NoMemory
7 -> NoSymbols
8 -> NoArmap
9 -> NoMoreArchivedFiles
10 -> MalformedArchive
11 -> FileNotRecognized s1 s2
12 -> FileAmbiguouslyRecognized
13 -> NoContents
14 -> NonrepresentableSection
15 -> NoDebugSection
16 -> BadValue
17 -> FileTruncated
18 -> FileTooBig
19 -> OnInput
_ -> InvalidErrorCode
throwIO e
foreign import ccall unsafe "bfd.h bfd_get_error" c_bfd_get_error
:: IO CInt
foreign import ccall unsafe "bfd.h bfd_errmsg" c_bfd_errmsg
:: CInt
-> CString