packages feed

haskell-gi-0.8: src/GI/Util.hs

module GI.Util
  ( maybeWithCString
  , getList
  , toFlags
  , split

  , prime
  , unprime
  , parenthesize

  , padTo
  , withComment
  ) where

import Foreign
import Foreign.C

import Data.List (unfoldr)

padTo n s = s ++ replicate (n - length s) ' '
withComment a b = padTo 40 a ++ "-- " ++ b

maybeWithCString :: Maybe String -> (CString -> IO a) -> IO a
maybeWithCString = maybe ($ nullPtr) withCString

getList :: (a -> IO CInt) -> (a -> CInt -> IO b) -> a -> IO [b]
getList getN getOne x = do
    n <- getN x
    mapM (getOne x) [0..n - 1]

toFlags :: Enum a => CInt -> [a]
toFlags n = loop n (sizeOf n * 8 - 1) -- Number of bits in the argument
    where loop _ (-1) = []
          loop n e =
              let rest = loop n (e - 1)
               in if testBit n e then toEnum (2 ^ e) : rest else rest

-- Splits a string separated by the given separator into a list of
-- constituents. For example: split '.' "A.BC.D" = ["A", "BC", "D"]
split :: Char -> String -> [String]
split sep = unfoldr span'
    where span' :: String -> Maybe (String, String)
          span' [] = Nothing
          span' s@(x:xs)
              | x == sep  = Just $ span (/= sep) xs
              | otherwise = Just $ span (/= sep) s

prime :: String -> String
prime = (++ "'")

-- Remove the prime at the end of the given string
unprime :: String -> String
unprime "" = error "Empty variable to unprime!"
unprime primed =
    case last primed of
      '\'' -> init primed
      _ -> error $ primed ++ " is not primed!"

parenthesize :: String -> String
parenthesize s = "(" ++ s ++ ")"