derive-storable (empty) → 0.1.0.0
raw patch · 10 files changed
+1562/−0 lines, 10 filesdep +QuickCheckdep +basedep +generic-storablesetup-changed
Dependencies added: QuickCheck, base, generic-storable, hspec
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- derive-storable.cabal +83/−0
- src/Foreign/Storable/Generic.hs +42/−0
- src/Foreign/Storable/Generic/Instances.hs +105/−0
- src/Foreign/Storable/Generic/Internal.hs +219/−0
- src/Foreign/Storable/Generic/Tools.hs +106/−0
- test/Basic/MemoryCSpec.hs +114/−0
- test/Basic/cbits/TestCases.c +870/−0
- test/Spec/Spec.hs +1/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2016 Mateusz Kloczko++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ derive-storable.cabal view
@@ -0,0 +1,83 @@+-- Initial derive-storable.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++-- The name of the package.+name: derive-storable++-- The package version. See the Haskell package versioning policy (PVP) +-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary: +-+------- breaking API changes+-- | | +----- non-breaking API additions+-- | | | +--- code changes with no API change+version: 0.1.0.0++-- A short (one-line) description of the package.+synopsis: Deriving Storable instances using generics. ++-- A longer description of the package.+-- description: ++-- The license under which the package is released.+license: MIT++-- The file containing the license text.+license-file: LICENSE++-- The package author(s).+author: Mateusz Kloczko++-- An email address to which users can send suggestions, bug reports, and +-- patches.+maintainer: mateusz.p.kloczko@gmail.com++-- A copyright notice.+-- copyright: ++category: FFI++build-type: Simple++-- Extra files to be distributed with the package, such as examples or a +-- README.+-- extra-source-files: ++-- Constraint on the version of Cabal needed to build this package.+cabal-version: >=1.10+++library+ -- Modules exported by the library.+ exposed-modules: Foreign.Storable.Generic, Foreign.Storable.Generic.Tools+ , Foreign.Storable.Generic.Internal, Foreign.Storable.Generic.Instances + + -- LANGUAGE extensions used by modules in this package.+ -- other-extensions: + + -- Other library packages from which modules are imported.+ build-depends: base >=4.8 && <4.10+ + -- Directories containing source files.+ hs-source-dirs: src+ + -- Base language which the package is written in.+ default-language: Haskell2010+ ++test-suite c_alignment+ type: exitcode-stdio-1.0+ + hs-source-dirs: src, test/Basic, test/Basic/cbits+ c-sources: test/Basic/cbits/TestCases.c + main-is: MemoryCSpec.hs+ build-depends: base >= 4.8 && <4.10, hspec == 2.2.* ,QuickCheck == 2.8.*, generic-storable+ + default-language: Haskell2010++test-suite spec+ type: exitcode-stdio-1.0+ hs-source-dirs: src/ test/Spec test/Basic test/GenericRep/+ Main-is: Spec.hs+ build-depends: base >= 4.8 && < 4.10, generic-storable, hspec == 2.2.*, QuickCheck == 2.8.*++ default-language: Haskell2010
+ src/Foreign/Storable/Generic.hs view
@@ -0,0 +1,42 @@+{-|+Module : Foreign.Storable.Generic+Copyright : (c) Mateusz Kłoczko, 2016+License : MIT+Maintainer : mateusz.p.kloczko@gmail.com+Stability : experimental+Portability : portable++++-}++{-#LANGUAGE FlexibleInstances #-}+{-#LANGUAGE FlexibleContexts #-}+{-#LANGUAGE TypeOperators #-}+{-#LANGUAGE ScopedTypeVariables #-}+{-#LANGUAGE UndecidableInstances #-}+++module Foreign.Storable.Generic (GStorable (..), Storable(..)) where++++import Foreign.Storable (Storable(..))++import Foreign.Storable.Generic.Internal (GStorable (..))+import Foreign.Storable.Generic.Instances+++------Association to Storable class-------++instance {-# OVERLAPS #-} (GStorable a) => (Storable a) where+ {-# INLINE sizeOf #-}+ sizeOf = gsizeOf+ {-# INLINE alignment #-}+ alignment = galignment+ {-# INLINE peekByteOff #-}+ peekByteOff = gpeekByteOff+ {-# INLINE pokeByteOff #-}+ pokeByteOff = gpokeByteOff++
+ src/Foreign/Storable/Generic/Instances.hs view
@@ -0,0 +1,105 @@+{-|+Module : Foreign.Storable.Generic.Instances+Copyright : (c) Mateusz Kłoczko, 2016+License : MIT+Maintainer : mateusz.p.kloczko@gmail.com+Stability : experimental+Portability : portable+++-}++{-# LANGUAGE CPP #-}+module Foreign.Storable.Generic.Instances () where++import Data.Int+import Data.Word+import Foreign.C.Types+import Foreign.Ptr+import Foreign.StablePtr+import Foreign.Storable+import Foreign.Storable.Generic.Internal+import GHC.Fingerprint.Type+import System.Posix.Types+import Data.Ratio (Ratio)++#define MakeGStorable(Type) \+instance GStorable Type where \+ {-#INLINE gsizeOf #-} \+; gsizeOf = sizeOf \+; {-#INLINE galignment #-} \+; galignment = alignment \+; {-#INLINE gpeekByteOff #-} \+; gpeekByteOff = peekByteOff \+; {-#INLINE gpokeByteOff #-} \+; gpokeByteOff = pokeByteOff \++-- Haskell primitives+MakeGStorable(Bool)+MakeGStorable(Char)+MakeGStorable(Double)+MakeGStorable(Float)++MakeGStorable(Int)+MakeGStorable(Int8)+MakeGStorable(Int16)+MakeGStorable(Int32)+MakeGStorable(Int64)++MakeGStorable(Word)+MakeGStorable(Word8)+MakeGStorable(Word16)+MakeGStorable(Word32)+MakeGStorable(Word64)++MakeGStorable (Fingerprint)++-- C primitives+MakeGStorable (CUIntMax)+MakeGStorable (CIntMax)+MakeGStorable (CSUSeconds)+MakeGStorable (CUSeconds)+MakeGStorable (CTime)+MakeGStorable (CClock)+MakeGStorable (CSigAtomic)+MakeGStorable (CPtrdiff)+MakeGStorable (CDouble)+MakeGStorable (CFloat)+MakeGStorable (CULLong)+MakeGStorable (CLLong)+MakeGStorable (CULong)+MakeGStorable (CLong)+MakeGStorable (CUInt)+MakeGStorable (CInt)+MakeGStorable (CUShort)+MakeGStorable (CShort)+MakeGStorable (CUChar)+MakeGStorable (CSChar)+MakeGStorable (CChar)++-- Ptr+MakeGStorable (IntPtr)+MakeGStorable (WordPtr)++MakeGStorable ((StablePtr a))+MakeGStorable ((Ptr a)) +MakeGStorable ((FunPtr a))++-- Posix+MakeGStorable (Fd)+MakeGStorable (CRLim)+MakeGStorable (CTcflag)+MakeGStorable (CSpeed)+MakeGStorable (CCc)+MakeGStorable (CUid)+MakeGStorable (CNlink)+MakeGStorable (CGid)+MakeGStorable (CSsize)+MakeGStorable (CPid)+MakeGStorable (COff)+MakeGStorable (CMode)+MakeGStorable (CIno)+MakeGStorable (CDev)+ ++
+ src/Foreign/Storable/Generic/Internal.hs view
@@ -0,0 +1,219 @@+{-|+Module : Foreign.Storable.Generic.Internal+Copyright : (c) Mateusz Kłoczko, 2016+License : MIT+Maintainer : mateusz.p.kloczko@gmail.com+Stability : experimental+Portability : portable+++-}++{-#LANGUAGE FlexibleInstances #-}+{-#LANGUAGE FlexibleContexts #-}+{-#LANGUAGE DefaultSignatures #-}+{-#LANGUAGE TypeOperators #-}+{-#LANGUAGE ScopedTypeVariables #-}+{-#LANGUAGE UndecidableInstances #-}++module Foreign.Storable.Generic.Internal (+ GStorable'(..),+ GStorable (..),+ internalSizeOf,+ internalAlignment,+ internalPeekByteOff,+ internalPokeByteOff,+ internalOffsets+ ) where++import GHC.Generics+import Foreign.Ptr+import Foreign.Storable+import Foreign.Marshal.Alloc+import Foreign.C.Types++import Data.Int++import Debug.Trace++import Foreign.Storable.Generic.Tools++import GHC.Exts++-- Defining the generics ---++class GStorable' f where+ -- | Read the element at a given offset. Additional information about the offests + -- of the subfields are needed.+ gpeekByteOff' :: [Int] -- ^ List of fields' offsets for the type/struct. + -> Int -- ^ The index. Used to obtain the correct offset+ -> Ptr b -- ^ The pointer to the type/struct.+ -> Int -- ^ Global offset.+ -> IO (f a) -- ^ The result, wrapped in GHC.Generic metadata.+ -- | Write the element at a given offset. Additional information about the offests + -- of the subfields are needed.+ gpokeByteOff' :: [Int] -- ^ List of fields' offsets for the type/struct.+ -> Int -- ^ The index. Used to obtain the correct offset.+ -> Ptr b -- ^ The pointer to the type/struct.+ -> Int -- ^ Global offset.+ -> (f a) -- ^ The element to write, wrapped in GHC.Generic metadata.+ -> IO ()++ -- | Calculates the number of type's/struct's fields.+ gnumberOf' :: f a -- ^ GHC.Generic information about a given type/struct.+ -> Int -- ^ Size.++ -- | Calculates the sizes of type's/struct's fields.+ glistSizeOf' :: f a -- ^ GHC.Generic information about a given type/struct. + -> [Size] -- ^ List of sizes.++ -- | Calculates the alignments of type's/struct's fields.+ glistAlignment' :: f a -- ^ GHC.Generic information about a given type/struct.+ -> [Alignment] -- ^ List of alignments.+++instance (GStorable' f) => GStorable' (M1 i t f) where+ -- Wrap the peeked value in metadata.+ {-# INLINE gpeekByteOff' #-}+ gpeekByteOff' offsets ix ptr offset = M1 <$> gpeekByteOff' offsets ix ptr offset+ -- Discard the metadata and go further.+ {-# INLINE gpokeByteOff' #-}+ gpokeByteOff' offsets ix ptr offset (M1 x) = gpokeByteOff' offsets ix ptr offset x + ++ gnumberOf' (M1 v) = gnumberOf' v+ glistSizeOf' _ = glistSizeOf' (undefined :: f p)+ glistAlignment' _ = glistAlignment' (undefined :: f p)++instance (GStorable' f, GStorable' g) => GStorable' (f :*: g) where+ -- Tree-like traversal for reading the type.+ {-# INLINE gpeekByteOff' #-}+ gpeekByteOff' offsets ix ptr offset = (:*:) <$> peeker new_ix <*> peeker ix+ where new_ix = ix - n2 -- The new index for the left part of the tree.+ n2 = gnumberOf' (undefined :: g a) -- Number of elements for the right part of the tree+ peeker n_ix = gpeekByteOff' offsets n_ix ptr offset -- gpeekByteOff' wrapped to peek into subtrees.+ -- Tree like traversal for writing the type.+ {-# INLINE gpokeByteOff' #-}+ gpokeByteOff' offsets ix ptr offset (x :*: y) = peeker new_ix x >> peeker ix y+ where new_ix = ix - n2 + n2 = gnumberOf' (undefined :: g a) -- Number of elements for the right part of the tree.+ peeker n_ix z = gpokeByteOff' offsets n_ix ptr offset z -- gpokeByteOff' wrapped to peek into the subtree+++++ gnumberOf' _ = gnumberOf' (undefined :: f a) + gnumberOf' (undefined :: g a)+ -- Concatenate the lists. + glistSizeOf' _ = glistSizeOf' (undefined :: f a) ++ glistSizeOf' (undefined :: g a)+ -- Concatenate the lists.+ glistAlignment' _ = glistAlignment' (undefined :: f a) ++ glistAlignment' (undefined :: g a)++instance (GStorable a) => GStorable' (K1 i a) where+ {-# INLINE gpeekByteOff' #-}+ gpeekByteOff' offsets ix ptr offset = K1 <$> gpeekByteOff ptr (off1 + offset)+ where off1 = inline (offsets !! ix)+ {-# INLINE gpokeByteOff' #-}+ gpokeByteOff' offsets ix ptr offset (K1 x) = gpokeByteOff ptr (off1 + offset) x+ where off1 = inline (offsets !! ix) +++ -- When we use the contructor, just return one.+ gnumberOf' _ = 1+ -- When the constructor is used, return the size of + -- the constructed type in a list.+ glistSizeOf' _ = [gsizeOf (undefined :: a)]+ -- When the constructor is used, return the alignment of + -- the constructed type in a list.+ glistAlignment' _ = [galignment (undefined :: a)] +++-- These functions were moved outside GStorable type class.+-- They take generic representations as input.++{-# INLINE internalSizeOf #-}+-- | Calculates the size of generic data-type.+internalSizeOf :: forall f p. (GStorable' f)+ => f p -- ^ Generic representation + -> Int -- ^ Resulting size+internalSizeOf _ = calcSize $ zip sizes aligns+ where sizes = glistSizeOf' (undefined :: f p)+ aligns = glistAlignment' (undefined :: f p)++{-# INLINE internalAlignment #-}+-- | Calculates the alignment of generic data-type.+internalAlignment :: forall f p. (GStorable' f) + => f p -- ^ Generic representation+ -> Alignment -- ^ Resulting alignment+internalAlignment _ = calcAlignment aligns+ where aligns = glistAlignment' (undefined :: f p)++{-# INLINE internalPeekByteOff #-}+-- | View the variable under a pointer, with offset.+internalPeekByteOff :: forall f p b. (GStorable' f) + => Ptr b -- ^ Pointer to peek + -> Offset -- ^ Offset + -> IO (f p) -- ^ Resulting generic representation+internalPeekByteOff ptr off = gpeekByteOff' offsets ix ptr off+ where offsets = internalOffsets (undefined :: f p)+ ix = gnumberOf' (undefined :: f p) - 1++{-# INLINE internalPokeByteOff #-}+-- | Write the variable under the pointer, with offset.+internalPokeByteOff :: forall f p b. (GStorable' f) + => Ptr b -- ^ Pointer to write to+ -> Offset -- ^ Offset + -> f p -- ^ Written generic representation + -> IO () +internalPokeByteOff ptr off rep = gpokeByteOff' offsets ix ptr off rep+ where offsets = internalOffsets (undefined :: f p)+ ix = gnumberOf' (undefined :: f p) - 1++{-# INLINE internalOffsets #-}+-- | Obtain the list of offsets+internalOffsets :: forall f p. (GStorable' f)+ => f p -- Generic representation+ -> [Offset] -- List of offsets+internalOffsets _ = calcOffsets $ zip sizes aligns+ where sizes = glistSizeOf' (undefined :: f p)+ aligns= glistAlignment' (undefined :: f p)++-- | The class uses the default Generic based implementations to +-- provide Storable instances for types made from primitive types.+-- Does not work on Algebraic Data Types with more than one constructor.+class GStorable a where+ -- | Calculate the size of the type.+ {-# INLINE gsizeOf #-}+ gsizeOf :: a -- ^ Element of a given type. Can be undefined.+ -> Int -- ^ Size.+ default gsizeOf :: (Generic a, GStorable' (Rep a))+ => a -> Int+ gsizeOf _ = internalSizeOf (undefined :: Rep a p) + + -- | Calculate the alignment of the type.+ {-# INLINE galignment #-}+ galignment :: a -- ^ Element of a given type. Can be undefined + -> Int -- ^ Alignment.+ default galignment :: (Generic a, GStorable' (Rep a))+ => a -> Int+ galignment _ = internalAlignment (undefined :: Rep a p) ++ -- | Read the variable from a given pointer.+ gpeekByteOff :: Ptr b -- ^ Pointer to the variable+ -> Int -- ^ Offset+ -> IO a -- ^ Returned variable.+ default gpeekByteOff :: (Generic a, GStorable' (Rep a))+ => Ptr b -> Int -> IO a+ {-# INLINE gpeekByteOff #-}+ gpeekByteOff ptr offset = to <$> internalPeekByteOff ptr offset++ -- | Write the variable to a pointer. + gpokeByteOff :: Ptr b -- ^ Pointer to the variable. + -> Int -- ^ Offset.+ -> a -- ^ The variable+ -> IO ()+ default gpokeByteOff :: (Generic a, GStorable' (Rep a))+ => Ptr b -> Int -> a -> IO ()+ {-# INLINE gpokeByteOff #-}+ gpokeByteOff ptr offset x = internalPokeByteOff ptr offset (from x)++
+ src/Foreign/Storable/Generic/Tools.hs view
@@ -0,0 +1,106 @@+{-|+Module : Foreign.Storable.Generic.Tools+Copyright : (c) Mateusz Kłoczko, 2016+License : MIT+Maintainer : mateusz.p.kloczko@gmail.com+Stability : experimental+Portability : portable+++-}+++{-#LANGUAGE FlexibleInstances #-}+{-#LANGUAGE FlexibleContexts #-}+{-#LANGUAGE TypeOperators #-}+{-#LANGUAGE ScopedTypeVariables #-}+{-#LANGUAGE UndecidableInstances #-}++module Foreign.Storable.Generic.Tools (+ Size,+ Alignment,+ Offset,+ Filling(..),+ calcOffsets,+ calcSize,+ calcAlignment,+ getFilling+) where++import Data.List+++-- | The datatype representing the memory layout of a given struct.+data Filling = Size Int | Padding Int deriving(Show, Eq)++-- | Checks whether the size or padding are zero.+not_zero :: Filling -> Bool+not_zero (Size 0) = False+not_zero (Padding 0) = False+not_zero _ = True+++type Size = Int+type Alignment = Int+type Offset = Int++++-- | Get the memory layout of a given type/struct. Used mostly as debug information.+getFilling :: [(Size,Alignment)] -- ^ List of sizes and aligments of the type's/struct's fields. [(Int,Int)]+ -> [Filling] -- ^ List representing the memory layout. [Filling]+getFilling size_align = reverse $ filter not_zero $ getFilling' (ordered ++ [(gl_size,0)]) 0 0 []+ where offsets = calcOffsets size_align :: [Offset]+ sizes = map fst size_align :: [Size]+ ordered = sortBy (\(o1,_) (o2,_) -> compare o1 o2) $ -- Needs to be sorted in case the fields are rearranged. + zip offsets sizes :: [(Offset,Size)] + gl_size = calcSize size_align :: Offset -- This variable is used as offset++getFilling' :: [(Offset, Size)] -- ^ List of struct's fields' offsets and sizes + -> Size -- ^ Size of the previous element+ -> Offset -- ^ Offest of the previous element+ -> [Filling] -- ^ Accumulator: List of filling+ -> [Filling] -- ^ Returned list of fillings.+getFilling' [] _ _ acc = acc+getFilling' ((o2,s2):rest) s1 o1 acc = getFilling' rest s2 o2 (Size s2 : Padding ((o2-o1) - s1) : acc )++{-# NOINLINE calcOffsets #-}+-- | Calculates the memory offset of type's/struct's fields.+calcOffsets :: [(Size, Alignment)] -- ^ List of sizes and aligments of the type's/struct's fields. [(Int,Int)]+ -> [Offset] -- ^ List representing the offests of the type's/struct's fields. [Int]+calcOffsets [] = []+calcOffsets size_align = reverse $ fst $ calcOffsets' size_align 0 []++++{-# NOINLINE calcOffsets' #-}+calcOffsets' :: [(Size, Alignment)] -- ^ List of struct's fields' sizes and alignments+ -> Int -- ^ The intermediate variable between the current and previous iteration.+ -> [Offset] -- ^ Accumulator+ -> ([Offset], Int) -- ^ List of offsets and the last intermediate value.+calcOffsets' [] inter acc = (acc, inter) +calcOffsets' ((s,a):rest) inter acc = calcOffsets' rest (last_off + s) (last_off: acc)+ where p = (a - inter) `mod` a -- Padding+ last_off = inter + p :: Offset+++{-# NOINLINE calcSize #-}+-- | Calculates the size of the type/struct.+calcSize :: [(Size, Alignment)] -- ^ List of sizes and aligments of the type's/struct's fields. [(Int,Int)].+ -> Size -- ^ The returned size. Int+calcSize size_align = inter + ((glob_align - inter) `mod` glob_align)+ where glob_align = calcAlignment $ map snd size_align+ inter = snd $ calcOffsets' size_align 0 []++{-# NOINLINE calcAlignment #-}+-- | Calculate the alignment of a struct.+calcAlignment :: [Alignment] -- ^ List of struct's fields' alignments.+ -> Alignment -- ^ The resulting alignment.+calcAlignment aligns = calcAlignment' aligns 1+++calcAlignment' :: [Alignment] -- ^ List of alignments+ -> Alignment -- ^ Accumulator+ -> Alignment -- ^ The resulting alignment.+calcAlignment' [] glob = glob+calcAlignment' (al:aligns) glob = calcAlignment' aligns (max glob al)
+ test/Basic/MemoryCSpec.hs view
@@ -0,0 +1,114 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts#-}+module Main where+++-- Tested module.+import TestCases++-- Test libraries+import Test.Hspec+import Test.QuickCheck++-- Helpers+import Foreign.Marshal.Array+import Foreign.Storable+++same_alignment a = getAlignment a `shouldReturn` alignment a+same_size a = getSize a `shouldReturn` sizeOf a+same_offsets a = do+ let offsets = goffsets a+ ptr <- mallocArray $ length offsets+ pokeArray ptr offsets+ checkOffsets a ptr `shouldReturn` True++same_fields a = do+ ptr1 <- newStorable a+ ptr2 <- new a+ checkFields ptr1 ptr2 `shouldReturn` True+main = hspec $ do+ describe "Test for same size" $ do+ it "C1" $ property $ (same_size :: C1 -> Expectation)+ it "C2" $ property $ (same_size :: C2 -> Expectation)+ it "C3" $ property $ (same_size :: C3 -> Expectation)+ it "C4" $ property $ (same_size :: C4 -> Expectation)+ it "C5" $ property $ (same_size :: C5 -> Expectation)+ it "C6" $ property $ (same_size :: C6 -> Expectation)+ it "C7" $ property $ (same_size :: C7 -> Expectation)+ it "C8" $ property $ (same_size :: C8 -> Expectation)+ it "C9" $ property $ (same_size :: C9 -> Expectation)+ it "C10" $ property $ (same_size :: C10 -> Expectation)+ it "C11" $ property $ (same_size :: C11 -> Expectation)+ it "C12" $ property $ (same_size :: C12 -> Expectation)+ it "C13" $ property $ (same_size :: C13 -> Expectation)+ it "C14" $ property $ (same_size :: C14 -> Expectation)+ it "C15" $ property $ (same_size :: C15 -> Expectation)+ it "C16" $ property $ (same_size :: C16 -> Expectation)+ it "C17" $ property $ (same_size :: C17 -> Expectation)+ it "C18" $ property $ (same_size :: C18 -> Expectation)+ it "C19" $ property $ (same_size :: C19 -> Expectation)+ it "C20" $ property $ (same_size :: C20 -> Expectation)+ describe "Test for same alignment" $ do+ it "C1" $ property $ (same_alignment :: C1 -> Expectation)+ it "C2" $ property $ (same_alignment :: C2 -> Expectation)+ it "C3" $ property $ (same_alignment :: C3 -> Expectation)+ it "C4" $ property $ (same_alignment :: C4 -> Expectation)+ it "C5" $ property $ (same_alignment :: C5 -> Expectation)+ it "C6" $ property $ (same_alignment :: C6 -> Expectation)+ it "C7" $ property $ (same_alignment :: C7 -> Expectation)+ it "C8" $ property $ (same_alignment :: C8 -> Expectation)+ it "C9" $ property $ (same_alignment :: C9 -> Expectation)+ it "C10" $ property $ (same_alignment :: C10 -> Expectation)+ it "C11" $ property $ (same_alignment :: C11 -> Expectation)+ it "C12" $ property $ (same_alignment :: C12 -> Expectation)+ it "C13" $ property $ (same_alignment :: C13 -> Expectation)+ it "C14" $ property $ (same_alignment :: C14 -> Expectation)+ it "C15" $ property $ (same_alignment :: C15 -> Expectation)+ it "C16" $ property $ (same_alignment :: C16 -> Expectation)+ it "C17" $ property $ (same_alignment :: C17 -> Expectation)+ it "C18" $ property $ (same_alignment :: C18 -> Expectation)+ it "C19" $ property $ (same_alignment :: C19 -> Expectation)+ it "C20" $ property $ (same_alignment :: C20 -> Expectation)+ describe "Test for same offsets" $ do+ it "C1" $ property $ (same_offsets :: C1 -> Expectation)+ it "C2" $ property $ (same_offsets :: C2 -> Expectation)+ it "C3" $ property $ (same_offsets :: C3 -> Expectation)+ it "C4" $ property $ (same_offsets :: C4 -> Expectation)+ it "C5" $ property $ (same_offsets :: C5 -> Expectation)+ it "C6" $ property $ (same_offsets :: C6 -> Expectation)+ it "C7" $ property $ (same_offsets :: C7 -> Expectation)+ it "C8" $ property $ (same_offsets :: C8 -> Expectation)+ it "C9" $ property $ (same_offsets :: C9 -> Expectation)+ it "C10" $ property $ (same_offsets :: C10 -> Expectation)+ it "C11" $ property $ (same_offsets :: C11 -> Expectation)+ it "C12" $ property $ (same_offsets :: C12 -> Expectation)+ it "C13" $ property $ (same_offsets :: C13 -> Expectation)+ it "C14" $ property $ (same_offsets :: C14 -> Expectation)+ it "C15" $ property $ (same_offsets :: C15 -> Expectation)+ it "C16" $ property $ (same_offsets :: C16 -> Expectation)+ it "C17" $ property $ (same_offsets :: C17 -> Expectation)+ it "C18" $ property $ (same_offsets :: C18 -> Expectation)+ it "C19" $ property $ (same_offsets :: C19 -> Expectation)+ it "C20" $ property $ (same_offsets :: C20 -> Expectation)+ describe "Test for same fields" $ do+ it "C1" $ property $ (same_fields :: C1 -> Expectation)+ it "C2" $ property $ (same_fields :: C2 -> Expectation)+ it "C3" $ property $ (same_fields :: C3 -> Expectation)+ it "C4" $ property $ (same_fields :: C4 -> Expectation)+ it "C5" $ property $ (same_fields :: C5 -> Expectation)+ it "C6" $ property $ (same_fields :: C6 -> Expectation)+ it "C7" $ property $ (same_fields :: C7 -> Expectation)+ it "C8" $ property $ (same_fields :: C8 -> Expectation)+ it "C9" $ property $ (same_fields :: C9 -> Expectation)+ it "C10" $ property $ (same_fields :: C10 -> Expectation)+ it "C11" $ property $ (same_fields :: C11 -> Expectation)+ it "C12" $ property $ (same_fields :: C12 -> Expectation)+ it "C13" $ property $ (same_fields :: C13 -> Expectation)+ it "C14" $ property $ (same_fields :: C14 -> Expectation)+ it "C15" $ property $ (same_fields :: C15 -> Expectation)+ it "C16" $ property $ (same_fields :: C16 -> Expectation)+ it "C17" $ property $ (same_fields :: C17 -> Expectation)+ it "C18" $ property $ (same_fields :: C18 -> Expectation)+ it "C19" $ property $ (same_fields :: C19 -> Expectation)+ it "C20" $ property $ (same_fields :: C20 -> Expectation)
+ test/Basic/cbits/TestCases.c view
@@ -0,0 +1,870 @@+#include <stddef.h>+#include <stdio.h>+#include <stdalign.h>+#include <stdlib.h>+#include "HsFFI.h"+typedef struct C1{+ HsInt32 a;+ HsInt32 b;+} C1;++C1 * newC1(HsInt32 a, HsInt32 b){+ C1 * ret = (C1*) malloc(sizeof(C1));+ ret->a = a;+ ret->b = b;+ return ret;+}++void pokeC1(C1* val, HsInt32 a, HsInt32 b){+ val->a = a;+ val->b = b;+}++int checkOffsetsC1(HsInt16 *offs){+ int a = offsetof(C1, a) == offs[0];+ int b = offsetof(C1, b) == offs[1];+ return a && b;+}++int checkFieldsC1(C1* s1, C1* s2){+ int a = s1->a == s2->a;+ int b = s1->b == s2->b;+ return a && b;+}++HsInt16 getSizeC1() {+ return sizeof(C1);+}++HsInt16 getAlignmentC1() {+ return alignof(C1);+}++typedef struct C2{+ HsInt32 a;+ HsInt16 b;+ HsInt8 c;+} C2;++C2 * newC2(HsInt32 a, HsInt16 b, HsInt8 c){+ C2 * ret = (C2*) malloc(sizeof(C2));+ ret->a = a;+ ret->b = b;+ ret->c = c;+ return ret;+}++void pokeC2(C2* val, HsInt32 a, HsInt16 b, HsInt8 c){+ val->a = a;+ val->b = b;+ val->c = c;+}++int checkOffsetsC2(HsInt16 *offs){+ int a = offsetof(C2, a) == offs[0];+ int b = offsetof(C2, b) == offs[1];+ int c = offsetof(C2, c) == offs[2];+ return a && b && c;+}++int checkFieldsC2(C2* s1, C2* s2){+ int a = s1->a == s2->a;+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ return a && b && c;+}++HsInt16 getSizeC2() {+ return sizeof(C2);+}++HsInt16 getAlignmentC2() {+ return alignof(C2);+}++typedef struct C3{+ HsInt32 a;+ HsInt8 b;+ HsInt16 c;+} C3;++C3 * newC3(HsInt32 a, HsInt8 b, HsInt16 c){+ C3 * ret = (C3*) malloc(sizeof(C3));+ ret->a = a;+ ret->b = b;+ ret->c = c;+ return ret;+}++void pokeC3(C3* val, HsInt32 a, HsInt8 b, HsInt16 c){+ val->a = a;+ val->b = b;+ val->c = c;+}++int checkOffsetsC3(HsInt16 *offs){+ int a = offsetof(C3, a) == offs[0];+ int b = offsetof(C3, b) == offs[1];+ int c = offsetof(C3, c) == offs[2];+ return a && b && c;+}++int checkFieldsC3(C3* s1, C3* s2){+ int a = s1->a == s2->a;+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ return a && b && c;+}++HsInt16 getSizeC3() {+ return sizeof(C3);+}++HsInt16 getAlignmentC3() {+ return alignof(C3);+}++typedef struct C4{+ HsInt32 a;+ HsInt8 b;+ HsInt8 c;+} C4;++C4 * newC4(HsInt32 a, HsInt8 b, HsInt8 c){+ C4 * ret = (C4*) malloc(sizeof(C4));+ ret->a = a;+ ret->b = b;+ ret->c = c;+ return ret;+}++void pokeC4(C4* val, HsInt32 a, HsInt8 b, HsInt8 c){+ val->a = a;+ val->b = b;+ val->c = c;+}++int checkOffsetsC4(HsInt16 *offs){+ int a = offsetof(C4, a) == offs[0];+ int b = offsetof(C4, b) == offs[1];+ int c = offsetof(C4, c) == offs[2];+ return a && b && c;+}++int checkFieldsC4(C4* s1, C4* s2){+ int a = s1->a == s2->a;+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ return a && b && c;+}++HsInt16 getSizeC4() {+ return sizeof(C4);+}++HsInt16 getAlignmentC4() {+ return alignof(C4);+}++typedef struct C5{+ HsInt32 a;+ HsInt16 b;+ HsInt8 c;+ HsInt8 d;+ HsInt8 e;+} C5;++C5 * newC5(HsInt32 a, HsInt16 b, HsInt8 c, HsInt8 d, HsInt8 e){+ C5 * ret = (C5*) malloc(sizeof(C5));+ ret->a = a;+ ret->b = b;+ ret->c = c;+ ret->d = d;+ ret->e = e;+ return ret;+}++void pokeC5(C5* val, HsInt32 a, HsInt16 b, HsInt8 c, HsInt8 d, HsInt8 e){+ val->a = a;+ val->b = b;+ val->c = c;+ val->d = d;+ val->e = e;+}++int checkOffsetsC5(HsInt16 *offs){+ int a = offsetof(C5, a) == offs[0];+ int b = offsetof(C5, b) == offs[1];+ int c = offsetof(C5, c) == offs[2];+ int d = offsetof(C5, d) == offs[3];+ int e = offsetof(C5, e) == offs[4];+ return a && b && c && d && e;+}++int checkFieldsC5(C5* s1, C5* s2){+ int a = s1->a == s2->a;+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ int d = s1->d == s2->d;+ int e = s1->e == s2->e;+ return a && b && c && d && e;+}++HsInt16 getSizeC5() {+ return sizeof(C5);+}++HsInt16 getAlignmentC5() {+ return alignof(C5);+}++typedef struct C6{+ HsInt64 a;+ HsInt8 b;+ HsInt64 c;+} C6;++C6 * newC6(HsInt64 a, HsInt8 b, HsInt64 c){+ C6 * ret = (C6*) malloc(sizeof(C6));+ ret->a = a;+ ret->b = b;+ ret->c = c;+ return ret;+}++void pokeC6(C6* val, HsInt64 a, HsInt8 b, HsInt64 c){+ val->a = a;+ val->b = b;+ val->c = c;+}++int checkOffsetsC6(HsInt16 *offs){+ int a = offsetof(C6, a) == offs[0];+ int b = offsetof(C6, b) == offs[1];+ int c = offsetof(C6, c) == offs[2];+ return a && b && c;+}++int checkFieldsC6(C6* s1, C6* s2){+ int a = s1->a == s2->a;+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ return a && b && c;+}++HsInt16 getSizeC6() {+ return sizeof(C6);+}++HsInt16 getAlignmentC6() {+ return alignof(C6);+}++typedef struct C7{+ C1 a;+ HsInt32 b;+} C7;++C7 * newC7(C1* a, HsInt32 b){+ C7 * ret = (C7*) malloc(sizeof(C7));+ ret->a = *a;+ ret->b = b;+ return ret;+}++void pokeC7(C7* val, C1* a, HsInt32 b){+ val->a = *a;+ val->b = b;+}++int checkOffsetsC7(HsInt16 *offs){+ int a = offsetof(C7, a) == offs[0];+ int b = offsetof(C7, b) == offs[1];+ return a && b;+}++int checkFieldsC7(C7* s1, C7* s2){+ int a = checkFieldsC1(&(s1->a),&(s2->a));+ int b = s1->b == s2->b;+ return a && b;+}++HsInt16 getSizeC7() {+ return sizeof(C7);+}++HsInt16 getAlignmentC7() {+ return alignof(C7);+}++typedef struct C8{+ C2 a;+ HsInt8 b;+ C4 c;+} C8;++C8 * newC8(C2* a, HsInt8 b, C4* c){+ C8 * ret = (C8*) malloc(sizeof(C8));+ ret->a = *a;+ ret->b = b;+ ret->c = *c;+ return ret;+}++void pokeC8(C8* val, C2* a, HsInt8 b, C4* c){+ val->a = *a;+ val->b = b;+ val->c = *c;+}++int checkOffsetsC8(HsInt16 *offs){+ int a = offsetof(C8, a) == offs[0];+ int b = offsetof(C8, b) == offs[1];+ int c = offsetof(C8, c) == offs[2];+ return a && b && c;+}++int checkFieldsC8(C8* s1, C8* s2){+ int a = checkFieldsC2(&(s1->a),&(s2->a));+ int b = s1->b == s2->b;+ int c = checkFieldsC4(&(s1->c),&(s2->c));+ return a && b && c;+}++HsInt16 getSizeC8() {+ return sizeof(C8);+}++HsInt16 getAlignmentC8() {+ return alignof(C8);+}++typedef struct C9{+ C5 a;+ HsInt8 b;+ HsInt8 c;+ HsInt8 d;+} C9;++C9 * newC9(C5* a, HsInt8 b, HsInt8 c, HsInt8 d){+ C9 * ret = (C9*) malloc(sizeof(C9));+ ret->a = *a;+ ret->b = b;+ ret->c = c;+ ret->d = d;+ return ret;+}++void pokeC9(C9* val, C5* a, HsInt8 b, HsInt8 c, HsInt8 d){+ val->a = *a;+ val->b = b;+ val->c = c;+ val->d = d;+}++int checkOffsetsC9(HsInt16 *offs){+ int a = offsetof(C9, a) == offs[0];+ int b = offsetof(C9, b) == offs[1];+ int c = offsetof(C9, c) == offs[2];+ int d = offsetof(C9, d) == offs[3];+ return a && b && c && d;+}++int checkFieldsC9(C9* s1, C9* s2){+ int a = checkFieldsC5(&(s1->a),&(s2->a));+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ int d = s1->d == s2->d;+ return a && b && c && d;+}++HsInt16 getSizeC9() {+ return sizeof(C9);+}++HsInt16 getAlignmentC9() {+ return alignof(C9);+}++typedef struct C10{+ C8 a;+ HsInt64 b;+ C1 c;+} C10;++C10 * newC10(C8* a, HsInt64 b, C1* c){+ C10 * ret = (C10*) malloc(sizeof(C10));+ ret->a = *a;+ ret->b = b;+ ret->c = *c;+ return ret;+}++void pokeC10(C10* val, C8* a, HsInt64 b, C1* c){+ val->a = *a;+ val->b = b;+ val->c = *c;+}++int checkOffsetsC10(HsInt16 *offs){+ int a = offsetof(C10, a) == offs[0];+ int b = offsetof(C10, b) == offs[1];+ int c = offsetof(C10, c) == offs[2];+ return a && b && c;+}++int checkFieldsC10(C10* s1, C10* s2){+ int a = checkFieldsC8(&(s1->a),&(s2->a));+ int b = s1->b == s2->b;+ int c = checkFieldsC1(&(s1->c),&(s2->c));+ return a && b && c;+}++HsInt16 getSizeC10() {+ return sizeof(C10);+}++HsInt16 getAlignmentC10() {+ return alignof(C10);+}++typedef struct C11{+ C10 a;+ C10 b;+} C11;++C11 * newC11(C10* a, C10* b){+ C11 * ret = (C11*) malloc(sizeof(C11));+ ret->a = *a;+ ret->b = *b;+ return ret;+}++void pokeC11(C11* val, C10* a, C10* b){+ val->a = *a;+ val->b = *b;+}++int checkOffsetsC11(HsInt16 *offs){+ int a = offsetof(C11, a) == offs[0];+ int b = offsetof(C11, b) == offs[1];+ return a && b;+}++int checkFieldsC11(C11* s1, C11* s2){+ int a = checkFieldsC10(&(s1->a),&(s2->a));+ int b = checkFieldsC10(&(s1->b),&(s2->b));+ return a && b;+}++HsInt16 getSizeC11() {+ return sizeof(C11);+}++HsInt16 getAlignmentC11() {+ return alignof(C11);+}++typedef struct C12{+ HsInt64 a;+ HsInt64 b;+ HsInt64 c;+ HsInt64 d;+} C12;++C12 * newC12(HsInt64 a, HsInt64 b, HsInt64 c, HsInt64 d){+ C12 * ret = (C12*) malloc(sizeof(C12));+ ret->a = a;+ ret->b = b;+ ret->c = c;+ ret->d = d;+ return ret;+}++void pokeC12(C12* val, HsInt64 a, HsInt64 b, HsInt64 c, HsInt64 d){+ val->a = a;+ val->b = b;+ val->c = c;+ val->d = d;+}++int checkOffsetsC12(HsInt16 *offs){+ int a = offsetof(C12, a) == offs[0];+ int b = offsetof(C12, b) == offs[1];+ int c = offsetof(C12, c) == offs[2];+ int d = offsetof(C12, d) == offs[3];+ return a && b && c && d;+}++int checkFieldsC12(C12* s1, C12* s2){+ int a = s1->a == s2->a;+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ int d = s1->d == s2->d;+ return a && b && c && d;+}++HsInt16 getSizeC12() {+ return sizeof(C12);+}++HsInt16 getAlignmentC12() {+ return alignof(C12);+}++typedef struct C13{+ C12 a;+ C12 b;+ C12 c;+ C12 d;+} C13;++C13 * newC13(C12* a, C12* b, C12* c, C12* d){+ C13 * ret = (C13*) malloc(sizeof(C13));+ ret->a = *a;+ ret->b = *b;+ ret->c = *c;+ ret->d = *d;+ return ret;+}++void pokeC13(C13* val, C12* a, C12* b, C12* c, C12* d){+ val->a = *a;+ val->b = *b;+ val->c = *c;+ val->d = *d;+}++int checkOffsetsC13(HsInt16 *offs){+ int a = offsetof(C13, a) == offs[0];+ int b = offsetof(C13, b) == offs[1];+ int c = offsetof(C13, c) == offs[2];+ int d = offsetof(C13, d) == offs[3];+ return a && b && c && d;+}++int checkFieldsC13(C13* s1, C13* s2){+ int a = checkFieldsC12(&(s1->a),&(s2->a));+ int b = checkFieldsC12(&(s1->b),&(s2->b));+ int c = checkFieldsC12(&(s1->c),&(s2->c));+ int d = checkFieldsC12(&(s1->d),&(s2->d));+ return a && b && c && d;+}++HsInt16 getSizeC13() {+ return sizeof(C13);+}++HsInt16 getAlignmentC13() {+ return alignof(C13);+}++typedef struct C14{+ C13 a;+ C13 b;+ C13 c;+ C13 d;+ HsInt8 e;+} C14;++C14 * newC14(C13* a, C13* b, C13* c, C13* d, HsInt8 e){+ C14 * ret = (C14*) malloc(sizeof(C14));+ ret->a = *a;+ ret->b = *b;+ ret->c = *c;+ ret->d = *d;+ ret->e = e;+ return ret;+}++void pokeC14(C14* val, C13* a, C13* b, C13* c, C13* d, HsInt8 e){+ val->a = *a;+ val->b = *b;+ val->c = *c;+ val->d = *d;+ val->e = e;+}++int checkOffsetsC14(HsInt16 *offs){+ int a = offsetof(C14, a) == offs[0];+ int b = offsetof(C14, b) == offs[1];+ int c = offsetof(C14, c) == offs[2];+ int d = offsetof(C14, d) == offs[3];+ int e = offsetof(C14, e) == offs[4];+ return a && b && c && d && e;+}++int checkFieldsC14(C14* s1, C14* s2){+ int a = checkFieldsC13(&(s1->a),&(s2->a));+ int b = checkFieldsC13(&(s1->b),&(s2->b));+ int c = checkFieldsC13(&(s1->c),&(s2->c));+ int d = checkFieldsC13(&(s1->d),&(s2->d));+ int e = s1->e == s2->e;+ return a && b && c && d && e;+}++HsInt16 getSizeC14() {+ return sizeof(C14);+}++HsInt16 getAlignmentC14() {+ return alignof(C14);+}++typedef struct C15{+ C12 a;+ C14 b;+} C15;++C15 * newC15(C12* a, C14* b){+ C15 * ret = (C15*) malloc(sizeof(C15));+ ret->a = *a;+ ret->b = *b;+ return ret;+}++void pokeC15(C15* val, C12* a, C14* b){+ val->a = *a;+ val->b = *b;+}++int checkOffsetsC15(HsInt16 *offs){+ int a = offsetof(C15, a) == offs[0];+ int b = offsetof(C15, b) == offs[1];+ return a && b;+}++int checkFieldsC15(C15* s1, C15* s2){+ int a = checkFieldsC12(&(s1->a),&(s2->a));+ int b = checkFieldsC14(&(s1->b),&(s2->b));+ return a && b;+}++HsInt16 getSizeC15() {+ return sizeof(C15);+}++HsInt16 getAlignmentC15() {+ return alignof(C15);+}++typedef struct C16{+ C10 a;+ C15 b;+ C7 c;+} C16;++C16 * newC16(C10* a, C15* b, C7* c){+ C16 * ret = (C16*) malloc(sizeof(C16));+ ret->a = *a;+ ret->b = *b;+ ret->c = *c;+ return ret;+}++void pokeC16(C16* val, C10* a, C15* b, C7* c){+ val->a = *a;+ val->b = *b;+ val->c = *c;+}++int checkOffsetsC16(HsInt16 *offs){+ int a = offsetof(C16, a) == offs[0];+ int b = offsetof(C16, b) == offs[1];+ int c = offsetof(C16, c) == offs[2];+ return a && b && c;+}++int checkFieldsC16(C16* s1, C16* s2){+ int a = checkFieldsC10(&(s1->a),&(s2->a));+ int b = checkFieldsC15(&(s1->b),&(s2->b));+ int c = checkFieldsC7(&(s1->c),&(s2->c));+ return a && b && c;+}++HsInt16 getSizeC16() {+ return sizeof(C16);+}++HsInt16 getAlignmentC16() {+ return alignof(C16);+}++typedef struct C17{+ HsFloat a;+ HsDouble b;+ HsFloat c;+} C17;++C17 * newC17(HsFloat a, HsDouble b, HsFloat c){+ C17 * ret = (C17*) malloc(sizeof(C17));+ ret->a = a;+ ret->b = b;+ ret->c = c;+ return ret;+}++void pokeC17(C17* val, HsFloat a, HsDouble b, HsFloat c){+ val->a = a;+ val->b = b;+ val->c = c;+}++int checkOffsetsC17(HsInt16 *offs){+ int a = offsetof(C17, a) == offs[0];+ int b = offsetof(C17, b) == offs[1];+ int c = offsetof(C17, c) == offs[2];+ return a && b && c;+}++int checkFieldsC17(C17* s1, C17* s2){+ int a = s1->a == s2->a;+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ return a && b && c;+}++HsInt16 getSizeC17() {+ return sizeof(C17);+}++HsInt16 getAlignmentC17() {+ return alignof(C17);+}++typedef struct C18{+ HsFloat a;+ HsFloat b;+ HsDouble c;+ HsFloat d;+} C18;++C18 * newC18(HsFloat a, HsFloat b, HsDouble c, HsFloat d){+ C18 * ret = (C18*) malloc(sizeof(C18));+ ret->a = a;+ ret->b = b;+ ret->c = c;+ ret->d = d;+ return ret;+}++void pokeC18(C18* val, HsFloat a, HsFloat b, HsDouble c, HsFloat d){+ val->a = a;+ val->b = b;+ val->c = c;+ val->d = d;+}++int checkOffsetsC18(HsInt16 *offs){+ int a = offsetof(C18, a) == offs[0];+ int b = offsetof(C18, b) == offs[1];+ int c = offsetof(C18, c) == offs[2];+ int d = offsetof(C18, d) == offs[3];+ return a && b && c && d;+}++int checkFieldsC18(C18* s1, C18* s2){+ int a = s1->a == s2->a;+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ int d = s1->d == s2->d;+ return a && b && c && d;+}++HsInt16 getSizeC18() {+ return sizeof(C18);+}++HsInt16 getAlignmentC18() {+ return alignof(C18);+}++typedef struct C19{+ C17 a;+ HsFloat b;+ HsDouble c;+} C19;++C19 * newC19(C17* a, HsFloat b, HsDouble c){+ C19 * ret = (C19*) malloc(sizeof(C19));+ ret->a = *a;+ ret->b = b;+ ret->c = c;+ return ret;+}++void pokeC19(C19* val, C17* a, HsFloat b, HsDouble c){+ val->a = *a;+ val->b = b;+ val->c = c;+}++int checkOffsetsC19(HsInt16 *offs){+ int a = offsetof(C19, a) == offs[0];+ int b = offsetof(C19, b) == offs[1];+ int c = offsetof(C19, c) == offs[2];+ return a && b && c;+}++int checkFieldsC19(C19* s1, C19* s2){+ int a = checkFieldsC17(&(s1->a),&(s2->a));+ int b = s1->b == s2->b;+ int c = s1->c == s2->c;+ return a && b && c;+}++HsInt16 getSizeC19() {+ return sizeof(C19);+}++HsInt16 getAlignmentC19() {+ return alignof(C19);+}++typedef struct C20{+ HsDouble a;+ C18 b;+ HsDouble c;+ C19 d;+} C20;++C20 * newC20(HsDouble a, C18* b, HsDouble c, C19* d){+ C20 * ret = (C20*) malloc(sizeof(C20));+ ret->a = a;+ ret->b = *b;+ ret->c = c;+ ret->d = *d;+ return ret;+}++void pokeC20(C20* val, HsDouble a, C18* b, HsDouble c, C19* d){+ val->a = a;+ val->b = *b;+ val->c = c;+ val->d = *d;+}++int checkOffsetsC20(HsInt16 *offs){+ int a = offsetof(C20, a) == offs[0];+ int b = offsetof(C20, b) == offs[1];+ int c = offsetof(C20, c) == offs[2];+ int d = offsetof(C20, d) == offs[3];+ return a && b && c && d;+}++int checkFieldsC20(C20* s1, C20* s2){+ int a = s1->a == s2->a;+ int b = checkFieldsC18(&(s1->b),&(s2->b));+ int c = s1->c == s2->c;+ int d = checkFieldsC19(&(s1->d),&(s2->d));+ return a && b && c && d;+}++HsInt16 getSizeC20() {+ return sizeof(C20);+}++HsInt16 getAlignmentC20() {+ return alignof(C20);+}+
+ test/Spec/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}