{-# language BangPatterns #-}

module Foreign.C.Error.Describe
  ( string
  , byteArray
  ) where

import Control.Monad.ST (runST)
import Data.Char (ord,chr)
import Data.Foldable (for_)
import Data.Primitive (SmallArray,ByteArray(..))
import Data.Primitive.Unlifted.Array (UnliftedArray)
import Data.Word (Word8)
import Foreign.C.Error (Errno(..))
import Foreign.C.Types (CInt)
import qualified Data.Primitive as PM
import qualified Data.Primitive.Unlifted.Array as PM
import qualified Foreign.C.Error as ERR
import qualified GHC.Exts as E

unErrno :: Errno -> CInt
unErrno :: Errno -> CInt
unErrno (Errno CInt
i) = CInt
i


string :: Errno -> String
string :: Errno -> String
string (Errno CInt
i) = if forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
i forall a. Ord a => a -> a -> Bool
< (Word
256 :: Word)
  then ByteArray -> String
asString (forall a. PrimUnlifted a => UnliftedArray a -> Int -> a
PM.indexUnliftedArray UnliftedArray ByteArray
table (forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
i))
  else String
unknownString

byteArray :: Errno -> ByteArray
byteArray :: Errno -> ByteArray
byteArray (Errno CInt
i) = if forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
i forall a. Ord a => a -> a -> Bool
< (Word
256 :: Word)
  then forall a. PrimUnlifted a => UnliftedArray a -> Int -> a
PM.indexUnliftedArray UnliftedArray ByteArray
table (forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
i)
  else case ByteArray
unknown of
    ByteArray ByteArray#
b -> ByteArray# -> ByteArray
ByteArray ByteArray#
b

{-# NOINLINE unknown #-}
unknown :: ByteArray
unknown :: ByteArray
unknown = String -> ByteArray
asBytes String
unknownString

unknownString :: String
unknownString :: String
unknownString = String
"UNKNOWN"

table :: UnliftedArray ByteArray
table :: UnliftedArray ByteArray
table = forall a. (forall s. ST s a) -> a
runST forall a b. (a -> b) -> a -> b
$ do
  MutableUnliftedArray s ByteArray
m <- forall (m :: * -> *) a.
(PrimMonad m, PrimUnlifted a) =>
Int -> a -> m (MutableUnliftedArray (PrimState m) a)
PM.newUnliftedArray Int
256 (forall a. Monoid a => a
mempty :: ByteArray)
  forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ SmallArray Description
codes forall a b. (a -> b) -> a -> b
$ \(Description CInt
code ByteArray
descr) -> do
    let ix :: Int
ix = forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
code :: Int
    if Int
ix forall a. Ord a => a -> a -> Bool
< (Int
256 :: Int)
      then if Int
ix forall a. Ord a => a -> a -> Bool
>= Int
0
        then forall (m :: * -> *) a.
(PrimMonad m, PrimUnlifted a) =>
MutableUnliftedArray (PrimState m) a -> Int -> a -> m ()
PM.writeUnliftedArray MutableUnliftedArray s ByteArray
m Int
ix ByteArray
descr
        else forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      else forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  forall (m :: * -> *) a.
PrimMonad m =>
MutableUnliftedArray (PrimState m) a -> m (UnliftedArray a)
PM.unsafeFreezeUnliftedArray MutableUnliftedArray s ByteArray
m

data Description = Description !CInt !ByteArray

asBytes :: String -> ByteArray
asBytes :: String -> ByteArray
asBytes String
s = forall a. (forall s. ST s a) -> a
runST forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray s
m <- forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
PM.newByteArray (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s)
  forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (forall a b. [a] -> [b] -> [(a, b)]
zip (forall a. Enum a => a -> [a]
enumFrom (Int
0 :: Int)) String
s) forall a b. (a -> b) -> a -> b
$ \(Int
ix,Char
c) -> do
    forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray s
m Int
ix (Char -> Word8
charToWord8 Char
c)
  forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
PM.unsafeFreezeByteArray MutableByteArray s
m

asString :: ByteArray -> String
asString :: ByteArray -> String
asString = forall a b. Prim a => (a -> b -> b) -> b -> ByteArray -> b
PM.foldrByteArray (\Word8
b String
cs -> Word8 -> Char
word8ToChar Word8
b forall a. a -> [a] -> [a]
: String
cs) []

charToWord8 :: Char -> Word8
charToWord8 :: Char -> Word8
charToWord8 = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord

word8ToChar :: Word8 -> Char
word8ToChar :: Word8 -> Char
word8ToChar = Int -> Char
chr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral

codes :: SmallArray Description
codes :: SmallArray Description
codes = forall l. IsList l => [Item l] -> l
E.fromList
  [ CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eOK) (String -> ByteArray
asBytes String
"EOK")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.e2BIG) (String -> ByteArray
asBytes String
"E2BIG")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eACCES) (String -> ByteArray
asBytes String
"EACCES")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eADDRINUSE) (String -> ByteArray
asBytes String
"EADDRINUSE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eADDRNOTAVAIL) (String -> ByteArray
asBytes String
"EADDRNOTAVAIL")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eADV) (String -> ByteArray
asBytes String
"EADV")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eAFNOSUPPORT) (String -> ByteArray
asBytes String
"EAFNOSUPPORT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eAGAIN) (String -> ByteArray
asBytes String
"EAGAIN")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eALREADY) (String -> ByteArray
asBytes String
"EALREADY")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eBADF) (String -> ByteArray
asBytes String
"EBADF")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eBADMSG) (String -> ByteArray
asBytes String
"EBADMSG")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eBADRPC) (String -> ByteArray
asBytes String
"EBADRPC")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eBUSY) (String -> ByteArray
asBytes String
"EBUSY")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eCHILD) (String -> ByteArray
asBytes String
"ECHILD")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eCOMM) (String -> ByteArray
asBytes String
"ECOMM")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eCONNABORTED) (String -> ByteArray
asBytes String
"ECONNABORTED")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eCONNREFUSED) (String -> ByteArray
asBytes String
"ECONNREFUSED")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eCONNRESET) (String -> ByteArray
asBytes String
"ECONNRESET")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eDEADLK) (String -> ByteArray
asBytes String
"EDEADLK")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eDESTADDRREQ) (String -> ByteArray
asBytes String
"EDESTADDRREQ")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eDIRTY) (String -> ByteArray
asBytes String
"EDIRTY")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eDOM) (String -> ByteArray
asBytes String
"EDOM")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eDQUOT) (String -> ByteArray
asBytes String
"EDQUOT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eEXIST) (String -> ByteArray
asBytes String
"EEXIST")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eFAULT) (String -> ByteArray
asBytes String
"EFAULT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eFBIG) (String -> ByteArray
asBytes String
"EFBIG")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eFTYPE) (String -> ByteArray
asBytes String
"EFTYPE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eHOSTDOWN) (String -> ByteArray
asBytes String
"EHOSTDOWN")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eHOSTUNREACH) (String -> ByteArray
asBytes String
"EHOSTUNREACH")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eIDRM) (String -> ByteArray
asBytes String
"EIDRM")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eILSEQ) (String -> ByteArray
asBytes String
"EILSEQ")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eINPROGRESS) (String -> ByteArray
asBytes String
"EINPROGRESS")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eINTR) (String -> ByteArray
asBytes String
"EINTR")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eINVAL) (String -> ByteArray
asBytes String
"EINVAL")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eIO) (String -> ByteArray
asBytes String
"EIO")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eISCONN) (String -> ByteArray
asBytes String
"EISCONN")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eISDIR) (String -> ByteArray
asBytes String
"EISDIR")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eLOOP) (String -> ByteArray
asBytes String
"ELOOP")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eMFILE) (String -> ByteArray
asBytes String
"EMFILE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eMLINK) (String -> ByteArray
asBytes String
"EMLINK")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eMSGSIZE) (String -> ByteArray
asBytes String
"EMSGSIZE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eMULTIHOP) (String -> ByteArray
asBytes String
"EMULTIHOP")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNAMETOOLONG) (String -> ByteArray
asBytes String
"ENAMETOOLONG")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNETDOWN) (String -> ByteArray
asBytes String
"ENETDOWN")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNETRESET) (String -> ByteArray
asBytes String
"ENETRESET")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNETUNREACH) (String -> ByteArray
asBytes String
"ENETUNREACH")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNFILE) (String -> ByteArray
asBytes String
"ENFILE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOBUFS) (String -> ByteArray
asBytes String
"ENOBUFS")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNODATA) (String -> ByteArray
asBytes String
"ENODATA")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNODEV) (String -> ByteArray
asBytes String
"ENODEV")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOENT) (String -> ByteArray
asBytes String
"ENOENT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOEXEC) (String -> ByteArray
asBytes String
"ENOEXEC")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOLCK) (String -> ByteArray
asBytes String
"ENOLCK")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOLINK) (String -> ByteArray
asBytes String
"ENOLINK")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOMEM) (String -> ByteArray
asBytes String
"ENOMEM")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOMSG) (String -> ByteArray
asBytes String
"ENOMSG")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNONET) (String -> ByteArray
asBytes String
"ENONET")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOPROTOOPT) (String -> ByteArray
asBytes String
"ENOPROTOOPT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOSPC) (String -> ByteArray
asBytes String
"ENOSPC")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOSR) (String -> ByteArray
asBytes String
"ENOSR")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOSTR) (String -> ByteArray
asBytes String
"ENOSTR")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOSYS) (String -> ByteArray
asBytes String
"ENOSYS")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOTBLK) (String -> ByteArray
asBytes String
"ENOTBLK")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOTCONN) (String -> ByteArray
asBytes String
"ENOTCONN")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOTDIR) (String -> ByteArray
asBytes String
"ENOTDIR")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOTEMPTY) (String -> ByteArray
asBytes String
"ENOTEMPTY")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOTSOCK) (String -> ByteArray
asBytes String
"ENOTSOCK")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOTSUP) (String -> ByteArray
asBytes String
"ENOTSUP")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNOTTY) (String -> ByteArray
asBytes String
"ENOTTY")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eNXIO) (String -> ByteArray
asBytes String
"ENXIO")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eOPNOTSUPP) (String -> ByteArray
asBytes String
"EOPNOTSUPP")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePERM) (String -> ByteArray
asBytes String
"EPERM")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePFNOSUPPORT) (String -> ByteArray
asBytes String
"EPFNOSUPPORT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePIPE) (String -> ByteArray
asBytes String
"EPIPE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePROCLIM) (String -> ByteArray
asBytes String
"EPROCLIM")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePROCUNAVAIL) (String -> ByteArray
asBytes String
"EPROCUNAVAIL")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePROGMISMATCH) (String -> ByteArray
asBytes String
"EPROGMISMATCH")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePROGUNAVAIL) (String -> ByteArray
asBytes String
"EPROGUNAVAIL")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePROTO) (String -> ByteArray
asBytes String
"EPROTO")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePROTONOSUPPORT) (String -> ByteArray
asBytes String
"EPROTONOSUPPORT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.ePROTOTYPE) (String -> ByteArray
asBytes String
"EPROTOTYPE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eRANGE) (String -> ByteArray
asBytes String
"ERANGE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eREMCHG) (String -> ByteArray
asBytes String
"EREMCHG")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eREMOTE) (String -> ByteArray
asBytes String
"EREMOTE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eROFS) (String -> ByteArray
asBytes String
"EROFS")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eRPCMISMATCH) (String -> ByteArray
asBytes String
"ERPCMISMATCH")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eRREMOTE) (String -> ByteArray
asBytes String
"ERREMOTE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eSHUTDOWN) (String -> ByteArray
asBytes String
"ESHUTDOWN")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eSOCKTNOSUPPORT) (String -> ByteArray
asBytes String
"ESOCKTNOSUPPORT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eSPIPE) (String -> ByteArray
asBytes String
"ESPIPE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eSRCH) (String -> ByteArray
asBytes String
"ESRCH")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eSRMNT) (String -> ByteArray
asBytes String
"ESRMNT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eSTALE) (String -> ByteArray
asBytes String
"ESTALE")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eTIME) (String -> ByteArray
asBytes String
"ETIME")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eTIMEDOUT) (String -> ByteArray
asBytes String
"ETIMEDOUT")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eTOOMANYREFS) (String -> ByteArray
asBytes String
"ETOOMANYREFS")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eTXTBSY) (String -> ByteArray
asBytes String
"ETXTBSY")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eUSERS) (String -> ByteArray
asBytes String
"EUSERS")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eWOULDBLOCK) (String -> ByteArray
asBytes String
"EWOULDBLOCK")
  , CInt -> ByteArray -> Description
Description (Errno -> CInt
unErrno Errno
ERR.eXDEV) (String -> ByteArray
asBytes String
"EXDEV")
  ]