[project @ 2002-07-16 16:08:58 by ross]
[haskell-directory.git] / System / Environment.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module      :  System.Environment
4 -- Copyright   :  (c) The University of Glasgow 2001
5 -- License     :  BSD-style (see the file libraries/base/LICENSE)
6 -- 
7 -- Maintainer  :  libraries@haskell.org
8 -- Stability   :  provisional
9 -- Portability :  portable
10 --
11 -- Miscellaneous information about the system environment.
12 --
13 -----------------------------------------------------------------------------
14
15 module System.Environment
16     ( 
17       getArgs       -- :: IO [String]
18     , getProgName   -- :: IO String
19     , getEnv        -- :: String -> IO String
20   ) where
21
22 import Prelude
23
24 #ifndef __HUGS__
25 import Foreign
26 import Foreign.C
27 import Control.Monad
28 #endif
29
30 #ifdef __GLASGOW_HASKELL__
31 import GHC.IOBase
32 #endif
33
34 #ifdef __HUGS__
35 import Hugs.System
36 #endif
37
38 -- ---------------------------------------------------------------------------
39 -- getArgs, getProgName, getEnv
40
41 -- Computation `getArgs' returns a list of the program's command
42 -- line arguments (not including the program name).
43
44 #ifndef __HUGS__
45 getArgs :: IO [String]
46 getArgs = 
47   alloca $ \ p_argc ->  
48   alloca $ \ p_argv -> do
49    getProgArgv p_argc p_argv
50    p    <- fromIntegral `liftM` peek p_argc
51    argv <- peek p_argv
52    peekArray (p - 1) (advancePtr argv 1) >>= mapM peekCString
53
54    
55 foreign import ccall unsafe "getProgArgv"
56   getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()
57
58 {-|
59 Computation 'getProgName' returns the name of the program as it was
60 invoked.
61
62 However, this is hard-to-impossible to implement on some non-Unix
63 OSes, so instead, for maximum portability, we just return the leafname
64 of the program as invoked. Even then there are some differences
65 between platforms: on Windows, for example, a program invoked as foo
66 is probably really @FOO.EXE@, and that is what 'getProgName' will return.
67 -}
68 getProgName :: IO String
69 getProgName = 
70   alloca $ \ p_argc ->
71   alloca $ \ p_argv -> do
72      getProgArgv p_argc p_argv
73      argv <- peek p_argv
74      unpackProgName argv
75   
76 unpackProgName  :: Ptr (Ptr CChar) -> IO String   -- argv[0]
77 unpackProgName argv = do 
78   s <- peekElemOff argv 0 >>= peekCString
79   return (basename s)
80   where
81    basename :: String -> String
82    basename f = go f f
83     where
84       go acc [] = acc
85       go acc (x:xs) 
86         | isPathSeparator x = go xs xs
87         | otherwise         = go acc xs
88
89    isPathSeparator :: Char -> Bool
90    isPathSeparator '/'  = True
91 #ifdef mingw32_TARGET_OS 
92    isPathSeparator '\\' = True
93 #endif
94    isPathSeparator _    = False
95
96
97 -- Computation `getEnv var' returns the value
98 -- of the environment variable {\em var}.  
99
100 -- This computation may fail with
101 --    NoSuchThing: The environment variable does not exist.
102
103 getEnv :: String -> IO String
104 getEnv name =
105     withCString name $ \s -> do
106       litstring <- c_getenv s
107       if litstring /= nullPtr
108         then peekCString litstring
109         else ioException (IOError Nothing NoSuchThing "getEnv"
110                           "no environment variable" (Just name))
111
112 foreign import ccall unsafe "getenv"
113    c_getenv :: CString -> IO (Ptr CChar)
114 #endif  /* __HUGS__ */