packages feed

Hs2lib-0.5.0: WinDll/Session/Debug.hs

{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE DeriveDataTypeable   #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Windll
-- Copyright   :  (c) Tamar Christina 2009 - 2010
-- License     :  BSD3
-- 
-- Maintainer  :  tamar@zhox.com
-- Stability   :  experimental
-- Portability :  portable
--
-- Session management information and global state modifiers for the 
-- debug program.
--
-----------------------------------------------------------------------------

module WinDll.Session.Debug (module WinDll.Session.Debug
                            ,module Control.Monad.State.Strict) where

import Control.Monad.State.Strict
import Control.Monad.Trans
import Control.Monad.Error
import Control.Monad

import System.Directory
import System.IO.Unsafe
import System.FilePath

import WinDll.Version.Debug
import WinDll.Debug.Records ( fileName, MemAlloc )
import {-# SOURCE #-} WinDll.Debug.Heap ( Heap(..) )

import Data.Either
import Data.Data
import Data.Char
import Data.Generics
import Data.Monoid

import GHC.Paths ( libdir )
import GHC (guessTarget, targetId, TargetId(..), runGhc)
import Module(moduleNameSlashes)

import Debug.Trace(trace)
                    
-- | The platform your compiling for, This determines the type of library that is created.
data Platform = Windows -- ^ Windows DLL
              | Unix    -- ^ Lib files
              deriving (Show,Eq,Read)
              
-- | Contains the enviroment settings, e.g. path to ghc,hsc2hs etc
data EnvPaths  = EnvPaths

-- | Simple flags, used with GetOpt
data Options = Version | Help
        deriving (Show,Eq)
                    
-- | Global session management information passed through each function                    
data Session = Session { mainFile           :: String         -- ^ @mainFile @ Main filename
                       , absPath            :: String         -- ^ @absPath@ The absolute path to the main file
                       , verbosity          :: Int            -- ^ @verbosity@ debugging verbosity level 
                       , outputDIR          :: String         -- ^ @outputDir@ Redirect output to a folder
                       , baseDir            :: String         -- ^ @baseDir@ Path to the base folder which contains the WinDll includes folder and template 
                       , outputFile         :: String         -- ^ @outputFile@ The output file name
                       , platform           :: Platform       -- ^ @platform@ The platform to compile for
                       , options            :: [Options]      -- ^ @options@ The none executable flags
                       , memAllocs          :: [MemAlloc]     -- ^ @memAllocs@ The list of memory allocations that we're processing
                       , memAllocsLen       :: Int            -- ^ @memAllocs@ The amount of allocations to process
                       , heap               :: Heap
                       }
                       deriving Show
     
-- | Monad transformer used to do all computations in     
type Exec a = StateT Session (ErrorT String IO) a

-- | Make the Either a Monad instance 
-- instance Monad (Either String) where
    -- fail str          = Left str
    -- return a          = Right a
    -- (Left str ) >>= _ = Left str
    -- (Right a)   >>= f = f a
    
-- | And also make the Either a Functor
instance Functor (Either String) where
    fmap f (Left str) = Left str
    fmap f (Right a)  = Right (f a)

-- | And a MonadPlus instance
instance MonadPlus (Either String) where
    mzero               = Left ""
    (Left _) `mplus` xs = xs
    xs       `mplus` ys = xs
    
-- | MonadIO instance so that liftIO can be used inside the StateT
-- instance MonadIO (Either String) where
    -- liftIO = (($!) return) . unsafePerformIO 

-- | The default session initialized to the values specific for windows
newSession = Session { mainFile     = ""
                     , absPath      = ""
                     , verbosity    = 0
                     , outputDIR    = "."
                     , baseDir      = []
                     , outputFile   = []
                     , platform     = Windows
                     , options      = []
                     , memAllocs    = []
                     , memAllocsLen = 0
                     , heap         = NoHeap
                     }

-- | Guess the fullname of a target file
guessPath :: FilePath -> IO FilePath
guessPath mangled = do fn <- fileName
                       let file      = takeFileName fn
                           fullname1 = mangled </> fn
                           fullname2 = mangled </> file
                       exists1 <- doesFileExist fullname1
                       exists2 <- doesFileExist fullname2
                       case (exists1, exists2) of 
                         (True,    _) -> return fullname1
                         (_   , True) -> return fullname2
                         (_   ,    _) -> error $ "Could not find '" ++ file ++ "' in the specified location"