Improve rule description
[sat-britney.git] / DebVersionCmp.hs
1 {-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
2 -- |
3 -- Module: DebVersionCmp
4 -- Copyright: (c) 2011 Joachim Breitner
5 -- License: GPL-2
6 --
7 module DebVersionCmp where
8
9 import System.IO.Unsafe
10 import Foreign
11 import Foreign.C.Types
12 import Foreign.C.String
13
14 import qualified Data.ByteString as BS
15
16 data ParsedVersion
17
18 foreign import ccall unsafe "dpkg/dpkg-db.h parseversion"
19     c_ParseVersion :: Ptr ParsedVersion -> CString -> IO CString
20
21 foreign import ccall unsafe "dpkg/dpkg-db.h versioncompare"
22     c_VersionCompare :: Ptr ParsedVersion -> Ptr ParsedVersion -> IO CInt
23
24 foreign export ccall "thisname" blubb :: ()
25
26 blubb :: ()
27 blubb = ()
28
29 versionCompare :: BS.ByteString -> BS.ByteString -> Ordering
30 versionCompare v1 v2 = unsafePerformIO $
31     -- 12 bytes is enough to carry a struct versionrevision
32     allocaBytes 12 $ \ptr1 -> allocaBytes 12 $ \ptr2 ->  
33     BS.useAsCString v1 $ \v1p -> BS.useAsCString v2 $ \v2p -> do
34         r1 <- c_ParseVersion ptr1 v1p
35         if (r1 /= nullPtr)
36             then peekCString r1 >>= \err -> error $ "Failed to parse " ++ show v1 ++ ": " ++ err
37             else do
38         r2 <- c_ParseVersion ptr2 v2p
39         if (r2 /= nullPtr) 
40             then peekCString r2 >>= \err -> error $ "Failed to parse " ++ show v2 ++ ": " ++ err
41             else do
42         r3 <- c_VersionCompare ptr1 ptr2
43         return $ if r3 < 0 then LT else if r3 == 0 then EQ else GT