X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=System%2FEnvironment.hs;h=c1b33b0cc5accb43de10e046599e38153d6adf68;hb=950ea620c19650754db3ae6058be71f0cdb89bb5;hp=c20d7d765b2942088329f1f9ff6c23be23285c22;hpb=2fec6a84226c1b78239e99a3883e31faedb62f46;p=ghc-base.git diff --git a/System/Environment.hs b/System/Environment.hs index c20d7d7..c1b33b0 100644 --- a/System/Environment.hs +++ b/System/Environment.hs @@ -14,27 +14,46 @@ module System.Environment ( - getArgs -- :: IO [String] - , getProgName -- :: IO String - , getEnv -- :: String -> IO String + getArgs, -- :: IO [String] + getProgName, -- :: IO String + getEnv, -- :: String -> IO String +#ifdef __GLASGOW_HASKELL__ + withArgs, + withProgName, +#endif ) where import Prelude +#ifndef __NHC__ +import Control.Exception ( bracket ) +#endif +#ifdef __GLASGOW_HASKELL__ import Foreign import Foreign.C import Control.Monad - -#ifdef __GLASGOW_HASKELL__ import GHC.IOBase #endif +#ifdef __HUGS__ +import Hugs.System +#endif + +#ifdef __NHC__ +import System + ( getArgs + , getProgName + , getEnv + ) +#endif + -- --------------------------------------------------------------------------- -- getArgs, getProgName, getEnv -- Computation `getArgs' returns a list of the program's command -- line arguments (not including the program name). +#ifdef __GLASGOW_HASKELL__ getArgs :: IO [String] getArgs = alloca $ \ p_argc -> @@ -104,3 +123,44 @@ getEnv name = foreign import ccall unsafe "getenv" c_getenv :: CString -> IO (Ptr CChar) + +{-| +@withArgs args act@ - while executing action @act@, have 'System.getArgs' +return @args@. +-} +withArgs xs act = do + p <- System.Environment.getProgName + withArgv (p:xs) act + +{-| +@withProgName name act@ - while executing action @act@, have 'System.getProgName'return @name@. +-} +withProgName nm act = do + xs <- System.Environment.getArgs + withArgv (nm:xs) act + +-- Worker routine which marshals and replaces an argv vector for +-- the duration of an action. + +withArgv new_args act = do + pName <- System.Environment.getProgName + existing_args <- System.Environment.getArgs + bracket (setArgs new_args) + (\argv -> do setArgs (pName:existing_args); freeArgv argv) + (const act) + +freeArgv :: Ptr CString -> IO () +freeArgv argv = do + size <- lengthArray0 nullPtr argv + sequence_ [peek (argv `advancePtr` i) >>= free | i <- [size, size-1 .. 0]] + free argv + +setArgs :: [String] -> IO (Ptr CString) +setArgs argv = do + vs <- mapM newCString argv >>= newArray0 nullPtr + setArgsPrim (length argv) vs + return vs + +foreign import ccall unsafe "setProgArgv" + setArgsPrim :: Int -> Ptr CString -> IO () +#endif /* __GLASGOW_HASKELL__ */