------------------------------------------------------------------------------- |-- Module : System.Environment-- Copyright : (c) The University of Glasgow 2001-- License : BSD-style (see the file libraries/base/LICENSE)-- -- Maintainer : libraries@haskell.org-- Stability : provisional-- Portability : portable---- Miscellaneous information about the system environment.-------------------------------------------------------------------------------moduleSystem.Environment(getArgs,-- :: IO [String]getProgName,-- :: IO StringgetEnv,-- :: String -> IO String#ifndef __NHC__withArgs,withProgName,#endif#ifdef __GLASGOW_HASKELL__getEnvironment,#endif)whereimportPrelude#ifdef __GLASGOW_HASKELL__importData.ListimportForeignimportForeign.CimportControl.Exception.Base(bracket)importControl.Monad-- import GHC.IOimportGHC.IO.Exception#endif#ifdef __HUGS__importHugs.System#endif#ifdef __NHC__importSystem(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->alloca$\p_argv->dogetProgArgvp_argcp_argvp<-fromIntegral`liftM`peekp_argcargv<-peekp_argvpeekArray(p-1)(advancePtrargv1)>>=mapMpeekCStringforeignimportccallunsafe"getProgArgv"getProgArgv::PtrCInt->Ptr(PtrCString)->IO(){-|
Computation 'getProgName' returns the name of the program as it was
invoked.
However, this is hard-to-impossible to implement on some non-Unix
OSes, so instead, for maximum portability, we just return the leafname
of the program as invoked. Even then there are some differences
between platforms: on Windows, for example, a program invoked as foo
is probably really @FOO.EXE@, and that is what 'getProgName' will return.
-}getProgName::IOStringgetProgName=alloca$\p_argc->alloca$\p_argv->dogetProgArgvp_argcp_argvargv<-peekp_argvunpackProgNameargvunpackProgName::Ptr(PtrCChar)->IOString-- argv[0]unpackProgNameargv=dos<-peekElemOffargv0>>=peekCStringreturn(basenames)wherebasename::String->Stringbasenamef=goffwheregoacc[]=accgoacc(x:xs)|isPathSeparatorx=goxsxs|otherwise=goaccxsisPathSeparator::Char->BoolisPathSeparator'/'=True#ifdef mingw32_HOST_OS isPathSeparator'\\'=True#endifisPathSeparator_=False-- | Computation 'getEnv' @var@ returns the value-- of the environment variable @var@. ---- This computation may fail with:---- * 'System.IO.Error.isDoesNotExistError' if the environment variable-- does not exist.getEnv::String->IOStringgetEnvname=withCStringname$\s->dolitstring<-c_getenvsiflitstring/=nullPtrthenpeekCStringlitstringelseioException(IOErrorNothingNoSuchThing"getEnv""no environment variable"Nothing(Justname))foreignimportccallunsafe"getenv"c_getenv::CString->IO(PtrCChar){-|
'withArgs' @args act@ - while executing action @act@, have 'getArgs'
return @args@.
-}withArgs::[String]->IOa->IOawithArgsxsact=dop<-System.Environment.getProgNamewithArgv(p:xs)act{-|
'withProgName' @name act@ - while executing action @act@,
have 'getProgName' return @name@.
-}withProgName::String->IOa->IOawithProgNamenmact=doxs<-System.Environment.getArgswithArgv(nm:xs)act-- Worker routine which marshals and replaces an argv vector for-- the duration of an action.withArgv::[String]->IOa->IOawithArgvnew_argsact=dopName<-System.Environment.getProgNameexisting_args<-System.Environment.getArgsbracket(setArgsnew_args)(\argv->do_<-setArgs(pName:existing_args)freeArgvargv)(constact)freeArgv::PtrCString->IO()freeArgvargv=dosize<-lengthArray0nullPtrargvsequence_[peek(argv`advancePtr`i)>>=free|i<-[size,size-1..0]]freeargvsetArgs::[String]->IO(PtrCString)setArgsargv=dovs<-mapMnewCStringargv>>=newArray0nullPtrsetArgsPrim(genericLengthargv)vsreturnvsforeignimportccallunsafe"setProgArgv"setArgsPrim::CInt->PtrCString->IO()-- |'getEnvironment' retrieves the entire environment as a-- list of @(key,value)@ pairs.---- If an environment entry does not contain an @\'=\'@ character,-- the @key@ is the whole entry and the @value@ is the empty string.getEnvironment::IO[(String,String)]getEnvironment=dopBlock<-getEnvBlockifpBlock==nullPtrthenreturn[]elsedostuff<-peekArray0nullPtrpBlock>>=mapMpeekCStringreturn(mapdivvystuff)wheredivvystr=casebreak(=='=')strof(xs,[])->(xs,[])-- don't barf (like Posix.getEnvironment)(name,_:value)->(name,value)foreignimportccallunsafe"__hscore_environ"getEnvBlock::IO(PtrCString)#endif /* __GLASGOW_HASKELL__ */