ba099eabd05576d1c56c4a5e6e1cc3a6b9906cc3
[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.Ptr
11 import Foreign.Marshal
12 import Foreign.C.Types
13 import Foreign.C.String
14
15 import qualified Data.ByteString as BS
16
17 data ParsedVersion
18
19 foreign import ccall unsafe "dpkg/dpkg-db.h parseversion"
20     c_ParseVersion :: Ptr ParsedVersion -> CString -> IO CString
21
22 foreign import ccall unsafe "dpkg/dpkg-db.h versioncompare"
23     c_VersionCompare :: Ptr ParsedVersion -> Ptr ParsedVersion -> IO CInt
24
25 foreign export ccall "thisname" blubb :: ()
26
27 blubb :: ()
28 blubb = ()
29
30 versionCompare :: BS.ByteString -> BS.ByteString -> Ordering
31 versionCompare v1 v2 = unsafePerformIO $
32     -- 12 bytes is enough to carry a struct versionrevision
33     allocaBytes 12 $ \ptr1 -> allocaBytes 12 $ \ptr2 ->  
34     BS.useAsCString v1 $ \v1p -> BS.useAsCString v2 $ \v2p -> do
35         r1 <- c_ParseVersion ptr1 v1p
36         if (r1 /= nullPtr)
37             then peekCString r1 >>= \err -> error $ "Failed to parse " ++ show v1 ++ ": " ++ err
38             else do
39         r2 <- c_ParseVersion ptr2 v2p
40         if (r2 /= nullPtr) 
41             then peekCString r2 >>= \err -> error $ "Failed to parse " ++ show v2 ++ ": " ++ err
42             else do
43         r3 <- c_VersionCompare ptr1 ptr2
44         return $ if r3 < 0 then LT else if r3 == 0 then EQ else GT