packages feed

Hs2lib-0.4.8: WinDll/Utils/Pragma.hs

-----------------------------------------------------------------------------
-- |
-- Module      :  Windll
-- Copyright   :  (c) Tamar Christina 2009 - 2010
-- License     :  BSD3
-- 
-- Maintainer  :  tamar@zhox.com
-- Stability   :  experimental
-- Portability :  portable
--
-- This module contains the basic Pragma processing functions
-- to handle custom pragmas. Or specifically, those updating
-- the lookup lists.
--
-----------------------------------------------------------------------------

module WinDll.Utils.Pragma where

import WinDll.Session
import WinDll.Utils.Feedback
import WinDll.Structs.Structures
import WinDll.Lib.Native

-- | Retreive the pragmas matching the given directive
getPragmas :: String -> [Pragma] -> [Pragma]
getPragmas str = filter (\(Pragma s _)->s==str)

-- | Validate a pragma based on the given mask. '#' are taken to be a 
--   single string entry, spaces indicate a next element. 
--   The mask "# #@#" is taken as two elements, where the second one 
--   consists of two strings seperated by a @ sign.
validate :: String -> Pragma -> Exec Pragma
validate mask p@(Pragma nm ld) 
 = do guard (not $ isValid (words mask) ld) >>
         (die $   "Syntax error in Pragma " ++ nm ++ ", supplied value '" 
                ++ unwords ld ++ "' does not match mask '" ++ mask ++ "'")
      return p
 where isValid :: [String] -> [String] -> Bool
       isValid []     []     = True
       isValid (x:xs) (y:ys) = cmp x y && isValid xs ys
       isValid _      _      = False
       
       cmp :: String -> String -> Bool
       cmp ('#':xs) str       = let (fs, sn) = span (/='@') str
                                in cmp xs sn
       cmp ('@':xs) ('@':str) = cmp xs str
       cmp []       []        = True
       cmp _        _         = False

-- | Process the four convertion pragmas and create the 
--   proper conversion sets
processConversionPragmas :: [Pragma] -> Session -> Exec Session
processConversionPragmas prg session 
   = do hs2c  <- mapM (validate "# #@#") $ getPragmas "HS2C"  prg
        hs2cs <- mapM (validate "# #"  ) $ getPragmas "HS2C#" prg
        hs2hs <- mapM (validate "# #"  ) $ getPragmas "HS2HS" prg
        
        put session
        updateFromPragma hs2c  updt1 (\x y->y{n_hs2c =x ++ nativeLisths2c})
        updateFromPragma hs2c  updt2 (\x y->y{n_csize=x ++ nativeC_sizes})
        updateFromPragma hs2cs updt3 (\x y->y{n_hs2cs= \b -> x ++ nativeCslist b})
        updateFromPragma hs2hs updt4 (\x y->y{n_hs2hs=x ++ nativeConvList})
        get
 where updt1 [x,y] = (x, takeWhile (/='@') y)
       updt2 [x,y] = (x, read $ tail (dropWhile (/='@') y))
       updt3 [x,y] = (x, y)
       updt4 [x,y] = (x, y)
      
-- | Update a session by processing the values inside the given Pragmas
updateFromPragma :: [Pragma] -> ([String] -> (a, b)) -> ([(a, b)] -> WorkingSet -> WorkingSet) -> Exec ()
updateFromPragma prg process update 
   = do session <- get
        let results = map (\(Pragma _ lst)->process lst) prg
        let wrk = update results (workingset session)
        put $ session{workingset = wrk}