File: Utils.hsc

package info (click to toggle)
magic-haskell 1.1-12
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 88 kB
  • sloc: haskell: 14; makefile: 2
file content (77 lines) | stat: -rw-r--r-- 2,143 bytes parent folder | download | duplicates (10)
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
{- -*- Mode: haskell; -*-
Haskell magic Interface
Copyright (C) 2005 John Goerzen <jgoerzen@complete.org>

This code is under a 3-clause BSD license; see COPYING for details.
-}

{- |
   Module     : Magic.Utils
   Copyright  : Copyright (C) 2005 John Goerzen
   License    : BSD

   Maintainer : John Goerzen,
   Maintainer : jgoerzen\@complete.org
   Stability  : provisional
   Portability: portable

Utils

Written by John Goerzen, jgoerzen\@complete.org
-}

module Magic.Utils (flaglist2int, fromMagicPtr, withMagicPtr, checkIntError,
                    throwErrorIfNull)
where

import Foreign
import Foreign.C.Error
import Foreign.C.String
import Foreign.ForeignPtr
import Magic.TypesLL
import Magic.Types
import Data.Bits
import Foreign.C.Types
import Magic.Data

flaglist2int :: [MagicFlag] -> CInt
flaglist2int mfl =
    foldl (\c f -> c .|. (fromIntegral . fromEnum $ f)) 0 mfl

fromMagicPtr :: String -> IO (Ptr CMagic) -> IO Magic
fromMagicPtr caller action =
    do ptr <- throwErrnoIfNull caller action
       newForeignPtr magic_close ptr

throwErrorIfNull :: String -> Magic -> IO (Ptr a) -> IO (Ptr a)
throwErrorIfNull caller m action =
    do res <- action
       if res == nullPtr
          then throwError caller m
          else return res

withMagicPtr :: Magic -> (Ptr CMagic -> IO a) -> IO a
withMagicPtr m = withForeignPtr m

throwError :: String -> Magic -> IO a
throwError caller m = withMagicPtr m (\cmagic ->
               do errormsg <- magic_error cmagic
                  if errormsg /= nullPtr
                     then do em <- peekCString errormsg
                             fail $ caller ++ ": " ++ em
                     else fail $ caller ++ ": got error code but no error message"
                                     )

checkIntError :: String -> Magic -> IO CInt -> IO ()
checkIntError caller m action = 
    do res <- action
       if res == 0
          then return ()
          else throwError caller m


foreign import ccall unsafe "magic.h &magic_close"
  magic_close :: FunPtr (Ptr CMagic -> IO ())

foreign import ccall unsafe "magic.h magic_error"
  magic_error :: Ptr CMagic -> IO CString