blob: c96eb00cbe92672668b2c673530f94cc0f74351a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
{-# LANGUAGE ForeignFunctionInterface #-}
module Semver where
#include "semantic_version_ffi.h"
import Foreign hiding (unsafePerformIO)
import Foreign.C.String
import Foreign.Storable
import System.IO.Unsafe (unsafePerformIO)
data Semver = Semver
{ vMajor :: #{type unsigned int}
, vMinor :: #{type unsigned int}
, vPatch :: #{type unsigned int}
, vPrerelease :: String
, vBuild :: String
} deriving (Eq, Show)
-- don't bother with the strings for now
instance Storable Semver where
sizeOf _ = #{size semver_t}
alignment _ = alignment (undefined :: Word32)
peek ptr = do
r1 <- #{peek semver_t, major} ptr
r2 <- #{peek semver_t, minor} ptr
r3 <- #{peek semver_t, patch} ptr
return (Semver r1 r2 r3 "" "")
poke ptr (Semver r1 r2 r3 _ _) = do
#{poke semver_t, major} ptr r1
#{poke semver_t, minor} ptr r2
#{poke semver_t, patch} ptr r3
-- c functions
foreign import ccall "semantic_version_ffi.h satisfies"
c_satisfies :: Ptr Semver -> Ptr Semver -> IO Int
foreign import ccall "semantic_version_ffi.h lessThan"
c_lessThan :: Ptr Semver -> Ptr Semver -> IO Int
foreign import ccall "semantic_version_ffi.h nextMajor"
c_nextMajor :: Ptr Semver -> Ptr Semver -> IO ()
foreign import ccall "semantic_version_ffi.h nextMinor"
c_nextMinor :: Ptr Semver -> Ptr Semver -> IO ()
foreign import ccall "semantic_version_ffi.h nextPatch"
c_nextPatch :: Ptr Semver -> Ptr Semver -> IO ()
-- haskell wrappers
satisfies :: Semver -> Semver -> Bool
satisfies a b =
unsafePerformIO $
alloca $ \a_ptr ->
alloca $ \b_ptr -> do
poke a_ptr a
poke b_ptr b
r <- c_satisfies a_ptr b_ptr
return $ if (r == 1) then True else False
lessThan :: Semver -> Semver -> Bool
lessThan a b =
unsafePerformIO $
alloca $ \a_ptr ->
alloca $ \b_ptr -> do
poke a_ptr a
poke b_ptr b
r <- c_lessThan a_ptr b_ptr
return $ if (r == 1) then True else False
nextFunc :: (Ptr Semver -> Ptr Semver -> IO ()) -> Semver -> Semver
nextFunc f a =
unsafePerformIO $
alloca $ \a_ptr ->
alloca $ \b_ptr -> do
poke a_ptr a
f a_ptr b_ptr
peek b_ptr
nextMajor :: Semver -> Semver
nextMajor = nextFunc c_nextMajor
nextMinor :: Semver -> Semver
nextMinor = nextFunc c_nextMinor
nextPatch :: Semver -> Semver
nextPatch = nextFunc c_nextPatch
|