a077f6f8c48e0164d78ed4caa82e65e8409c51e7
[ghc.git] / libraries / base / GHC / Environment.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE NoImplicitPrelude #-}
3 {-# LANGUAGE CPP #-}
4
5 module GHC.Environment (getFullArgs) where
6
7 import Foreign
8 import Foreign.C
9 import GHC.Base
10 import GHC.Real ( fromIntegral )
11
12 #if defined(mingw32_HOST_OS)
13 import GHC.IO (finally)
14 import GHC.Windows
15
16 # if defined(i386_HOST_ARCH)
17 # define WINDOWS_CCONV stdcall
18 # elif defined(x86_64_HOST_ARCH)
19 # define WINDOWS_CCONV ccall
20 # else
21 # error Unknown mingw32 arch
22 # endif
23 #else
24 import GHC.IO.Encoding
25 import qualified GHC.Foreign as GHC
26 #endif
27
28 -- | Computation 'getFullArgs' is the "raw" version of 'getArgs', similar
29 -- to @argv@ in other languages. It returns a list of the program's
30 -- command line arguments, starting with the program name, and
31 -- including those normally eaten by the RTS (+RTS ... -RTS).
32 getFullArgs :: IO [String]
33 #if defined(mingw32_HOST_OS)
34 -- Ignore the arguments to hs_init on Windows for the sake of Unicode compat
35 getFullArgs = do
36 p_arg_string <- c_GetCommandLine
37 alloca $ \p_argc -> do
38 p_argv <- c_CommandLineToArgv p_arg_string p_argc
39 if p_argv == nullPtr
40 then throwGetLastError "getFullArgs"
41 else flip finally (c_LocalFree p_argv) $ do
42 argc <- peek p_argc
43 p_argvs <- peekArray (fromIntegral argc) p_argv
44 mapM peekCWString p_argvs
45
46 foreign import WINDOWS_CCONV unsafe "windows.h GetCommandLineW"
47 c_GetCommandLine :: IO (Ptr CWString)
48
49 foreign import WINDOWS_CCONV unsafe "windows.h CommandLineToArgvW"
50 c_CommandLineToArgv :: Ptr CWString -> Ptr CInt -> IO (Ptr CWString)
51
52 foreign import WINDOWS_CCONV unsafe "Windows.h LocalFree"
53 c_LocalFree :: Ptr a -> IO (Ptr a)
54 #else
55 getFullArgs =
56 alloca $ \ p_argc ->
57 alloca $ \ p_argv -> do
58 getFullProgArgv p_argc p_argv
59 p <- fromIntegral `liftM` peek p_argc
60 argv <- peek p_argv
61 enc <- getFileSystemEncoding
62 peekArray p argv >>= mapM (GHC.peekCString enc)
63
64 foreign import ccall unsafe "getFullProgArgv"
65 getFullProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()
66 #endif