Commit df7fc576 authored by ijones's avatar ijones
Browse files

wad of changes imported from CVS, various authors

parent f0c5e1b9
......@@ -3,11 +3,11 @@ module Distribution.Compat.Directory (
findExecutable, copyFile
) where
#if __GLASGOW_HASKELL__ < 603
#if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 603
#include "config.h"
#endif
#if __GLASGOW_HASKELL__ > 602
#if !__GLASGOW_HASKELL__ || __GLASGOW_HASKELL__ > 602
import System.Directory ( findExecutable, copyFile )
......
{-# OPTIONS -cpp #-}
module Distribution.Compat.RawSystem (rawSystem) where
#if (!(defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ > 600))
#if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 602
import Data.List (intersperse)
import System.Cmd (system)
import System.Exit (ExitCode)
......@@ -9,9 +9,8 @@ import System.Exit (ExitCode)
import System.Cmd (rawSystem)
#endif
#if (!(defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ > 600))
#if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 602
rawSystem :: String -> [String] -> IO ExitCode
rawSystem p args = system $ concat $ intersperse " " (p : map esc args)
where esc arg = "\"" ++ arg ++ "\"" -- this is hideously broken, actually
where esc arg = "'" ++ arg ++ "'" -- this is hideously broken, actually
#endif
......@@ -74,7 +74,7 @@ module Distribution.Compat.ReadP
)
where
#if __GLASGOW_HASKELL__ >= 603
#if __GLASGOW_HASKELL__ >= 603 || __HUGS__
import Text.ParserCombinators.ReadP hiding (ReadP)
import qualified Text.ParserCombinators.ReadP as ReadP
......@@ -193,7 +193,7 @@ look = R Look
-- ^ Always fails.
pfail = R (\_ -> Fail)
--(+++) :: ReadP a -> ReadP a -> ReadP a
--(+++) :: ReadP r a -> ReadP r a -> ReadP r a
-- ^ Symmetric choice.
R f1 +++ R f2 = R (\k -> f1 k `mplus` f2 k)
......
......@@ -57,8 +57,8 @@ module Distribution.InstalledPackageInfo (
import Distribution.ParseUtils (
StanzaField(..), singleStanza, PError(..),
simpleField, listField, licenseField,
parseFilePath, parseLibName, parseModuleName,
showFilePath, parseReadS, parseOptVersion )
parseFilePathQ, parseLibNameQ, parseModuleNameQ, parsePackageNameQ,
showFilePath, parseReadS, parseOptVersion, parseQuoted)
import Distribution.License ( License(..) )
import Distribution.Extension ( Opt )
import Distribution.Package ( PackageIdentifier(..), showPackageId,
......@@ -181,7 +181,7 @@ fields = basicStanzaFields ++ installedStanzaFields
basicStanzaFields :: [StanzaField InstalledPackageInfo]
basicStanzaFields =
[ simpleField "name"
text parsePackageName
text parsePackageNameQ
(pkgName . package) (\name pkg -> pkg{package=(package pkg){pkgName=name}})
, simpleField "version"
(text . showVersion) parseOptVersion
......@@ -222,52 +222,53 @@ installedStanzaFields = [
(text.show) parseReadS
exposed (\val pkg -> pkg{exposed=val})
, listField "exposed-modules"
text parseModuleName
text parseModuleNameQ
exposedModules (\xs pkg -> pkg{exposedModules=xs})
, listField "hidden-modules"
text parseModuleName
text parseModuleNameQ
hiddenModules (\xs pkg -> pkg{hiddenModules=xs})
, listField "import-dirs"
showFilePath parseFilePath
showFilePath parseFilePathQ
importDirs (\xs pkg -> pkg{importDirs=xs})
, listField "library-dirs"
showFilePath parseFilePath
showFilePath parseFilePathQ
libraryDirs (\xs pkg -> pkg{libraryDirs=xs})
, listField "hs-libraries"
showFilePath parseLibName
showFilePath parseLibNameQ
hsLibraries (\xs pkg -> pkg{hsLibraries=xs})
, listField "extra-libs"
text parseLibName
text parseLibNameQ
extraLibraries (\xs pkg -> pkg{extraLibraries=xs})
, listField "include-dirs"
showFilePath parseFilePath
showFilePath parseFilePathQ
includeDirs (\xs pkg -> pkg{includeDirs=xs})
, listField "includes"
showFilePath parseFilePath
showFilePath parseFilePathQ
includes (\xs pkg -> pkg{includes=xs})
, listField "depends"
(text.showPackageId) parsePackageId
(text.showPackageId) parsePackageId'
depends (\xs pkg -> pkg{depends=xs})
, listField "extra-hugs-opts"
text parseFilePath
text parseFilePathQ
extraHugsOpts (\path pkg -> pkg{extraHugsOpts=path})
, listField "extra-cc-opts"
text parseFilePath
text parseFilePathQ
extraCcOpts (\path pkg -> pkg{extraCcOpts=path})
, listField "extra-ld-opts"
text parseFilePath
text parseFilePathQ
extraLdOpts (\path pkg -> pkg{extraLdOpts=path})
, listField "framework-dirs"
showFilePath parseFilePath
showFilePath parseFilePathQ
frameworkDirs (\xs pkg -> pkg{frameworkDirs=xs})
, listField "extra-frameworks"
showFilePath parseFilePath
showFilePath parseFilePathQ
extraFrameworks (\xs pkg -> pkg{extraFrameworks=xs})
, listField "haddock-interfaces"
showFilePath parseFilePath
showFilePath parseFilePathQ
haddockInterfaces (\xs pkg -> pkg{haddockInterfaces=xs})
, listField "haddock-html"
showFilePath parseFilePath
showFilePath parseFilePathQ
haddockHTMLs (\xs pkg -> pkg{haddockHTMLs=xs})
]
parsePackageId' = parseQuoted parsePackageId <++ parsePackageId
......@@ -257,7 +257,7 @@ basicStanzaFields =
text (munch (const True))
author (\val pkg -> pkg{author=val})
, listField "tested-with"
showTestedWith parseTestedWith
showTestedWith parseTestedWithQ
testedWith (\val pkg -> pkg{testedWith=val})
]
......@@ -268,7 +268,7 @@ executableStanzaFields =
text (munch (const True))
exeName (\xs exe -> exe{exeName=xs})
, simpleField "main-is"
showFilePath parseFilePath
showFilePath parseFilePathQ
modulePath (\xs exe -> exe{modulePath=xs})
]
......@@ -278,28 +278,28 @@ binfoFields =
showDependency parseDependency
buildDepends (\xs binfo -> binfo{buildDepends=xs})
, listField "modules"
text parseModuleName
text parseModuleNameQ
modules (\xs binfo -> binfo{modules=xs})
, listField "exposed-modules"
text parseModuleName
text parseModuleNameQ
exposedModules (\xs binfo -> binfo{exposedModules=xs})
, listField "c-sources"
showFilePath parseFilePath
showFilePath parseFilePathQ
cSources (\paths binfo -> binfo{cSources=paths})
, listField "extensions"
(text . show) parseExtension
(text . show) parseExtensionQ
extensions (\exts binfo -> binfo{extensions=exts})
, listField "extra-libs"
text parseLibName
text parseLibNameQ
extraLibs (\xs binfo -> binfo{extraLibs=xs})
, listField "includes"
showFilePath parseFilePath
showFilePath parseFilePathQ
includes (\paths binfo -> binfo{includes=paths})
, listField "include-dirs"
showFilePath parseFilePath
showFilePath parseFilePathQ
includes (\paths binfo -> binfo{includeDirs=paths})
, simpleField "hs-source-dir"
showFilePath parseFilePath
showFilePath parseFilePathQ
hsSourceDir (\path binfo -> binfo{hsSourceDir=path})
, optsField "options-ghc" GHC
options (\path binfo -> binfo{options=path})
......
......@@ -46,11 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -}
module Distribution.ParseUtils (
LineNo, PError(..), showError, myError, runP,
StanzaField(..), splitStanzas, Stanza, singleStanza,
parseFilePath, parseLibName,
parseModuleName, parseReadS, parseDependency, parseOptVersion,
parseTestedWith, parseLicense, parseExtension, parseCommaList,
parseFilePathQ, parseLibNameQ,
parseModuleNameQ, parseDependency, parseOptVersion,
parsePackageNameQ, parseVersionRangeQ,
parseTestedWithQ, parseLicenseQ, parseExtensionQ, parseCommaList,
showFilePath, showTestedWith, showDependency,
simpleField, listField, licenseField, optsField,
simpleField, listField, licenseField, optsField,
parseReadS, parseQuoted,
) where
import Text.PrettyPrint.HughesPJ
......@@ -141,10 +143,10 @@ licenseField name flag get set = StanzaField name
(\lineNo val st ->
if flag
then do
path <- runP lineNo name parseFilePath val
path <- runP lineNo name parseFilePathQ val
return (set (OtherLicense path) st)
else do
x <- runP lineNo name parseLicense val
x <- runP lineNo name parseLicenseQ val
return (set x st))
optsField :: String -> CompilerFlavor -> (b -> [(CompilerFlavor,[String])]) -> ([(CompilerFlavor,[String])] -> b -> b) -> StanzaField b
......@@ -199,49 +201,64 @@ brk (n,xs) = case break (==':') xs of
(_, _) -> fail $ "Line "++show n++": Invalid syntax (no colon after field name)"
-- |parse a module name
parseModuleName :: ReadP r String
parseModuleName = do c <- satisfy isUpper
cs <- munch (\x -> isAlphaNum x || x `elem` "_'.")
return (c:cs)
parseModuleNameQ :: ReadP r String
parseModuleNameQ = parseQuoted mod <++ mod
where mod = do
c <- satisfy isUpper
cs <- munch (\x -> isAlphaNum x || x `elem` "_'.")
return (c:cs)
parseFilePath :: ReadP r FilePath
parseFilePath = parseReadS <++ (munch1 (\x -> isAlphaNum x || x `elem` "-+/_."))
parseFilePathQ :: ReadP r FilePath
parseFilePathQ = parseReadS <++ (munch1 (\x -> isAlphaNum x || x `elem` "-+/_."))
parseReadS :: Read a => ReadP r a
parseReadS = readS_to_P reads
parseDependency :: ReadP r Dependency
parseDependency = do name <- parsePackageName
parseDependency = do name <- parsePackageNameQ
skipSpaces
ver <- parseVersionRange <++ return AnyVersion
ver <- parseVersionRangeQ <++ return AnyVersion
skipSpaces
return $ Dependency name ver
parsePackageNameQ = parseQuoted parsePackageName <++ parsePackageName
parseVersionRangeQ = parseQuoted parseVersionRange <++ parseVersionRange
parseOptVersion :: ReadP r Version
parseOptVersion = parseVersion <++ return noVersion
where noVersion = Version{ versionBranch=[], versionTags=[] }
parseOptVersion = parseQuoted ver <++ ver
where ver = parseVersion <++ return noVersion
noVersion = Version{ versionBranch=[], versionTags=[] }
parseTestedWithQ :: ReadP r (CompilerFlavor,VersionRange)
parseTestedWithQ = parseQuoted tw <++ tw
where tw = do compiler <- parseReadS
skipSpaces
version <- parseVersionRange <++ return AnyVersion
skipSpaces
return (compiler,version)
parseTestedWith :: ReadP [(CompilerFlavor,VersionRange)] (CompilerFlavor,VersionRange)
parseTestedWith = do compiler <- parseReadS
skipSpaces
version <- parseVersionRange <++ return AnyVersion
skipSpaces
return (compiler,version)
parseLicenseQ :: ReadP r License
parseLicenseQ = parseQuoted parseReadS <++ parseReadS
parseLicense :: ReadP r License
parseLicense = parseReadS
-- urgh, we can't define optQuotes :: ReadP r a -> ReadP r a
-- because the "compat" version of ReadP isn't quite powerful enough. In
-- particular, the type of <++ is ReadP r r -> ReadP r a -> ReadP r a
-- Hence the trick above to make 'lic' polymorphic.
parseExtension :: ReadP r Extension
parseExtension = parseReadS
parseExtensionQ :: ReadP r Extension
parseExtensionQ = parseQuoted parseReadS <++ parseReadS
parseLibName :: ReadP r String
parseLibName = parseReadS <++ munch1 (\x -> not (isSpace x) && x /= ',')
parseLibNameQ :: ReadP r String
parseLibNameQ = parseReadS <++ munch1 (\x -> not (isSpace x) && x /= ',')
parseCommaList :: ReadP r a -- ^The parser for the stuff between commas
-> ReadP r [a]
parseCommaList p = sepBy p separator
where separator = skipSpaces >> ReadP.char ',' >> skipSpaces
parseQuoted :: ReadP r a -> ReadP r a
parseQuoted p = between (ReadP.char '"') (ReadP.char '"') p
-- --------------------------------------------
-- ** Pretty printing
......
......@@ -54,10 +54,12 @@ module Distribution.Simple.Configure (writePersistBuildConfig,
)
where
#if __GLASGOW_HASKELL__ < 603
#if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 603
#include "config.h"
#endif
import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..))
import Distribution.Simple.Register (removeInstalledConfig)
import Distribution.Extension(extensionsToGHCFlag,
extensionsToNHCFlag, extensionsToHugsFlag)
import Distribution.Setup(ConfigFlags,CompilerFlavor(..), Compiler(..))
......@@ -89,23 +91,6 @@ import Prelude hiding (catch)
import HUnit
#endif
-- |Data cached after configuration step.
data LocalBuildInfo = LocalBuildInfo {
prefix :: FilePath,
-- ^ The installation directory (eg. @/usr/local@, or
-- @C:/Program Files/foo-1.2@ on Windows.
compiler :: Compiler,
-- ^ The compiler we're building with
packageDeps :: [PackageIdentifier],
-- ^ Which packages we depend on, *exactly*, The
-- 'PackageDescription' specifies a set of build dependencies
-- that must be satisfied in terms of version ranges. This
-- field fixes those dependencies to the specific versions
-- available on this machine for this compiler.
executableDeps :: [(String,[PackageIdentifier])]
}
deriving (Show, Read, Eq)
-- |Throws an error if it's not found.
exeDeps :: String -> LocalBuildInfo -> [PackageIdentifier]
exeDeps s d = fromJust $ lookup s (executableDeps d)
......@@ -140,6 +125,7 @@ configure :: PackageDescription -> ConfigFlags -> IO LocalBuildInfo
configure pkg_descr (maybe_hc_flavor, maybe_hc_path, maybe_hc_pkg, maybe_prefix)
= do
setupMessage "Configuring" pkg_descr
removeInstalledConfig
let lib = library pkg_descr
-- prefix
let pref = case maybe_prefix of
......
......@@ -22,7 +22,7 @@ module Distribution.Simple.GHCPackageConfig (
import Distribution.PackageDescription (PackageDescription(..), BuildInfo(..))
import Distribution.Package (PackageIdentifier(..), showPackageId)
import Distribution.Simple.Configure (LocalBuildInfo(..))
import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..))
import Distribution.Simple.Install (mkLibDir)
import Control.Exception (try)
......
......@@ -50,7 +50,7 @@ module Distribution.Simple.Install (
#endif
) where
#if __GLASGOW_HASKELL__ < 603
#if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 603
#include "config.h"
#endif
......@@ -58,7 +58,7 @@ import Distribution.PackageDescription (
PackageDescription(..), BuildInfo(..), Executable(..),
setupMessage, hasLibs, withLib)
import Distribution.Package (showPackageId)
import Distribution.Simple.Configure(LocalBuildInfo(..))
import Distribution.Simple.LocalBuildInfo(LocalBuildInfo(..))
import Distribution.Simple.Utils(moveSources, rawSystemExit,
mkLibName,
die, createIfNotExists
......
......@@ -47,24 +47,34 @@ module Distribution.Simple.Register (
register,
unregister,
writeInstalledConfig,
removeInstalledConfig,
installedPkgConfigFile,
#ifdef DEBUG
hunitTests
#endif
) where
import Distribution.Simple.Configure (LocalBuildInfo, compiler)
import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..))
import Distribution.Simple.Install (mkLibDir)
import Distribution.Setup (CompilerFlavor(..), Compiler(..))
import Distribution.PackageDescription (setupMessage, PackageDescription(..))
import Distribution.Package (PackageIdentifier(..))
import Distribution.PackageDescription (setupMessage, PackageDescription(..),
BuildInfo(..))
import Distribution.Package (PackageIdentifier(..), showPackageId)
import Distribution.Version (Version(..))
import Distribution.InstalledPackageInfo
(InstalledPackageInfo, showInstalledPackageInfo,
emptyInstalledPackageInfo)
import qualified Distribution.InstalledPackageInfo as IPI
import Distribution.Simple.Utils (rawSystemExit, die)
import Distribution.Simple.GHCPackageConfig (mkGHCPackageConfig, showGHCPackageConfig)
import qualified Distribution.Simple.GHCPackageConfig
as GHC (localPackageConfig, canWriteLocalPackageConfig, maybeCreateLocalPackageConfig)
import System.Directory(doesFileExist)
import System.Directory(doesFileExist, removeFile)
import System.IO (try)
import Control.Monad (when, unless)
import Data.Maybe (isNothing, fromJust)
#ifdef DEBUG
import HUnit (Test)
......@@ -82,38 +92,110 @@ register :: PackageDescription -> LocalBuildInfo
-> IO ()
register pkg_descr lbi userInst = do
setupMessage "Registering" pkg_descr
if isNothing (library pkg_descr)
then do setupMessage "No package to register" pkg_descr
return ()
else do
case compilerFlavor (compiler lbi) of
GHC -> do when userInst (GHC.maybeCreateLocalPackageConfig >> return() )
localConf <- GHC.localPackageConfig
pkgConfWriteable <- GHC.canWriteLocalPackageConfig
when (userInst && (not pkgConfWriteable))
(die ("--user flag passed, but cannot write to local package config: "
++ localConf))
instConfExists <- doesFileExist installedPkgConfigFile
unless instConfExists (writeInstalledConfig pkg_descr lbi)
rawSystemExit (compilerPkgTool (compiler lbi))
(["--auto-ghci-libs", "--update-package",
"--input-file="++installedPkgConfigFile]
++ (if userInst
then ["--config-file=" ++ localConf]
else []))
GHC -> do
let ghc_63_plus = compilerVersion (compiler lbi) >= Version [6,3] []
config_flags <-
if userInst
then if ghc_63_plus
then return ["--user"]
else do
GHC.maybeCreateLocalPackageConfig
localConf <- GHC.localPackageConfig
pkgConfWriteable <- GHC.canWriteLocalPackageConfig
when (not pkgConfWriteable) $ userPkgConfErr localConf
return ["--config-file=" ++ localConf]
else return []
instConfExists <- doesFileExist installedPkgConfigFile
unless instConfExists (writeInstalledConfig pkg_descr lbi)
let register_flags
| ghc_63_plus = ["register", installedPkgConfigFile]
| otherwise = ["--update-package",
"--input_file="++installedPkgConfigFile]
rawSystemExit (compilerPkgTool (compiler lbi))
(["--auto-ghci-libs"]
++ register_flags
++ config_flags)
-- FIX (HUGS):
Hugs -> setupMessage "Warning: Hugs has no packaging tool\nLibrary files will just be moved into place." pkg_descr
_ -> die ("only registering with GHC is implemented")
userPkgConfErr local_conf =
die ("--user flag passed, but cannot write to local package config: "
++ local_conf )
-- |Register doesn't drop the register info file, it must be done in a separate step.
writeInstalledConfig :: PackageDescription -> LocalBuildInfo -> IO ()
writeInstalledConfig pkg_descr lbi = do
case compilerFlavor (compiler lbi) of
GHC -> do let pkg_config = mkGHCPackageConfig pkg_descr lbi
writeFile installedPkgConfigFile (showGHCPackageConfig pkg_config)
let hc = compiler lbi
case compilerFlavor hc of
GHC ->
let pkg_config
| compilerVersion hc >= Version [6,3] []
= showInstalledPackageInfo (mkInstalledPackageInfo pkg_descr lbi)
| otherwise
= showGHCPackageConfig (mkGHCPackageConfig pkg_descr lbi)
in
writeFile installedPkgConfigFile ( pkg_config)
Hugs -> return ()
_ -> die ("only registering with GHC is implemented")
removeInstalledConfig :: IO ()
removeInstalledConfig = try (removeFile installedPkgConfigFile) >> return ()
installedPkgConfigFile :: String
installedPkgConfigFile = ".installed-pkg-config"
-- -----------------------------------------------------------------------------
-- Making the InstalledPackageInfo
mkInstalledPackageInfo
:: PackageDescription
-> LocalBuildInfo
-> InstalledPackageInfo
mkInstalledPackageInfo pkg_descr lbi
= let
lib = fromJust (library pkg_descr) -- checked for Nothing earlier
in
emptyInstalledPackageInfo{
IPI.package = package pkg_descr,
IPI.license = license pkg_descr,
IPI.copyright = copyright pkg_descr,
IPI.maintainer = maintainer pkg_descr,
IPI.author = author pkg_descr,
IPI.stability = stability pkg_descr,
IPI.homepage = homepage pkg_descr,
IPI.pkgUrl = pkgUrl pkg_descr,
IPI.description = description pkg_descr,
IPI.category = category pkg_descr,
IPI.exposed = True,
IPI.exposedModules = exposedModules lib,
IPI.hiddenModules = filter (`notElem` exposedModules lib) (modules lib),
IPI.importDirs = [mkLibDir pkg_descr lbi Nothing],
IPI.libraryDirs = [mkLibDir pkg_descr lbi Nothing],
IPI.hsLibraries = ["HS" ++ showPackageId (package pkg_descr)],
IPI.extraLibraries = extraLibs lib,
IPI.includeDirs = includeDirs lib,
IPI.includes = includes lib,
IPI.depends = packageDeps lbi,
IPI.extraHugsOpts = concat [opts | (Hugs,opts) <- options lib],
IPI.extraCcOpts = [],
IPI.extraLdOpts = [],
IPI.frameworkDirs = [],
IPI.extraFrameworks = [],
IPI.haddockInterfaces = [],
IPI.haddockHTMLs = []
}
-- -----------------------------------------------------------------------------
-- Unregistration
......
......@@ -62,7 +62,7 @@ module Distribution.Simple.Utils (
#endif
) where
#if __GLASGOW_HASKELL__ < 603
#if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 603
#include "config.h"
#endif
......@@ -75,7 +75,7 @@ import Data.Maybe(Maybe, catMaybes)
import System.IO (hPutStr, stderr, hFlush, stdout)
import System.IO.Error
import System.Exit
#if defined(__GLASGOW_HASKELL__) && !defined(mingw32_TARGET_OS)
#if (__GLASGOW_HASKELL__ || __HUGS__) && !defined(mingw32_TARGET_OS)
import System.Posix.Internals (c_getpid)
#endif
......@@ -294,9 +294,10 @@ withTempFile tmp_dir extn action
if b then findTempName tmp_dir (x+1)
else action filename `finally` try (removeFile filename)
#ifdef mingw32_HOST_OS
foreign import ccall unsafe "_getpid" getProcessID :: IO Int -- relies on Int == Int32 on Windows
#elif defined(__GLASGOW_HASKELL__)
#ifdef mingw32_TARGET_OS
foreign import ccall unsafe "_getpid" getProcessID :: IO Int
-- relies on Int == Int32 on Windows
#elif __GLASGOW_HASKELL__ || __HUGS__
getProcessID :: IO Int
getProcessID = System.Posix.Internals.c_getpid >>= return . fromIntegral
#else
......
......@@ -63,7 +63,7 @@ module Distribution.Version (
#endif
) where
#if __GLASGOW_HASKELL__ >= 603
#if !__GLASGOW_HASKELL__ || __GLASGOW_HASKELL__ >= 603
import Data.Version ( Version(..), showVersion, parseVersion )
#endif
......@@ -80,7 +80,7 @@ import HUnit
-- -----------------------------------------------------------------------------
-- The Version type
#if __GLASGOW_HASKELL__ < 603
#if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 603