Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new testsuite to check types of System.Posix.Types #59

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ jobs:
ghc:
- 8.8.4
- 8.10.7
- 9.0.1
- 9.2.1
- 9.0.2
- 9.2.4
fail-fast: false
continue-on-error: ${{ startsWith(matrix.os, 'windows') && startsWith(matrix.ghc, '9.2') }}

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
*.swp
.ghc.*
.stack-work
cabal.project.local
1 change: 1 addition & 0 deletions cabal.project
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
packages: ./unix-compat.cabal
150 changes: 133 additions & 17 deletions src/System/PosixCompat/Types.hs
Original file line number Diff line number Diff line change
@@ -1,47 +1,163 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

{-# OPTIONS_GHC -Wno-unused-imports #-}

{-|
This module re-exports the types from @System.Posix.Types@ on all platforms.

On Windows 'UserID', 'GroupID' and 'LinkCount' are missing, so they are
redefined by this module.
It defines drop-in replacements for types that are missing from that module on a
specific OS. Namely Mac OS and Windows are supported.
-}
module System.PosixCompat.Types (
module System.Posix.Types
#ifdef darwin_HOST_OS
, CTimer(..)
#endif
#ifdef mingw32_HOST_OS
, CBlkCnt(..)
, CBlkSize(..)
, CCc(..)
, CFsBlkCnt(..)
, CFsFilCnt(..)
, CId(..)
, CKey(..)
, CRLim(..)
, CSpeed(..)
, CTcflag(..)
, CTimer(..)
, UserID
, CUid(..)
, GroupID
, CGid(..)
, LinkCount
, CNlink(..)
#endif
#if defined mingw32_HOST_OS || !MIN_VERSION_base(4, 14, 0)
, CNfds(..)
, CSocklen(..)
#endif
) where

import Data.Int (Int32, Int64)
import Data.Word (Word8, Word32, Word64)
import Foreign (Ptr)
import System.Posix.Types

#ifdef darwin_HOST_OS

newtype CTimer = CTimer (Ptr ())
deriving (Eq, Ord)
instance Show CTimer where show (CTimer x) = show x

#endif

#ifdef mingw32_HOST_OS
-- Since CIno (FileID's underlying type) reflects <sys/type.h> ino_t,
-- which mingw defines as short int (int16), it must be overriden to
-- match the size of windows fileIndex (word64).
import System.Posix.Types

import Data.Word (Word32)
newtype CBlkCnt = CBlkCnt Int64
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CBlkCnt where show (CBlkCnt x) = show x
instance Read CBlkCnt where readsPrec i s = [ (CBlkCnt x, s')
| (x,s') <- readsPrec i s]

newtype UserID = UserID Word32
newtype CBlkSize = CBlkSize Int64
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show UserID where show (UserID x) = show x
instance Read UserID where readsPrec i s = [ (UserID x, s')
instance Show CBlkSize where show (CBlkSize x) = show x
instance Read CBlkSize where readsPrec i s = [ (CBlkSize x, s')
| (x,s') <- readsPrec i s]

newtype GroupID = GroupID Word32
newtype CCc = CCc Word8
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CCc where show (CCc x) = show x
instance Read CCc where readsPrec i s = [ (CCc x, s')
| (x,s') <- readsPrec i s]

newtype CFsBlkCnt = CFsBlkCnt Word64
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show GroupID where show (GroupID x) = show x
instance Read GroupID where readsPrec i s = [ (GroupID x, s')
instance Show CFsBlkCnt where show (CFsBlkCnt x) = show x
instance Read CFsBlkCnt where readsPrec i s = [ (CFsBlkCnt x, s')
| (x,s') <- readsPrec i s]

newtype LinkCount = LinkCount Word32
newtype CFsFilCnt = CFsFilCnt Word64
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show LinkCount where show (LinkCount x) = show x
instance Read LinkCount where readsPrec i s = [ (LinkCount x, s')
| (x,s') <- readsPrec i s]
instance Show CFsFilCnt where show (CFsFilCnt x) = show x
instance Read CFsFilCnt where readsPrec i s = [ (CFsFilCnt x, s')
| (x,s') <- readsPrec i s]

newtype CId = CId Word32
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CId where show (CId x) = show x
instance Read CId where readsPrec i s = [ (CId x, s')
| (x,s') <- readsPrec i s]

newtype CKey = CKey Int32
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CKey where show (CKey x) = show x
instance Read CKey where readsPrec i s = [ (CKey x, s')
| (x,s') <- readsPrec i s]

newtype CRLim = CRLim Word64
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CRLim where show (CRLim x) = show x
instance Read CRLim where readsPrec i s = [ (CRLim x, s')
| (x,s') <- readsPrec i s]

newtype CSpeed = CSpeed Word32
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CSpeed where show (CSpeed x) = show x
instance Read CSpeed where readsPrec i s = [ (CSpeed x, s')
| (x,s') <- readsPrec i s]

newtype CTcflag = CTcflag Word32
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CTcflag where show (CTcflag x) = show x
instance Read CTcflag where readsPrec i s = [ (CTcflag x, s')
| (x,s') <- readsPrec i s]

newtype CTimer = CTimer (Ptr ())
deriving (Eq, Ord)
instance Show CTimer where show (CTimer x) = show x

type UserID = CUid

newtype CUid = CUid Word32
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CUid where show (CUid x) = show x
instance Read CUid where readsPrec i s = [ (CUid x, s')
| (x,s') <- readsPrec i s]

type GroupID = CGid

newtype CGid = CGid Word32
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CGid where show (CGid x) = show x
instance Read CGid where readsPrec i s = [ (CGid x, s')
| (x,s') <- readsPrec i s]

type LinkCount = CNlink

newtype CNlink = CNlink Word64
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CNlink where show (CNlink x) = show x
instance Read CNlink where readsPrec i s = [ (CNlink x, s')
| (x,s') <- readsPrec i s]

#endif

#if defined mingw32_HOST_OS || !MIN_VERSION_base(4, 14, 0)

newtype CNfds = CNfds Word64
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CNfds where show (CNfds x) = show x
instance Read CNfds where readsPrec i s = [ (CNfds x, s')
| (x,s') <- readsPrec i s]

newtype CSocklen = CSocklen Word32
deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real)
instance Show CSocklen where show (CSocklen x) = show x
instance Read CSocklen where readsPrec i s = [ (CSocklen x, s')
| (x,s') <- readsPrec i s]

#else
import System.Posix.Types
#endif
178 changes: 178 additions & 0 deletions tests/check-types.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
{-# LANGUAGE CPP #-}

{-# OPTIONS_GHC -Wno-unused-top-binds #-}

module Main (main) where

import Data.Int
import Data.Word
import System.PosixCompat.Types

import qualified Foreign
import qualified Foreign.C.Types

main :: IO ()
main = pure ()

newtypeCBlkCnt :: CBlkCnt -> Int64
newtypeCBlkCnt (CBlkCnt x) = x

#ifdef darwin_HOST_OS
newtypeCBlkSize :: CBlkSize -> Int32
#else
newtypeCBlkSize :: CBlkSize -> Int64
#endif
newtypeCBlkSize (CBlkSize x) = x

newtypeCCc :: CCc -> Word8
newtypeCCc (CCc x) = x

#ifdef darwin_HOST_OS
newtypeCClockId :: CClockId -> Word32
#else
newtypeCClockId :: CClockId -> Int32
#endif
newtypeCClockId (CClockId x) = x

#ifdef darwin_HOST_OS
newtypeCDev :: CDev -> Int32
#elif defined mingw32_HOST_OS
newtypeCDev :: CDev -> Word32
#else
newtypeCDev :: CDev -> Word64
#endif
newtypeCDev (CDev x) = x

#ifdef darwin_HOST_OS
newtypeCFsBlkCnt :: CFsBlkCnt -> Word32
#else
newtypeCFsBlkCnt :: CFsBlkCnt -> Word64
#endif
newtypeCFsBlkCnt (CFsBlkCnt x) = x

#ifdef darwin_HOST_OS
newtypeCFsFilCnt :: CFsFilCnt -> Word32
#else
newtypeCFsFilCnt :: CFsFilCnt -> Word64
#endif
newtypeCFsFilCnt (CFsFilCnt x) = x

newtypeCGid :: CGid -> Word32
newtypeCGid (CGid x) = x

newtypeCId :: CId -> Word32
newtypeCId (CId x) = x

#ifdef mingw32_HOST_OS
newtypeCIno :: CIno -> Word16
#else
newtypeCIno :: CIno -> Word64
#endif
newtypeCIno (CIno x) = x

newtypeCKey :: CKey -> Int32
newtypeCKey (CKey x) = x

#ifdef darwin_HOST_OS
newtypeCMode :: CMode -> Word16
#elif defined mingw32_HOST_OS
newtypeCMode :: CMode -> Word16
#else
newtypeCMode :: CMode -> Word32
#endif
newtypeCMode (CMode x) = x

#if defined darwin_HOST_OS && MIN_VERSION_base(4, 14, 0)
newtypeCNfds :: CNfds -> Word32
#else
newtypeCNfds :: CNfds -> Word64
#endif
newtypeCNfds (CNfds x) = x

#ifdef darwin_HOST_OS
newtypeCNlink :: CNlink -> Word16
#else
newtypeCNlink :: CNlink -> Word64
#endif
newtypeCNlink (CNlink x) = x

newtypeCOff :: COff -> Int64
newtypeCOff (COff x) = x

#ifdef mingw32_HOST_OS
newtypeCPid :: CPid -> Int64
#else
newtypeCPid :: CPid -> Int32
#endif
newtypeCPid (CPid x) = x

newtypeCRLim :: CRLim -> Word64
newtypeCRLim (CRLim x) = x

newtypeCSocklen :: CSocklen -> Word32
newtypeCSocklen (CSocklen x) = x

#ifdef darwin_HOST_OS
newtypeCSpeed :: CSpeed -> Word64
#else
newtypeCSpeed :: CSpeed -> Word32
#endif
newtypeCSpeed (CSpeed x) = x

newtypeCSsize :: CSsize -> Int64
newtypeCSsize (CSsize x) = x

#ifdef darwin_HOST_OS
newtypeCTcflag :: CTcflag -> Word64
#else
newtypeCTcflag :: CTcflag -> Word32
#endif
newtypeCTcflag (CTcflag x) = x

newtypeCTimer :: CTimer -> Foreign.Ptr ()
newtypeCTimer (CTimer x) = x

newtypeCUid :: CUid -> Word32
newtypeCUid (CUid x) = x

newtypeFd :: Fd -> Foreign.C.Types.CInt
newtypeFd (Fd x) = x

typeByteCount :: ByteCount -> Foreign.C.Types.CSize
typeByteCount = id

typeClockTick :: ClockTick -> Foreign.C.Types.CClock
typeClockTick = id

typeDeviceID :: DeviceID -> CDev
typeDeviceID = id

typeEpochTime :: EpochTime -> Foreign.C.Types.CTime
typeEpochTime = id

typeFileID :: FileID -> CIno
typeFileID = id

typeFileMode :: FileMode -> CMode
typeFileMode = id

typeFileOffset :: FileOffset -> COff
typeFileOffset = id

typeGroupID :: GroupID -> CGid
typeGroupID = id

typeLimit :: Limit -> Foreign.C.Types.CLong
typeLimit = id

typeLinkCount :: LinkCount -> CNlink
typeLinkCount = id

typeProcessGroupID :: ProcessGroupID -> CPid
typeProcessGroupID = id

typeProcessID :: ProcessID -> CPid
typeProcessID = id

typeUserID :: UserID -> CUid
typeUserID = id
12 changes: 12 additions & 0 deletions unix-compat.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,15 @@ Test-Suite unix-compat-testsuite
cc-options: -DSOLARIS

build-depends: directory >= 1.3.1 && < 1.4

Test-Suite unix-compat-check-types
default-language: Haskell2010
type: exitcode-stdio-1.0
hs-source-dirs: tests
ghc-options: -Wall
main-is: check-types.hs

build-depends:
unix-compat
, base == 4.*