directory 1.2.2.1 → 1.2.3.0
raw patch · 81 files changed
+1631/−8944 lines, 81 filesdep ~Win32dep ~filepathdep ~timesetup-changedPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: Win32, filepath, time, unix
API changes (from Hackage documentation)
- System.Directory: instance Enum DirectoryType
- System.Directory: instance Eq DirectoryType
- System.Directory: instance Eq Permissions
- System.Directory: instance Ord DirectoryType
- System.Directory: instance Ord Permissions
- System.Directory: instance Read DirectoryType
- System.Directory: instance Read Permissions
- System.Directory: instance Show DirectoryType
- System.Directory: instance Show Permissions
+ System.Directory: XdgCache :: XdgDirectory
+ System.Directory: XdgConfig :: XdgDirectory
+ System.Directory: XdgData :: XdgDirectory
+ System.Directory: data XdgDirectory
+ System.Directory: getAccessTime :: FilePath -> IO UTCTime
+ System.Directory: getXdgDirectory :: XdgDirectory -> FilePath -> IO FilePath
+ System.Directory: instance GHC.Classes.Eq System.Directory.DirectoryType
+ System.Directory: instance GHC.Classes.Eq System.Directory.Permissions
+ System.Directory: instance GHC.Classes.Eq System.Directory.XdgDirectory
+ System.Directory: instance GHC.Classes.Ord System.Directory.DirectoryType
+ System.Directory: instance GHC.Classes.Ord System.Directory.Permissions
+ System.Directory: instance GHC.Classes.Ord System.Directory.XdgDirectory
+ System.Directory: instance GHC.Enum.Bounded System.Directory.XdgDirectory
+ System.Directory: instance GHC.Enum.Enum System.Directory.DirectoryType
+ System.Directory: instance GHC.Enum.Enum System.Directory.XdgDirectory
+ System.Directory: instance GHC.Read.Read System.Directory.DirectoryType
+ System.Directory: instance GHC.Read.Read System.Directory.Permissions
+ System.Directory: instance GHC.Read.Read System.Directory.XdgDirectory
+ System.Directory: instance GHC.Show.Show System.Directory.DirectoryType
+ System.Directory: instance GHC.Show.Show System.Directory.Permissions
+ System.Directory: instance GHC.Show.Show System.Directory.XdgDirectory
+ System.Directory: setAccessTime :: FilePath -> UTCTime -> IO ()
+ System.Directory: setModificationTime :: FilePath -> UTCTime -> IO ()
+ System.Directory: withCurrentDirectory :: FilePath -> IO a -> IO a
- System.Directory: getAppUserDataDirectory :: String -> IO FilePath
+ System.Directory: getAppUserDataDirectory :: FilePath -> IO FilePath
Files
- Setup.hs +0/−2
- System/Directory.hs +539/−245
- System/Directory/Internal.hsc +31/−0
- System/Directory/Internal/C_utimensat.hsc +48/−0
- System/Directory/Internal/Posix.hsc +42/−0
- System/Directory/Internal/Windows.hsc +23/−0
- cbits/directory.c +2/−0
- changelog.md +34/−12
- config.guess +0/−1420
- config.sub +0/−1794
- configure +134/−1
- configure.ac +8/−1
- directory.cabal +16/−27
- include/HsDirectory.h +5/−5
- include/HsDirectoryConfig.h.in +15/−0
- install-sh +0/−527
- tests/CanonicalizePath.hs +23/−0
- tests/CopyFile001.hs +22/−0
- tests/CopyFile002.hs +21/−0
- tests/CreateDirectory001.hs +11/−0
- tests/CreateDirectoryIfMissing001.hs +104/−0
- tests/CurrentDirectory001.hs +14/−0
- tests/Directory001.hs +19/−0
- tests/DoesDirectoryExist001.hs +17/−0
- tests/FileTime.hs +53/−0
- tests/GetDirContents001.hs +20/−0
- tests/GetDirContents002.hs +10/−0
- tests/GetHomeDirectory001.hs +16/−0
- tests/GetPermissions001.hs +47/−0
- tests/Main.hs +39/−0
- tests/Makefile +0/−7
- tests/RemoveDirectoryRecursive001.hs +91/−0
- tests/RenameFile001.hs +18/−0
- tests/T8482.hs +14/−9
- tests/T8482.stdout +0/−3
- tests/TestUtils.hs +0/−1
- tests/Util.hs +165/−0
- tests/WithCurrentDirectory.hs +26/−0
- tests/all.T +0/−32
- tests/canonicalizePath001.hs +0/−8
- tests/canonicalizePath001.stdout +0/−1
- tests/copyFile001.hs +0/−26
- tests/copyFile001.stdout +0/−5
- tests/copyFile001dir/source +0/−1
- tests/copyFile002.hs +0/−31
- tests/copyFile002.stdout +0/−5
- tests/copyFile002dir/source +0/−1
- tests/createDirectory001.hs +0/−12
- tests/createDirectory001.stdout +0/−1
- tests/createDirectory001.stdout-mingw32 +0/−1
- tests/createDirectoryIfMissing001.hs +0/−79
- tests/createDirectoryIfMissing001.stdout +0/−8
- tests/createDirectoryIfMissing001.stdout-mingw32 +0/−8
- tests/currentDirectory001.hs +0/−27
- tests/currentDirectory001.stdout +0/−1
- tests/directory001.hs +0/−16
- tests/directory001.stdout +0/−1
- tests/doesDirectoryExist001.hs +0/−11
- tests/doesDirectoryExist001.stdout +0/−1
- tests/getDirContents001.hs +0/−18
- tests/getDirContents001.stdout +0/−2
- tests/getDirContents002.hs +0/−3
- tests/getDirContents002.stderr +0/−1
- tests/getDirContents002.stderr-mingw32 +0/−1
- tests/getHomeDirectory001.hs +0/−8
- tests/getPermissions001.hs +0/−20
- tests/getPermissions001.stdout +0/−3
- tests/getPermissions001.stdout-alpha-dec-osf3 +0/−3
- tests/getPermissions001.stdout-i386-unknown-freebsd +0/−3
- tests/getPermissions001.stdout-i386-unknown-openbsd +0/−3
- tests/getPermissions001.stdout-mingw +0/−3
- tests/getPermissions001.stdout-x86_64-unknown-openbsd +0/−3
- tests/removeDirectoryRecursive001.hs +0/−93
- tests/removeDirectoryRecursive001.stdout +0/−19
- tests/renameFile001.hs +0/−13
- tests/renameFile001.stdout +0/−2
- tests/util.inl +4/−0
- tools/dispatch-tests.hs +0/−67
- tools/ghc-test-framework.LICENSE +0/−44
- tools/ghc-test-framework.shar +0/−4253
- tools/run-tests +0/−52
Setup.hs view
@@ -1,8 +1,6 @@ module Main (main) where import Distribution.Simple-import Distribution.Simple.Program (simpleProgram) main :: IO () main = defaultMainWithHooks autoconfUserHooks- { hookedPrograms = [simpleProgram "python", simpleProgram "which"] }
System/Directory.hs view
@@ -1,7 +1,4 @@ {-# LANGUAGE CPP, NondecreasingIndentation #-}-#ifdef __GLASGOW_HASKELL__-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- |@@ -27,13 +24,16 @@ , removeDirectory , removeDirectoryRecursive , renameDirectory- , getDirectoryContents+ -- ** Current working directory , getCurrentDirectory , setCurrentDirectory+ , withCurrentDirectory -- * Pre-defined directories , getHomeDirectory+ , XdgDirectory(..)+ , getXdgDirectory , getAppUserDataDirectory , getUserDocumentsDirectory , getTemporaryDirectory@@ -77,34 +77,62 @@ -- * Timestamps + , getAccessTime , getModificationTime+ , setAccessTime+ , setModificationTime+ ) where+import Control.Exception ( bracket, bracketOnError )+import Control.Monad ( when, unless )+#if !MIN_VERSION_base(4, 8, 0)+import Data.Functor ((<$>))+#endif+import Data.Maybe+ ( listToMaybe+#ifdef mingw32_HOST_OS+ , maybeToList+#endif+ )+import Data.Tuple (swap) import System.FilePath import System.IO import System.IO.Error-import Control.Monad ( when, unless )-import Control.Exception.Base as E+ ( catchIOError+ , ioeSetErrorString+ , ioeSetFileName+ , ioeSetLocation+ , isAlreadyExistsError+ , isDoesNotExistError+ , isPermissionError+ , mkIOError+ , modifyIOError+ , tryIOError ) #ifdef __HUGS__ import Hugs.Directory #endif /* __HUGS__ */ import Foreign-import Foreign.C {-# CFILES cbits/directory.c #-} -import Data.Maybe- import Data.Time ( UTCTime )-import Data.Time.Clock.POSIX ( posixSecondsToUTCTime )+import Data.Time.Clock.POSIX+ ( posixSecondsToUTCTime+ , utcTimeToPOSIXSeconds+#ifdef mingw32_HOST_OS+ , POSIXTime+#endif+ ) #ifdef __GLASGOW_HASKELL__ import GHC.IO.Exception ( IOErrorType(InappropriateType) ) #ifdef mingw32_HOST_OS+import Foreign.C import System.Posix.Types import System.Posix.Internals import qualified System.Win32 as Win32@@ -115,8 +143,28 @@ import qualified System.Posix as Posix #endif +#include <HsDirectoryConfig.h>+#ifdef HAVE_UTIMENSAT+import Foreign.C (throwErrnoPathIfMinus1_)+import System.Posix.Internals ( withFilePath )+#endif+ #endif /* __GLASGOW_HASKELL__ */ +import System.Directory.Internal++#ifdef mingw32_HOST_OS+win32_cSIDL_LOCAL_APPDATA :: Win32.CSIDL+win32_fILE_SHARE_DELETE :: Win32.ShareMode+#if MIN_VERSION_Win32(2, 3, 1)+win32_cSIDL_LOCAL_APPDATA = Win32.cSIDL_LOCAL_APPDATA -- only on HEAD atm+win32_fILE_SHARE_DELETE = Win32.fILE_SHARE_DELETE -- added in 2.3.0.2+#else+win32_cSIDL_LOCAL_APPDATA = 0x001c+win32_fILE_SHARE_DELETE = 0x00000004+#endif+#endif+ {- $intro A directory contains a series of entries, each of which is a named reference to a file system object (file, directory etc.). Some@@ -369,16 +417,15 @@ parents = reverse . scanl1 (</>) . splitDirectories . normalise createDirs [] = return ()- createDirs (dir:[]) = createDir dir throwIO+ createDirs (dir:[]) = createDir dir ioError createDirs (dir:dirs) = createDir dir $ \_ -> do createDirs dirs- createDir dir throwIO+ createDir dir ioError - createDir :: FilePath -> (IOException -> IO ()) -> IO () createDir dir notExistHandler = do- r <- E.try $ createDirectory dir- case (r :: Either IOException ()) of+ r <- tryIOError (createDirectory dir)+ case r of Right () -> return () Left e | isDoesNotExistError e -> notExistHandler e@@ -396,16 +443,17 @@ -- This caused GHCi to crash when loading a module in the root -- directory. | isAlreadyExistsError e- || isPermissionError e -> do+ || isPermissionError e -> do+ canIgnore <- isDir `catchIOError` \ _ ->+ return (isAlreadyExistsError e)+ unless canIgnore (ioError e)+ | otherwise -> ioError e+ where #ifdef mingw32_HOST_OS- canIgnore <- (withFileStatus "createDirectoryIfMissing" dir isDirectory)+ isDir = withFileStatus "createDirectoryIfMissing" dir isDirectory #else- canIgnore <- (Posix.isDirectory `fmap` Posix.getFileStatus dir)+ isDir = (Posix.isDirectory <$> Posix.getFileStatus dir) #endif- `E.catch` ((\ _ -> return (isAlreadyExistsError e))- :: IOException -> IO Bool)- unless canIgnore (throwIO e)- | otherwise -> throwIO e #if __GLASGOW_HASKELL__ @@ -422,7 +470,7 @@ getDirectoryType path = (`ioeSetLocation` "getDirectoryType") `modifyIOError` do #ifdef mingw32_HOST_OS- fmap classify (Win32.getFileAttributes path)+ classify <$> Win32.getFileAttributes path where fILE_ATTRIBUTE_REPARSE_POINT = 0x400 classify attr | attr .&. Win32.fILE_ATTRIBUTE_DIRECTORY == 0 = NotDirectory@@ -487,8 +535,8 @@ #endif -- | @'removeDirectoryRecursive' dir@ removes an existing directory /dir/--- together with its contents and subdirectories. Symbolic links are removed--- without affecting their the targets.+-- together with its contents and subdirectories. Within this directory,+-- symbolic links are removed without affecting their the targets. removeDirectoryRecursive :: FilePath -> IO () removeDirectoryRecursive path = (`ioeSetLocation` "removeDirectoryRecursive") `modifyIOError` do@@ -716,7 +764,7 @@ copyFile :: FilePath -> FilePath -> IO () copyFile fromFPath toFPath =- copy `catchIOError` (\exc -> throwIO $ ioeSetLocation exc "copyFile")+ copy `catchIOError` (\ exc -> ioError (ioeSetLocation exc "copyFile")) where copy = bracket (openBinaryFile fromFPath ReadMode) hClose $ \hFrom -> bracketOnError openTmp cleanTmp $ \(tmpFPath, hTmp) -> do allocaBytes bufferSize $ copyContents hFrom hTmp@@ -737,61 +785,87 @@ ignoreIOExceptions io = io `catchIOError` (\_ -> return ()) --- | Canonicalize the path of an existing file or directory. The intent is--- that two paths referring to the same file\/directory will map to the same--- canonicalized path.+-- | Make a path absolute and remove as many indirections from it as possible.+-- Indirections include the two special directories @.@ and @..@, as well as+-- any symbolic links. The input path need not point to an existing file or+-- directory. ----- __Note__: if you only require an absolute path, consider using--- @'makeAbsolute'@ instead, which is more reliable and does not have--- unspecified behavior on nonexistent paths.+-- __Note__: if you require only an absolute path, use 'makeAbsolute' instead.+-- Most programs need not care about whether a path contains symbolic links. ----- It is impossible to guarantee that the implication (same file\/dir \<=\>--- same canonicalized path) holds in either direction: this function can make--- only a best-effort attempt.+-- Due to the fact that symbolic links and @..@ are dependent on the state of+-- the existing filesystem, the function can only make a conservative,+-- best-effort attempt. Nevertheless, if the input path points to an existing+-- file or directory, then the output path shall also point to the same file+-- or directory. ----- The precise behaviour is that of the POSIX @realpath@ function (or--- @GetFullPathNameW@ on Windows). In particular, the behaviour on paths that--- don't exist can vary from platform to platform. Some platforms do not--- alter the input, some do, and some throw an exception.+-- Formally, symbolic links and @..@ are removed from the longest prefix of+-- the path that still points to an existing file. The function is not+-- atomic, therefore concurrent changes in the filesystem may lead to+-- incorrect results. ----- An empty path is considered to be equivalent to the current directory.+-- (Despite the name, the function does not guarantee canonicity of the+-- returned path due to the presence of hard links, mount points, etc.) ----- /Known bug(s)/: on Windows, this function does not resolve symbolic links.+-- Similar to 'normalise', an empty path is equivalent to the current+-- directory. --+-- /Known bug(s)/: on Windows, the function does not resolve symbolic links.+--+-- /Changes since 1.2.3.0:/ The function has been altered to be more robust+-- and has the same exception behavior as 'makeAbsolute'.+-- canonicalizePath :: FilePath -> IO FilePath-canonicalizePath "" = canonicalizePath "."-canonicalizePath fpath =+canonicalizePath = \ path ->+ modifyIOError ((`ioeSetLocation` "canonicalizePath") .+ (`ioeSetFileName` path)) $+ -- normalise does more stuff, like upper-casing the drive letter+ normalise <$> (transform =<< makeAbsolute path)+ where #if defined(mingw32_HOST_OS)- do path <- Win32.getFullPathName fpath+ transform path = Win32.getFullPathName path+ `catchIOError` \ _ -> return path #else- do enc <- getFileSystemEncoding- GHC.withCString enc fpath $ \pInPath ->- allocaBytes long_path_size $ \pOutPath ->- do _ <- throwErrnoPathIfNull "canonicalizePath" fpath $ c_realpath pInPath pOutPath+ transform path = copySlash path <$> do+ encoding <- getFileSystemEncoding+ realpathPrefix encoding (reverse (zip prefixes suffixes)) path+ where segments = splitPath path+ prefixes = scanl1 (</>) segments+ suffixes = tail (scanr (</>) "" segments) - -- NB: pOutPath will be passed thru as result pointer by c_realpath- path <- GHC.peekCString enc pOutPath-#endif- return (normalise path)- -- normalise does more stuff, like upper-casing the drive letter+ -- call realpath on the largest possible prefix+ realpathPrefix encoding ((prefix, suffix) : rest) path = do+ exist <- doesPathExist prefix+ if exist -- never call realpath on an inaccessible path+ then ((</> suffix) <$> realpath encoding prefix)+ `catchIOError` \ _ -> realpathPrefix encoding rest path+ else realpathPrefix encoding rest path+ realpathPrefix _ _ path = return path -#if !defined(mingw32_HOST_OS)-foreign import ccall unsafe "realpath"- c_realpath :: CString- -> CString- -> IO CString+ realpath encoding path =+ GHC.withCString encoding path+ (`withRealpath` GHC.peekCString encoding)++ doesPathExist path = (Posix.getFileStatus path >> return True)+ `catchIOError` \ _ -> return False++ -- make sure trailing slash is preserved+ copySlash path | hasTrailingPathSeparator path = addTrailingPathSeparator+ | otherwise = id #endif -- | Make a path absolute by prepending the current directory (if it isn't--- already absolute) and applying @'normalise'@ to the result.+-- already absolute) and applying 'normalise' to the result. ----- The operation may fail with the same exceptions as @'getCurrentDirectory'@.+-- If the path is already absolute, the operation never fails. Otherwise, the+-- operation may fail with the same exceptions as 'getCurrentDirectory'. ----- /Since: 1.2.2.0/+-- @since 1.2.2.0 makeAbsolute :: FilePath -> IO FilePath-makeAbsolute = fmap normalise . absolutize+makeAbsolute = (normalise <$>) . absolutize where absolutize path -- avoid the call to `getCurrentDirectory` if we can- | isRelative path = fmap (</> path) getCurrentDirectory+ | isRelative path = (</> path) . addTrailingPathSeparator <$>+ getCurrentDirectory | otherwise = return path -- | 'makeRelative' the current directory.@@ -826,11 +900,11 @@ -- | Given a file name, searches for the file and returns a list of all -- occurences that are executable. ----- /Since: 1.2.2.0/+-- @since 1.2.2.0 findExecutables :: String -> IO [FilePath] findExecutables binary = do #if defined(mingw32_HOST_OS)- file <- Win32.searchPath Nothing binary ('.':exeExtension)+ file <- Win32.searchPath Nothing binary exeExtension return $ maybeToList file #else path <- getEnv "PATH"@@ -850,7 +924,7 @@ -- | Search through the given set of directories for the given file and -- returns a list of paths where the given file exists. ----- /Since: 1.2.1.0/+-- @since 1.2.1.0 findFiles :: [FilePath] -> String -> IO [FilePath] findFiles = findFilesWith (\_ -> return True) @@ -858,7 +932,7 @@ -- with the given property (usually permissions) and returns a list of -- paths where the given file exists and has the property. ----- /Since: 1.2.1.0/+-- @since 1.2.1.0 findFilesWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO [FilePath] findFilesWith _ [] _ = return [] findFilesWith f (d:ds) fileName = do@@ -941,36 +1015,33 @@ #endif /* __GLASGOW_HASKELL__ */ -{- |If the operating system has a notion of current directories,-'getCurrentDirectory' returns an absolute path to the-current directory of the calling process.--The operation may fail with:--* 'HardwareFault'-A physical I\/O error has occurred.-@[EIO]@--* 'isDoesNotExistError' \/ 'NoSuchThing'-There is no path referring to the current directory.-@[EPERM, ENOENT, ESTALE...]@--* 'isPermissionError' \/ 'PermissionDenied'-The process has insufficient privileges to perform the operation.-@[EACCES]@--* 'ResourceExhausted'-Insufficient resources are available to perform the operation.--* 'UnsupportedOperation'-The operating system has no notion of current directory.--Note that in a concurrent program, the current directory is global-state shared between all threads of the process. When using-filesystem operations from multiple threads, it is therefore highly-recommended to use absolute rather than relative `FilePath`s.---}+-- | Obtain the current working directory as an absolute path.+--+-- In a multithreaded program, the current working directory is a global state+-- shared among all threads of the process. Therefore, when performing+-- filesystem operations from multiple threads, it is highly recommended to+-- use absolute rather than relative paths (see: 'makeAbsolute').+--+-- The operation may fail with:+--+-- * 'HardwareFault'+-- A physical I\/O error has occurred.+-- @[EIO]@+--+-- * 'isDoesNotExistError' or 'NoSuchThing'+-- There is no path referring to the working directory.+-- @[EPERM, ENOENT, ESTALE...]@+--+-- * 'isPermissionError' or 'PermissionDenied'+-- The process has insufficient privileges to perform the operation.+-- @[EACCES]@+--+-- * 'ResourceExhausted'+-- Insufficient resources are available to perform the operation.+--+-- * 'UnsupportedOperation'+-- The operating system has no notion of current working directory.+-- #ifdef __GLASGOW_HASKELL__ getCurrentDirectory :: IO FilePath getCurrentDirectory = do@@ -980,54 +1051,64 @@ Posix.getWorkingDirectory #endif -{- |If the operating system has a notion of current directories,-@'setCurrentDirectory' dir@ changes the current-directory of the calling process to /dir/.--The operation may fail with:--* 'HardwareFault'-A physical I\/O error has occurred.-@[EIO]@--* 'InvalidArgument'-The operand is not a valid directory name.-@[ENAMETOOLONG, ELOOP]@--* 'isDoesNotExistError' \/ 'NoSuchThing'-The directory does not exist.-@[ENOENT, ENOTDIR]@--* 'isPermissionError' \/ 'PermissionDenied'-The process has insufficient privileges to perform the operation.-@[EACCES]@--* 'UnsupportedOperation'-The operating system has no notion of current directory, or the-current directory cannot be dynamically changed.--* 'InappropriateType'-The path refers to an existing non-directory object.-@[ENOTDIR]@--Note that in a concurrent program, the current directory is global-state shared between all threads of the process. When using-filesystem operations from multiple threads, it is therefore highly-recommended to use absolute rather than relative `FilePath`s.---}-+-- | Change the working directory to the given path.+--+-- In a multithreaded program, the current working directory is a global state+-- shared among all threads of the process. Therefore, when performing+-- filesystem operations from multiple threads, it is highly recommended to+-- use absolute rather than relative paths (see: 'makeAbsolute').+--+-- The operation may fail with:+--+-- * 'HardwareFault'+-- A physical I\/O error has occurred.+-- @[EIO]@+--+-- * 'InvalidArgument'+-- The operand is not a valid directory name.+-- @[ENAMETOOLONG, ELOOP]@+--+-- * 'isDoesNotExistError' or 'NoSuchThing'+-- The directory does not exist.+-- @[ENOENT, ENOTDIR]@+--+-- * 'isPermissionError' or 'PermissionDenied'+-- The process has insufficient privileges to perform the operation.+-- @[EACCES]@+--+-- * 'UnsupportedOperation'+-- The operating system has no notion of current working directory, or the+-- working directory cannot be dynamically changed.+--+-- * 'InappropriateType'+-- The path refers to an existing non-directory object.+-- @[ENOTDIR]@+-- setCurrentDirectory :: FilePath -> IO ()-setCurrentDirectory path =+setCurrentDirectory = #ifdef mingw32_HOST_OS- Win32.setCurrentDirectory path+ Win32.setCurrentDirectory #else- Posix.changeWorkingDirectory path+ Posix.changeWorkingDirectory #endif -#endif /* __GLASGOW_HASKELL__ */+-- | Run an 'IO' action with the given working directory and restore the+-- original working directory afterwards, even if the given action fails due+-- to an exception.+--+-- The operation may fail with the same exceptions as 'getCurrentDirectory'+-- and 'setCurrentDirectory'.+--+-- @since 1.2.3.0+--+withCurrentDirectory :: FilePath -- ^ Directory to execute in+ -> IO a -- ^ Action to be executed+ -> IO a+withCurrentDirectory dir action =+ bracket getCurrentDirectory setCurrentDirectory $ \ _ -> do+ setCurrentDirectory dir+ action -#ifdef __GLASGOW_HASKELL__ {- |The operation 'doesDirectoryExist' returns 'True' if the argument file exists and is either a directory or a symbolic link to a directory, and 'False' otherwise.@@ -1041,7 +1122,7 @@ (do stat <- Posix.getFileStatus name return (Posix.isDirectory stat)) #endif- `E.catch` ((\ _ -> return False) :: IOException -> IO Bool)+ `catchIOError` \ _ -> return False {- |The operation 'doesFileExist' returns 'True' if the argument file exists and is not a directory, and 'False' otherwise.@@ -1055,47 +1136,197 @@ (do stat <- Posix.getFileStatus name return (not (Posix.isDirectory stat))) #endif- `E.catch` ((\ _ -> return False) :: IOException -> IO Bool)--{- |The 'getModificationTime' operation returns the-clock time at which the file or directory was last modified.--The operation may fail with:--* 'isPermissionError' if the user is not permitted to access- the modification time; or+ `catchIOError` \ _ -> return False -* 'isDoesNotExistError' if the file or directory does not exist.+#ifdef mingw32_HOST_OS+-- | Open the handle of an existing file or directory.+openFileHandle :: String -> Win32.AccessMode -> IO Win32.HANDLE+openFileHandle path mode = Win32.createFile path mode share Nothing+ Win32.oPEN_EXISTING flags Nothing+ where share = win32_fILE_SHARE_DELETE+ .|. Win32.fILE_SHARE_READ+ .|. Win32.fILE_SHARE_WRITE+ flags = Win32.fILE_ATTRIBUTE_NORMAL+ .|. Win32.fILE_FLAG_BACKUP_SEMANTICS -- required for directories+#endif -Note: This function returns a timestamp with sub-second resolution-only if this package is compiled against @unix-2.6.0.0@ or later-for unix systems, and @Win32-2.3.1.0@ or later for windows systems.-Of course this also requires that the underlying file system supports-such high resolution timestamps.--}+-- | Obtain the time at which the file or directory was last accessed.+--+-- The operation may fail with:+--+-- * 'isPermissionError' if the user is not permitted to read+-- the access time; or+--+-- * 'isDoesNotExistError' if the file or directory does not exist.+--+-- Caveat for POSIX systems: This function returns a timestamp with sub-second+-- resolution only if this package is compiled against @unix-2.6.0.0@ or later+-- and the underlying filesystem supports them.+--+-- @since 1.2.3.0+--+getAccessTime :: FilePath -> IO UTCTime+getAccessTime = modifyIOError (`ioeSetLocation` "getAccessTime") .+ getFileTime False +-- | Obtain the time at which the file or directory was last modified.+--+-- The operation may fail with:+--+-- * 'isPermissionError' if the user is not permitted to read+-- the modification time; or+--+-- * 'isDoesNotExistError' if the file or directory does not exist.+--+-- Caveat for POSIX systems: This function returns a timestamp with sub-second+-- resolution only if this package is compiled against @unix-2.6.0.0@ or later+-- and the underlying filesystem supports them.+-- getModificationTime :: FilePath -> IO UTCTime-getModificationTime name = do+getModificationTime = modifyIOError (`ioeSetLocation` "getModificationTime") .+ getFileTime True++getFileTime :: Bool -> FilePath -> IO UTCTime+getFileTime isMtime path = modifyIOError (`ioeSetFileName` path) $+ posixSecondsToUTCTime <$> getTime+ where+ path' = normalise path -- handle empty paths #ifdef mingw32_HOST_OS-#if MIN_VERSION_Win32(2,3,1)- fad <- Win32.getFileAttributesExStandard name- let win32_epoch_adjust = 116444736000000000- Win32.FILETIME ft = Win32.fadLastWriteTime fad- mod_time = fromIntegral (ft - win32_epoch_adjust) / 10000000+ getTime =+ bracket (openFileHandle path' Win32.gENERIC_READ)+ Win32.closeHandle $ \ handle ->+ alloca $ \ time -> do+ Win32.failIf_ not "" .+ uncurry (Win32.c_GetFileTime handle nullPtr) $+ swapIf isMtime (time, nullPtr)+ windowsToPosixTime <$> peek time #else- mod_time <- withFileStatus "getModificationTime" name $ \stat -> do- mtime <- st_mtime stat- return $ realToFrac (mtime :: CTime)+ getTime = convertTime <$> Posix.getFileStatus path'+# if MIN_VERSION_unix(2, 6, 0)+ convertTime = if isMtime then Posix.modificationTimeHiRes+ else Posix.accessTimeHiRes+# else+ convertTime = realToFrac . if isMtime then Posix.modificationTime+ else Posix.accessTime+# endif #endif-#else- stat <- Posix.getFileStatus name-#if MIN_VERSION_unix(2,6,0)- let mod_time = Posix.modificationTimeHiRes stat++-- | Change the time at which the file or directory was last accessed.+--+-- The operation may fail with:+--+-- * 'isPermissionError' if the user is not permitted to alter the+-- access time; or+--+-- * 'isDoesNotExistError' if the file or directory does not exist.+--+-- Some caveats for POSIX systems:+--+-- * Not all systems support @utimensat@, in which case the function can only+-- emulate the behavior by reading the modification time and then setting+-- both the access and modification times together. On systems where+-- @utimensat@ is supported, the access time is set atomically with+-- nanosecond precision.+--+-- * If compiled against a version of @unix@ prior to @2.7.0.0@, the function+-- would not be able to set timestamps with sub-second resolution. In this+-- case, there would also be loss of precision in the modification time.+--+-- @since 1.2.3.0+--+setAccessTime :: FilePath -> UTCTime -> IO ()+setAccessTime path =+ modifyIOError (`ioeSetLocation` "setAccessTime") .+ setFileTime False path++-- | Change the time at which the file or directory was last modified.+--+-- The operation may fail with:+--+-- * 'isPermissionError' if the user is not permitted to alter the+-- modification time; or+--+-- * 'isDoesNotExistError' if the file or directory does not exist.+--+-- Some caveats for POSIX systems:+--+-- * Not all systems support @utimensat@, in which case the function can only+-- emulate the behavior by reading the access time and then setting both the+-- access and modification times together. On systems where @utimensat@ is+-- supported, the modification time is set atomically with nanosecond+-- precision.+--+-- * If compiled against a version of @unix@ prior to @2.7.0.0@, the function+-- would not be able to set timestamps with sub-second resolution. In this+-- case, there would also be loss of precision in the access time.+--+-- @since 1.2.3.0+--+setModificationTime :: FilePath -> UTCTime -> IO ()+setModificationTime path =+ modifyIOError (`ioeSetLocation` "setModificationTime") .+ setFileTime True path++setFileTime :: Bool -> FilePath -> UTCTime -> IO ()+setFileTime isMtime path = modifyIOError (`ioeSetFileName` path) .+ setTime . utcTimeToPOSIXSeconds+ where+ path' = normalise path -- handle empty paths+#ifdef mingw32_HOST_OS+ setTime time =+ bracket (openFileHandle path' Win32.gENERIC_WRITE)+ Win32.closeHandle $ \ handle ->+ with (posixToWindowsTime time) $ \ time' ->+ Win32.failIf_ not "" .+ uncurry (Win32.c_SetFileTime handle nullPtr) $+ swapIf isMtime (time', nullPtr)+#elif defined HAVE_UTIMENSAT+ setTime time =+ withFilePath path' $ \ path'' ->+ withArray [atime, mtime] $ \ times ->+ throwErrnoPathIfMinus1_ "" path' $+ c_utimensat c_AT_FDCWD path'' times 0+ where (atime, mtime) = swapIf isMtime (toCTimeSpec time, utimeOmit) #else- let mod_time = realToFrac $ Posix.modificationTime stat+ setTime time = do+ stat <- Posix.getFileStatus path'+ uncurry (setFileTimes path') $+ swapIf isMtime (convertTime time, otherTime stat)+# if MIN_VERSION_unix(2, 7, 0)+ setFileTimes = Posix.setFileTimesHiRes+ convertTime = id+ otherTime = if isMtime+ then Posix.accessTimeHiRes+ else Posix.modificationTimeHiRes+# else+ setFileTimes = Posix.setFileTimes+ convertTime = fromInteger . truncate+ otherTime = if isMtime+ then Posix.accessTime+ else Posix.modificationTime+# endif #endif++swapIf :: Bool -> (a, a) -> (a, a)+swapIf True = swap+swapIf False = id++#ifdef mingw32_HOST_OS+-- | Difference between the Windows and POSIX epochs in units of 100ns.+windowsPosixEpochDifference :: Num a => a+windowsPosixEpochDifference = 116444736000000000++-- | Convert from Windows time to POSIX time.+windowsToPosixTime :: Win32.FILETIME -> POSIXTime+windowsToPosixTime (Win32.FILETIME t) =+ (fromIntegral t - windowsPosixEpochDifference) / 10000000++-- | Convert from POSIX time to Windows time. This is lossy as Windows time+-- has a resolution of only 100ns.+posixToWindowsTime :: POSIXTime -> Win32.FILETIME+posixToWindowsTime t = Win32.FILETIME $+ truncate (t * 10000000 + windowsPosixEpochDifference) #endif- return $ posixSecondsToUTCTime mod_time #endif /* __GLASGOW_HASKELL__ */ @@ -1116,34 +1347,18 @@ fileNameEndClean :: String -> String fileNameEndClean name = if isDrive name then addTrailingPathSeparator name else dropTrailingPathSeparator name--foreign import ccall unsafe "HsDirectory.h __hscore_S_IRUSR" s_IRUSR :: CMode-foreign import ccall unsafe "HsDirectory.h __hscore_S_IWUSR" s_IWUSR :: CMode-foreign import ccall unsafe "HsDirectory.h __hscore_S_IXUSR" s_IXUSR :: CMode-foreign import ccall unsafe "__hscore_S_IFDIR" s_IFDIR :: CMode #endif -#ifndef mingw32_HOST_OS-#ifdef __GLASGOW_HASKELL__-foreign import ccall unsafe "__hscore_long_path_size"- long_path_size :: Int-#else-long_path_size :: Int-long_path_size = 2048 -- // guess?-#endif /* __GLASGOW_HASKELL__ */-#endif /* !mingw32_HOST_OS */- {- | Returns the current user's home directory. The directory returned is expected to be writable by the current user, but note that it isn't generally considered good practice to store-application-specific data here; use 'getAppUserDataDirectory'-instead.+application-specific data here; use 'getXdgDirectory' or+'getAppUserDataDirectory' instead. On Unix, 'getHomeDirectory' returns the value of the @HOME@ environment variable. On Windows, the system is queried for a-suitable path; a typical path might be-@C:\/Documents And Settings\/user@.+suitable path; a typical path might be @C:\/Users\//\<user\>/@. The operation may fail with: @@ -1155,51 +1370,142 @@ cannot be found. -} getHomeDirectory :: IO FilePath-getHomeDirectory =- modifyIOError ((`ioeSetLocation` "getHomeDirectory")) $ do+getHomeDirectory = modifyIOError (`ioeSetLocation` "getHomeDirectory") get+ where #if defined(mingw32_HOST_OS)- r <- E.try $ Win32.sHGetFolderPath nullPtr Win32.cSIDL_PROFILE nullPtr 0- case (r :: Either IOException String) of- Right s -> return s- Left _ -> do- r1 <- E.try $ Win32.sHGetFolderPath nullPtr Win32.cSIDL_WINDOWS nullPtr 0- case r1 of- Right s -> return s- Left e -> ioError (e :: IOException)+ get = getFolderPath Win32.cSIDL_PROFILE `catchIOError` \ _ ->+ getFolderPath Win32.cSIDL_WINDOWS+ getFolderPath what = Win32.sHGetFolderPath nullPtr what nullPtr 0 #else- getEnv "HOME"+ get = getEnv "HOME" #endif -{- | Returns the pathname of a directory in which application-specific-data for the current user can be stored. The result of-'getAppUserDataDirectory' for a given application is specific to-the current user.--The argument should be the name of the application, which will be used-to construct the pathname (so avoid using unusual characters that-might result in an invalid pathname).--Note: the directory may not actually exist, and may need to be created-first. It is expected that the parent directory exists and is-writable.--On Unix, this function returns @$HOME\/.appName@. On Windows, a-typical path might be+-- | Special directories for storing user-specific application data,+-- configuration, and cache files, as specified by the+-- <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.+--+-- Note: On Windows, 'XdgData' and 'XdgConfig' map to the same directory.+--+-- @since 1.2.3.0+data XdgDirectory+ = XdgData+ -- ^ For data files (e.g. images).+ -- Defaults to @~\/.local\/share@ and can be+ -- overridden by the @XDG_DATA_HOME@ environment variable.+ -- On Windows, it is @%APPDATA%@+ -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming@).+ -- Can be considered as the user-specific equivalent of @\/usr\/share@.+ | XdgConfig+ -- ^ For configuration files.+ -- Defaults to @~\/.config@ and can be+ -- overridden by the @XDG_CONFIG_HOME@ environment variable.+ -- On Windows, it is @%APPDATA%@+ -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming@).+ -- Can be considered as the user-specific equivalent of @\/etc@.+ | XdgCache+ -- ^ For non-essential files (e.g. cache).+ -- Defaults to @~\/.cache@ and can be+ -- overridden by the @XDG_CACHE_HOME@ environment variable.+ -- On Windows, it is @%LOCALAPPDATA%@+ -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Local@).+ -- Can be considered as the user-specific equivalent of @\/var\/cache@.+ deriving (Bounded, Enum, Eq, Ord, Read, Show) -> C:/Users/user/AppData/Roaming/appName+-- | Obtain the paths to special directories for storing user-specific+-- application data, configuration, and cache files, conforming to the+-- <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.+-- Compared with 'getAppUserDataDirectory', this function provides a more+-- fine-grained hierarchy as well as greater flexibility for the user.+--+-- It also works on Windows, although in that case 'XdgData' and 'XdgConfig'+-- will map to the same directory.+--+-- The second argument is usually the name of the application. Since it+-- will be integrated into the path, it must consist of valid path+-- characters.+--+-- Note: The directory may not actually exist, in which case you would need+-- to create it with file mode @700@ (i.e. only accessible by the owner).+--+-- @since 1.2.3.0+getXdgDirectory :: XdgDirectory -- ^ which special directory+ -> FilePath -- ^ a relative path that is appended+ -- to the path; if empty, the base+ -- path is returned+ -> IO FilePath+getXdgDirectory xdgDir suffix =+ modifyIOError (`ioeSetLocation` "getXdgDirectory") $+ normalise . (</> suffix) <$>+ case xdgDir of+ XdgData -> get False "XDG_DATA_HOME" ".local/share"+ XdgConfig -> get False "XDG_CONFIG_HOME" ".config"+ XdgCache -> get True "XDG_CACHE_HOME" ".cache"+ where+#if defined(mingw32_HOST_OS)+ get isLocal _ _ = Win32.sHGetFolderPath nullPtr which nullPtr 0+ where which | isLocal = win32_cSIDL_LOCAL_APPDATA+ | otherwise = Win32.cSIDL_APPDATA+#else+ get _ name fallback = do+ env <- lookupEnv name+ case env of+ Nothing -> fallback'+ Just path | isRelative path -> fallback'+ | otherwise -> return path+ where fallback' = (</> fallback) <$> getHomeDirectory -The operation may fail with:+-- | Return the value of an environment variable, or 'Nothing' if there is no+-- such value. (Equivalent to "lookupEnv" from base-4.6.)+lookupEnv :: String -> IO (Maybe String)+lookupEnv name = do+ env <- tryIOErrorType isDoesNotExistError (getEnv name)+ case env of+ Left _ -> return Nothing+ Right value -> return (Just value) -* 'UnsupportedOperation'-The operating system has no notion of application-specific data directory.+-- | Similar to 'try' but only catches a specify kind of 'IOError' as+-- specified by the predicate.+tryIOErrorType :: (IOError -> Bool) -> IO a -> IO (Either IOError a)+tryIOErrorType check action = do+ result <- tryIOError action+ case result of+ Left err -> if check err then return (Left err) else ioError err+ Right val -> return (Right val)+#endif -* 'isDoesNotExistError'-The home directory for the current user does not exist, or-cannot be found.--}-getAppUserDataDirectory :: String -> IO FilePath+-- | Obtain the path to a special directory for storing user-specific+-- application data (traditional Unix location). Except for backward+-- compatibility reasons, newer applications may prefer the the+-- XDG-conformant location provided by 'getXdgDirectory', which offers a+-- more fine-grained hierarchy as well as greater flexibility for the user+-- (<https://github.com/haskell/directory/issues/6#issuecomment-96521020 migration guide>).+--+-- The argument is usually the name of the application. Since it will be+-- integrated into the path, it must consist of valid path characters.+--+-- * On Unix-like systems, the path is @~\/./\<app\>/@.+-- * On Windows, the path is @%APPDATA%\//\<app\>/@+-- (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming\//\<app\>/@)+--+-- Note: the directory may not actually exist, in which case you would need+-- to create it. It is expected that the parent directory exists and is+-- writable.+--+-- The operation may fail with:+--+-- * 'UnsupportedOperation'+-- The operating system has no notion of application-specific data+-- directory.+--+-- * 'isDoesNotExistError'+-- The home directory for the current user does not exist, or cannot be+-- found.+--+getAppUserDataDirectory :: FilePath -- ^ a relative path that is appended+ -- to the path+ -> IO FilePath getAppUserDataDirectory appName = do- modifyIOError ((`ioeSetLocation` "getAppUserDataDirectory")) $ do+ modifyIOError (`ioeSetLocation` "getAppUserDataDirectory") $ do #if defined(mingw32_HOST_OS) s <- Win32.sHGetFolderPath nullPtr Win32.cSIDL_APPDATA nullPtr 0 return (s++'\\':appName)@@ -1212,13 +1518,12 @@ The directory returned is expected to be writable by the current user, but note that it isn't generally considered good practice to store-application-specific data here; use 'getAppUserDataDirectory'-instead.+application-specific data here; use 'getXdgDirectory' or+'getAppUserDataDirectory' instead. On Unix, 'getUserDocumentsDirectory' returns the value of the @HOME@ environment variable. On Windows, the system is queried for a-suitable path; a typical path might be-@C:\/Documents And Settings\/user\/My Documents@.+suitable path; a typical path might be @C:\/Users\//\<user\>/\/Documents@. The operation may fail with: @@ -1231,7 +1536,7 @@ -} getUserDocumentsDirectory :: IO FilePath getUserDocumentsDirectory = do- modifyIOError ((`ioeSetLocation` "getUserDocumentsDirectory")) $ do+ modifyIOError (`ioeSetLocation` "getUserDocumentsDirectory") $ do #if defined(mingw32_HOST_OS) Win32.sHGetFolderPath nullPtr Win32.cSIDL_PERSONAL nullPtr 0 #else@@ -1265,21 +1570,10 @@ The function doesn\'t verify whether the path exists. -} getTemporaryDirectory :: IO FilePath-getTemporaryDirectory = do+getTemporaryDirectory = #if defined(mingw32_HOST_OS) Win32.getTemporaryDirectory #else- getEnv "TMPDIR"- `catchIOError` \e -> if isDoesNotExistError e then return "/tmp"- else throwIO e-#endif---- ToDo: This should be determined via autoconf (AC_EXEEXT)--- | Extension for executable files--- (typically @\"\"@ on Unix and @\"exe\"@ on Windows or OS\/2)-exeExtension :: String-#ifdef mingw32_HOST_OS-exeExtension = "exe"-#else-exeExtension = ""+ getEnv "TMPDIR" `catchIOError` \ err ->+ if isDoesNotExistError err then return "/tmp" else ioError err #endif
+ System/Directory/Internal.hsc view
@@ -0,0 +1,31 @@+#include <HsDirectoryConfig.h>++module System.Directory.Internal+ ( module System.Directory.Internal++#ifdef HAVE_UTIMENSAT+ , module System.Directory.Internal.C_utimensat+#endif++#ifdef mingw32_HOST_OS+ , module System.Directory.Internal.Windows+#else+ , module System.Directory.Internal.Posix+#endif++) where++#ifdef HAVE_UTIMENSAT+import System.Directory.Internal.C_utimensat+#endif++#ifdef mingw32_HOST_OS+import System.Directory.Internal.Windows+#else+import System.Directory.Internal.Posix+#endif++-- | Filename extension for executable files (including the dot if any)+-- (usually @\"\"@ on POSIX systems and @\".exe\"@ on Windows or OS\/2).+exeExtension :: String+exeExtension = (#const_str EXE_EXTENSION)
+ System/Directory/Internal/C_utimensat.hsc view
@@ -0,0 +1,48 @@+#include <HsDirectoryConfig.h>++#ifdef HAVE_FCNTL_H+# include <fcntl.h>+#endif+#ifdef HAVE_TIME_H+# include <time.h>+#endif+#ifdef HAVE_SYS_STAT_H+# include <sys/stat.h>+#endif++module System.Directory.Internal.C_utimensat where+#ifdef HAVE_UTIMENSAT+import Foreign+import Foreign.C+import Data.Time.Clock.POSIX (POSIXTime)+import System.Posix.Types++data CTimeSpec = CTimeSpec EpochTime CLong++instance Storable CTimeSpec where+ sizeOf _ = #size struct timespec+ alignment _ = alignment (undefined :: CInt)+ poke p (CTimeSpec sec nsec) = do+ (#poke struct timespec, tv_sec ) p sec+ (#poke struct timespec, tv_nsec) p nsec+ peek p = do+ sec <- #{peek struct timespec, tv_sec } p+ nsec <- #{peek struct timespec, tv_nsec} p+ return (CTimeSpec sec nsec)++c_AT_FDCWD :: Integral a => a+c_AT_FDCWD = (#const AT_FDCWD)++utimeOmit :: CTimeSpec+utimeOmit = CTimeSpec (CTime 0) (#const UTIME_OMIT)++toCTimeSpec :: POSIXTime -> CTimeSpec+toCTimeSpec t = CTimeSpec (CTime sec) (truncate $ 10 ^ (9 :: Int) * frac)+ where+ (sec, frac) = if frac' < 0 then (sec' - 1, frac' + 1) else (sec', frac')+ (sec', frac') = properFraction (toRational t)++foreign import ccall unsafe "utimensat" c_utimensat+ :: CInt -> CString -> Ptr CTimeSpec -> CInt -> IO CInt++#endif
+ System/Directory/Internal/Posix.hsc view
@@ -0,0 +1,42 @@+#include <HsDirectoryConfig.h>++#ifdef HAVE_LIMITS_H+# include <limits.h>+#endif++module System.Directory.Internal.Posix where+#ifndef mingw32_HOST_OS+import Control.Monad ((>=>))+import Control.Exception (bracket)+import Foreign+import Foreign.C++-- we use the 'free' from the standard library here since it's not entirely+-- clear whether Haskell's 'free' corresponds to the same one+foreign import ccall unsafe "free" c_free :: Ptr a -> IO ()++c_PATH_MAX :: Maybe Int+#ifdef PATH_MAX+c_PATH_MAX | c_PATH_MAX' > toInteger maxValue = Nothing+ | otherwise = Just (fromInteger c_PATH_MAX')+ where c_PATH_MAX' = (#const PATH_MAX)+ maxValue = maxBound `asTypeOf` case c_PATH_MAX of ~(Just x) -> x+#else+c_PATH_MAX = Nothing+#endif++foreign import ccall unsafe "realpath" c_realpath+ :: CString -> CString -> IO CString++withRealpath :: CString -> (CString -> IO a) -> IO a+withRealpath path action = case c_PATH_MAX of+ Nothing ->+ -- newer versions of POSIX support cases where the 2nd arg is NULL;+ -- hopefully that is the case here, as there is no safer way+ bracket (realpath nullPtr) c_free action+ Just pathMax ->+ -- allocate one extra just to be safe+ allocaBytes (pathMax + 1) (realpath >=> action)+ where realpath = throwErrnoIfNull "" . c_realpath path++#endif
+ System/Directory/Internal/Windows.hsc view
@@ -0,0 +1,23 @@+#include <HsDirectoryConfig.h>++#ifdef HAVE_SYS_STAT_H+# include <sys/stat.h>+#endif++module System.Directory.Internal.Windows where+#ifdef mingw32_HOST_OS+import System.Posix.Types++s_IRUSR :: CMode+s_IRUSR = (#const S_IRUSR)++s_IWUSR :: CMode+s_IWUSR = (#const S_IWUSR)++s_IXUSR :: CMode+s_IXUSR = (#const S_IXUSR)++s_IFDIR :: CMode+s_IFDIR = (#const S_IFDIR)++#endif
cbits/directory.c view
@@ -4,6 +4,8 @@ * */ +/* [DEPRECATED] This file may be removed in future versions. */+ #define INLINE #include "HsDirectory.h"
changelog.md view
@@ -1,10 +1,32 @@ Changelog for the [`directory`][1] package ========================================== +## 1.2.3.0 (July 2015)++ * Add support for XDG Base Directory Specification+ ([#6](https://github.com/haskell/directory/issues/6))++ * Implement `setModificationTime` counterpart to `getModificationTime`+ ([#13](https://github.com/haskell/directory/issues/13))++ * Implement `getAccessTime` and `setAccessTime`++ * Fix `canonicalizePath` so that it always returns a reasonable result even+ if the path is inaccessible and will not throw exceptions unless the+ current directory cannot be obtained+ ([#23](https://github.com/haskell/directory/issues/23))++ * Corrected the trailing slash behavior of `makeAbsolute`+ so that `makeAbsolute "" == makeAbsolute "."`++ * Deprecate use of `HsDirectory.h` and `HsDirectoryConfig.h`++ * Implement `withCurrentDirectory`+ ## 1.2.2.1 (Apr 2015) - * [#24](https://github.com/haskell/directory/issues/24):- Fix dependency problem on NixOS when building with tests+ * Fix dependency problem on NixOS when building with tests+ ([#24](https://github.com/haskell/directory/issues/24)) ## 1.2.2.0 (Mar 2015) @@ -16,23 +38,23 @@ * Replace `throw` by better defined `throwIO`s - * [#17](https://github.com/haskell/directory/pull/17):- Avoid stack overflow in `getDirectoryContents`+ * Avoid stack overflow in `getDirectoryContents`+ ([#17](https://github.com/haskell/directory/pull/17)) - * [#14](https://github.com/haskell/directory/issues/14):- Expose `findExecutables`+ * Expose `findExecutables`+ ([#14](https://github.com/haskell/directory/issues/14)) - * [#15](https://github.com/haskell/directory/issues/15):- `removeDirectoryRecursive` no longer follows symlinks under any+ * `removeDirectoryRecursive` no longer follows symlinks under any circumstances+ ([#15](https://github.com/haskell/directory/issues/15)) - * [#9](https://github.com/haskell/directory/issues/9):- Allow trailing path separators in `getPermissions` on Windows+ * Allow trailing path separators in `getPermissions` on Windows+ ([#9](https://github.com/haskell/directory/issues/9)) - * [#8](https://github.com/haskell/directory/pull/8):- `renameFile` now always throws the correct error type+ * `renameFile` now always throws the correct error type (`InappropriateType`) when the destination is a directory, as long as the filesystem is not being modified concurrently+ ([#8](https://github.com/haskell/directory/pull/8)) * Add `makeAbsolute`, which should be preferred over `canonicalizePath` unless one requires symbolic links to be resolved
− config.guess
@@ -1,1420 +0,0 @@-#! /bin/sh-# Attempt to guess a canonical system name.-# Copyright 1992-2014 Free Software Foundation, Inc.--timestamp='2014-03-23'--# This file is free software; you can redistribute it and/or modify it-# under the terms of the GNU General Public License as published by-# the Free Software Foundation; either version 3 of the License, or-# (at your option) any later version.-#-# This program is distributed in the hope that it will be useful, but-# WITHOUT ANY WARRANTY; without even the implied warranty of-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU-# General Public License for more details.-#-# You should have received a copy of the GNU General Public License-# along with this program; if not, see <http://www.gnu.org/licenses/>.-#-# As a special exception to the GNU General Public License, if you-# distribute this file as part of a program that contains a-# configuration script generated by Autoconf, you may include it under-# the same distribution terms that you use for the rest of that-# program. This Exception is an additional permission under section 7-# of the GNU General Public License, version 3 ("GPLv3").-#-# Originally written by Per Bothner.-#-# You can get the latest version of this script from:-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD-#-# Please send patches with a ChangeLog entry to config-patches@gnu.org.---me=`echo "$0" | sed -e 's,.*/,,'`--usage="\-Usage: $0 [OPTION]--Output the configuration name of the system \`$me' is run on.--Operation modes:- -h, --help print this help, then exit- -t, --time-stamp print date of last modification, then exit- -v, --version print version number, then exit--Report bugs and patches to <config-patches@gnu.org>."--version="\-GNU config.guess ($timestamp)--Originally written by Per Bothner.-Copyright 1992-2014 Free Software Foundation, Inc.--This is free software; see the source for copying conditions. There is NO-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."--help="-Try \`$me --help' for more information."--# Parse command line-while test $# -gt 0 ; do- case $1 in- --time-stamp | --time* | -t )- echo "$timestamp" ; exit ;;- --version | -v )- echo "$version" ; exit ;;- --help | --h* | -h )- echo "$usage"; exit ;;- -- ) # Stop option processing- shift; break ;;- - ) # Use stdin as input.- break ;;- -* )- echo "$me: invalid option $1$help" >&2- exit 1 ;;- * )- break ;;- esac-done--if test $# != 0; then- echo "$me: too many arguments$help" >&2- exit 1-fi--trap 'exit 1' 1 2 15--# CC_FOR_BUILD -- compiler used by this script. Note that the use of a-# compiler to aid in system detection is discouraged as it requires-# temporary files to be created and, as you can see below, it is a-# headache to deal with in a portable fashion.--# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still-# use `HOST_CC' if defined, but it is deprecated.--# Portable tmp directory creation inspired by the Autoconf team.--set_cc_for_build='-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;-: ${TMPDIR=/tmp} ;- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;-dummy=$tmp/dummy ;-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;-case $CC_FOR_BUILD,$HOST_CC,$CC in- ,,) echo "int x;" > $dummy.c ;- for c in cc gcc c89 c99 ; do- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then- CC_FOR_BUILD="$c"; break ;- fi ;- done ;- if test x"$CC_FOR_BUILD" = x ; then- CC_FOR_BUILD=no_compiler_found ;- fi- ;;- ,,*) CC_FOR_BUILD=$CC ;;- ,*,*) CC_FOR_BUILD=$HOST_CC ;;-esac ; set_cc_for_build= ;'--# This is needed to find uname on a Pyramid OSx when run in the BSD universe.-# (ghazi@noc.rutgers.edu 1994-08-24)-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then- PATH=$PATH:/.attbin ; export PATH-fi--UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown--case "${UNAME_SYSTEM}" in-Linux|GNU|GNU/*)- # If the system lacks a compiler, then just pick glibc.- # We could probably try harder.- LIBC=gnu-- eval $set_cc_for_build- cat <<-EOF > $dummy.c- #include <features.h>- #if defined(__UCLIBC__)- LIBC=uclibc- #elif defined(__dietlibc__)- LIBC=dietlibc- #else- LIBC=gnu- #endif- EOF- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`- ;;-esac--# Note: order is significant - the case branches are not exclusive.--case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in- *:NetBSD:*:*)- # NetBSD (nbsd) targets should (where applicable) match one or- # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently- # switched to ELF, *-*-netbsd* would select the old- # object file format. This provides both forward- # compatibility and a consistent mechanism for selecting the- # object file format.- #- # Note: NetBSD doesn't particularly care about the vendor- # portion of the name. We always set it to "unknown".- sysctl="sysctl -n hw.machine_arch"- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`- case "${UNAME_MACHINE_ARCH}" in- armeb) machine=armeb-unknown ;;- arm*) machine=arm-unknown ;;- sh3el) machine=shl-unknown ;;- sh3eb) machine=sh-unknown ;;- sh5el) machine=sh5le-unknown ;;- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;- esac- # The Operating System including object format, if it has switched- # to ELF recently, or will in the future.- case "${UNAME_MACHINE_ARCH}" in- arm*|i386|m68k|ns32k|sh3*|sparc|vax)- eval $set_cc_for_build- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \- | grep -q __ELF__- then- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).- # Return netbsd for either. FIX?- os=netbsd- else- os=netbsdelf- fi- ;;- *)- os=netbsd- ;;- esac- # The OS release- # Debian GNU/NetBSD machines have a different userland, and- # thus, need a distinct triplet. However, they do not need- # kernel version information, so it can be replaced with a- # suitable tag, in the style of linux-gnu.- case "${UNAME_VERSION}" in- Debian*)- release='-gnu'- ;;- *)- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`- ;;- esac- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:- # contains redundant information, the shorter form:- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.- echo "${machine}-${os}${release}"- exit ;;- *:Bitrig:*:*)- UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}- exit ;;- *:OpenBSD:*:*)- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}- exit ;;- *:ekkoBSD:*:*)- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}- exit ;;- *:SolidBSD:*:*)- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}- exit ;;- macppc:MirBSD:*:*)- echo powerpc-unknown-mirbsd${UNAME_RELEASE}- exit ;;- *:MirBSD:*:*)- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}- exit ;;- alpha:OSF1:*:*)- case $UNAME_RELEASE in- *4.0)- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`- ;;- *5.*)- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`- ;;- esac- # According to Compaq, /usr/sbin/psrinfo has been available on- # OSF/1 and Tru64 systems produced since 1995. I hope that- # covers most systems running today. This code pipes the CPU- # types through head -n 1, so we only detect the type of CPU 0.- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`- case "$ALPHA_CPU_TYPE" in- "EV4 (21064)")- UNAME_MACHINE="alpha" ;;- "EV4.5 (21064)")- UNAME_MACHINE="alpha" ;;- "LCA4 (21066/21068)")- UNAME_MACHINE="alpha" ;;- "EV5 (21164)")- UNAME_MACHINE="alphaev5" ;;- "EV5.6 (21164A)")- UNAME_MACHINE="alphaev56" ;;- "EV5.6 (21164PC)")- UNAME_MACHINE="alphapca56" ;;- "EV5.7 (21164PC)")- UNAME_MACHINE="alphapca57" ;;- "EV6 (21264)")- UNAME_MACHINE="alphaev6" ;;- "EV6.7 (21264A)")- UNAME_MACHINE="alphaev67" ;;- "EV6.8CB (21264C)")- UNAME_MACHINE="alphaev68" ;;- "EV6.8AL (21264B)")- UNAME_MACHINE="alphaev68" ;;- "EV6.8CX (21264D)")- UNAME_MACHINE="alphaev68" ;;- "EV6.9A (21264/EV69A)")- UNAME_MACHINE="alphaev69" ;;- "EV7 (21364)")- UNAME_MACHINE="alphaev7" ;;- "EV7.9 (21364A)")- UNAME_MACHINE="alphaev79" ;;- esac- # A Pn.n version is a patched version.- # A Vn.n version is a released version.- # A Tn.n version is a released field test version.- # A Xn.n version is an unreleased experimental baselevel.- # 1.2 uses "1.2" for uname -r.- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.- exitcode=$?- trap '' 0- exit $exitcode ;;- Alpha\ *:Windows_NT*:*)- # How do we know it's Interix rather than the generic POSIX subsystem?- # Should we change UNAME_MACHINE based on the output of uname instead- # of the specific Alpha model?- echo alpha-pc-interix- exit ;;- 21064:Windows_NT:50:3)- echo alpha-dec-winnt3.5- exit ;;- Amiga*:UNIX_System_V:4.0:*)- echo m68k-unknown-sysv4- exit ;;- *:[Aa]miga[Oo][Ss]:*:*)- echo ${UNAME_MACHINE}-unknown-amigaos- exit ;;- *:[Mm]orph[Oo][Ss]:*:*)- echo ${UNAME_MACHINE}-unknown-morphos- exit ;;- *:OS/390:*:*)- echo i370-ibm-openedition- exit ;;- *:z/VM:*:*)- echo s390-ibm-zvmoe- exit ;;- *:OS400:*:*)- echo powerpc-ibm-os400- exit ;;- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)- echo arm-acorn-riscix${UNAME_RELEASE}- exit ;;- arm*:riscos:*:*|arm*:RISCOS:*:*)- echo arm-unknown-riscos- exit ;;- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)- echo hppa1.1-hitachi-hiuxmpp- exit ;;- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.- if test "`(/bin/universe) 2>/dev/null`" = att ; then- echo pyramid-pyramid-sysv3- else- echo pyramid-pyramid-bsd- fi- exit ;;- NILE*:*:*:dcosx)- echo pyramid-pyramid-svr4- exit ;;- DRS?6000:unix:4.0:6*)- echo sparc-icl-nx6- exit ;;- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)- case `/usr/bin/uname -p` in- sparc) echo sparc-icl-nx7; exit ;;- esac ;;- s390x:SunOS:*:*)- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`- exit ;;- sun4H:SunOS:5.*:*)- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`- exit ;;- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`- exit ;;- i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)- echo i386-pc-auroraux${UNAME_RELEASE}- exit ;;- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)- eval $set_cc_for_build- SUN_ARCH="i386"- # If there is a compiler, see if it is configured for 64-bit objects.- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.- # This test works for both compilers.- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \- grep IS_64BIT_ARCH >/dev/null- then- SUN_ARCH="x86_64"- fi- fi- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`- exit ;;- sun4*:SunOS:6*:*)- # According to config.sub, this is the proper way to canonicalize- # SunOS6. Hard to guess exactly what SunOS6 will be like, but- # it's likely to be more like Solaris than SunOS4.- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`- exit ;;- sun4*:SunOS:*:*)- case "`/usr/bin/arch -k`" in- Series*|S4*)- UNAME_RELEASE=`uname -v`- ;;- esac- # Japanese Language versions have a version number like `4.1.3-JL'.- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`- exit ;;- sun3*:SunOS:*:*)- echo m68k-sun-sunos${UNAME_RELEASE}- exit ;;- sun*:*:4.2BSD:*)- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3- case "`/bin/arch`" in- sun3)- echo m68k-sun-sunos${UNAME_RELEASE}- ;;- sun4)- echo sparc-sun-sunos${UNAME_RELEASE}- ;;- esac- exit ;;- aushp:SunOS:*:*)- echo sparc-auspex-sunos${UNAME_RELEASE}- exit ;;- # The situation for MiNT is a little confusing. The machine name- # can be virtually everything (everything which is not- # "atarist" or "atariste" at least should have a processor- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"- # to the lowercase version "mint" (or "freemint"). Finally- # the system name "TOS" denotes a system which is actually not- # MiNT. But MiNT is downward compatible to TOS, so this should- # be no problem.- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)- echo m68k-atari-mint${UNAME_RELEASE}- exit ;;- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)- echo m68k-atari-mint${UNAME_RELEASE}- exit ;;- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)- echo m68k-atari-mint${UNAME_RELEASE}- exit ;;- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)- echo m68k-milan-mint${UNAME_RELEASE}- exit ;;- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)- echo m68k-hades-mint${UNAME_RELEASE}- exit ;;- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)- echo m68k-unknown-mint${UNAME_RELEASE}- exit ;;- m68k:machten:*:*)- echo m68k-apple-machten${UNAME_RELEASE}- exit ;;- powerpc:machten:*:*)- echo powerpc-apple-machten${UNAME_RELEASE}- exit ;;- RISC*:Mach:*:*)- echo mips-dec-mach_bsd4.3- exit ;;- RISC*:ULTRIX:*:*)- echo mips-dec-ultrix${UNAME_RELEASE}- exit ;;- VAX*:ULTRIX*:*:*)- echo vax-dec-ultrix${UNAME_RELEASE}- exit ;;- 2020:CLIX:*:* | 2430:CLIX:*:*)- echo clipper-intergraph-clix${UNAME_RELEASE}- exit ;;- mips:*:*:UMIPS | mips:*:*:RISCos)- eval $set_cc_for_build- sed 's/^ //' << EOF >$dummy.c-#ifdef __cplusplus-#include <stdio.h> /* for printf() prototype */- int main (int argc, char *argv[]) {-#else- int main (argc, argv) int argc; char *argv[]; {-#endif- #if defined (host_mips) && defined (MIPSEB)- #if defined (SYSTYPE_SYSV)- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);- #endif- #if defined (SYSTYPE_SVR4)- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);- #endif- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);- #endif- #endif- exit (-1);- }-EOF- $CC_FOR_BUILD -o $dummy $dummy.c &&- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&- SYSTEM_NAME=`$dummy $dummyarg` &&- { echo "$SYSTEM_NAME"; exit; }- echo mips-mips-riscos${UNAME_RELEASE}- exit ;;- Motorola:PowerMAX_OS:*:*)- echo powerpc-motorola-powermax- exit ;;- Motorola:*:4.3:PL8-*)- echo powerpc-harris-powermax- exit ;;- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)- echo powerpc-harris-powermax- exit ;;- Night_Hawk:Power_UNIX:*:*)- echo powerpc-harris-powerunix- exit ;;- m88k:CX/UX:7*:*)- echo m88k-harris-cxux7- exit ;;- m88k:*:4*:R4*)- echo m88k-motorola-sysv4- exit ;;- m88k:*:3*:R3*)- echo m88k-motorola-sysv3- exit ;;- AViiON:dgux:*:*)- # DG/UX returns AViiON for all architectures- UNAME_PROCESSOR=`/usr/bin/uname -p`- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]- then- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \- [ ${TARGET_BINARY_INTERFACE}x = x ]- then- echo m88k-dg-dgux${UNAME_RELEASE}- else- echo m88k-dg-dguxbcs${UNAME_RELEASE}- fi- else- echo i586-dg-dgux${UNAME_RELEASE}- fi- exit ;;- M88*:DolphinOS:*:*) # DolphinOS (SVR3)- echo m88k-dolphin-sysv3- exit ;;- M88*:*:R3*:*)- # Delta 88k system running SVR3- echo m88k-motorola-sysv3- exit ;;- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)- echo m88k-tektronix-sysv3- exit ;;- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)- echo m68k-tektronix-bsd- exit ;;- *:IRIX*:*:*)- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`- exit ;;- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '- i*86:AIX:*:*)- echo i386-ibm-aix- exit ;;- ia64:AIX:*:*)- if [ -x /usr/bin/oslevel ] ; then- IBM_REV=`/usr/bin/oslevel`- else- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}- fi- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}- exit ;;- *:AIX:2:3)- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then- eval $set_cc_for_build- sed 's/^ //' << EOF >$dummy.c- #include <sys/systemcfg.h>-- main()- {- if (!__power_pc())- exit(1);- puts("powerpc-ibm-aix3.2.5");- exit(0);- }-EOF- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`- then- echo "$SYSTEM_NAME"- else- echo rs6000-ibm-aix3.2.5- fi- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then- echo rs6000-ibm-aix3.2.4- else- echo rs6000-ibm-aix3.2- fi- exit ;;- *:AIX:*:[4567])- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then- IBM_ARCH=rs6000- else- IBM_ARCH=powerpc- fi- if [ -x /usr/bin/oslevel ] ; then- IBM_REV=`/usr/bin/oslevel`- else- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}- fi- echo ${IBM_ARCH}-ibm-aix${IBM_REV}- exit ;;- *:AIX:*:*)- echo rs6000-ibm-aix- exit ;;- ibmrt:4.4BSD:*|romp-ibm:BSD:*)- echo romp-ibm-bsd4.4- exit ;;- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to- exit ;; # report: romp-ibm BSD 4.3- *:BOSX:*:*)- echo rs6000-bull-bosx- exit ;;- DPX/2?00:B.O.S.:*:*)- echo m68k-bull-sysv3- exit ;;- 9000/[34]??:4.3bsd:1.*:*)- echo m68k-hp-bsd- exit ;;- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)- echo m68k-hp-bsd4.4- exit ;;- 9000/[34678]??:HP-UX:*:*)- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`- case "${UNAME_MACHINE}" in- 9000/31? ) HP_ARCH=m68000 ;;- 9000/[34]?? ) HP_ARCH=m68k ;;- 9000/[678][0-9][0-9])- if [ -x /usr/bin/getconf ]; then- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`- case "${sc_cpu_version}" in- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1- 532) # CPU_PA_RISC2_0- case "${sc_kernel_bits}" in- 32) HP_ARCH="hppa2.0n" ;;- 64) HP_ARCH="hppa2.0w" ;;- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20- esac ;;- esac- fi- if [ "${HP_ARCH}" = "" ]; then- eval $set_cc_for_build- sed 's/^ //' << EOF >$dummy.c-- #define _HPUX_SOURCE- #include <stdlib.h>- #include <unistd.h>-- int main ()- {- #if defined(_SC_KERNEL_BITS)- long bits = sysconf(_SC_KERNEL_BITS);- #endif- long cpu = sysconf (_SC_CPU_VERSION);-- switch (cpu)- {- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;- case CPU_PA_RISC2_0:- #if defined(_SC_KERNEL_BITS)- switch (bits)- {- case 64: puts ("hppa2.0w"); break;- case 32: puts ("hppa2.0n"); break;- default: puts ("hppa2.0"); break;- } break;- #else /* !defined(_SC_KERNEL_BITS) */- puts ("hppa2.0"); break;- #endif- default: puts ("hppa1.0"); break;- }- exit (0);- }-EOF- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`- test -z "$HP_ARCH" && HP_ARCH=hppa- fi ;;- esac- if [ ${HP_ARCH} = "hppa2.0w" ]- then- eval $set_cc_for_build-- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler- # generating 64-bit code. GNU and HP use different nomenclature:- #- # $ CC_FOR_BUILD=cc ./config.guess- # => hppa2.0w-hp-hpux11.23- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess- # => hppa64-hp-hpux11.23-- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |- grep -q __LP64__- then- HP_ARCH="hppa2.0w"- else- HP_ARCH="hppa64"- fi- fi- echo ${HP_ARCH}-hp-hpux${HPUX_REV}- exit ;;- ia64:HP-UX:*:*)- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`- echo ia64-hp-hpux${HPUX_REV}- exit ;;- 3050*:HI-UX:*:*)- eval $set_cc_for_build- sed 's/^ //' << EOF >$dummy.c- #include <unistd.h>- int- main ()- {- long cpu = sysconf (_SC_CPU_VERSION);- /* The order matters, because CPU_IS_HP_MC68K erroneously returns- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct- results, however. */- if (CPU_IS_PA_RISC (cpu))- {- switch (cpu)- {- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;- default: puts ("hppa-hitachi-hiuxwe2"); break;- }- }- else if (CPU_IS_HP_MC68K (cpu))- puts ("m68k-hitachi-hiuxwe2");- else puts ("unknown-hitachi-hiuxwe2");- exit (0);- }-EOF- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&- { echo "$SYSTEM_NAME"; exit; }- echo unknown-hitachi-hiuxwe2- exit ;;- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )- echo hppa1.1-hp-bsd- exit ;;- 9000/8??:4.3bsd:*:*)- echo hppa1.0-hp-bsd- exit ;;- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)- echo hppa1.0-hp-mpeix- exit ;;- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )- echo hppa1.1-hp-osf- exit ;;- hp8??:OSF1:*:*)- echo hppa1.0-hp-osf- exit ;;- i*86:OSF1:*:*)- if [ -x /usr/sbin/sysversion ] ; then- echo ${UNAME_MACHINE}-unknown-osf1mk- else- echo ${UNAME_MACHINE}-unknown-osf1- fi- exit ;;- parisc*:Lites*:*:*)- echo hppa1.1-hp-lites- exit ;;- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)- echo c1-convex-bsd- exit ;;- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)- if getsysinfo -f scalar_acc- then echo c32-convex-bsd- else echo c2-convex-bsd- fi- exit ;;- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)- echo c34-convex-bsd- exit ;;- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)- echo c38-convex-bsd- exit ;;- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)- echo c4-convex-bsd- exit ;;- CRAY*Y-MP:*:*:*)- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'- exit ;;- CRAY*[A-Z]90:*:*:*)- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \- -e 's/\.[^.]*$/.X/'- exit ;;- CRAY*TS:*:*:*)- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'- exit ;;- CRAY*T3E:*:*:*)- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'- exit ;;- CRAY*SV1:*:*:*)- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'- exit ;;- *:UNICOS/mp:*:*)- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'- exit ;;- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"- exit ;;- 5000:UNIX_System_V:4.*:*)- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"- exit ;;- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}- exit ;;- sparc*:BSD/OS:*:*)- echo sparc-unknown-bsdi${UNAME_RELEASE}- exit ;;- *:BSD/OS:*:*)- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}- exit ;;- *:FreeBSD:*:*)- UNAME_PROCESSOR=`/usr/bin/uname -p`- case ${UNAME_PROCESSOR} in- amd64)- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;- *)- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;- esac- exit ;;- i*:CYGWIN*:*)- echo ${UNAME_MACHINE}-pc-cygwin- exit ;;- *:MINGW64*:*)- echo ${UNAME_MACHINE}-pc-mingw64- exit ;;- *:MINGW*:*)- echo ${UNAME_MACHINE}-pc-mingw32- exit ;;- *:MSYS*:*)- echo ${UNAME_MACHINE}-pc-msys- exit ;;- i*:windows32*:*)- # uname -m includes "-pc" on this system.- echo ${UNAME_MACHINE}-mingw32- exit ;;- i*:PW*:*)- echo ${UNAME_MACHINE}-pc-pw32- exit ;;- *:Interix*:*)- case ${UNAME_MACHINE} in- x86)- echo i586-pc-interix${UNAME_RELEASE}- exit ;;- authenticamd | genuineintel | EM64T)- echo x86_64-unknown-interix${UNAME_RELEASE}- exit ;;- IA64)- echo ia64-unknown-interix${UNAME_RELEASE}- exit ;;- esac ;;- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)- echo i${UNAME_MACHINE}-pc-mks- exit ;;- 8664:Windows_NT:*)- echo x86_64-pc-mks- exit ;;- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)- # How do we know it's Interix rather than the generic POSIX subsystem?- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we- # UNAME_MACHINE based on the output of uname instead of i386?- echo i586-pc-interix- exit ;;- i*:UWIN*:*)- echo ${UNAME_MACHINE}-pc-uwin- exit ;;- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)- echo x86_64-unknown-cygwin- exit ;;- p*:CYGWIN*:*)- echo powerpcle-unknown-cygwin- exit ;;- prep*:SunOS:5.*:*)- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`- exit ;;- *:GNU:*:*)- # the GNU system- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`- exit ;;- *:GNU/*:*:*)- # other systems with GNU libc and userland- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}- exit ;;- i*86:Minix:*:*)- echo ${UNAME_MACHINE}-pc-minix- exit ;;- aarch64:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- aarch64_be:Linux:*:*)- UNAME_MACHINE=aarch64_be- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- alpha:Linux:*:*)- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in- EV5) UNAME_MACHINE=alphaev5 ;;- EV56) UNAME_MACHINE=alphaev56 ;;- PCA56) UNAME_MACHINE=alphapca56 ;;- PCA57) UNAME_MACHINE=alphapca56 ;;- EV6) UNAME_MACHINE=alphaev6 ;;- EV67) UNAME_MACHINE=alphaev67 ;;- EV68*) UNAME_MACHINE=alphaev68 ;;- esac- objdump --private-headers /bin/sh | grep -q ld.so.1- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- arc:Linux:*:* | arceb:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- arm*:Linux:*:*)- eval $set_cc_for_build- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \- | grep -q __ARM_EABI__- then- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- else- if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \- | grep -q __ARM_PCS_VFP- then- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi- else- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf- fi- fi- exit ;;- avr32*:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- cris:Linux:*:*)- echo ${UNAME_MACHINE}-axis-linux-${LIBC}- exit ;;- crisv32:Linux:*:*)- echo ${UNAME_MACHINE}-axis-linux-${LIBC}- exit ;;- frv:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- hexagon:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- i*86:Linux:*:*)- echo ${UNAME_MACHINE}-pc-linux-${LIBC}- exit ;;- ia64:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- m32r*:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- m68*:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- mips:Linux:*:* | mips64:Linux:*:*)- eval $set_cc_for_build- sed 's/^ //' << EOF >$dummy.c- #undef CPU- #undef ${UNAME_MACHINE}- #undef ${UNAME_MACHINE}el- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)- CPU=${UNAME_MACHINE}el- #else- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)- CPU=${UNAME_MACHINE}- #else- CPU=- #endif- #endif-EOF- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }- ;;- openrisc*:Linux:*:*)- echo or1k-unknown-linux-${LIBC}- exit ;;- or32:Linux:*:* | or1k*:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- padre:Linux:*:*)- echo sparc-unknown-linux-${LIBC}- exit ;;- parisc64:Linux:*:* | hppa64:Linux:*:*)- echo hppa64-unknown-linux-${LIBC}- exit ;;- parisc:Linux:*:* | hppa:Linux:*:*)- # Look for CPU level- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in- PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;- PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;- *) echo hppa-unknown-linux-${LIBC} ;;- esac- exit ;;- ppc64:Linux:*:*)- echo powerpc64-unknown-linux-${LIBC}- exit ;;- ppc:Linux:*:*)- echo powerpc-unknown-linux-${LIBC}- exit ;;- ppc64le:Linux:*:*)- echo powerpc64le-unknown-linux-${LIBC}- exit ;;- ppcle:Linux:*:*)- echo powerpcle-unknown-linux-${LIBC}- exit ;;- s390:Linux:*:* | s390x:Linux:*:*)- echo ${UNAME_MACHINE}-ibm-linux-${LIBC}- exit ;;- sh64*:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- sh*:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- sparc:Linux:*:* | sparc64:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- tile*:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- vax:Linux:*:*)- echo ${UNAME_MACHINE}-dec-linux-${LIBC}- exit ;;- x86_64:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- xtensa*:Linux:*:*)- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}- exit ;;- i*86:DYNIX/ptx:4*:*)- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.- # earlier versions are messed up and put the nodename in both- # sysname and nodename.- echo i386-sequent-sysv4- exit ;;- i*86:UNIX_SV:4.2MP:2.*)- # Unixware is an offshoot of SVR4, but it has its own version- # number series starting with 2...- # I am not positive that other SVR4 systems won't match this,- # I just have to hope. -- rms.- # Use sysv4.2uw... so that sysv4* matches it.- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}- exit ;;- i*86:OS/2:*:*)- # If we were able to find `uname', then EMX Unix compatibility- # is probably installed.- echo ${UNAME_MACHINE}-pc-os2-emx- exit ;;- i*86:XTS-300:*:STOP)- echo ${UNAME_MACHINE}-unknown-stop- exit ;;- i*86:atheos:*:*)- echo ${UNAME_MACHINE}-unknown-atheos- exit ;;- i*86:syllable:*:*)- echo ${UNAME_MACHINE}-pc-syllable- exit ;;- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)- echo i386-unknown-lynxos${UNAME_RELEASE}- exit ;;- i*86:*DOS:*:*)- echo ${UNAME_MACHINE}-pc-msdosdjgpp- exit ;;- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}- else- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}- fi- exit ;;- i*86:*:5:[678]*)- # UnixWare 7.x, OpenUNIX and OpenServer 6.- case `/bin/uname -X | grep "^Machine"` in- *486*) UNAME_MACHINE=i486 ;;- *Pentium) UNAME_MACHINE=i586 ;;- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;- esac- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}- exit ;;- i*86:*:3.2:*)- if test -f /usr/options/cb.name; then- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL- elif /bin/uname -X 2>/dev/null >/dev/null ; then- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \- && UNAME_MACHINE=i586- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \- && UNAME_MACHINE=i686- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \- && UNAME_MACHINE=i686- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL- else- echo ${UNAME_MACHINE}-pc-sysv32- fi- exit ;;- pc:*:*:*)- # Left here for compatibility:- # uname -m prints for DJGPP always 'pc', but it prints nothing about- # the processor, so we play safe by assuming i586.- # Note: whatever this is, it MUST be the same as what config.sub- # prints for the "djgpp" host, or else GDB configury will decide that- # this is a cross-build.- echo i586-pc-msdosdjgpp- exit ;;- Intel:Mach:3*:*)- echo i386-pc-mach3- exit ;;- paragon:*:*:*)- echo i860-intel-osf1- exit ;;- i860:*:4.*:*) # i860-SVR4- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4- else # Add other i860-SVR4 vendors below as they are discovered.- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4- fi- exit ;;- mini*:CTIX:SYS*5:*)- # "miniframe"- echo m68010-convergent-sysv- exit ;;- mc68k:UNIX:SYSTEM5:3.51m)- echo m68k-convergent-sysv- exit ;;- M680?0:D-NIX:5.3:*)- echo m68k-diab-dnix- exit ;;- M68*:*:R3V[5678]*:*)- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)- OS_REL=''- test -r /etc/.relid \- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \- && { echo i486-ncr-sysv4; exit; } ;;- NCR*:*:4.2:* | MPRAS*:*:4.2:*)- OS_REL='.3'- test -r /etc/.relid \- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }- /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)- echo m68k-unknown-lynxos${UNAME_RELEASE}- exit ;;- mc68030:UNIX_System_V:4.*:*)- echo m68k-atari-sysv4- exit ;;- TSUNAMI:LynxOS:2.*:*)- echo sparc-unknown-lynxos${UNAME_RELEASE}- exit ;;- rs6000:LynxOS:2.*:*)- echo rs6000-unknown-lynxos${UNAME_RELEASE}- exit ;;- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)- echo powerpc-unknown-lynxos${UNAME_RELEASE}- exit ;;- SM[BE]S:UNIX_SV:*:*)- echo mips-dde-sysv${UNAME_RELEASE}- exit ;;- RM*:ReliantUNIX-*:*:*)- echo mips-sni-sysv4- exit ;;- RM*:SINIX-*:*:*)- echo mips-sni-sysv4- exit ;;- *:SINIX-*:*:*)- if uname -p 2>/dev/null >/dev/null ; then- UNAME_MACHINE=`(uname -p) 2>/dev/null`- echo ${UNAME_MACHINE}-sni-sysv4- else- echo ns32k-sni-sysv- fi- exit ;;- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort- # says <Richard.M.Bartel@ccMail.Census.GOV>- echo i586-unisys-sysv4- exit ;;- *:UNIX_System_V:4*:FTX*)- # From Gerald Hewes <hewes@openmarket.com>.- # How about differentiating between stratus architectures? -djm- echo hppa1.1-stratus-sysv4- exit ;;- *:*:*:FTX*)- # From seanf@swdc.stratus.com.- echo i860-stratus-sysv4- exit ;;- i*86:VOS:*:*)- # From Paul.Green@stratus.com.- echo ${UNAME_MACHINE}-stratus-vos- exit ;;- *:VOS:*:*)- # From Paul.Green@stratus.com.- echo hppa1.1-stratus-vos- exit ;;- mc68*:A/UX:*:*)- echo m68k-apple-aux${UNAME_RELEASE}- exit ;;- news*:NEWS-OS:6*:*)- echo mips-sony-newsos6- exit ;;- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)- if [ -d /usr/nec ]; then- echo mips-nec-sysv${UNAME_RELEASE}- else- echo mips-unknown-sysv${UNAME_RELEASE}- fi- exit ;;- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.- echo powerpc-be-beos- exit ;;- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.- echo powerpc-apple-beos- exit ;;- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.- echo i586-pc-beos- exit ;;- BePC:Haiku:*:*) # Haiku running on Intel PC compatible.- echo i586-pc-haiku- exit ;;- x86_64:Haiku:*:*)- echo x86_64-unknown-haiku- exit ;;- SX-4:SUPER-UX:*:*)- echo sx4-nec-superux${UNAME_RELEASE}- exit ;;- SX-5:SUPER-UX:*:*)- echo sx5-nec-superux${UNAME_RELEASE}- exit ;;- SX-6:SUPER-UX:*:*)- echo sx6-nec-superux${UNAME_RELEASE}- exit ;;- SX-7:SUPER-UX:*:*)- echo sx7-nec-superux${UNAME_RELEASE}- exit ;;- SX-8:SUPER-UX:*:*)- echo sx8-nec-superux${UNAME_RELEASE}- exit ;;- SX-8R:SUPER-UX:*:*)- echo sx8r-nec-superux${UNAME_RELEASE}- exit ;;- Power*:Rhapsody:*:*)- echo powerpc-apple-rhapsody${UNAME_RELEASE}- exit ;;- *:Rhapsody:*:*)- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}- exit ;;- *:Darwin:*:*)- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown- eval $set_cc_for_build- if test "$UNAME_PROCESSOR" = unknown ; then- UNAME_PROCESSOR=powerpc- fi- if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \- grep IS_64BIT_ARCH >/dev/null- then- case $UNAME_PROCESSOR in- i386) UNAME_PROCESSOR=x86_64 ;;- powerpc) UNAME_PROCESSOR=powerpc64 ;;- esac- fi- fi- elif test "$UNAME_PROCESSOR" = i386 ; then- # Avoid executing cc on OS X 10.9, as it ships with a stub- # that puts up a graphical alert prompting to install- # developer tools. Any system running Mac OS X 10.7 or- # later (Darwin 11 and later) is required to have a 64-bit- # processor. This is not true of the ARM version of Darwin- # that Apple uses in portable devices.- UNAME_PROCESSOR=x86_64- fi- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}- exit ;;- *:procnto*:*:* | *:QNX:[0123456789]*:*)- UNAME_PROCESSOR=`uname -p`- if test "$UNAME_PROCESSOR" = "x86"; then- UNAME_PROCESSOR=i386- UNAME_MACHINE=pc- fi- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}- exit ;;- *:QNX:*:4*)- echo i386-pc-qnx- exit ;;- NEO-?:NONSTOP_KERNEL:*:*)- echo neo-tandem-nsk${UNAME_RELEASE}- exit ;;- NSE-*:NONSTOP_KERNEL:*:*)- echo nse-tandem-nsk${UNAME_RELEASE}- exit ;;- NSR-?:NONSTOP_KERNEL:*:*)- echo nsr-tandem-nsk${UNAME_RELEASE}- exit ;;- *:NonStop-UX:*:*)- echo mips-compaq-nonstopux- exit ;;- BS2000:POSIX*:*:*)- echo bs2000-siemens-sysv- exit ;;- DS/*:UNIX_System_V:*:*)- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}- exit ;;- *:Plan9:*:*)- # "uname -m" is not consistent, so use $cputype instead. 386- # is converted to i386 for consistency with other x86- # operating systems.- if test "$cputype" = "386"; then- UNAME_MACHINE=i386- else- UNAME_MACHINE="$cputype"- fi- echo ${UNAME_MACHINE}-unknown-plan9- exit ;;- *:TOPS-10:*:*)- echo pdp10-unknown-tops10- exit ;;- *:TENEX:*:*)- echo pdp10-unknown-tenex- exit ;;- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)- echo pdp10-dec-tops20- exit ;;- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)- echo pdp10-xkl-tops20- exit ;;- *:TOPS-20:*:*)- echo pdp10-unknown-tops20- exit ;;- *:ITS:*:*)- echo pdp10-unknown-its- exit ;;- SEI:*:*:SEIUX)- echo mips-sei-seiux${UNAME_RELEASE}- exit ;;- *:DragonFly:*:*)- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`- exit ;;- *:*VMS:*:*)- UNAME_MACHINE=`(uname -p) 2>/dev/null`- case "${UNAME_MACHINE}" in- A*) echo alpha-dec-vms ; exit ;;- I*) echo ia64-dec-vms ; exit ;;- V*) echo vax-dec-vms ; exit ;;- esac ;;- *:XENIX:*:SysV)- echo i386-pc-xenix- exit ;;- i*86:skyos:*:*)- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'- exit ;;- i*86:rdos:*:*)- echo ${UNAME_MACHINE}-pc-rdos- exit ;;- i*86:AROS:*:*)- echo ${UNAME_MACHINE}-pc-aros- exit ;;- x86_64:VMkernel:*:*)- echo ${UNAME_MACHINE}-unknown-esx- exit ;;-esac--cat >&2 <<EOF-$0: unable to guess system type--This script, last modified $timestamp, has failed to recognize-the operating system you are using. It is advised that you-download the most up to date version of the config scripts from-- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD-and- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD--If the version you run ($0) is already up to date, please-send the following data and any information you think might be-pertinent to <config-patches@gnu.org> in order to provide the needed-information to handle your system.--config.guess timestamp = $timestamp--uname -m = `(uname -m) 2>/dev/null || echo unknown`-uname -r = `(uname -r) 2>/dev/null || echo unknown`-uname -s = `(uname -s) 2>/dev/null || echo unknown`-uname -v = `(uname -v) 2>/dev/null || echo unknown`--/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`--hostinfo = `(hostinfo) 2>/dev/null`-/bin/universe = `(/bin/universe) 2>/dev/null`-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`-/bin/arch = `(/bin/arch) 2>/dev/null`-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`--UNAME_MACHINE = ${UNAME_MACHINE}-UNAME_RELEASE = ${UNAME_RELEASE}-UNAME_SYSTEM = ${UNAME_SYSTEM}-UNAME_VERSION = ${UNAME_VERSION}-EOF--exit 1--# Local variables:-# eval: (add-hook 'write-file-hooks 'time-stamp)-# time-stamp-start: "timestamp='"-# time-stamp-format: "%:y-%02m-%02d"-# time-stamp-end: "'"-# End:
− config.sub
@@ -1,1794 +0,0 @@-#! /bin/sh-# Configuration validation subroutine script.-# Copyright 1992-2014 Free Software Foundation, Inc.--timestamp='2014-05-01'--# This file is free software; you can redistribute it and/or modify it-# under the terms of the GNU General Public License as published by-# the Free Software Foundation; either version 3 of the License, or-# (at your option) any later version.-#-# This program is distributed in the hope that it will be useful, but-# WITHOUT ANY WARRANTY; without even the implied warranty of-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU-# General Public License for more details.-#-# You should have received a copy of the GNU General Public License-# along with this program; if not, see <http://www.gnu.org/licenses/>.-#-# As a special exception to the GNU General Public License, if you-# distribute this file as part of a program that contains a-# configuration script generated by Autoconf, you may include it under-# the same distribution terms that you use for the rest of that-# program. This Exception is an additional permission under section 7-# of the GNU General Public License, version 3 ("GPLv3").---# Please send patches with a ChangeLog entry to config-patches@gnu.org.-#-# Configuration subroutine to validate and canonicalize a configuration type.-# Supply the specified configuration type as an argument.-# If it is invalid, we print an error message on stderr and exit with code 1.-# Otherwise, we print the canonical config type on stdout and succeed.--# You can get the latest version of this script from:-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD--# This file is supposed to be the same for all GNU packages-# and recognize all the CPU types, system types and aliases-# that are meaningful with *any* GNU software.-# Each package is responsible for reporting which valid configurations-# it does not support. The user should be able to distinguish-# a failure to support a valid configuration from a meaningless-# configuration.--# The goal of this file is to map all the various variations of a given-# machine specification into a single specification in the form:-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM-# or in some cases, the newer four-part form:-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM-# It is wrong to echo any other type of specification.--me=`echo "$0" | sed -e 's,.*/,,'`--usage="\-Usage: $0 [OPTION] CPU-MFR-OPSYS- $0 [OPTION] ALIAS--Canonicalize a configuration name.--Operation modes:- -h, --help print this help, then exit- -t, --time-stamp print date of last modification, then exit- -v, --version print version number, then exit--Report bugs and patches to <config-patches@gnu.org>."--version="\-GNU config.sub ($timestamp)--Copyright 1992-2014 Free Software Foundation, Inc.--This is free software; see the source for copying conditions. There is NO-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."--help="-Try \`$me --help' for more information."--# Parse command line-while test $# -gt 0 ; do- case $1 in- --time-stamp | --time* | -t )- echo "$timestamp" ; exit ;;- --version | -v )- echo "$version" ; exit ;;- --help | --h* | -h )- echo "$usage"; exit ;;- -- ) # Stop option processing- shift; break ;;- - ) # Use stdin as input.- break ;;- -* )- echo "$me: invalid option $1$help"- exit 1 ;;-- *local*)- # First pass through any local machine types.- echo $1- exit ;;-- * )- break ;;- esac-done--case $# in- 0) echo "$me: missing argument$help" >&2- exit 1;;- 1) ;;- *) echo "$me: too many arguments$help" >&2- exit 1;;-esac--# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).-# Here we must recognize all the valid KERNEL-OS combinations.-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`-case $maybe_os in- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \- knetbsd*-gnu* | netbsd*-gnu* | \- kopensolaris*-gnu* | \- storm-chaos* | os2-emx* | rtmk-nova*)- os=-$maybe_os- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`- ;;- android-linux)- os=-linux-android- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown- ;;- *)- basic_machine=`echo $1 | sed 's/-[^-]*$//'`- if [ $basic_machine != $1 ]- then os=`echo $1 | sed 's/.*-/-/'`- else os=; fi- ;;-esac--### Let's recognize common machines as not being operating systems so-### that things like config.sub decstation-3100 work. We also-### recognize some manufacturers as not being operating systems, so we-### can provide default operating systems below.-case $os in- -sun*os*)- # Prevent following clause from handling this invalid input.- ;;- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \- -apple | -axis | -knuth | -cray | -microblaze*)- os=- basic_machine=$1- ;;- -bluegene*)- os=-cnk- ;;- -sim | -cisco | -oki | -wec | -winbond)- os=- basic_machine=$1- ;;- -scout)- ;;- -wrs)- os=-vxworks- basic_machine=$1- ;;- -chorusos*)- os=-chorusos- basic_machine=$1- ;;- -chorusrdb)- os=-chorusrdb- basic_machine=$1- ;;- -hiux*)- os=-hiuxwe2- ;;- -sco6)- os=-sco5v6- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -sco5)- os=-sco3.2v5- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -sco4)- os=-sco3.2v4- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -sco3.2.[4-9]*)- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -sco3.2v[4-9]*)- # Don't forget version if it is 3.2v4 or newer.- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -sco5v6*)- # Don't forget version if it is 3.2v4 or newer.- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -sco*)- os=-sco3.2v2- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -udk*)- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -isc)- os=-isc2.2- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -clix*)- basic_machine=clipper-intergraph- ;;- -isc*)- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`- ;;- -lynx*178)- os=-lynxos178- ;;- -lynx*5)- os=-lynxos5- ;;- -lynx*)- os=-lynxos- ;;- -ptx*)- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`- ;;- -windowsnt*)- os=`echo $os | sed -e 's/windowsnt/winnt/'`- ;;- -psos*)- os=-psos- ;;- -mint | -mint[0-9]*)- basic_machine=m68k-atari- os=-mint- ;;-esac--# Decode aliases for certain CPU-COMPANY combinations.-case $basic_machine in- # Recognize the basic CPU types without company name.- # Some are omitted here because they have special meanings below.- 1750a | 580 \- | a29k \- | aarch64 | aarch64_be \- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \- | am33_2.0 \- | arc | arceb \- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \- | avr | avr32 \- | be32 | be64 \- | bfin \- | c4x | c8051 | clipper \- | d10v | d30v | dlx | dsp16xx \- | epiphany \- | fido | fr30 | frv \- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \- | hexagon \- | i370 | i860 | i960 | ia64 \- | ip2k | iq2000 \- | k1om \- | le32 | le64 \- | lm32 \- | m32c | m32r | m32rle | m68000 | m68k | m88k \- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \- | mips | mipsbe | mipseb | mipsel | mipsle \- | mips16 \- | mips64 | mips64el \- | mips64octeon | mips64octeonel \- | mips64orion | mips64orionel \- | mips64r5900 | mips64r5900el \- | mips64vr | mips64vrel \- | mips64vr4100 | mips64vr4100el \- | mips64vr4300 | mips64vr4300el \- | mips64vr5000 | mips64vr5000el \- | mips64vr5900 | mips64vr5900el \- | mipsisa32 | mipsisa32el \- | mipsisa32r2 | mipsisa32r2el \- | mipsisa32r6 | mipsisa32r6el \- | mipsisa64 | mipsisa64el \- | mipsisa64r2 | mipsisa64r2el \- | mipsisa64r6 | mipsisa64r6el \- | mipsisa64sb1 | mipsisa64sb1el \- | mipsisa64sr71k | mipsisa64sr71kel \- | mipsr5900 | mipsr5900el \- | mipstx39 | mipstx39el \- | mn10200 | mn10300 \- | moxie \- | mt \- | msp430 \- | nds32 | nds32le | nds32be \- | nios | nios2 | nios2eb | nios2el \- | ns16k | ns32k \- | open8 | or1k | or1knd | or32 \- | pdp10 | pdp11 | pj | pjl \- | powerpc | powerpc64 | powerpc64le | powerpcle \- | pyramid \- | rl78 | rx \- | score \- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \- | sh64 | sh64le \- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \- | spu \- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \- | ubicom32 \- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \- | we32k \- | x86 | xc16x | xstormy16 | xtensa \- | z8k | z80)- basic_machine=$basic_machine-unknown- ;;- c54x)- basic_machine=tic54x-unknown- ;;- c55x)- basic_machine=tic55x-unknown- ;;- c6x)- basic_machine=tic6x-unknown- ;;- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)- basic_machine=$basic_machine-unknown- os=-none- ;;- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)- ;;- ms1)- basic_machine=mt-unknown- ;;-- strongarm | thumb | xscale)- basic_machine=arm-unknown- ;;- xgate)- basic_machine=$basic_machine-unknown- os=-none- ;;- xscaleeb)- basic_machine=armeb-unknown- ;;-- xscaleel)- basic_machine=armel-unknown- ;;-- # We use `pc' rather than `unknown'- # because (1) that's what they normally are, and- # (2) the word "unknown" tends to confuse beginning users.- i*86 | x86_64)- basic_machine=$basic_machine-pc- ;;- # Object if more than one company name word.- *-*-*)- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2- exit 1- ;;- # Recognize the basic CPU types with company name.- 580-* \- | a29k-* \- | aarch64-* | aarch64_be-* \- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \- | avr-* | avr32-* \- | be32-* | be64-* \- | bfin-* | bs2000-* \- | c[123]* | c30-* | [cjt]90-* | c4x-* \- | c8051-* | clipper-* | craynv-* | cydra-* \- | d10v-* | d30v-* | dlx-* \- | elxsi-* \- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \- | h8300-* | h8500-* \- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \- | hexagon-* \- | i*86-* | i860-* | i960-* | ia64-* \- | ip2k-* | iq2000-* \- | k1om-* \- | le32-* | le64-* \- | lm32-* \- | m32c-* | m32r-* | m32rle-* \- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \- | microblaze-* | microblazeel-* \- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \- | mips16-* \- | mips64-* | mips64el-* \- | mips64octeon-* | mips64octeonel-* \- | mips64orion-* | mips64orionel-* \- | mips64r5900-* | mips64r5900el-* \- | mips64vr-* | mips64vrel-* \- | mips64vr4100-* | mips64vr4100el-* \- | mips64vr4300-* | mips64vr4300el-* \- | mips64vr5000-* | mips64vr5000el-* \- | mips64vr5900-* | mips64vr5900el-* \- | mipsisa32-* | mipsisa32el-* \- | mipsisa32r2-* | mipsisa32r2el-* \- | mipsisa32r6-* | mipsisa32r6el-* \- | mipsisa64-* | mipsisa64el-* \- | mipsisa64r2-* | mipsisa64r2el-* \- | mipsisa64r6-* | mipsisa64r6el-* \- | mipsisa64sb1-* | mipsisa64sb1el-* \- | mipsisa64sr71k-* | mipsisa64sr71kel-* \- | mipsr5900-* | mipsr5900el-* \- | mipstx39-* | mipstx39el-* \- | mmix-* \- | mt-* \- | msp430-* \- | nds32-* | nds32le-* | nds32be-* \- | nios-* | nios2-* | nios2eb-* | nios2el-* \- | none-* | np1-* | ns16k-* | ns32k-* \- | open8-* \- | or1k*-* \- | orion-* \- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \- | pyramid-* \- | rl78-* | romp-* | rs6000-* | rx-* \- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \- | sparclite-* \- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \- | tahoe-* \- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \- | tile*-* \- | tron-* \- | ubicom32-* \- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \- | vax-* \- | we32k-* \- | x86-* | x86_64-* | xc16x-* | xps100-* \- | xstormy16-* | xtensa*-* \- | ymp-* \- | z8k-* | z80-*)- ;;- # Recognize the basic CPU types without company name, with glob match.- xtensa*)- basic_machine=$basic_machine-unknown- ;;- # Recognize the various machine names and aliases which stand- # for a CPU type and a company and sometimes even an OS.- 386bsd)- basic_machine=i386-unknown- os=-bsd- ;;- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)- basic_machine=m68000-att- ;;- 3b*)- basic_machine=we32k-att- ;;- a29khif)- basic_machine=a29k-amd- os=-udi- ;;- abacus)- basic_machine=abacus-unknown- ;;- adobe68k)- basic_machine=m68010-adobe- os=-scout- ;;- alliant | fx80)- basic_machine=fx80-alliant- ;;- altos | altos3068)- basic_machine=m68k-altos- ;;- am29k)- basic_machine=a29k-none- os=-bsd- ;;- amd64)- basic_machine=x86_64-pc- ;;- amd64-*)- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- amdahl)- basic_machine=580-amdahl- os=-sysv- ;;- amiga | amiga-*)- basic_machine=m68k-unknown- ;;- amigaos | amigados)- basic_machine=m68k-unknown- os=-amigaos- ;;- amigaunix | amix)- basic_machine=m68k-unknown- os=-sysv4- ;;- apollo68)- basic_machine=m68k-apollo- os=-sysv- ;;- apollo68bsd)- basic_machine=m68k-apollo- os=-bsd- ;;- aros)- basic_machine=i386-pc- os=-aros- ;;- aux)- basic_machine=m68k-apple- os=-aux- ;;- balance)- basic_machine=ns32k-sequent- os=-dynix- ;;- blackfin)- basic_machine=bfin-unknown- os=-linux- ;;- blackfin-*)- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`- os=-linux- ;;- bluegene*)- basic_machine=powerpc-ibm- os=-cnk- ;;- c54x-*)- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- c55x-*)- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- c6x-*)- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- c90)- basic_machine=c90-cray- os=-unicos- ;;- cegcc)- basic_machine=arm-unknown- os=-cegcc- ;;- convex-c1)- basic_machine=c1-convex- os=-bsd- ;;- convex-c2)- basic_machine=c2-convex- os=-bsd- ;;- convex-c32)- basic_machine=c32-convex- os=-bsd- ;;- convex-c34)- basic_machine=c34-convex- os=-bsd- ;;- convex-c38)- basic_machine=c38-convex- os=-bsd- ;;- cray | j90)- basic_machine=j90-cray- os=-unicos- ;;- craynv)- basic_machine=craynv-cray- os=-unicosmp- ;;- cr16 | cr16-*)- basic_machine=cr16-unknown- os=-elf- ;;- crds | unos)- basic_machine=m68k-crds- ;;- crisv32 | crisv32-* | etraxfs*)- basic_machine=crisv32-axis- ;;- cris | cris-* | etrax*)- basic_machine=cris-axis- ;;- crx)- basic_machine=crx-unknown- os=-elf- ;;- da30 | da30-*)- basic_machine=m68k-da30- ;;- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)- basic_machine=mips-dec- ;;- decsystem10* | dec10*)- basic_machine=pdp10-dec- os=-tops10- ;;- decsystem20* | dec20*)- basic_machine=pdp10-dec- os=-tops20- ;;- delta | 3300 | motorola-3300 | motorola-delta \- | 3300-motorola | delta-motorola)- basic_machine=m68k-motorola- ;;- delta88)- basic_machine=m88k-motorola- os=-sysv3- ;;- dicos)- basic_machine=i686-pc- os=-dicos- ;;- djgpp)- basic_machine=i586-pc- os=-msdosdjgpp- ;;- dpx20 | dpx20-*)- basic_machine=rs6000-bull- os=-bosx- ;;- dpx2* | dpx2*-bull)- basic_machine=m68k-bull- os=-sysv3- ;;- ebmon29k)- basic_machine=a29k-amd- os=-ebmon- ;;- elxsi)- basic_machine=elxsi-elxsi- os=-bsd- ;;- encore | umax | mmax)- basic_machine=ns32k-encore- ;;- es1800 | OSE68k | ose68k | ose | OSE)- basic_machine=m68k-ericsson- os=-ose- ;;- fx2800)- basic_machine=i860-alliant- ;;- genix)- basic_machine=ns32k-ns- ;;- gmicro)- basic_machine=tron-gmicro- os=-sysv- ;;- go32)- basic_machine=i386-pc- os=-go32- ;;- h3050r* | hiux*)- basic_machine=hppa1.1-hitachi- os=-hiuxwe2- ;;- h8300hms)- basic_machine=h8300-hitachi- os=-hms- ;;- h8300xray)- basic_machine=h8300-hitachi- os=-xray- ;;- h8500hms)- basic_machine=h8500-hitachi- os=-hms- ;;- harris)- basic_machine=m88k-harris- os=-sysv3- ;;- hp300-*)- basic_machine=m68k-hp- ;;- hp300bsd)- basic_machine=m68k-hp- os=-bsd- ;;- hp300hpux)- basic_machine=m68k-hp- os=-hpux- ;;- hp3k9[0-9][0-9] | hp9[0-9][0-9])- basic_machine=hppa1.0-hp- ;;- hp9k2[0-9][0-9] | hp9k31[0-9])- basic_machine=m68000-hp- ;;- hp9k3[2-9][0-9])- basic_machine=m68k-hp- ;;- hp9k6[0-9][0-9] | hp6[0-9][0-9])- basic_machine=hppa1.0-hp- ;;- hp9k7[0-79][0-9] | hp7[0-79][0-9])- basic_machine=hppa1.1-hp- ;;- hp9k78[0-9] | hp78[0-9])- # FIXME: really hppa2.0-hp- basic_machine=hppa1.1-hp- ;;- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)- # FIXME: really hppa2.0-hp- basic_machine=hppa1.1-hp- ;;- hp9k8[0-9][13679] | hp8[0-9][13679])- basic_machine=hppa1.1-hp- ;;- hp9k8[0-9][0-9] | hp8[0-9][0-9])- basic_machine=hppa1.0-hp- ;;- hppa-next)- os=-nextstep3- ;;- hppaosf)- basic_machine=hppa1.1-hp- os=-osf- ;;- hppro)- basic_machine=hppa1.1-hp- os=-proelf- ;;- i370-ibm* | ibm*)- basic_machine=i370-ibm- ;;- i*86v32)- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`- os=-sysv32- ;;- i*86v4*)- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`- os=-sysv4- ;;- i*86v)- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`- os=-sysv- ;;- i*86sol2)- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`- os=-solaris2- ;;- i386mach)- basic_machine=i386-mach- os=-mach- ;;- i386-vsta | vsta)- basic_machine=i386-unknown- os=-vsta- ;;- iris | iris4d)- basic_machine=mips-sgi- case $os in- -irix*)- ;;- *)- os=-irix4- ;;- esac- ;;- isi68 | isi)- basic_machine=m68k-isi- os=-sysv- ;;- m68knommu)- basic_machine=m68k-unknown- os=-linux- ;;- m68knommu-*)- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`- os=-linux- ;;- m88k-omron*)- basic_machine=m88k-omron- ;;- magnum | m3230)- basic_machine=mips-mips- os=-sysv- ;;- merlin)- basic_machine=ns32k-utek- os=-sysv- ;;- microblaze*)- basic_machine=microblaze-xilinx- ;;- mingw64)- basic_machine=x86_64-pc- os=-mingw64- ;;- mingw32)- basic_machine=i686-pc- os=-mingw32- ;;- mingw32ce)- basic_machine=arm-unknown- os=-mingw32ce- ;;- miniframe)- basic_machine=m68000-convergent- ;;- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)- basic_machine=m68k-atari- os=-mint- ;;- mips3*-*)- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`- ;;- mips3*)- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown- ;;- monitor)- basic_machine=m68k-rom68k- os=-coff- ;;- morphos)- basic_machine=powerpc-unknown- os=-morphos- ;;- msdos)- basic_machine=i386-pc- os=-msdos- ;;- ms1-*)- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`- ;;- msys)- basic_machine=i686-pc- os=-msys- ;;- mvs)- basic_machine=i370-ibm- os=-mvs- ;;- nacl)- basic_machine=le32-unknown- os=-nacl- ;;- ncr3000)- basic_machine=i486-ncr- os=-sysv4- ;;- netbsd386)- basic_machine=i386-unknown- os=-netbsd- ;;- netwinder)- basic_machine=armv4l-rebel- os=-linux- ;;- news | news700 | news800 | news900)- basic_machine=m68k-sony- os=-newsos- ;;- news1000)- basic_machine=m68030-sony- os=-newsos- ;;- news-3600 | risc-news)- basic_machine=mips-sony- os=-newsos- ;;- necv70)- basic_machine=v70-nec- os=-sysv- ;;- next | m*-next )- basic_machine=m68k-next- case $os in- -nextstep* )- ;;- -ns2*)- os=-nextstep2- ;;- *)- os=-nextstep3- ;;- esac- ;;- nh3000)- basic_machine=m68k-harris- os=-cxux- ;;- nh[45]000)- basic_machine=m88k-harris- os=-cxux- ;;- nindy960)- basic_machine=i960-intel- os=-nindy- ;;- mon960)- basic_machine=i960-intel- os=-mon960- ;;- nonstopux)- basic_machine=mips-compaq- os=-nonstopux- ;;- np1)- basic_machine=np1-gould- ;;- neo-tandem)- basic_machine=neo-tandem- ;;- nse-tandem)- basic_machine=nse-tandem- ;;- nsr-tandem)- basic_machine=nsr-tandem- ;;- op50n-* | op60c-*)- basic_machine=hppa1.1-oki- os=-proelf- ;;- openrisc | openrisc-*)- basic_machine=or32-unknown- ;;- os400)- basic_machine=powerpc-ibm- os=-os400- ;;- OSE68000 | ose68000)- basic_machine=m68000-ericsson- os=-ose- ;;- os68k)- basic_machine=m68k-none- os=-os68k- ;;- pa-hitachi)- basic_machine=hppa1.1-hitachi- os=-hiuxwe2- ;;- paragon)- basic_machine=i860-intel- os=-osf- ;;- parisc)- basic_machine=hppa-unknown- os=-linux- ;;- parisc-*)- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`- os=-linux- ;;- pbd)- basic_machine=sparc-tti- ;;- pbb)- basic_machine=m68k-tti- ;;- pc532 | pc532-*)- basic_machine=ns32k-pc532- ;;- pc98)- basic_machine=i386-pc- ;;- pc98-*)- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- pentium | p5 | k5 | k6 | nexgen | viac3)- basic_machine=i586-pc- ;;- pentiumpro | p6 | 6x86 | athlon | athlon_*)- basic_machine=i686-pc- ;;- pentiumii | pentium2 | pentiumiii | pentium3)- basic_machine=i686-pc- ;;- pentium4)- basic_machine=i786-pc- ;;- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- pentiumpro-* | p6-* | 6x86-* | athlon-*)- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- pentium4-*)- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- pn)- basic_machine=pn-gould- ;;- power) basic_machine=power-ibm- ;;- ppc | ppcbe) basic_machine=powerpc-unknown- ;;- ppc-* | ppcbe-*)- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- ppcle | powerpclittle | ppc-le | powerpc-little)- basic_machine=powerpcle-unknown- ;;- ppcle-* | powerpclittle-*)- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- ppc64) basic_machine=powerpc64-unknown- ;;- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- ppc64le | powerpc64little | ppc64-le | powerpc64-little)- basic_machine=powerpc64le-unknown- ;;- ppc64le-* | powerpc64little-*)- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- ps2)- basic_machine=i386-ibm- ;;- pw32)- basic_machine=i586-unknown- os=-pw32- ;;- rdos | rdos64)- basic_machine=x86_64-pc- os=-rdos- ;;- rdos32)- basic_machine=i386-pc- os=-rdos- ;;- rom68k)- basic_machine=m68k-rom68k- os=-coff- ;;- rm[46]00)- basic_machine=mips-siemens- ;;- rtpc | rtpc-*)- basic_machine=romp-ibm- ;;- s390 | s390-*)- basic_machine=s390-ibm- ;;- s390x | s390x-*)- basic_machine=s390x-ibm- ;;- sa29200)- basic_machine=a29k-amd- os=-udi- ;;- sb1)- basic_machine=mipsisa64sb1-unknown- ;;- sb1el)- basic_machine=mipsisa64sb1el-unknown- ;;- sde)- basic_machine=mipsisa32-sde- os=-elf- ;;- sei)- basic_machine=mips-sei- os=-seiux- ;;- sequent)- basic_machine=i386-sequent- ;;- sh)- basic_machine=sh-hitachi- os=-hms- ;;- sh5el)- basic_machine=sh5le-unknown- ;;- sh64)- basic_machine=sh64-unknown- ;;- sparclite-wrs | simso-wrs)- basic_machine=sparclite-wrs- os=-vxworks- ;;- sps7)- basic_machine=m68k-bull- os=-sysv2- ;;- spur)- basic_machine=spur-unknown- ;;- st2000)- basic_machine=m68k-tandem- ;;- stratus)- basic_machine=i860-stratus- os=-sysv4- ;;- strongarm-* | thumb-*)- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`- ;;- sun2)- basic_machine=m68000-sun- ;;- sun2os3)- basic_machine=m68000-sun- os=-sunos3- ;;- sun2os4)- basic_machine=m68000-sun- os=-sunos4- ;;- sun3os3)- basic_machine=m68k-sun- os=-sunos3- ;;- sun3os4)- basic_machine=m68k-sun- os=-sunos4- ;;- sun4os3)- basic_machine=sparc-sun- os=-sunos3- ;;- sun4os4)- basic_machine=sparc-sun- os=-sunos4- ;;- sun4sol2)- basic_machine=sparc-sun- os=-solaris2- ;;- sun3 | sun3-*)- basic_machine=m68k-sun- ;;- sun4)- basic_machine=sparc-sun- ;;- sun386 | sun386i | roadrunner)- basic_machine=i386-sun- ;;- sv1)- basic_machine=sv1-cray- os=-unicos- ;;- symmetry)- basic_machine=i386-sequent- os=-dynix- ;;- t3e)- basic_machine=alphaev5-cray- os=-unicos- ;;- t90)- basic_machine=t90-cray- os=-unicos- ;;- tile*)- basic_machine=$basic_machine-unknown- os=-linux-gnu- ;;- tx39)- basic_machine=mipstx39-unknown- ;;- tx39el)- basic_machine=mipstx39el-unknown- ;;- toad1)- basic_machine=pdp10-xkl- os=-tops20- ;;- tower | tower-32)- basic_machine=m68k-ncr- ;;- tpf)- basic_machine=s390x-ibm- os=-tpf- ;;- udi29k)- basic_machine=a29k-amd- os=-udi- ;;- ultra3)- basic_machine=a29k-nyu- os=-sym1- ;;- v810 | necv810)- basic_machine=v810-nec- os=-none- ;;- vaxv)- basic_machine=vax-dec- os=-sysv- ;;- vms)- basic_machine=vax-dec- os=-vms- ;;- vpp*|vx|vx-*)- basic_machine=f301-fujitsu- ;;- vxworks960)- basic_machine=i960-wrs- os=-vxworks- ;;- vxworks68)- basic_machine=m68k-wrs- os=-vxworks- ;;- vxworks29k)- basic_machine=a29k-wrs- os=-vxworks- ;;- w65*)- basic_machine=w65-wdc- os=-none- ;;- w89k-*)- basic_machine=hppa1.1-winbond- os=-proelf- ;;- xbox)- basic_machine=i686-pc- os=-mingw32- ;;- xps | xps100)- basic_machine=xps100-honeywell- ;;- xscale-* | xscalee[bl]-*)- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`- ;;- ymp)- basic_machine=ymp-cray- os=-unicos- ;;- z8k-*-coff)- basic_machine=z8k-unknown- os=-sim- ;;- z80-*-coff)- basic_machine=z80-unknown- os=-sim- ;;- none)- basic_machine=none-none- os=-none- ;;--# Here we handle the default manufacturer of certain CPU types. It is in-# some cases the only manufacturer, in others, it is the most popular.- w89k)- basic_machine=hppa1.1-winbond- ;;- op50n)- basic_machine=hppa1.1-oki- ;;- op60c)- basic_machine=hppa1.1-oki- ;;- romp)- basic_machine=romp-ibm- ;;- mmix)- basic_machine=mmix-knuth- ;;- rs6000)- basic_machine=rs6000-ibm- ;;- vax)- basic_machine=vax-dec- ;;- pdp10)- # there are many clones, so DEC is not a safe bet- basic_machine=pdp10-unknown- ;;- pdp11)- basic_machine=pdp11-dec- ;;- we32k)- basic_machine=we32k-att- ;;- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)- basic_machine=sh-unknown- ;;- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)- basic_machine=sparc-sun- ;;- cydra)- basic_machine=cydra-cydrome- ;;- orion)- basic_machine=orion-highlevel- ;;- orion105)- basic_machine=clipper-highlevel- ;;- mac | mpw | mac-mpw)- basic_machine=m68k-apple- ;;- pmac | pmac-mpw)- basic_machine=powerpc-apple- ;;- *-unknown)- # Make sure to match an already-canonicalized machine name.- ;;- *)- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2- exit 1- ;;-esac--# Here we canonicalize certain aliases for manufacturers.-case $basic_machine in- *-digital*)- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`- ;;- *-commodore*)- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`- ;;- *)- ;;-esac--# Decode manufacturer-specific aliases for certain operating systems.--if [ x"$os" != x"" ]-then-case $os in- # First match some system type aliases- # that might get confused with valid system types.- # -solaris* is a basic system type, with this one exception.- -auroraux)- os=-auroraux- ;;- -solaris1 | -solaris1.*)- os=`echo $os | sed -e 's|solaris1|sunos4|'`- ;;- -solaris)- os=-solaris2- ;;- -svr4*)- os=-sysv4- ;;- -unixware*)- os=-sysv4.2uw- ;;- -gnu/linux*)- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`- ;;- # First accept the basic system types.- # The portable systems comes first.- # Each alternative MUST END IN A *, to match a version number.- # -sysv* is not here because it comes later, after sysvr4.- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \- | -sym* | -kopensolaris* | -plan9* \- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \- | -aos* | -aros* \- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \- | -bitrig* | -openbsd* | -solidbsd* \- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \- | -chorusos* | -chorusrdb* | -cegcc* \- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \- | -linux-newlib* | -linux-musl* | -linux-uclibc* \- | -uxpv* | -beos* | -mpeix* | -udk* \- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)- # Remember, each alternative MUST END IN *, to match a version number.- ;;- -qnx*)- case $basic_machine in- x86-* | i*86-*)- ;;- *)- os=-nto$os- ;;- esac- ;;- -nto-qnx*)- ;;- -nto*)- os=`echo $os | sed -e 's|nto|nto-qnx|'`- ;;- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)- ;;- -mac*)- os=`echo $os | sed -e 's|mac|macos|'`- ;;- -linux-dietlibc)- os=-linux-dietlibc- ;;- -linux*)- os=`echo $os | sed -e 's|linux|linux-gnu|'`- ;;- -sunos5*)- os=`echo $os | sed -e 's|sunos5|solaris2|'`- ;;- -sunos6*)- os=`echo $os | sed -e 's|sunos6|solaris3|'`- ;;- -opened*)- os=-openedition- ;;- -os400*)- os=-os400- ;;- -wince*)- os=-wince- ;;- -osfrose*)- os=-osfrose- ;;- -osf*)- os=-osf- ;;- -utek*)- os=-bsd- ;;- -dynix*)- os=-bsd- ;;- -acis*)- os=-aos- ;;- -atheos*)- os=-atheos- ;;- -syllable*)- os=-syllable- ;;- -386bsd)- os=-bsd- ;;- -ctix* | -uts*)- os=-sysv- ;;- -nova*)- os=-rtmk-nova- ;;- -ns2 )- os=-nextstep2- ;;- -nsk*)- os=-nsk- ;;- # Preserve the version number of sinix5.- -sinix5.*)- os=`echo $os | sed -e 's|sinix|sysv|'`- ;;- -sinix*)- os=-sysv4- ;;- -tpf*)- os=-tpf- ;;- -triton*)- os=-sysv3- ;;- -oss*)- os=-sysv3- ;;- -svr4)- os=-sysv4- ;;- -svr3)- os=-sysv3- ;;- -sysvr4)- os=-sysv4- ;;- # This must come after -sysvr4.- -sysv*)- ;;- -ose*)- os=-ose- ;;- -es1800*)- os=-ose- ;;- -xenix)- os=-xenix- ;;- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)- os=-mint- ;;- -aros*)- os=-aros- ;;- -zvmoe)- os=-zvmoe- ;;- -dicos*)- os=-dicos- ;;- -nacl*)- ;;- -none)- ;;- *)- # Get rid of the `-' at the beginning of $os.- os=`echo $os | sed 's/[^-]*-//'`- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2- exit 1- ;;-esac-else--# Here we handle the default operating systems that come with various machines.-# The value should be what the vendor currently ships out the door with their-# machine or put another way, the most popular os provided with the machine.--# Note that if you're going to try to match "-MANUFACTURER" here (say,-# "-sun"), then you have to tell the case statement up towards the top-# that MANUFACTURER isn't an operating system. Otherwise, code above-# will signal an error saying that MANUFACTURER isn't an operating-# system, and we'll never get to this point.--case $basic_machine in- score-*)- os=-elf- ;;- spu-*)- os=-elf- ;;- *-acorn)- os=-riscix1.2- ;;- arm*-rebel)- os=-linux- ;;- arm*-semi)- os=-aout- ;;- c4x-* | tic4x-*)- os=-coff- ;;- c8051-*)- os=-elf- ;;- hexagon-*)- os=-elf- ;;- tic54x-*)- os=-coff- ;;- tic55x-*)- os=-coff- ;;- tic6x-*)- os=-coff- ;;- # This must come before the *-dec entry.- pdp10-*)- os=-tops20- ;;- pdp11-*)- os=-none- ;;- *-dec | vax-*)- os=-ultrix4.2- ;;- m68*-apollo)- os=-domain- ;;- i386-sun)- os=-sunos4.0.2- ;;- m68000-sun)- os=-sunos3- ;;- m68*-cisco)- os=-aout- ;;- mep-*)- os=-elf- ;;- mips*-cisco)- os=-elf- ;;- mips*-*)- os=-elf- ;;- or32-*)- os=-coff- ;;- *-tti) # must be before sparc entry or we get the wrong os.- os=-sysv3- ;;- sparc-* | *-sun)- os=-sunos4.1.1- ;;- *-be)- os=-beos- ;;- *-haiku)- os=-haiku- ;;- *-ibm)- os=-aix- ;;- *-knuth)- os=-mmixware- ;;- *-wec)- os=-proelf- ;;- *-winbond)- os=-proelf- ;;- *-oki)- os=-proelf- ;;- *-hp)- os=-hpux- ;;- *-hitachi)- os=-hiux- ;;- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)- os=-sysv- ;;- *-cbm)- os=-amigaos- ;;- *-dg)- os=-dgux- ;;- *-dolphin)- os=-sysv3- ;;- m68k-ccur)- os=-rtu- ;;- m88k-omron*)- os=-luna- ;;- *-next )- os=-nextstep- ;;- *-sequent)- os=-ptx- ;;- *-crds)- os=-unos- ;;- *-ns)- os=-genix- ;;- i370-*)- os=-mvs- ;;- *-next)- os=-nextstep3- ;;- *-gould)- os=-sysv- ;;- *-highlevel)- os=-bsd- ;;- *-encore)- os=-bsd- ;;- *-sgi)- os=-irix- ;;- *-siemens)- os=-sysv4- ;;- *-masscomp)- os=-rtu- ;;- f30[01]-fujitsu | f700-fujitsu)- os=-uxpv- ;;- *-rom68k)- os=-coff- ;;- *-*bug)- os=-coff- ;;- *-apple)- os=-macos- ;;- *-atari*)- os=-mint- ;;- *)- os=-none- ;;-esac-fi--# Here we handle the case where we know the os, and the CPU type, but not the-# manufacturer. We pick the logical manufacturer.-vendor=unknown-case $basic_machine in- *-unknown)- case $os in- -riscix*)- vendor=acorn- ;;- -sunos*)- vendor=sun- ;;- -cnk*|-aix*)- vendor=ibm- ;;- -beos*)- vendor=be- ;;- -hpux*)- vendor=hp- ;;- -mpeix*)- vendor=hp- ;;- -hiux*)- vendor=hitachi- ;;- -unos*)- vendor=crds- ;;- -dgux*)- vendor=dg- ;;- -luna*)- vendor=omron- ;;- -genix*)- vendor=ns- ;;- -mvs* | -opened*)- vendor=ibm- ;;- -os400*)- vendor=ibm- ;;- -ptx*)- vendor=sequent- ;;- -tpf*)- vendor=ibm- ;;- -vxsim* | -vxworks* | -windiss*)- vendor=wrs- ;;- -aux*)- vendor=apple- ;;- -hms*)- vendor=hitachi- ;;- -mpw* | -macos*)- vendor=apple- ;;- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)- vendor=atari- ;;- -vos*)- vendor=stratus- ;;- esac- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`- ;;-esac--echo $basic_machine$os-exit--# Local variables:-# eval: (add-hook 'write-file-hooks 'time-stamp)-# time-stamp-start: "timestamp='"-# time-stamp-format: "%:y-%02m-%02d"-# time-stamp-end: "'"-# End:
configure view
@@ -1624,6 +1624,119 @@ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile++# ac_fn_c_try_link LINENO+# -----------------------+# Try to link conftest.$ac_ext, and return whether this succeeded.+ac_fn_c_try_link ()+{+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+ rm -f conftest.$ac_objext conftest$ac_exeext+ if { { ac_try="$ac_link"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+$as_echo "$ac_try_echo"; } >&5+ (eval "$ac_link") 2>conftest.err+ ac_status=$?+ if test -s conftest.err; then+ grep -v '^ *+' conftest.err >conftest.er1+ cat conftest.er1 >&5+ mv -f conftest.er1 conftest.err+ fi+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+ test $ac_status = 0; } && {+ test -z "$ac_c_werror_flag" ||+ test ! -s conftest.err+ } && test -s conftest$ac_exeext && {+ test "$cross_compiling" = yes ||+ test -x conftest$ac_exeext+ }; then :+ ac_retval=0+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ ac_retval=1+fi+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would+ # interfere with the next link command; also delete a directory that is+ # left behind by Apple's compiler. We do this before executing the actions.+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+ as_fn_set_status $ac_retval++} # ac_fn_c_try_link++# ac_fn_c_check_func LINENO FUNC VAR+# ----------------------------------+# Tests whether FUNC exists, setting the cache variable VAR accordingly+ac_fn_c_check_func ()+{+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5+$as_echo_n "checking for $2... " >&6; }+if eval \${$3+:} false; then :+ $as_echo_n "(cached) " >&6+else+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h. */+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.+ For example, HP-UX 11i <limits.h> declares gettimeofday. */+#define $2 innocuous_$2++/* System header to define __stub macros and hopefully few prototypes,+ which can conflict with char $2 (); below.+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since+ <limits.h> exists even on freestanding compilers. */++#ifdef __STDC__+# include <limits.h>+#else+# include <assert.h>+#endif++#undef $2++/* Override any GCC internal prototype to avoid an error.+ Use char because int might match the return type of a GCC+ builtin and then its argument prototype would still apply. */+#ifdef __cplusplus+extern "C"+#endif+char $2 ();+/* The GNU C library defines this for functions which it implements+ to always fail with ENOSYS. Some functions are actually named+ something starting with __ and the normal name is an alias. */+#if defined __stub_$2 || defined __stub___$2+choke me+#endif++int+main ()+{+return $2 ();+ ;+ return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+ eval "$3=yes"+else+ eval "$3=no"+fi+rm -f core conftest.err conftest.$ac_objext \+ conftest$ac_exeext conftest.$ac_ext+fi+eval ac_res=\$$3+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+$as_echo "$ac_res" >&6; }+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno++} # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake.@@ -3178,7 +3291,7 @@ done -for ac_header in sys/types.h unistd.h sys/stat.h+for ac_header in fcntl.h limits.h sys/types.h sys/stat.h time.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"@@ -3190,6 +3303,26 @@ fi done+++for ac_func in utimensat+do :+ ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat"+if test "x$ac_cv_func_utimensat" = xyes; then :+ cat >>confdefs.h <<_ACEOF+#define HAVE_UTIMENSAT 1+_ACEOF++fi+done+++# EXTEXT is defined automatically by AC_PROG_CC;+# we just need to capture it in the header file++cat >>confdefs.h <<_ACEOF+#define EXE_EXTENSION "$EXEEXT"+_ACEOF cat >confcache <<\_ACEOF
configure.ac view
@@ -11,6 +11,13 @@ AC_PROG_CC() # check for specific header (.h) files that we are interested in-AC_CHECK_HEADERS([sys/types.h unistd.h sys/stat.h])+AC_CHECK_HEADERS([fcntl.h limits.h sys/types.h sys/stat.h time.h])++AC_CHECK_FUNCS([utimensat])++# EXTEXT is defined automatically by AC_PROG_CC;+# we just need to capture it in the header file+AC_DEFINE_UNQUOTED([EXE_EXTENSION], ["$EXEEXT"],+ [Filename extension of executable files]) AC_OUTPUT
directory.cabal view
@@ -1,5 +1,5 @@ name: directory-version: 1.2.2.1+version: 1.2.3.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 license-file: LICENSE@@ -10,7 +10,7 @@ This library provides a basic set of operations for manipulating files and directories in a portable way. category: System-build-type: Custom+build-type: Configure cabal-version: >= 1.10 tested-with: GHC>=7.4.1 @@ -23,31 +23,12 @@ extra-source-files: changelog.md README.md- config.guess- config.sub configure configure.ac directory.buildinfo include/HsDirectoryConfig.h.in- install-sh tests/*.hs- tests/*.stderr- tests/*.stdout- tests/Makefile- tests/all.T- tests/copyFile001dir/source- tests/copyFile002dir/source- tests/createDirectory001.stdout-mingw32- tests/createDirectoryIfMissing001.stdout-mingw32- tests/getDirContents002.stderr-mingw32- tests/getPermissions001.stdout-alpha-dec-osf3- tests/getPermissions001.stdout-i386-unknown-freebsd- tests/getPermissions001.stdout-i386-unknown-openbsd- tests/getPermissions001.stdout-mingw- tests/getPermissions001.stdout-x86_64-unknown-openbsd- tools/ghc-test-framework.LICENSE- tools/ghc-test-framework.shar- tools/run-tests+ tests/util.inl source-repository head type: git@@ -62,6 +43,11 @@ exposed-modules: System.Directory+ other-modules:+ System.Directory.Internal+ System.Directory.Internal.C_utimensat+ System.Directory.Internal.Posix+ System.Directory.Internal.Windows c-sources: cbits/directory.c@@ -84,10 +70,13 @@ test-suite test default-language: Haskell2010- other-extensions: CPP ForeignFunctionInterface+ other-extensions: BangPatterns, CPP ghc-options: -Wall- hs-source-dirs: tools- build-tools: python, which- main-is: dispatch-tests.hs+ hs-source-dirs: tests+ main-is: Main.hs type: exitcode-stdio-1.0- build-depends: base, directory+ build-depends: base, directory, filepath, time+ if os(windows)+ build-depends: Win32+ else+ build-depends: unix
include/HsDirectory.h view
@@ -6,6 +6,9 @@ * * ---------------------------------------------------------------------------*/ +/* [DEPRECATED] Do not include this header nor HsDirectoryConfig.h. They are+ for internal use only and may be removed in future versions. */+ #ifndef __HSDIRECTORY_H__ #define __HSDIRECTORY_H__ @@ -49,10 +52,8 @@ # endif #endif -/* A size that will contain many path names, but not necessarily all- * (PATH_MAX is not defined on systems with unlimited path length,- * e.g. the Hurd).- */+/* Do not use: it may give the wrong value on systems where PATH_MAX is not+ defined (e.g. Hurd). Instead, use System.Directory.Internal.c_PATH_MAX. */ INLINE HsInt __hscore_long_path_size(void) { #ifdef PATH_MAX return PATH_MAX;@@ -67,4 +68,3 @@ INLINE mode_t __hscore_S_IFDIR(void) { return S_IFDIR; } #endif /* __HSDIRECTORY_H__ */-
include/HsDirectoryConfig.h.in view
@@ -1,8 +1,17 @@ /* include/HsDirectoryConfig.h.in. Generated from configure.ac by autoheader. */ +/* Filename extension of executable files */+#undef EXE_EXTENSION++/* Define to 1 if you have the <fcntl.h> header file. */+#undef HAVE_FCNTL_H+ /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have the <limits.h> header file. */+#undef HAVE_LIMITS_H+ /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H @@ -24,8 +33,14 @@ /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the <time.h> header file. */+#undef HAVE_TIME_H+ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H++/* Define to 1 if you have the `utimensat' function. */+#undef HAVE_UTIMENSAT /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT
− install-sh
@@ -1,527 +0,0 @@-#!/bin/sh-# install - install a program, script, or datafile--scriptversion=2011-11-20.07; # UTC--# This originates from X11R5 (mit/util/scripts/install.sh), which was-# later released in X11R6 (xc/config/util/install.sh) with the-# following copyright and license.-#-# Copyright (C) 1994 X Consortium-#-# Permission is hereby granted, free of charge, to any person obtaining a copy-# of this software and associated documentation files (the "Software"), to-# deal in the Software without restriction, including without limitation the-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or-# sell copies of the Software, and to permit persons to whom the Software is-# furnished to do so, subject to the following conditions:-#-# The above copyright notice and this permission notice shall be included in-# all copies or substantial portions of the Software.-#-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC--# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.-#-# Except as contained in this notice, the name of the X Consortium shall not-# be used in advertising or otherwise to promote the sale, use or other deal--# ings in this Software without prior written authorization from the X Consor--# tium.-#-#-# FSF changes to this file are in the public domain.-#-# Calling this script install-sh is preferred over install.sh, to prevent-# 'make' implicit rules from creating a file called install from it-# when there is no Makefile.-#-# This script is compatible with the BSD install script, but was written-# from scratch.--nl='-'-IFS=" "" $nl"--# set DOITPROG to echo to test this script--# Don't use :- since 4.3BSD and earlier shells don't like it.-doit=${DOITPROG-}-if test -z "$doit"; then- doit_exec=exec-else- doit_exec=$doit-fi--# Put in absolute file names if you don't have them in your path;-# or use environment vars.--chgrpprog=${CHGRPPROG-chgrp}-chmodprog=${CHMODPROG-chmod}-chownprog=${CHOWNPROG-chown}-cmpprog=${CMPPROG-cmp}-cpprog=${CPPROG-cp}-mkdirprog=${MKDIRPROG-mkdir}-mvprog=${MVPROG-mv}-rmprog=${RMPROG-rm}-stripprog=${STRIPPROG-strip}--posix_glob='?'-initialize_posix_glob='- test "$posix_glob" != "?" || {- if (set -f) 2>/dev/null; then- posix_glob=- else- posix_glob=:- fi- }-'--posix_mkdir=--# Desired mode of installed file.-mode=0755--chgrpcmd=-chmodcmd=$chmodprog-chowncmd=-mvcmd=$mvprog-rmcmd="$rmprog -f"-stripcmd=--src=-dst=-dir_arg=-dst_arg=--copy_on_change=false-no_target_directory=--usage="\-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE- or: $0 [OPTION]... SRCFILES... DIRECTORY- or: $0 [OPTION]... -t DIRECTORY SRCFILES...- or: $0 [OPTION]... -d DIRECTORIES...--In the 1st form, copy SRCFILE to DSTFILE.-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.-In the 4th, create DIRECTORIES.--Options:- --help display this help and exit.- --version display version info and exit.-- -c (ignored)- -C install only if different (preserve the last data modification time)- -d create directories instead of installing files.- -g GROUP $chgrpprog installed files to GROUP.- -m MODE $chmodprog installed files to MODE.- -o USER $chownprog installed files to USER.- -s $stripprog installed files.- -t DIRECTORY install into DIRECTORY.- -T report an error if DSTFILE is a directory.--Environment variables override the default commands:- CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG- RMPROG STRIPPROG-"--while test $# -ne 0; do- case $1 in- -c) ;;-- -C) copy_on_change=true;;-- -d) dir_arg=true;;-- -g) chgrpcmd="$chgrpprog $2"- shift;;-- --help) echo "$usage"; exit $?;;-- -m) mode=$2- case $mode in- *' '* | *' '* | *'-'* | *'*'* | *'?'* | *'['*)- echo "$0: invalid mode: $mode" >&2- exit 1;;- esac- shift;;-- -o) chowncmd="$chownprog $2"- shift;;-- -s) stripcmd=$stripprog;;-- -t) dst_arg=$2- # Protect names problematic for 'test' and other utilities.- case $dst_arg in- -* | [=\(\)!]) dst_arg=./$dst_arg;;- esac- shift;;-- -T) no_target_directory=true;;-- --version) echo "$0 $scriptversion"; exit $?;;-- --) shift- break;;-- -*) echo "$0: invalid option: $1" >&2- exit 1;;-- *) break;;- esac- shift-done--if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then- # When -d is used, all remaining arguments are directories to create.- # When -t is used, the destination is already specified.- # Otherwise, the last argument is the destination. Remove it from $@.- for arg- do- if test -n "$dst_arg"; then- # $@ is not empty: it contains at least $arg.- set fnord "$@" "$dst_arg"- shift # fnord- fi- shift # arg- dst_arg=$arg- # Protect names problematic for 'test' and other utilities.- case $dst_arg in- -* | [=\(\)!]) dst_arg=./$dst_arg;;- esac- done-fi--if test $# -eq 0; then- if test -z "$dir_arg"; then- echo "$0: no input file specified." >&2- exit 1- fi- # It's OK to call 'install-sh -d' without argument.- # This can happen when creating conditional directories.- exit 0-fi--if test -z "$dir_arg"; then- do_exit='(exit $ret); exit $ret'- trap "ret=129; $do_exit" 1- trap "ret=130; $do_exit" 2- trap "ret=141; $do_exit" 13- trap "ret=143; $do_exit" 15-- # Set umask so as not to create temps with too-generous modes.- # However, 'strip' requires both read and write access to temps.- case $mode in- # Optimize common cases.- *644) cp_umask=133;;- *755) cp_umask=22;;-- *[0-7])- if test -z "$stripcmd"; then- u_plus_rw=- else- u_plus_rw='% 200'- fi- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;- *)- if test -z "$stripcmd"; then- u_plus_rw=- else- u_plus_rw=,u+rw- fi- cp_umask=$mode$u_plus_rw;;- esac-fi--for src-do- # Protect names problematic for 'test' and other utilities.- case $src in- -* | [=\(\)!]) src=./$src;;- esac-- if test -n "$dir_arg"; then- dst=$src- dstdir=$dst- test -d "$dstdir"- dstdir_status=$?- else-- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command- # might cause directories to be created, which would be especially bad- # if $src (and thus $dsttmp) contains '*'.- if test ! -f "$src" && test ! -d "$src"; then- echo "$0: $src does not exist." >&2- exit 1- fi-- if test -z "$dst_arg"; then- echo "$0: no destination specified." >&2- exit 1- fi- dst=$dst_arg-- # If destination is a directory, append the input filename; won't work- # if double slashes aren't ignored.- if test -d "$dst"; then- if test -n "$no_target_directory"; then- echo "$0: $dst_arg: Is a directory" >&2- exit 1- fi- dstdir=$dst- dst=$dstdir/`basename "$src"`- dstdir_status=0- else- # Prefer dirname, but fall back on a substitute if dirname fails.- dstdir=`- (dirname "$dst") 2>/dev/null ||- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \- X"$dst" : 'X\(//\)[^/]' \| \- X"$dst" : 'X\(//\)$' \| \- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||- echo X"$dst" |- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{- s//\1/- q- }- /^X\(\/\/\)[^/].*/{- s//\1/- q- }- /^X\(\/\/\)$/{- s//\1/- q- }- /^X\(\/\).*/{- s//\1/- q- }- s/.*/./; q'- `-- test -d "$dstdir"- dstdir_status=$?- fi- fi-- obsolete_mkdir_used=false-- if test $dstdir_status != 0; then- case $posix_mkdir in- '')- # Create intermediate dirs using mode 755 as modified by the umask.- # This is like FreeBSD 'install' as of 1997-10-28.- umask=`umask`- case $stripcmd.$umask in- # Optimize common cases.- *[2367][2367]) mkdir_umask=$umask;;- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;-- *[0-7])- mkdir_umask=`expr $umask + 22 \- - $umask % 100 % 40 + $umask % 20 \- - $umask % 10 % 4 + $umask % 2- `;;- *) mkdir_umask=$umask,go-w;;- esac-- # With -d, create the new directory with the user-specified mode.- # Otherwise, rely on $mkdir_umask.- if test -n "$dir_arg"; then- mkdir_mode=-m$mode- else- mkdir_mode=- fi-- posix_mkdir=false- case $umask in- *[123567][0-7][0-7])- # POSIX mkdir -p sets u+wx bits regardless of umask, which- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.- ;;- *)- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0-- if (umask $mkdir_umask &&- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1- then- if test -z "$dir_arg" || {- # Check for POSIX incompatibilities with -m.- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or- # other-writable bit of parent directory when it shouldn't.- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.- ls_ld_tmpdir=`ls -ld "$tmpdir"`- case $ls_ld_tmpdir in- d????-?r-*) different_mode=700;;- d????-?--*) different_mode=755;;- *) false;;- esac &&- $mkdirprog -m$different_mode -p -- "$tmpdir" && {- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"- }- }- then posix_mkdir=:- fi- rmdir "$tmpdir/d" "$tmpdir"- else- # Remove any dirs left behind by ancient mkdir implementations.- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null- fi- trap '' 0;;- esac;;- esac-- if- $posix_mkdir && (- umask $mkdir_umask &&- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"- )- then :- else-- # The umask is ridiculous, or mkdir does not conform to POSIX,- # or it failed possibly due to a race condition. Create the- # directory the slow way, step by step, checking for races as we go.-- case $dstdir in- /*) prefix='/';;- [-=\(\)!]*) prefix='./';;- *) prefix='';;- esac-- eval "$initialize_posix_glob"-- oIFS=$IFS- IFS=/- $posix_glob set -f- set fnord $dstdir- shift- $posix_glob set +f- IFS=$oIFS-- prefixes=-- for d- do- test X"$d" = X && continue-- prefix=$prefix$d- if test -d "$prefix"; then- prefixes=- else- if $posix_mkdir; then- (umask=$mkdir_umask &&- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break- # Don't fail if two instances are running concurrently.- test -d "$prefix" || exit 1- else- case $prefix in- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;- *) qprefix=$prefix;;- esac- prefixes="$prefixes '$qprefix'"- fi- fi- prefix=$prefix/- done-- if test -n "$prefixes"; then- # Don't fail if two instances are running concurrently.- (umask $mkdir_umask &&- eval "\$doit_exec \$mkdirprog $prefixes") ||- test -d "$dstdir" || exit 1- obsolete_mkdir_used=true- fi- fi- fi-- if test -n "$dir_arg"; then- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1- else-- # Make a couple of temp file names in the proper directory.- dsttmp=$dstdir/_inst.$$_- rmtmp=$dstdir/_rm.$$_-- # Trap to clean up those temp files at exit.- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0-- # Copy the file name to the temp name.- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&-- # and set any options; do chmod last to preserve setuid bits.- #- # If any of these fail, we abort the whole thing. If we want to- # ignore errors from any of these, just make sure not to ignore- # errors from the above "$doit $cpprog $src $dsttmp" command.- #- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&- { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&- { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&-- # If -C, don't bother to copy if it wouldn't change the file.- if $copy_on_change &&- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&-- eval "$initialize_posix_glob" &&- $posix_glob set -f &&- set X $old && old=:$2:$4:$5:$6 &&- set X $new && new=:$2:$4:$5:$6 &&- $posix_glob set +f &&-- test "$old" = "$new" &&- $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1- then- rm -f "$dsttmp"- else- # Rename the file to the real destination.- $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||-- # The rename failed, perhaps because mv can't rename something else- # to itself, or perhaps because mv is so ancient that it does not- # support -f.- {- # Now remove or move aside any old file at destination location.- # We try this two ways since rm can't unlink itself on some- # systems and the destination file might be busy for other- # reasons. In this case, the final cleanup might fail but the new- # file should still install successfully.- {- test ! -f "$dst" ||- $doit $rmcmd -f "$dst" 2>/dev/null ||- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }- } ||- { echo "$0: cannot unlink or rename $dst" >&2- (exit 1); exit 1- }- } &&-- # Now rename the file to the real destination.- $doit $mvcmd "$dsttmp" "$dst"- }- fi || exit 1-- trap '' 0- fi-done--# Local variables:-# eval: (add-hook 'write-file-hooks 'time-stamp)-# time-stamp-start: "scriptversion="-# time-stamp-format: "%:y-%02m-%02d.%02H"-# time-stamp-time-zone: "UTC"-# time-stamp-end: "; # UTC"-# End:
+ tests/CanonicalizePath.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE CPP #-}+module CanonicalizePath where+#include "util.inl"+import System.Directory+import System.FilePath ((</>), normalise)++main :: TestEnv -> IO ()+main _t = do+ dot <- canonicalizePath "."+ nul <- canonicalizePath ""+ T(expectEq) () dot nul++ writeFile "bar" ""+ bar <- canonicalizePath "bar"+ T(expectEq) () bar (normalise (dot </> "bar"))++ createDirectory "foo"+ foo <- canonicalizePath "foo/"+ T(expectEq) () foo (normalise (dot </> "foo/"))++ -- should not fail for non-existent paths+ fooNon <- canonicalizePath "foo/non-existent"+ T(expectEq) () fooNon (normalise (foo </> "non-existent"))
+ tests/CopyFile001.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE CPP #-}+module CopyFile001 where+#include "util.inl"+import System.Directory+import Data.List (sort)+import Data.Monoid ((<>))+import System.FilePath ((</>))++main :: TestEnv -> IO ()+main _t = do+ createDirectory dir+ writeFile (dir </> from) contents+ T(expectEq) () (specials <> [from]) . sort =<< getDirectoryContents dir+ copyFile (dir </> from) (dir </> to)+ T(expectEq) () (specials <> [from, to]) . sort =<< getDirectoryContents dir+ T(expectEq) () contents =<< readFile (dir </> to)+ where+ specials = [".", ".."]+ contents = "This is the data\n"+ from = "source"+ to = "target"+ dir = "dir"
+ tests/CopyFile002.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE CPP #-}+module CopyFile002 where+#include "util.inl"+import System.Directory+import Data.List (sort)+import Data.Monoid ((<>))++main :: TestEnv -> IO ()+main _t = do+ -- Similar to CopyFile001 but moves a file in the current directory+ -- (Bug #1652 on GHC Trac)+ writeFile from contents+ T(expectEq) () (specials <> [from]) . sort =<< getDirectoryContents "."+ copyFile from to+ T(expectEq) () (specials <> [from, to]) . sort =<< getDirectoryContents "."+ T(expectEq) () contents =<< readFile to+ where+ specials = [".", ".."]+ contents = "This is the data\n"+ from = "source"+ to = "target"
+ tests/CreateDirectory001.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE CPP #-}+module CreateDirectory001 where+#include "util.inl"+import System.Directory+import System.IO.Error (isAlreadyExistsError)++main :: TestEnv -> IO ()+main _t = do+ createDirectory testdir+ T(expectIOErrorType) () isAlreadyExistsError (createDirectory testdir)+ where testdir = "dir"
+ tests/CreateDirectoryIfMissing001.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE CPP #-}+module CreateDirectoryIfMissing001 where+#include "util.inl"+import System.Directory+import Control.Concurrent (forkIO, newEmptyMVar, putMVar, takeMVar)+import qualified Control.Exception as E+import Control.Monad (replicateM_)+import System.FilePath ((</>), addTrailingPathSeparator)+import System.IO (hFlush, stdout)+import System.IO.Error(isAlreadyExistsError, isDoesNotExistError,+ isPermissionError)+#ifndef mingw32_HOST_OS+import GHC.IO.Exception (IOErrorType(InappropriateType))+import System.IO.Error(ioeGetErrorType)+#endif++main :: TestEnv -> IO ()+main _t = do++ createDirectoryIfMissing False testdir+ cleanup++ T(expectIOErrorType) () isDoesNotExistError $+ createDirectoryIfMissing False testdir_a++ createDirectoryIfMissing True testdir_a+ createDirectoryIfMissing False testdir_a+ createDirectoryIfMissing False (addTrailingPathSeparator testdir_a)+ cleanup++ createDirectoryIfMissing True (addTrailingPathSeparator testdir_a)++ putStrLn "testing for race conditions ..."+ hFlush stdout+ raceCheck1+ raceCheck2+ putStrLn "done."+ hFlush stdout+ cleanup++ writeFile testdir testdir+ T(expectIOErrorType) () isAlreadyExistsError $+ createDirectoryIfMissing False testdir+ removeFile testdir+ cleanup++ writeFile testdir testdir+ T(expectIOErrorType) () isNotADirectoryError $+ createDirectoryIfMissing True testdir_a+ removeFile testdir+ cleanup++ where++ testdir = "createDirectoryIfMissing001.d"+ testdir_a = testdir </> "a"++ -- Look for race conditions (bug #2808 on GHC Trac). This fails with+ -- +RTS -N2 and directory 1.0.0.2.+ raceCheck1 = do+ m <- newEmptyMVar+ _ <- forkIO $ do+ replicateM_ 10000 create+ putMVar m ()+ _ <- forkIO $ do+ replicateM_ 10000 cleanup+ putMVar m ()+ replicateM_ 2 (takeMVar m)++ -- This test fails on Windows (see bug #2924 on GHC Trac):+ raceCheck2 = do+ m <- newEmptyMVar+ replicateM_ 4 $+ forkIO $ do+ replicateM_ 10000 $ do+ create+ cleanup+ putMVar m ()+ replicateM_ 4 (takeMVar m)++ -- createDirectoryIfMissing is allowed to fail with isDoesNotExistError if+ -- another process/thread removes one of the directories during the process+ -- of creating the hierarchy.+ --+ -- It is also allowed to fail with permission errors+ -- (see bug #2924 on GHC Trac)+ create =+ createDirectoryIfMissing True testdir_a `E.catch` \ e ->+ if isDoesNotExistError e || isPermissionError e+ then return ()+ else ioError e++ cleanup = removeDirectoryRecursive testdir `catchAny` \ _ -> return ()++ catchAny :: IO a -> (E.SomeException -> IO a) -> IO a+ catchAny = E.catch++#ifdef mingw32_HOST_OS+ isNotADirectoryError = isAlreadyExistsError+#else+ isNotADirectoryError e = case ioeGetErrorType e of+ InappropriateType -> True+ _ -> False+#endif
+ tests/CurrentDirectory001.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE CPP #-}+module CurrentDirectory001 where+#include "util.inl"+import System.Directory+import Data.List (sort)++main :: TestEnv -> IO ()+main _t = do+ prevDir <- getCurrentDirectory+ createDirectory "dir"+ setCurrentDirectory "dir"+ T(expectEq) () [".", ".."] . sort =<< getDirectoryContents "."+ setCurrentDirectory prevDir+ removeDirectory "dir"
+ tests/Directory001.hs view
@@ -0,0 +1,19 @@+{-# LANGUAGE CPP #-}+module Directory001 where+#include "util.inl"+import System.Directory++main :: TestEnv -> IO ()+main _t = do++ createDirectory "foo"+ writeFile "foo/bar" str+ renameFile "foo/bar" "foo/baz"+ renameDirectory "foo" "bar"+ str' <- readFile "bar/baz"+ T(expectEq) () str' str+ removeFile "bar/baz"+ removeDirectory "bar"++ where+ str = "Okay\n"
+ tests/DoesDirectoryExist001.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE CPP #-}+module DoesDirectoryExist001 where+#include "util.inl"+import System.Directory++main :: TestEnv -> IO ()+main _t = do++ -- [regression test] "/" was not recognised as a directory prior to GHC 6.1+ T(expect) () =<< doesDirectoryExist rootDir++ where+#ifdef mingw32_HOST_OS+ rootDir = "C:\\"+#else+ rootDir = "/"+#endif
+ tests/FileTime.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE CPP #-}+module FileTime where+#include "util.inl"+import System.Directory+import System.IO.Error (isDoesNotExistError)+import Data.Foldable (for_)+import qualified Data.Time.Clock as Time++main :: TestEnv -> IO ()+main _t = do+ now <- Time.getCurrentTime+ let someTimeAgo = Time.addUTCTime (-3600) now+ someTimeAgo' = Time.addUTCTime (-7200) now++ T(expectIOErrorType) () isDoesNotExistError $+ getAccessTime "nonexistent-file"+ T(expectIOErrorType) () isDoesNotExistError $+ setAccessTime "nonexistent-file" someTimeAgo+ T(expectIOErrorType) () isDoesNotExistError $+ getModificationTime "nonexistent-file"+ T(expectIOErrorType) () isDoesNotExistError $+ setModificationTime "nonexistent-file" someTimeAgo++ writeFile "foo" ""+ for_ [ "foo", ".", "" ] $ \ file -> do+ let mtime = someTimeAgo+ atime = someTimeAgo'++ atime1 <- getAccessTime file++ setModificationTime file mtime++ atime2 <- getAccessTime file+ mtime2 <- getModificationTime file++ -- modification time should be set with at worst 1 sec resolution+ T(expectNearTime) file mtime mtime2 1++ -- access time should not change, although it may lose some precision+ -- on POSIX systems without 'utimensat'+ T(expectNearTime) file atime1 atime2 1++ setAccessTime file atime++ atime3 <- getAccessTime file+ mtime3 <- getModificationTime file++ -- access time should be set with at worst 1 sec resolution+ T(expectNearTime) file atime atime3 1++ -- modification time should not change, although it may lose some precision+ -- on POSIX systems without 'utimensat'+ T(expectNearTime) file mtime2 mtime3 1
+ tests/GetDirContents001.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE CPP #-}+module GetDirContents001 where+#include "util.inl"+import System.Directory+import Data.List (sort)+import Data.Monoid ((<>))+import Data.Traversable (for)+import System.FilePath ((</>))++main :: TestEnv -> IO ()+main _t = do+ createDirectory dir+ T(expectEq) () specials . sort =<< getDirectoryContents dir+ names <- for [1 .. 100 :: Int] $ \ i -> do+ let name = 'f' : show i+ writeFile (dir </> name) ""+ return name+ T(expectEq) () (sort (specials <> names)) . sort =<< getDirectoryContents dir+ where dir = "dir"+ specials = [".", ".."]
+ tests/GetDirContents002.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}+module GetDirContents002 where+#include "util.inl"+import System.Directory+import System.IO.Error (isDoesNotExistError)++main :: TestEnv -> IO ()+main _t = do+ T(expectIOErrorType) () isDoesNotExistError $+ getDirectoryContents "nonexistent"
+ tests/GetHomeDirectory001.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE CPP #-}+module GetHomeDirectory001 where+#include "util.inl"+import System.Directory++main :: TestEnv -> IO ()+main _t = do+ homeDir <- getHomeDirectory+ T(expect) () (homeDir /= "") -- sanity check+ _ <- getAppUserDataDirectory "test"+ _ <- getXdgDirectory XdgCache "test"+ _ <- getXdgDirectory XdgConfig "test"+ _ <- getXdgDirectory XdgData "test"+ _ <- getUserDocumentsDirectory+ _ <- getTemporaryDirectory+ return ()
+ tests/GetPermissions001.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE CPP #-}+module GetPermissions001 where+#include "util.inl"+import System.Directory++main :: TestEnv -> IO ()+main _t = do++ checkCurrentDir+ checkExecutable+ checkOrdinary+ checkTrailingSlash++ where++ checkCurrentDir = do+ -- since the current directory is created by the test runner,+ -- it should be readable, writable, and searchable+ p <- getPermissions "."+ T(expect) () (readable p)+ T(expect) () (writable p)+ T(expect) () (not (executable p))+ T(expect) () (searchable p)++ checkExecutable = do+ -- 'find' expected to exist on both Windows and POSIX,+ -- though we have no idea if it's writable+ Just f <- findExecutable "find"+ p <- getPermissions f+ T(expect) () (readable p)+ T(expect) () (executable p)+ T(expect) () (not (searchable p))++ checkOrdinary = do+ writeFile "foo" ""+ p <- getPermissions "foo"+ T(expect) () (readable p)+ T(expect) () (writable p)+ T(expect) () (not (executable p))+ T(expect) () (not (searchable p))++ -- [regression test] (issue #9)+ -- Windows doesn't like trailing path separators+ checkTrailingSlash = do+ createDirectory "bar"+ _ <- getPermissions "bar/"+ return ()
+ tests/Main.hs view
@@ -0,0 +1,39 @@+module Main (main) where+import qualified Util as T+import qualified CanonicalizePath+import qualified CopyFile001+import qualified CopyFile002+import qualified CreateDirectory001+import qualified CreateDirectoryIfMissing001+import qualified CurrentDirectory001+import qualified Directory001+import qualified DoesDirectoryExist001+import qualified FileTime+import qualified GetDirContents001+import qualified GetDirContents002+import qualified GetHomeDirectory001+import qualified GetPermissions001+import qualified RemoveDirectoryRecursive001+import qualified RenameFile001+import qualified T8482+import qualified WithCurrentDirectory++main :: IO ()+main = T.testMain $ \ _t -> do+ T.isolatedRun _t "CanonicalizePath" CanonicalizePath.main+ T.isolatedRun _t "CopyFile001" CopyFile001.main+ T.isolatedRun _t "CopyFile002" CopyFile002.main+ T.isolatedRun _t "CreateDirectory001" CreateDirectory001.main+ T.isolatedRun _t "CreateDirectoryIfMissing001" CreateDirectoryIfMissing001.main+ T.isolatedRun _t "CurrentDirectory001" CurrentDirectory001.main+ T.isolatedRun _t "Directory001" Directory001.main+ T.isolatedRun _t "DoesDirectoryExist001" DoesDirectoryExist001.main+ T.isolatedRun _t "FileTime" FileTime.main+ T.isolatedRun _t "GetDirContents001" GetDirContents001.main+ T.isolatedRun _t "GetDirContents002" GetDirContents002.main+ T.isolatedRun _t "GetHomeDirectory001" GetHomeDirectory001.main+ T.isolatedRun _t "GetPermissions001" GetPermissions001.main+ T.isolatedRun _t "RemoveDirectoryRecursive001" RemoveDirectoryRecursive001.main+ T.isolatedRun _t "RenameFile001" RenameFile001.main+ T.isolatedRun _t "T8482" T8482.main+ T.isolatedRun _t "WithCurrentDirectory" WithCurrentDirectory.main
− tests/Makefile
@@ -1,7 +0,0 @@-# This Makefile runs the tests using GHC's testsuite framework. It-# assumes the package is part of a GHC build tree with the testsuite-# installed in ../../../testsuite.--TOP=../../../testsuite-include $(TOP)/mk/boilerplate.mk-include $(TOP)/mk/test.mk
+ tests/RemoveDirectoryRecursive001.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE CPP #-}+module RemoveDirectoryRecursive001 where+#include "util.inl"+import System.Directory+import Data.List (sort)+import System.FilePath ((</>), normalise)+import System.IO.Error (catchIOError)+import TestUtils++main :: TestEnv -> IO ()+main _t = do++ ------------------------------------------------------------+ -- clean up junk from previous invocations++ modifyPermissions (tmp "c") (\ p -> p { writable = True })+ `catchIOError` \ _ -> return ()+ removeDirectoryRecursive tmpD+ `catchIOError` \ _ -> return ()++ ------------------------------------------------------------+ -- set up++ createDirectoryIfMissing True (tmp "a/x/w")+ createDirectoryIfMissing True (tmp "a/y")+ createDirectoryIfMissing True (tmp "a/z")+ createDirectoryIfMissing True (tmp "b")+ createDirectoryIfMissing True (tmp "c")+ writeFile (tmp "a/x/w/u") "foo"+ writeFile (tmp "a/t") "bar"+ tryCreateSymbolicLink (normalise "../a") (tmp "b/g")+ tryCreateSymbolicLink (normalise "../b") (tmp "c/h")+ tryCreateSymbolicLink (normalise "a") (tmp "d")+ modifyPermissions (tmp "c") (\ p -> p { writable = False })++ ------------------------------------------------------------+ -- tests++ T(expectEq) () [".", "..", "a", "b", "c", "d"] . sort =<<+ getDirectoryContents tmpD+ T(expectEq) () [".", "..", "t", "x", "y", "z"] . sort =<<+ getDirectoryContents (tmp "a")+ T(expectEq) () [".", "..", "g"] . sort =<<+ getDirectoryContents (tmp "b")+ T(expectEq) () [".", "..", "h"] . sort =<<+ getDirectoryContents (tmp "c")+ T(expectEq) () [".", "..", "t", "x", "y", "z"] . sort =<<+ getDirectoryContents (tmp "d")++ removeDirectoryRecursive (tmp "d")+ `catchIOError` \ _ -> removeFile (tmp "d")+#ifdef mingw32_HOST_OS+ `catchIOError` \ _ -> removeDirectory (tmp "d")+#endif++ T(expectEq) () [".", "..", "a", "b", "c"] . sort =<<+ getDirectoryContents tmpD+ T(expectEq) () [".", "..", "t", "x", "y", "z"] . sort =<<+ getDirectoryContents (tmp "a")+ T(expectEq) () [".", "..", "g"] . sort =<<+ getDirectoryContents (tmp "b")+ T(expectEq) () [".", "..", "h"] . sort =<<+ getDirectoryContents (tmp "c")++ removeDirectoryRecursive (tmp "c")+ `catchIOError` \ _ -> do+ modifyPermissions (tmp "c") (\ p -> p { writable = True })+ removeDirectoryRecursive (tmp "c")++ T(expectEq) () [".", "..", "a", "b"] . sort =<<+ getDirectoryContents tmpD+ T(expectEq) () [".", "..", "t", "x", "y", "z"] . sort =<<+ getDirectoryContents (tmp "a")+ T(expectEq) () [".", "..", "g"] . sort =<<+ getDirectoryContents (tmp "b")++ removeDirectoryRecursive (tmp "b")++ T(expectEq) () [".", "..", "a"] . sort =<<+ getDirectoryContents tmpD+ T(expectEq) () [".", "..", "t", "x", "y", "z"] . sort =<<+ getDirectoryContents (tmp "a")++ removeDirectoryRecursive (tmp "a")++ T(expectEq) () [".", ".."] . sort =<<+ getDirectoryContents tmpD++ where testName = "removeDirectoryRecursive001"+ tmpD = testName ++ ".tmp"+ tmp s = tmpD </> normalise s
+ tests/RenameFile001.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE CPP #-}+module RenameFile001 where+#include "util.inl"+import System.Directory++main :: TestEnv -> IO ()+main _t = do+ writeFile tmp1 contents1+ renameFile tmp1 tmp2+ T(expectEq) () contents1 =<< readFile tmp2+ writeFile tmp1 contents2+ renameFile tmp2 tmp1+ T(expectEq) () contents1 =<< readFile tmp1+ where+ tmp1 = "tmp1"+ tmp2 = "tmp2"+ contents1 = "test"+ contents2 = "test2"
tests/T8482.hs view
@@ -1,16 +1,21 @@+{-# LANGUAGE CPP #-}+module T8482 where+#include "util.inl"+import GHC.IO.Exception (IOErrorType(InappropriateType)) import System.Directory-import Control.Exception+import System.IO.Error (ioeGetErrorType) +tmp1 :: FilePath tmp1 = "T8482.tmp1"++testdir :: FilePath testdir = "T8482.dir" -main = do+main :: TestEnv -> IO ()+main _t = do writeFile tmp1 "hello" createDirectory testdir- tryRenameFile testdir tmp1 >>= print -- InappropriateType- tryRenameFile tmp1 testdir >>= print -- InappropriateType- tryRenameFile tmp1 "." >>= print -- InappropriateType- removeDirectory testdir- removeFile tmp1- where tryRenameFile :: FilePath -> FilePath -> IO (Either IOException ())- tryRenameFile opath npath = try $ renameFile opath npath+ T(expectIOErrorType) () (is InappropriateType) (renameFile testdir tmp1)+ T(expectIOErrorType) () (is InappropriateType) (renameFile tmp1 testdir)+ T(expectIOErrorType) () (is InappropriateType) (renameFile tmp1 ".")+ where is t = (== t) . ioeGetErrorType
− tests/T8482.stdout
@@ -1,3 +0,0 @@-Left T8482.dir: renameFile: inappropriate type (is a directory)-Left T8482.dir: renameFile: inappropriate type (is a directory)-Left .: renameFile: inappropriate type (is a directory)
tests/TestUtils.hs view
@@ -12,7 +12,6 @@ import Foreign (Ptr) import Foreign.C (CUChar(..), CULong(..), CWchar(..), withCWString) import System.FilePath (takeDirectory)-import System.IO (hPutStrLn, stderr) import System.IO.Error (catchIOError, ioeSetErrorString, isPermissionError, mkIOError, permissionErrorType) import System.Win32.Types (failWith, getLastError)
+ tests/Util.hs view
@@ -0,0 +1,165 @@+{-# LANGUAGE BangPatterns, CPP #-}+module Util where+import Prelude (Eq(..), Num(..), Ord(..), RealFrac(..), Show(..),+ Bool(..), Double, Either(..), Int, Integer, Maybe(..), String,+ ($), (.), otherwise)+import Data.IORef (IORef, newIORef, readIORef, writeIORef)+import Data.List (elem, intercalate)+import Data.Monoid ((<>))+import Data.Time.Clock (NominalDiffTime, UTCTime, diffUTCTime)+import Control.Concurrent (forkIO, killThread)+import Control.Concurrent.MVar (newEmptyMVar, putMVar, readMVar)+import Control.Exception (SomeException, bracket_, catch,+ mask, onException, try)+import Control.Monad (Monad(..), unless, when)+import System.Directory (createDirectory, makeAbsolute,+ removeDirectoryRecursive, withCurrentDirectory)+import System.Exit (exitFailure)+import System.FilePath (FilePath, normalise)+import System.IO (IO, hFlush, hPutStrLn, putStrLn, stderr, stdout)+import System.IO.Error (IOError, isDoesNotExistError,+ ioError, tryIOError, userError)+import System.Timeout (timeout)++modifyIORef' :: IORef a -> (a -> a) -> IO ()+modifyIORef' r f = do+ x <- readIORef r+ let !x' = f x in writeIORef r x'++tryAny :: IO a -> IO (Either SomeException a)+tryAny action = do+ result <- newEmptyMVar+ mask $ \ unmask -> do+ thread <- forkIO (try (unmask action) >>= putMVar result)+ unmask (readMVar result) `onException` killThread thread++timeLimit :: Double -> IO a -> IO a+timeLimit time action = do+ result <- timeout (round (1000000 * time)) action+ case result of+ Nothing -> ioError (userError "timed out")+ Just x -> return x++data TestEnv =+ TestEnv+ { testCounter :: IORef Int+ , testSilent :: Bool+ , testKeepDirs :: Bool+ }++defaultTestEnv :: IORef Int -> TestEnv+defaultTestEnv counter =+ TestEnv+ { testCounter = counter+ , testSilent = False+ , testKeepDirs = False+ }++showSuccess :: TestEnv -> [String] -> IO ()+showSuccess TestEnv{testSilent = True} _ = return ()+showSuccess TestEnv{testSilent = False} msg = do+ putStrLn (intercalate ": " msg)+ hFlush stdout++showFailure :: TestEnv -> [String] -> IO ()+showFailure TestEnv{testCounter = n} msg = do+ modifyIORef' n (+ 1)+ hPutStrLn stderr ("*** " <> intercalate ": " msg)+ hFlush stderr++check :: TestEnv -> Bool -> [String] -> [String] -> [String] -> IO ()+check t True prefix msg _ = showSuccess t (prefix <> msg)+check t False prefix _ msg = showFailure t (prefix <> msg)++checkEither :: TestEnv -> [String] -> Either [String] [String] -> IO ()+checkEither t prefix (Right msg) = showSuccess t (prefix <> msg)+checkEither t prefix (Left msg) = showFailure t (prefix <> msg)++showContext :: Show a => String -> Integer -> a -> String+showContext file line context =+ file <> ":" <> show line <>+ case show context of+ "()" -> ""+ s -> ":" <> s++expect :: Show a => TestEnv -> String -> Integer -> a -> Bool -> IO ()+expect t file line context x =+ check t x+ [showContext file line context]+ ["True"]+ ["False, but True was expected"]++expectEq :: (Eq a, Show a, Show b) =>+ TestEnv -> String -> Integer -> b -> a -> a -> IO ()+expectEq t file line context x y =+ check t (x == y)+ [showContext file line context]+ [show x <> " equals " <> show y]+ [show x <> " is not equal to " <> show y]++expectNear :: (Num a, Ord a, Show a, Show b) =>+ TestEnv -> String -> Integer -> b -> a -> a -> a -> IO ()+expectNear t file line context x y diff =+ check t (abs (x - y) <= diff)+ [showContext file line context]+ [show x <> " is near " <> show y]+ [show x <> " is not near " <> show y]++expectNearTime :: Show a =>+ TestEnv -> String -> Integer -> a ->+ UTCTime -> UTCTime -> NominalDiffTime -> IO ()+expectNearTime t file line context x y diff =+ check t (abs (diffUTCTime x y) <= diff)+ [showContext file line context]+ [show x <> " is near " <> show y]+ [show x <> " is not near " <> show y]++expectIOErrorType :: Show a =>+ TestEnv -> String -> Integer -> a+ -> (IOError -> Bool) -> IO b -> IO ()+expectIOErrorType t file line context which action = do+ result <- tryIOError action+ checkEither t [showContext file line context] $ case result of+ Left e | which e -> Right ["got expected exception (" <> show e <> ")"]+ | otherwise -> Left ["got wrong exception: ", show e]+ Right _ -> Left ["did not throw an exception"]++withNewDirectory :: FilePath -> IO a -> IO a+withNewDirectory dir action = do+ dir' <- makeAbsolute dir+ bracket_ (createDirectory dir')+ (removeDirectoryRecursive dir') action++isolateWorkingDirectory :: FilePath -> IO a -> IO a+isolateWorkingDirectory dir action = do+ when (normalise dir `elem` [".", "./"]) $+ ioError (userError ("isolateWorkingDirectory cannot be used " <>+ "with current directory"))+ dir' <- makeAbsolute dir+ removeDirectoryRecursive dir' `catch` \ e ->+ unless (isDoesNotExistError e) $+ ioError e+ withNewDirectory dir' $+ withCurrentDirectory dir' $+ action++run :: TestEnv -> String -> (TestEnv -> IO ()) -> IO ()+run t name action = do+ result <- tryAny (action t)+ case result of+ Left e -> check t False [name] [] ["exception", show e]+ Right () -> return ()++isolatedRun :: TestEnv -> String -> (TestEnv -> IO ()) -> IO ()+isolatedRun t name action = do+ run t name (isolateWorkingDirectory ("test-" <> name <> ".tmp") . action)++testMain :: (TestEnv -> IO ()) -> IO ()+testMain action = do+ counter <- newIORef 0+ action (defaultTestEnv counter)+ n <- readIORef (counter)+ unless (n == 0) $ do+ putStrLn ("[" <> show n <> " failures]")+ hFlush stdout+ exitFailure
+ tests/WithCurrentDirectory.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE CPP #-}+module WithCurrentDirectory where+#include "util.inl"+import Data.Monoid ((<>))+import Data.List (sort)+import System.Directory+import System.FilePath ((</>))++main :: TestEnv -> IO ()+main _t = do+ createDirectory dir+ -- Make sure we're starting empty+ T(expectEq) () specials . sort =<< getDirectoryContents dir+ cwd <- getCurrentDirectory+ withCurrentDirectory dir (writeFile testfile contents)+ -- Are we still in original directory?+ T(expectEq) () cwd =<< getCurrentDirectory+ -- Did the test file get created?+ T(expectEq) () (specials <> [testfile]) . sort =<< getDirectoryContents dir+ -- Does the file contain what we expected to write?+ T(expectEq) () contents =<< readFile (dir </> testfile)+ where+ testfile = "testfile"+ contents = "some data\n"+ dir = "dir"+ specials = [".", ".."]
− tests/all.T
@@ -1,32 +0,0 @@-test('canonicalizePath001', normal, compile_and_run, [''])-test('currentDirectory001', normal, compile_and_run, [''])-test('directory001', normal, compile_and_run, [''])-test('doesDirectoryExist001', normal, compile_and_run, [''])--# This test is a bit bogus. Disable for GHCi.-test('getDirContents001', omit_ways(['ghci']), compile_and_run, ['-fno-gen-manifest'])--test('getDirContents002', [ normalise_exe, exit_code(1) ],- compile_and_run, [''])--# Depends on binary from previous run, which gets removed by the driver way=ghci-test('getPermissions001', omit_ways(['ghci']), compile_and_run, ['-cpp'])--test('copyFile001', extra_clean(['copyFile001dir/target']),- compile_and_run, [''])-test('copyFile002', extra_clean(['copyFile002dir/target']),- compile_and_run, [''])--test('renameFile001', extra_clean(['renameFile001.tmp1','renameFile001.tmp2']),- compile_and_run, [''])--test('createDirectory001', normal, compile_and_run, [''])--test('createDirectoryIfMissing001', normal, compile_and_run, [''])--# No sane way to tell whether the output is reasonable here...-test('getHomeDirectory001', ignore_output, compile_and_run, [''])--test('T8482', normal, compile_and_run, [''])--test('removeDirectoryRecursive001', normal, compile_and_run, [''])
− tests/canonicalizePath001.hs
@@ -1,8 +0,0 @@-module Main (main) where-import System.Directory-import System.IO.Error (catchIOError)--main = do- dot <- canonicalizePath "."- nul <- canonicalizePath "" `catchIOError` \ _ -> return ""- print (dot == nul)
− tests/canonicalizePath001.stdout
@@ -1,1 +0,0 @@-True
− tests/copyFile001.hs
@@ -1,26 +0,0 @@--module Main (main) where--import Control.Exception-import Data.List-import System.Directory-import System.IO--main :: IO ()-main = do tryIO $ removeFile to- cs_before <- getDirectoryContents "copyFile001dir"- putStrLn "Before:"- print $ sort cs_before- copyFile from to- cs_before <- getDirectoryContents "copyFile001dir"- putStrLn "After:"- print $ sort cs_before- readFile to >>= print--tryIO :: IO a -> IO (Either IOException a)-tryIO = try--from, to :: FilePath-from = "copyFile001dir/source"-to = "copyFile001dir/target"-
− tests/copyFile001.stdout
@@ -1,5 +0,0 @@-Before:-[".","..","source"]-After:-[".","..","source","target"]-"This is the data"
− tests/copyFile001dir/source
@@ -1,1 +0,0 @@-This is the data
− tests/copyFile002.hs
@@ -1,31 +0,0 @@--module Main (main) where--import Control.Exception-import Data.List-import System.Directory-import System.IO---- like copyFile001, but moves a file in the current directory--- See bug #1652-main :: IO ()-main = do d <- getCurrentDirectory- flip finally (setCurrentDirectory d) $ do- setCurrentDirectory "copyFile002dir"- tryIO $ removeFile to- cs_before <- getDirectoryContents "."- putStrLn "Before:"- print $ sort cs_before- copyFile from to- cs_before <- getDirectoryContents "."- putStrLn "After:"- print $ sort cs_before- readFile to >>= print--tryIO :: IO a -> IO (Either IOException a)-tryIO = try--from, to :: FilePath-from = "source"-to = "target"-
− tests/copyFile002.stdout
@@ -1,5 +0,0 @@-Before:-[".","..","source"]-After:-[".","..","source","target"]-"This is the data"
− tests/copyFile002dir/source
@@ -1,1 +0,0 @@-This is the data
− tests/createDirectory001.hs
@@ -1,12 +0,0 @@-import System.Directory -import Control.Exception - -testdir = "createDirectory001.dir" - -main = do - try (removeDirectory testdir) :: IO (Either IOException ()) - createDirectory testdir - r <- try $ createDirectory testdir - print (r :: Either IOException ()) -- already exists - removeDirectory testdir -
− tests/createDirectory001.stdout
@@ -1,1 +0,0 @@-Left createDirectory001.dir: createDirectory: already exists (File exists)
− tests/createDirectory001.stdout-mingw32
@@ -1,1 +0,0 @@-Left CreateDirectory "createDirectory001.dir": already exists (Cannot create a file when that file already exists.)
− tests/createDirectoryIfMissing001.hs
@@ -1,79 +0,0 @@-module Main(main) where--import Control.Concurrent-import Control.Monad-import Control.Exception as E-import System.Directory-import System.FilePath-import System.IO.Error--testdir = "createDirectoryIfMissing001.d"-testdir_a = testdir </> "a"--main = do- cleanup-- report $ createDirectoryIfMissing False testdir- cleanup-- report $ createDirectoryIfMissing False testdir_a- -- should fail with does not exist-- report $ createDirectoryIfMissing True testdir_a- -- should succeed with no error- report $ createDirectoryIfMissing False testdir_a- -- should succeed with no error- report $ createDirectoryIfMissing False (addTrailingPathSeparator testdir_a)- -- should succeed with no error-- cleanup- report $ createDirectoryIfMissing True (addTrailingPathSeparator testdir_a)-- -- look for race conditions: #2808. This fails with- -- +RTS -N2 and directory 1.0.0.2.- m <- newEmptyMVar- forkIO $ do replicateM_ 10000 create; putMVar m ()- forkIO $ do replicateM_ 10000 cleanup; putMVar m ()- replicateM_ 2 $ takeMVar m---- This test fails on Windows; see #2924--- replicateM_ 2 $ --- forkIO $ do replicateM_ 5000 (do create; cleanup); putMVar m ()--- replicateM_ 2 $ takeMVar m-- cleanup-- -- these are all supposed to fail-- writeFile testdir testdir- report $ createDirectoryIfMissing False testdir- removeFile testdir- cleanup-- writeFile testdir testdir- report $ createDirectoryIfMissing True testdir_a- removeFile testdir- cleanup---- createDirectoryIfMissing is allowed to fail with isDoesNotExistError if--- another process/thread removes one of the directories during the proces--- of creating the hierarchy.------ It is also allowed to fail with permission errors (see #2924)-create = tryJust (guard . (\e -> isDoesNotExistError e || isPermissionError e)) $ createDirectoryIfMissing True testdir_a--cleanup = ignore $ removeDirectoryRecursive testdir--report :: Show a => IO a -> IO ()-report io = do- r <- E.try io- case r of- Left e -> print (e :: SomeException)- Right a -> print a--ignore :: IO a -> IO ()-ignore io = do- r <- E.try io- case r of- Left e -> let _ = e :: SomeException in return ()- Right a -> return ()
− tests/createDirectoryIfMissing001.stdout
@@ -1,8 +0,0 @@-()-createDirectoryIfMissing001.d/a: createDirectory: does not exist (No such file or directory)-()-()-()-()-createDirectoryIfMissing001.d: createDirectory: already exists (File exists)-createDirectoryIfMissing001.d/a: createDirectory: inappropriate type (Not a directory)
− tests/createDirectoryIfMissing001.stdout-mingw32
@@ -1,8 +0,0 @@-()-CreateDirectory "createDirectoryIfMissing001.d\\a": does not exist (The system cannot find the path specified.)-()-()-()-()-CreateDirectory "createDirectoryIfMissing001.d": already exists (Cannot create a file when that file already exists.)-CreateDirectory "createDirectoryIfMissing001.d": already exists (Cannot create a file when that file already exists.)
− tests/currentDirectory001.hs
@@ -1,27 +0,0 @@--import System.Directory (getCurrentDirectory, setCurrentDirectory,- createDirectory, removeDirectory,- getDirectoryContents)--main :: IO ()-main = do- oldpwd <- getCurrentDirectory- createDirectory dir- setCurrentDirectory dir- ~[n1, n2] <- getDirectoryContents "."- if dot n1 && dot n2 - then do- setCurrentDirectory oldpwd- removeDirectory dir- putStr "Okay\n"- else- ioError (userError "Oops")--dot :: String -> Bool-dot "." = True-dot ".." = True-dot _ = False--dir :: FilePath-dir = "currentDirectory001-dir"-
− tests/currentDirectory001.stdout
@@ -1,1 +0,0 @@-Okay
− tests/directory001.hs
@@ -1,16 +0,0 @@-import System.IO-import System.Directory--main = do- createDirectory "foo"- h <- openFile "foo/bar" WriteMode- hPutStr h "Okay\n"- hClose h- renameFile "foo/bar" "foo/baz"- renameDirectory "foo" "bar"- h <- openFile "bar/baz" ReadMode- stuff <- hGetContents h- putStr stuff--- hClose h -- an error !- removeFile "bar/baz"- removeDirectory "bar"
− tests/directory001.stdout
@@ -1,1 +0,0 @@-Okay
− tests/doesDirectoryExist001.hs
@@ -1,11 +0,0 @@-{-# LANGUAGE CPP #-}--- !!! "/" was not recognised as a directory in 6.0.x-import System.Directory--#ifdef mingw32_HOST_OS-root = "C:\\"-#else-root = "/"-#endif--main = doesDirectoryExist root >>= print
− tests/doesDirectoryExist001.stdout
@@ -1,1 +0,0 @@-True
− tests/getDirContents001.hs
@@ -1,18 +0,0 @@-import System.Directory-import Control.Exception-import System.FilePath-import Data.List--dir = "getDirContents001.dir"--main = do- try cleanup :: IO (Either IOException ())- bracket (createDirectory dir) (const cleanup) $ \_ -> do- getDirectoryContents dir >>= print . sort- mapM_ (\s -> writeFile (dir </> ('f':show s)) (show s)) [1..100]- getDirectoryContents dir >>= print . sort--cleanup = do- files <- getDirectoryContents dir- mapM_ (removeFile . (dir </>)) (filter (not . ("." `isPrefixOf`)) files)- removeDirectory dir
− tests/getDirContents001.stdout
@@ -1,2 +0,0 @@-[".",".."]-[".","..","f1","f10","f100","f11","f12","f13","f14","f15","f16","f17","f18","f19","f2","f20","f21","f22","f23","f24","f25","f26","f27","f28","f29","f3","f30","f31","f32","f33","f34","f35","f36","f37","f38","f39","f4","f40","f41","f42","f43","f44","f45","f46","f47","f48","f49","f5","f50","f51","f52","f53","f54","f55","f56","f57","f58","f59","f6","f60","f61","f62","f63","f64","f65","f66","f67","f68","f69","f7","f70","f71","f72","f73","f74","f75","f76","f77","f78","f79","f8","f80","f81","f82","f83","f84","f85","f86","f87","f88","f89","f9","f90","f91","f92","f93","f94","f95","f96","f97","f98","f99"]
− tests/getDirContents002.hs
@@ -1,3 +0,0 @@-import System.Directory - -main = getDirectoryContents "nonexistent"
− tests/getDirContents002.stderr
@@ -1,1 +0,0 @@-getDirContents002: nonexistent: getDirectoryContents: does not exist (No such file or directory)
− tests/getDirContents002.stderr-mingw32
@@ -1,1 +0,0 @@-getDirContents002.exe: nonexistent: getDirectoryContents: does not exist (The system cannot find the path specified.)
− tests/getHomeDirectory001.hs
@@ -1,8 +0,0 @@-import System.Directory - -main = do - getHomeDirectory >>= print - getAppUserDataDirectory "test" >>= print - getUserDocumentsDirectory >>= print - getTemporaryDirectory >>= print - return ()
− tests/getPermissions001.hs
@@ -1,20 +0,0 @@-{-# LANGUAGE CPP #-}-import System.Directory--main = do-#ifdef mingw32_HOST_OS- let exe = ".exe"-#else- let exe = ""-#endif- p <- getPermissions "."- print p- p <- getPermissions "getPermissions001.hs"- print p- p <- getPermissions ("getPermissions001" ++ exe)- print p-- -- issue #9: Windows doesn't like trailing path separators- _ <- getPermissions "../tests/"-- return ()
− tests/getPermissions001.stdout
@@ -1,3 +0,0 @@-Permissions {readable = True, writable = True, executable = False, searchable = True}-Permissions {readable = True, writable = True, executable = False, searchable = False}-Permissions {readable = True, writable = True, executable = True, searchable = False}
− tests/getPermissions001.stdout-alpha-dec-osf3
@@ -1,3 +0,0 @@-Permissions {readable = True, writable = True, executable = False, searchable = True}-Permissions {readable = True, writable = True, executable = False, searchable = False}-Permissions {readable = True, writable = False, executable = True, searchable = False}
− tests/getPermissions001.stdout-i386-unknown-freebsd
@@ -1,3 +0,0 @@-Permissions {readable = True, writable = True, executable = False, searchable = True}-Permissions {readable = True, writable = True, executable = False, searchable = False}-Permissions {readable = True, writable = False, executable = True, searchable = False}
− tests/getPermissions001.stdout-i386-unknown-openbsd
@@ -1,3 +0,0 @@-Permissions {readable = True, writable = True, executable = False, searchable = True}-Permissions {readable = True, writable = True, executable = False, searchable = False}-Permissions {readable = True, writable = False, executable = True, searchable = False}
− tests/getPermissions001.stdout-mingw
@@ -1,3 +0,0 @@-Permissions {readable = True, writable = True, executable = True, searchable = True}-Permissions {readable = True, writable = True, executable = True, searchable = True}-Permissions {readable = True, writable = True, executable = True, searchable = True}
− tests/getPermissions001.stdout-x86_64-unknown-openbsd
@@ -1,3 +0,0 @@-Permissions {readable = True, writable = True, executable = False, searchable = True}-Permissions {readable = True, writable = True, executable = False, searchable = False}-Permissions {readable = True, writable = False, executable = True, searchable = False}
− tests/removeDirectoryRecursive001.hs
@@ -1,93 +0,0 @@-{-# LANGUAGE CPP #-}-module Main (main) where-import Data.List (sort)-import System.Directory-import System.FilePath ((</>), normalise)-import System.IO.Error (catchIOError)-import TestUtils--testName :: String-testName = "removeDirectoryRecursive001"--tmpD :: String-tmpD = testName ++ ".tmp"--tmp :: String -> String-tmp s = tmpD </> normalise s--main :: IO ()-main = do-- ------------------------------------------------------------- -- clean up junk from previous invocations-- modifyPermissions (tmp "c") (\ p -> p { writable = True })- `catchIOError` \ _ -> return ()- removeDirectoryRecursive tmpD- `catchIOError` \ _ -> return ()-- ------------------------------------------------------------- -- set up-- createDirectoryIfMissing True (tmp "a/x/w")- createDirectoryIfMissing True (tmp "a/y")- createDirectoryIfMissing True (tmp "a/z")- createDirectoryIfMissing True (tmp "b")- createDirectoryIfMissing True (tmp "c")- writeFile (tmp "a/x/w/u") "foo"- writeFile (tmp "a/t") "bar"- tryCreateSymbolicLink (normalise "../a") (tmp "b/g")- tryCreateSymbolicLink (normalise "../b") (tmp "c/h")- tryCreateSymbolicLink (normalise "a") (tmp "d")- modifyPermissions (tmp "c") (\ p -> p { writable = False })-- ------------------------------------------------------------- -- tests-- getDirectoryContents tmpD >>= putStrLn . unwords . sort- getDirectoryContents (tmp "a") >>= putStrLn . unwords . sort- getDirectoryContents (tmp "b") >>= putStrLn . unwords . sort- getDirectoryContents (tmp "c") >>= putStrLn . unwords . sort- getDirectoryContents (tmp "d") >>= putStrLn . unwords . sort-- putStrLn ""-- removeDirectoryRecursive (tmp "d")- `catchIOError` \ _ -> removeFile (tmp "d")-#ifdef mingw32_HOST_OS- `catchIOError` \ _ -> removeDirectory (tmp "d")-#endif-- getDirectoryContents tmpD >>= putStrLn . unwords . sort- getDirectoryContents (tmp "a") >>= putStrLn . unwords . sort- getDirectoryContents (tmp "b") >>= putStrLn . unwords . sort- getDirectoryContents (tmp "c") >>= putStrLn . unwords . sort-- putStrLn ""-- removeDirectoryRecursive (tmp "c")- `catchIOError` \ _ -> do- modifyPermissions (tmp "c") (\ p -> p { writable = True })- removeDirectoryRecursive (tmp "c")-- getDirectoryContents tmpD >>= putStrLn . unwords . sort- getDirectoryContents (tmp "a") >>= putStrLn . unwords . sort- getDirectoryContents (tmp "b") >>= putStrLn . unwords . sort-- putStrLn ""-- removeDirectoryRecursive (tmp "b")-- getDirectoryContents tmpD >>= putStrLn . unwords . sort- getDirectoryContents (tmp "a") >>= putStrLn . unwords . sort-- putStrLn ""-- removeDirectoryRecursive (tmp "a")-- getDirectoryContents tmpD >>= putStrLn . unwords . sort-- ------------------------------------------------------------- -- clean up-- removeDirectoryRecursive tmpD
− tests/removeDirectoryRecursive001.stdout
@@ -1,19 +0,0 @@-. .. a b c d-. .. t x y z-. .. g-. .. h-. .. t x y z--. .. a b c-. .. t x y z-. .. g-. .. h--. .. a b-. .. t x y z-. .. g--. .. a-. .. t x y z--. ..
− tests/renameFile001.hs
@@ -1,13 +0,0 @@-import System.Directory - -tmp1 = "renameFile001.tmp1" -tmp2 = "renameFile001.tmp2" - -main = do - writeFile tmp1 "test" - renameFile tmp1 tmp2 - readFile tmp2 >>= print - writeFile tmp1 "test2" - renameFile tmp2 tmp1 - readFile tmp1 >>= print -
− tests/renameFile001.stdout
@@ -1,2 +0,0 @@-"test"-"test"
+ tests/util.inl view
@@ -0,0 +1,4 @@+#define T(expect) (T./**/expect _t __FILE__ __LINE__)++import Util (TestEnv)+import qualified Util as T
− tools/dispatch-tests.hs
@@ -1,67 +0,0 @@-{-# LANGUAGE CPP, ForeignFunctionInterface #-}-module Main (main) where-import Prelude (($), (.), (=<<), (==), Eq, IO, Int, String,- id, fromIntegral, otherwise, unwords)-import Data.Functor ((<$>))-import Data.Monoid ((<>), mconcat)-import Foreign (Ptr)-import Foreign.C (CChar(..), CInt(..), withCString)-import System.Directory () -- to ensure `directory` is built beforehand-import System.Environment (getArgs)-import System.Exit (ExitCode(ExitSuccess, ExitFailure), exitWith)--main :: IO ()-main = do-- -- check if 'cabal exec' is supported (didn't exist until 1.20)- cabalExecTest <- rawSystem "sh" ["-c", "cabal >/dev/null 2>&1 exec true"]-- -- execute in the Cabal sandbox environment if possible- let prefix = case cabalExecTest of- ExitSuccess -> ["cabal", "exec", "--"]- ExitFailure _ -> []-- args <- getArgs- let command : arguments = prefix <> ["sh", "tools/run-tests"] <> args- exitWith =<< normalizeExitCode <$> rawSystem command arguments--makeExitCode :: Int -> ExitCode-makeExitCode 0 = ExitSuccess-makeExitCode e = ExitFailure e---- on Linux the exit code is right-shifted by 8 bits, causing exit codes to be--- rather large; older versions of GHC don't seem to handle that well in--- `exitWith`-normalizeExitCode :: ExitCode -> ExitCode-normalizeExitCode ExitSuccess = ExitSuccess-normalizeExitCode (ExitFailure _) = ExitFailure 1---- we can't use the `process` library as it causes a dependency cycle with--- Cabal, so we reinvent the wheel here in a simplistic way; this will--- probably break with non-ASCII characters on Windows-rawSystem :: String -> [String] -> IO ExitCode-rawSystem cmd args =- withCString (quoteCmdArgs (cmd : args)) $ \ c_command ->- makeExitCode . fromIntegral <$> c_system c_command---- handle the different quoting rules in CMD.EXE vs POSIX shells-quoteCmdArgs :: [String] -> String-quoteCmdArgs cmdArgs =-#ifdef mingw32_HOST_OS- -- the arcane quoting rules require us to add an extra set of quotes- -- around the entire thing: see `help cmd` or look at- -- https://superuser.com/a/238813- let quote s = "\"" <> replaceElem '"' "\"\"" s <> "\""- in (\ s -> "\"" <> s <> "\"") $-#else- let quote s = "'" <> replaceElem '\'' "'\\''" s <> "'"- in id $-#endif- unwords (quote <$> cmdArgs)--replaceElem :: Eq a => a -> [a] -> [a] -> [a]-replaceElem match repl = mconcat . (replace <$>)- where replace c | c == match = repl- | otherwise = [c]--foreign import ccall safe "stdlib.h system" c_system :: Ptr CChar -> IO CInt
− tools/ghc-test-framework.LICENSE
@@ -1,44 +0,0 @@-The Glasgow Haskell Compiler License--Copyright 2002, The University Court of the University of Glasgow. -All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are met:--- Redistributions of source code must retain the above copyright notice,-this list of conditions and the following disclaimer.- -- Redistributions in binary form must reproduce the above copyright notice,-this list of conditions and the following disclaimer in the documentation-and/or other materials provided with the distribution.- -- Neither name of the University nor the names of its contributors may be-used to endorse or promote products derived from this software without-specific prior written permission. --THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF-GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE-UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH-DAMAGE.--================================================================================-The GHC testsuite contains several files under different licenses, explained-here:-- The following tests are under the GPLv3, or (at your option) any later version:-- - tests/indexed-types/should_compile/T3787.hs- - tests/typecheck/should_compile/T4524.hs- - tests/simplCore/should_run/T3591.hs-- You should have received a copy of the GNU General Public License along with- the GHC testsuite, in LICENSE.GPL
− tools/ghc-test-framework.shar
@@ -1,4253 +0,0 @@-#!/bin/sh-# from ghc commit 6b96eeb72a17e35c59830952732170d29d99a598--mkdir -p 'ghc-test-framework/config'-sed "s/^ //" <<"EOF" >'ghc-test-framework/config/bad.ps'- This is a bad postscript file-EOF-chmod 644 'ghc-test-framework/config/bad.ps'--mkdir -p 'ghc-test-framework/config'-sed "s/^ //" <<"EOF" >'ghc-test-framework/config/ghc'- import os- import re-- # Testsuite configuration setup for GHC- #- # This file is Python source- #- config.compiler_type = 'ghc'- config.compiler = 'ghc'- config.compiler_always_flags = ghc_compiler_always_flags.split()-- config.hp2ps = 'hp2ps'- config.hpc = 'hpc'- config.gs = 'gs'- config.confdir = '.'-- # By default, the 'normal' and 'hpc' ways are enabled. In addition, certain- # ways are enabled automatically if this GHC supports them. Ways that fall in- # this group are 'optasm', 'optllvm', 'profasm', 'threaded1', 'threaded2',- # 'profthreaded', 'ghci', and whichever of 'static/dyn' is not this GHC's- # default mode. Other ways should be set explicitly from .T files.- config.compile_ways = ['normal', 'hpc']- config.run_ways = ['normal', 'hpc']-- # ways that are not enabled by default, but can always be invoked explicitly- config.other_ways = ['prof',- 'prof_hc_hb','prof_hb',- 'prof_hd','prof_hy','prof_hr',- 'threaded1_ls', 'threaded2_hT',- 'llvm', 'debugllvm',- 'profllvm', 'profoptllvm', 'profthreadedllvm',- 'debug']-- if (ghc_with_native_codegen == 1):- config.compile_ways.append('optasm')- config.run_ways.append('optasm')-- config.compiler_debugged = ghc_debugged-- if (ghc_with_vanilla == 1):- config.have_vanilla = True-- if (ghc_with_dynamic == 1):- config.have_dynamic = True-- if (ghc_with_profiling == 1):- config.have_profiling = True- config.compile_ways.append('profasm')- config.run_ways.append('profasm')-- if (ghc_with_interpreter == 1):- config.have_interp = True- config.run_ways.append('ghci')-- config.unregisterised = (ghc_unregisterised == 1)-- if (ghc_with_threaded_rts == 1):- config.run_ways.append('threaded1')- if (ghc_with_smp == 1):- config.have_smp = True- config.run_ways.append('threaded2')-- if (ghc_with_dynamic_rts == 1):- config.have_shared_libs = True-- config.ghc_dynamic_by_default = ghc_dynamic_by_default- if ghc_dynamic_by_default and ghc_with_vanilla == 1:- config.run_ways.append('static')- else:- if (ghc_with_dynamic_rts == 1):- config.run_ways.append('dyn')-- config.ghc_dynamic = ghc_dynamic-- if (ghc_with_profiling == 1 and ghc_with_threaded_rts == 1):- config.run_ways.append('profthreaded')-- if (ghc_with_llvm == 1):- config.compile_ways.append('optllvm')- config.run_ways.append('optllvm')-- config.in_tree_compiler = in_tree_compiler- config.clean_only = clean_only-- config.way_flags = lambda name : {- 'normal' : [],- 'g1' : [],- 'optasm' : ['-O', '-fasm'],- 'llvm' : ['-fllvm'],- 'optllvm' : ['-O', '-fllvm'],- 'debugllvm' : ['-fllvm', '-keep-llvm-files'],- 'prof' : ['-prof', '-static', '-auto-all', '-fasm'],- 'profasm' : ['-O', '-prof', '-static', '-auto-all'],- 'profthreaded' : ['-O', '-prof', '-static', '-auto-all', '-threaded'],- 'ghci' : ['--interactive', '-v0', '-ignore-dot-ghci', '+RTS', '-I0.1', '-RTS'],- 'threaded1' : ['-threaded', '-debug'],- 'threaded1_ls' : ['-threaded', '-debug'],- 'threaded2' : ['-O', '-threaded', '-eventlog'],- 'threaded2_hT' : ['-O', '-threaded'],- 'hpc' : ['-O', '-fhpc', '-hpcdir', '.hpc.' + name ],- 'prof_hc_hb' : ['-O', '-prof', '-static', '-auto-all'],- 'prof_hb' : ['-O', '-prof', '-static', '-auto-all'],- 'prof_hd' : ['-O', '-prof', '-static', '-auto-all'],- 'prof_hy' : ['-O', '-prof', '-static', '-auto-all'],- 'prof_hr' : ['-O', '-prof', '-static', '-auto-all'],- 'dyn' : ['-O', '-dynamic'],- 'static' : ['-O', '-static'],- 'debug' : ['-O', '-g', '-dannot-lint'],- # llvm variants...- 'profllvm' : ['-prof', '-static', '-auto-all', '-fllvm'],- 'profoptllvm' : ['-O', '-prof', '-static', '-auto-all', '-fllvm'],- 'profthreadedllvm' : ['-O', '-prof', '-static', '-auto-all', '-threaded', '-fllvm'],- }-- config.way_rts_flags = { - 'normal' : [],- 'g1' : ['-G1'],- 'optasm' : [],- 'llvm' : [],- 'optllvm' : [],- 'debugllvm' : [],- 'prof' : ['-p'],- 'profasm' : ['-hc', '-p'], # test heap profiling too- 'profthreaded' : ['-p'],- 'ghci' : [],- 'threaded1' : [],- 'threaded1_ls' : ['-ls'],- 'threaded2' : ['-N2 -ls'],- 'threaded2_hT' : ['-N2', '-hT'],- 'hpc' : [],- 'prof_hc_hb' : ['-hc -hbvoid'],- 'prof_hb' : ['-hb'],- 'prof_hd' : ['-hd'],- 'prof_hy' : ['-hy'],- 'prof_hr' : ['-hr'],- 'dyn' : [],- 'static' : [],- 'debug' : [],- # llvm variants...- 'profllvm' : ['-p'],- 'profoptllvm' : ['-hc', '-p'],- 'profthreadedllvm' : ['-p'],- }-- # Useful classes of ways that can be used with only_ways() and- # expect_broken_for().-- prof_ways = [x[0] for x in config.way_flags('dummy_name').items()- if '-prof' in x[1]]-- threaded_ways = [x[0] for x in config.way_flags('dummy_name').items()- if '-threaded' in x[1] or 'ghci' == x[0]]-- opt_ways = [x[0] for x in config.way_flags('dummy_name').items()- if '-O' in x[1]]-- llvm_ways = [x[0] for x in config.way_flags('dummy_name').items()- if '-fflvm' in x[1]]-- def get_compiler_info():- # This should really not go through the shell- h = os.popen(config.compiler + ' --info', 'r')- s = h.read()- s = re.sub('[\r\n]', '', s)- h.close()- compilerInfoDict = dict(eval(s))- h = os.popen(config.compiler + ' +RTS --info', 'r')- s = h.read()- s = re.sub('[\r\n]', '', s)- h.close()- rtsInfoDict = dict(eval(s))-- # We use a '/'-separated path for libdir, even on Windows- config.libdir = re.sub('\\\\','/',compilerInfoDict['LibDir'])-- v = compilerInfoDict["Project version"].split('-')- config.compiler_version = v[0]- config.compiler_maj_version = re.sub('^([0-9]+\.[0-9]+).*',r'\1', v[0])- config.compiler_tags = v[1:]-- # -fno-ghci-history was added in 7.3- if version_ge(config.compiler_version, '7.3'):- config.compiler_always_flags = \- config.compiler_always_flags + ['-fno-ghci-history']-- if re.match(".*_p(_.*|$)", rtsInfoDict["RTS way"]):- config.compiler_profiled = True- config.run_ways = [x for x in config.run_ways if x != 'ghci']- else:- config.compiler_profiled = False-- try:- config.package_conf_cache_file = compilerInfoDict["Global Package DB"] + '/package.cache'- except:- config.package_conf_cache_file = ''-- try:- if compilerInfoDict["GHC Dynamic"] == "YES":- ghcDynamic = True- elif compilerInfoDict["GHC Dynamic"] == "NO":- ghcDynamic = False- else:- raise 'Bad value for "GHC Dynamic"'- except KeyError:- # GHC < 7.7 doesn't have a "GHC Dynamic" field- ghcDynamic = False-- if ghcDynamic:- config.ghc_th_way_flags = "-dynamic"- config.ghci_way_flags = "-dynamic"- config.ghc_th_way = "dyn"- config.ghc_plugin_way = "dyn"- else:- config.ghc_th_way_flags = "-static"- config.ghci_way_flags = "-static"- config.ghc_th_way = "normal"- config.ghc_plugin_way = "normal"--EOF-chmod 644 'ghc-test-framework/config/ghc'--mkdir -p 'ghc-test-framework/config'-sed "s/^ //" <<"EOF" >'ghc-test-framework/config/good.ps'- % this is a good postscript file-EOF-chmod 644 'ghc-test-framework/config/good.ps'--mkdir -p 'ghc-test-framework/driver'-sed "s/^ //" <<"EOF" >'ghc-test-framework/driver/runtests.py'- # - # (c) Simon Marlow 2002- #-- from __future__ import print_function-- import sys- import os- import string- import getopt- import platform- import time- import re-- # We don't actually need subprocess in runtests.py, but:- # * We do need it in testlibs.py- # * We can't import testlibs.py until after we have imported ctypes- # * If we import ctypes before subprocess on cygwin, then sys.exit(0)- # says "Aborted" and we fail with exit code 134.- # So we import it here first, so that the testsuite doesn't appear to fail.- try:- import subprocess- except:- pass-- PYTHON3 = sys.version_info >= (3, 0)- if PYTHON3:- print("*** WARNING: running testsuite using Python 3.\n"- "*** Python 3 support is experimental. See Trac #9184.")-- from testutil import *- from testglobals import *-- # Readline sometimes spews out ANSI escapes for some values of TERM,- # which result in test failures. Thus set TERM to a nice, simple, safe- # value.- os.environ['TERM'] = 'vt100'-- global config- config = getConfig() # get it from testglobals-- # ------------------------------------------------------------------------------ # cmd-line options-- long_options = [- "config=", # config file- "rootdir=", # root of tree containing tests (default: .)- "output-summary=", # file in which to save the (human-readable) summary- "only=", # just this test (can be give multiple --only= flags)- "way=", # just this way- "skipway=", # skip this way- "threads=", # threads to run simultaneously- "check-files-written", # check files aren't written by multiple tests- "verbose=", # verbose (0,1,2 so far)- "skip-perf-tests", # skip performance tests- ]-- opts, args = getopt.getopt(sys.argv[1:], "e:", long_options)- - for opt,arg in opts:- if opt == '--config':- exec(open(arg).read())-- # -e is a string to execute from the command line. For example:- # testframe -e 'config.compiler=ghc-5.04'- if opt == '-e':- exec(arg)-- if opt == '--rootdir':- config.rootdirs.append(arg)-- if opt == '--output-summary':- config.output_summary = arg-- if opt == '--only':- config.only.append(arg)-- if opt == '--way':- if (arg not in config.run_ways and arg not in config.compile_ways and arg not in config.other_ways):- sys.stderr.write("ERROR: requested way \'" +- arg + "\' does not exist\n")- sys.exit(1)- config.cmdline_ways = [arg] + config.cmdline_ways- if (arg in config.other_ways):- config.run_ways = [arg] + config.run_ways- config.compile_ways = [arg] + config.compile_ways-- if opt == '--skipway':- if (arg not in config.run_ways and arg not in config.compile_ways and arg not in config.other_ways):- sys.stderr.write("ERROR: requested way \'" +- arg + "\' does not exist\n")- sys.exit(1)- config.other_ways = [w for w in config.other_ways if w != arg]- config.run_ways = [w for w in config.run_ways if w != arg]- config.compile_ways = [w for w in config.compile_ways if w != arg]-- if opt == '--threads':- config.threads = int(arg)- config.use_threads = 1-- if opt == '--check-files-written':- config.check_files_written = True-- if opt == '--skip-perf-tests':- config.skip_perf_tests = True-- if opt == '--verbose':- if arg not in ["0","1","2","3","4"]:- sys.stderr.write("ERROR: requested verbosity %s not supported, use 0,1,2,3 or 4" % arg)- sys.exit(1)- config.verbose = int(arg)--- if config.use_threads == 1:- # Trac #1558 says threads don't work in python 2.4.4, but do- # in 2.5.2. Probably >= 2.5 is sufficient, but let's be- # conservative here.- # Some versions of python have things like '1c1' for some of- # these components (see trac #3091), but int() chokes on the- # 'c1', so we drop it.- (maj, min, pat) = platform.python_version_tuple()- # We wrap maj, min, and pat in str() to work around a bug in python- # 2.6.1- maj = int(re.sub('[^0-9].*', '', str(maj)))- min = int(re.sub('[^0-9].*', '', str(min)))- pat = int(re.sub('[^0-9].*', '', str(pat)))- if (maj, min) < (2, 6):- print("Python < 2.6 is not supported")- sys.exit(1)- # We also need to disable threads for python 2.7.2, because of- # this bug: http://bugs.python.org/issue13817- elif (maj, min, pat) == (2, 7, 2):- print("Warning: Ignoring request to use threads as python version is 2.7.2")- print("See http://bugs.python.org/issue13817 for details.")- config.use_threads = 0- if windows:- print("Warning: Ignoring request to use threads as running on Windows")- config.use_threads = 0-- config.cygwin = False- config.msys = False-- if windows:- h = os.popen('uname -s', 'r')- v = h.read()- h.close()- if v.startswith("CYGWIN"):- config.cygwin = True- elif v.startswith("MINGW") or v.startswith("MSYS"):- # msys gives "MINGW32"- # msys2 gives "MINGW_NT-6.2" or "MSYS_NT-6.3"- config.msys = True- else:- raise Exception("Can't detect Windows terminal type")-- # Try to use UTF8- if windows:- import ctypes- # Windows Python provides windll, mingw python provides cdll.- if hasattr(ctypes, 'windll'):- mydll = ctypes.windll- else:- mydll = ctypes.cdll-- # This actually leaves the terminal in codepage 65001 (UTF8) even- # after python terminates. We ought really remember the old codepage- # and set it back.- if mydll.kernel32.SetConsoleCP(65001) == 0:- raise Exception("Failure calling SetConsoleCP(65001)")- if mydll.kernel32.SetConsoleOutputCP(65001) == 0:- raise Exception("Failure calling SetConsoleOutputCP(65001)")- else:- # Try and find a utf8 locale to use- # First see if we already have a UTF8 locale- h = os.popen('locale | grep LC_CTYPE | grep -i utf', 'r')- v = h.read()- h.close()- if v == '':- # We don't, so now see if 'locale -a' works- h = os.popen('locale -a', 'r')- v = h.read()- h.close()- if v != '':- # If it does then use the first utf8 locale that is available- h = os.popen('locale -a | grep -i "utf8\|utf-8" 2>/dev/null', 'r')- v = h.readline().strip()- h.close()- if v != '':- os.environ['LC_ALL'] = v- print("setting LC_ALL to", v)- else:- print('WARNING: No UTF8 locale found.')- print('You may get some spurious test failures.')-- # This has to come after arg parsing as the args can change the compiler- get_compiler_info()-- # Can't import this earlier as we need to know if threading will be- # enabled or not- from testlib import *-- # On Windows we need to set $PATH to include the paths to all the DLLs- # in order for the dynamic library tests to work.- if windows or darwin:- pkginfo = getStdout([config.ghc_pkg, 'dump'])- topdir = config.libdir- for line in pkginfo.split('\n'):- if line.startswith('library-dirs:'):- path = line.rstrip()- path = re.sub('^library-dirs: ', '', path)- path = re.sub('\\$topdir', topdir, path)- if path.startswith('"'):- path = re.sub('^"(.*)"$', '\\1', path)- path = re.sub('\\\\(.)', '\\1', path)- if windows:- if config.cygwin:- # On cygwin we can't put "c:\foo" in $PATH, as : is a- # field separator. So convert to /cygdrive/c/foo instead.- # Other pythons use ; as the separator, so no problem.- path = re.sub('([a-zA-Z]):', '/cygdrive/\\1', path)- path = re.sub('\\\\', '/', path)- os.environ['PATH'] = os.pathsep.join([path, os.environ.get("PATH", "")])- else:- # darwin- os.environ['DYLD_LIBRARY_PATH'] = os.pathsep.join([path, os.environ.get("DYLD_LIBRARY_PATH", "")])-- global testopts_local- testopts_local.x = TestOptions()-- if config.use_threads:- t.lock = threading.Lock()- t.thread_pool = threading.Condition(t.lock)- t.lockFilesWritten = threading.Lock()- t.running_threads = 0-- # if timeout == -1 then we try to calculate a sensible value- if config.timeout == -1:- config.timeout = int(read_no_crs(config.top + '/timeout/calibrate.out'))-- print('Timeout is ' + str(config.timeout))-- # ------------------------------------------------------------------------------ # The main dude-- if config.rootdirs == []:- config.rootdirs = ['.']-- t_files = findTFiles(config.rootdirs)-- print('Found', len(t_files), '.T files...')-- t = getTestRun()-- # Avoid cmd.exe built-in 'date' command on Windows- t.start_time = time.localtime()-- print('Beginning test run at', time.strftime("%c %Z",t.start_time))-- sys.stdout.flush()- if PYTHON3:- # in Python 3, we output text, which cannot be unbuffered- sys.stdout = os.fdopen(sys.__stdout__.fileno(), "w")- else:- # set stdout to unbuffered (is this the best way to do it?)- sys.stdout = os.fdopen(sys.__stdout__.fileno(), "w", 0)-- # First collect all the tests to be run- for file in t_files:- if_verbose(2, '====> Scanning %s' % file)- newTestDir(os.path.dirname(file))- try:- exec(open(file).read())- except Exception:- print('*** framework failure: found an error while executing ', file, ':')- t.n_framework_failures = t.n_framework_failures + 1- traceback.print_exc()-- if config.list_broken:- global brokens- print('')- print('Broken tests:')- print(' '.join(map (lambda bdn: '#' + str(bdn[0]) + '(' + bdn[1] + '/' + bdn[2] + ')', brokens)))- print('')-- if t.n_framework_failures != 0:- print('WARNING:', str(t.n_framework_failures), 'framework failures!')- print('')- else:- # Now run all the tests- if config.use_threads:- t.running_threads=0- for oneTest in parallelTests:- if stopping():- break- oneTest()- if config.use_threads:- t.thread_pool.acquire()- while t.running_threads>0:- t.thread_pool.wait()- t.thread_pool.release()- config.use_threads = False- for oneTest in aloneTests:- if stopping():- break- oneTest()- - summary(t, sys.stdout)-- if config.output_summary != '':- summary(t, open(config.output_summary, 'w'))-- sys.exit(0)--EOF-chmod 644 'ghc-test-framework/driver/runtests.py'--mkdir -p 'ghc-test-framework/driver'-sed "s/^ //" <<"EOF" >'ghc-test-framework/driver/testglobals.py'- # - # (c) Simon Marlow 2002- #-- # ------------------------------------------------------------------------------ # Configuration info-- # There is a single global instance of this structure, stored in the- # variable config below. The fields of the structure are filled in by- # the appropriate config script(s) for this compiler/platform, in- # ../config.- # - # Bits of the structure may also be filled in from the command line,- # via the build system, using the '-e' option to runtests.-- class TestConfig:- def __init__(self):-- # Where the testsuite root is- self.top = ''-- # Directories below which to look for test description files (foo.T)- self.rootdirs = []-- # Run these tests only (run all tests if empty)- self.only = []-- # Accept new output which differs from the sample?- self.accept = 0-- # File in which to save the summary- self.output_summary = ''-- # File in which to save the times- self.times_file = ''-- # What platform are we running on?- self.platform = ''- self.os = ''- self.arch = ''-- # What is the wordsize (in bits) of this platform?- self.wordsize = ''-- # Verbosity level- self.verbose = 3-- # run the "fast" version of the test suite- self.fast = 0-- self.list_broken = False-- # Compiler type (ghc, hugs, nhc, etc.)- self.compiler_type = ''-- # Path to the compiler- self.compiler = ''- # and ghc-pkg- self.ghc_pkg = ''-- # Compiler version info- self.compiler_version = ''- self.compiler_maj_version = ''- self.compiler_tags = []-- # Flags we always give to this compiler- self.compiler_always_flags = []- - # Which ways to run tests (when compiling and running respectively)- # Other ways are added from the command line if we have the appropriate- # libraries.- self.compile_ways = []- self.run_ways = []- self.other_ways = []-- # The ways selected via the command line.- self.cmdline_ways = []-- # Lists of flags for each way- self.way_flags = {}- self.way_rts_flags = {}-- # Do we have vanilla libraries?- self.have_vanilla = False-- # Do we have dynamic libraries?- self.have_dynamic = False-- # Do we have profiling support?- self.have_profiling = False-- # Do we have interpreter support?- self.have_interp = False-- # Do we have shared libraries?- self.have_shared_libs = False-- # Do we have SMP support?- self.have_smp = False-- # Are we testing an in-tree compiler?- self.in_tree_compiler = True-- # the timeout program- self.timeout_prog = ''- self.timeout = 300- - # threads- self.threads = 1- self.use_threads = 0-- # Should we check for files being written more than once?- self.check_files_written = False-- # Should we skip performance tests- self.skip_perf_tests = False-- global config- config = TestConfig()-- def getConfig():- return config-- # ------------------------------------------------------------------------------ # Information about the current test run-- class TestRun:- def __init__(self):- self.start_time = None- self.total_tests = 0- self.total_test_cases = 0- self.n_framework_failures = 0- self.framework_failures = {}- self.n_tests_skipped = 0- self.tests_skipped = {}- self.n_expected_passes = 0- self.expected_passes = {}- self.n_expected_failures = 0- self.expected_failures = {}- self.n_missing_libs = 0- self.missing_libs = {}- self.n_unexpected_passes = 0- self.unexpected_passes = {}- self.n_unexpected_failures = 0- self.unexpected_failures = {}- self.n_unexpected_stat_failures = 0- self.unexpected_stat_failures = {}- - global t- t = TestRun()-- def getTestRun():- return t-- # ------------------------------------------------------------------------------ # Information about the current test-- class TestOptions:- def __init__(self):- # if not None then we look for namebase.stderr etc rather than- # using the test name- self.with_namebase = None-- # skip this test?- self.skip = 0-- # skip these ways- self.omit_ways = []-- # skip all ways except these (None == do all ways)- self.only_ways = None-- # add these ways to the default set- self.extra_ways = []-- # the result we normally expect for this test- self.expect = 'pass'-- # override the expected result for certain ways- self.expect_fail_for = []-- # the stdin file that this test will use (empty for <name>.stdin)- self.stdin = ''-- # don't compare output- self.ignore_output = 0-- # don't give anything as stdin- self.no_stdin = 0-- # compile this test to .hc only- self.compile_to_hc = 0-- # We sometimes want to modify the compiler_always_flags, so- # they are copied from config.compiler_always_flags when we- # make a new instance of TestOptions.- self.compiler_always_flags = []-- # extra compiler opts for this test- self.extra_hc_opts = ''-- # extra run opts for this test- self.extra_run_opts = ''-- # expected exit code- self.exit_code = 0-- # should we clean up after ourselves?- self.cleanup = ''-- # extra files to clean afterward- self.clean_files = []-- # which -t numeric fields do we want to look at, and what bounds must- # they fall within?- # Elements of these lists should be things like- # ('bytes allocated',- # 9300000000,- # 10)- # To allow a 10% deviation from 9300000000.- self.compiler_stats_range_fields = {}- self.stats_range_fields = {}-- # should we run this test alone, i.e. not run it in parallel with- # any other threads- self.alone = False-- # Does this test use a literate (.lhs) file?- self.literate = 0-- # Does this test use a .c, .m or .mm file?- self.c_src = 0- self.objc_src = 0- self.objcpp_src = 0-- # Does this test use a .cmm file?- self.cmm_src = 0-- # Should we put .hi/.o files in a subdirectory?- self.outputdir = None-- # Command to run before the test- self.pre_cmd = None-- # Command to run for extra cleaning- self.clean_cmd = None-- # Command wrapper: a function to apply to the command before running it- self.cmd_wrapper = None-- # Prefix to put on the command before compiling it- self.compile_cmd_prefix = ''-- # Extra output normalisation- self.extra_normaliser = lambda x: x-- # Custom output checker, otherwise do a comparison with expected- # stdout file. Accepts two arguments: filename of actual stdout- # output, and a normaliser function given other test options- self.check_stdout = None-- # Extra normalisation for compiler error messages- self.extra_errmsg_normaliser = lambda x: x-- # The directory the test is in- self.testdir = '.'-- # Should we redirect stdout and stderr to a single file?- self.combined_output = False-- # How should the timeout be adjusted on this test?- self.timeout_multiplier = 1.0-- # The default set of options- global default_testopts- default_testopts = TestOptions()-- # (bug, directory, name) of tests marked broken- global brokens- brokens = []--EOF-chmod 644 'ghc-test-framework/driver/testglobals.py'--mkdir -p 'ghc-test-framework/driver'-sed "s/^ //" <<"EOF" >'ghc-test-framework/driver/testlib.py'- #- # (c) Simon Marlow 2002- #-- from __future__ import print_function-- import shutil- import sys- import os- import errno- import string- import re- import traceback- import time- import datetime- import copy- import glob- from math import ceil, trunc- import collections-- have_subprocess = False- try:- import subprocess- have_subprocess = True- except:- print("Warning: subprocess not found, will fall back to spawnv")-- from testglobals import *- from testutil import *-- if config.use_threads:- import threading- try:- import thread- except ImportError: # Python 3- import _thread as thread-- global wantToStop- wantToStop = False- def stopNow():- global wantToStop- wantToStop = True- def stopping():- return wantToStop-- # Options valid for the current test only (these get reset to- # testdir_testopts after each test).-- global testopts_local- if config.use_threads:- testopts_local = threading.local()- else:- class TestOpts_Local:- pass- testopts_local = TestOpts_Local()-- def getTestOpts():- return testopts_local.x-- def setLocalTestOpts(opts):- global testopts_local- testopts_local.x=opts-- def isStatsTest():- opts = getTestOpts()- return len(opts.compiler_stats_range_fields) > 0 or len(opts.stats_range_fields) > 0--- # This can be called at the top of a file of tests, to set default test options- # for the following tests.- def setTestOpts( f ):- global thisdir_settings- thisdir_settings = [thisdir_settings, f]-- # ------------------------------------------------------------------------------ # Canned setup functions for common cases. eg. for a test you might say- #- # test('test001', normal, compile, [''])- #- # to run it without any options, but change it to- #- # test('test001', expect_fail, compile, [''])- #- # to expect failure for this test.-- def normal( name, opts ):- return;-- def skip( name, opts ):- opts.skip = 1-- def expect_fail( name, opts ):- opts.expect = 'fail';-- def reqlib( lib ):- return lambda name, opts, l=lib: _reqlib (name, opts, l )-- # Cache the results of looking to see if we have a library or not.- # This makes quite a difference, especially on Windows.- have_lib = {}-- def _reqlib( name, opts, lib ):- if lib in have_lib:- got_it = have_lib[lib]- else:- if have_subprocess:- # By preference we use subprocess, as the alternative uses- # /dev/null which mingw doesn't have.- cmd = strip_quotes(config.ghc_pkg)- p = subprocess.Popen([cmd, '--no-user-package-db', 'describe', lib],- stdout=subprocess.PIPE,- stderr=subprocess.PIPE)- # read from stdout and stderr to avoid blocking due to- # buffers filling- p.communicate()- r = p.wait()- else:- r = os.system(config.ghc_pkg + ' --no-user-package-db describe '- + lib + ' > /dev/null 2> /dev/null')- got_it = r == 0- have_lib[lib] = got_it-- if not got_it:- opts.expect = 'missing-lib'-- def req_profiling( name, opts ):- if not config.have_profiling:- opts.expect = 'fail'-- def req_shared_libs( name, opts ):- if not config.have_shared_libs:- opts.expect = 'fail'-- def req_interp( name, opts ):- if not config.have_interp:- opts.expect = 'fail'-- def req_smp( name, opts ):- if not config.have_smp:- opts.expect = 'fail'-- def ignore_output( name, opts ):- opts.ignore_output = 1-- def no_stdin( name, opts ):- opts.no_stdin = 1-- def combined_output( name, opts ):- opts.combined_output = True-- # ------- def expect_fail_for( ways ):- return lambda name, opts, w=ways: _expect_fail_for( name, opts, w )-- def _expect_fail_for( name, opts, ways ):- opts.expect_fail_for = ways-- def expect_broken( bug ):- return lambda name, opts, b=bug: _expect_broken (name, opts, b )-- def _expect_broken( name, opts, bug ):- record_broken(name, opts, bug)- opts.expect = 'fail';-- def expect_broken_for( bug, ways ):- return lambda name, opts, b=bug, w=ways: _expect_broken_for( name, opts, b, w )-- def _expect_broken_for( name, opts, bug, ways ):- record_broken(name, opts, bug)- opts.expect_fail_for = ways-- def record_broken(name, opts, bug):- global brokens- me = (bug, opts.testdir, name)- if not me in brokens:- brokens.append(me)-- # ------- def omit_ways( ways ):- return lambda name, opts, w=ways: _omit_ways( name, opts, w )-- def _omit_ways( name, opts, ways ):- opts.omit_ways = ways-- # ------- def only_ways( ways ):- return lambda name, opts, w=ways: _only_ways( name, opts, w )-- def _only_ways( name, opts, ways ):- opts.only_ways = ways-- # ------- def extra_ways( ways ):- return lambda name, opts, w=ways: _extra_ways( name, opts, w )-- def _extra_ways( name, opts, ways ):- opts.extra_ways = ways-- # ------- def omit_compiler_types( compiler_types ):- return lambda name, opts, c=compiler_types: _omit_compiler_types(name, opts, c)-- def _omit_compiler_types( name, opts, compiler_types ):- if config.compiler_type in compiler_types:- opts.skip = 1-- # ------- def only_compiler_types( compiler_types ):- return lambda name, opts, c=compiler_types: _only_compiler_types(name, opts, c)-- def _only_compiler_types( name, opts, compiler_types ):- if config.compiler_type not in compiler_types:- opts.skip = 1-- # ------- def set_stdin( file ):- return lambda name, opts, f=file: _set_stdin(name, opts, f);-- def _set_stdin( name, opts, f ):- opts.stdin = f-- # ------- def exit_code( val ):- return lambda name, opts, v=val: _exit_code(name, opts, v);-- def _exit_code( name, opts, v ):- opts.exit_code = v-- def signal_exit_code( val ):- if opsys('solaris2'):- return exit_code( val );- else:- # When application running on Linux receives fatal error- # signal, then its exit code is encoded as 128 + signal- # value. See http://www.tldp.org/LDP/abs/html/exitcodes.html- # I assume that Mac OS X behaves in the same way at least Mac- # OS X builder behavior suggests this.- return exit_code( val+128 );-- # ------- def timeout_multiplier( val ):- return lambda name, opts, v=val: _timeout_multiplier(name, opts, v)-- def _timeout_multiplier( name, opts, v ):- opts.timeout_multiplier = v-- # ------- def extra_run_opts( val ):- return lambda name, opts, v=val: _extra_run_opts(name, opts, v);-- def _extra_run_opts( name, opts, v ):- opts.extra_run_opts = v-- # ------- def extra_hc_opts( val ):- return lambda name, opts, v=val: _extra_hc_opts(name, opts, v);-- def _extra_hc_opts( name, opts, v ):- opts.extra_hc_opts = v-- # ------- def extra_clean( files ):- return lambda name, opts, v=files: _extra_clean(name, opts, v);-- def _extra_clean( name, opts, v ):- opts.clean_files = v-- # ------- def stats_num_field( field, expecteds ):- return lambda name, opts, f=field, e=expecteds: _stats_num_field(name, opts, f, e);-- def _stats_num_field( name, opts, field, expecteds ):- if field in opts.stats_range_fields:- framework_fail(name, 'duplicate-numfield', 'Duplicate ' + field + ' num_field check')-- if type(expecteds) is list:- for (b, expected, dev) in expecteds:- if b:- opts.stats_range_fields[field] = (expected, dev)- return- framework_fail(name, 'numfield-no-expected', 'No expected value found for ' + field + ' in num_field check')-- else:- (expected, dev) = expecteds- opts.stats_range_fields[field] = (expected, dev)-- def compiler_stats_num_field( field, expecteds ):- return lambda name, opts, f=field, e=expecteds: _compiler_stats_num_field(name, opts, f, e);-- def _compiler_stats_num_field( name, opts, field, expecteds ):- if field in opts.compiler_stats_range_fields:- framework_fail(name, 'duplicate-numfield', 'Duplicate ' + field + ' num_field check')-- # Compiler performance numbers change when debugging is on, making the results- # useless and confusing. Therefore, skip if debugging is on.- if compiler_debugged():- skip(name, opts)-- for (b, expected, dev) in expecteds:- if b:- opts.compiler_stats_range_fields[field] = (expected, dev)- return-- framework_fail(name, 'numfield-no-expected', 'No expected value found for ' + field + ' in num_field check')-- # ------- def when(b, f):- # When list_brokens is on, we want to see all expect_broken calls,- # so we always do f- if b or config.list_broken:- return f- else:- return normal-- def unless(b, f):- return when(not b, f)-- def doing_ghci():- return 'ghci' in config.run_ways-- def ghci_dynamic( ):- return config.ghc_dynamic-- def fast():- return config.fast-- def platform( plat ):- return config.platform == plat-- def opsys( os ):- return config.os == os-- def arch( arch ):- return config.arch == arch-- def wordsize( ws ):- return config.wordsize == str(ws)-- def msys( ):- return config.msys-- def cygwin( ):- return config.cygwin-- def have_vanilla( ):- return config.have_vanilla-- def have_dynamic( ):- return config.have_dynamic-- def have_profiling( ):- return config.have_profiling-- def in_tree_compiler( ):- return config.in_tree_compiler-- def compiler_type( compiler ):- return config.compiler_type == compiler-- def compiler_lt( compiler, version ):- return config.compiler_type == compiler and \- version_lt(config.compiler_version, version)-- def compiler_le( compiler, version ):- return config.compiler_type == compiler and \- version_le(config.compiler_version, version)-- def compiler_gt( compiler, version ):- return config.compiler_type == compiler and \- version_gt(config.compiler_version, version)-- def compiler_ge( compiler, version ):- return config.compiler_type == compiler and \- version_ge(config.compiler_version, version)-- def unregisterised( ):- return config.unregisterised-- def compiler_profiled( ):- return config.compiler_profiled-- def compiler_debugged( ):- return config.compiler_debugged-- def tag( t ):- return t in config.compiler_tags-- # ----- def namebase( nb ):- return lambda opts, nb=nb: _namebase(opts, nb)-- def _namebase( opts, nb ):- opts.with_namebase = nb-- # ----- def high_memory_usage(name, opts):- opts.alone = True-- # If a test is for a multi-CPU race, then running the test alone- # increases the chance that we'll actually see it.- def multi_cpu_race(name, opts):- opts.alone = True-- # ---- def literate( name, opts ):- opts.literate = 1;-- def c_src( name, opts ):- opts.c_src = 1;-- def objc_src( name, opts ):- opts.objc_src = 1;-- def objcpp_src( name, opts ):- opts.objcpp_src = 1;-- def cmm_src( name, opts ):- opts.cmm_src = 1;-- def outputdir( odir ):- return lambda name, opts, d=odir: _outputdir(name, opts, d)-- def _outputdir( name, opts, odir ):- opts.outputdir = odir;-- # ------ def pre_cmd( cmd ):- return lambda name, opts, c=cmd: _pre_cmd(name, opts, cmd)-- def _pre_cmd( name, opts, cmd ):- opts.pre_cmd = cmd-- # ------ def clean_cmd( cmd ):- return lambda name, opts, c=cmd: _clean_cmd(name, opts, cmd)-- def _clean_cmd( name, opts, cmd ):- opts.clean_cmd = cmd-- # ------ def cmd_prefix( prefix ):- return lambda name, opts, p=prefix: _cmd_prefix(name, opts, prefix)-- def _cmd_prefix( name, opts, prefix ):- opts.cmd_wrapper = lambda cmd, p=prefix: p + ' ' + cmd;-- # ------ def cmd_wrapper( fun ):- return lambda name, opts, f=fun: _cmd_wrapper(name, opts, fun)-- def _cmd_wrapper( name, opts, fun ):- opts.cmd_wrapper = fun-- # ------ def compile_cmd_prefix( prefix ):- return lambda name, opts, p=prefix: _compile_cmd_prefix(name, opts, prefix)-- def _compile_cmd_prefix( name, opts, prefix ):- opts.compile_cmd_prefix = prefix-- # ------ def check_stdout( f ):- return lambda name, opts, f=f: _check_stdout(name, opts, f)-- def _check_stdout( name, opts, f ):- opts.check_stdout = f-- # ------ def normalise_slashes( name, opts ):- _normalise_fun(name, opts, normalise_slashes_)-- def normalise_exe( name, opts ):- _normalise_fun(name, opts, normalise_exe_)-- def normalise_fun( *fs ):- return lambda name, opts: _normalise_fun(name, opts, fs)-- def _normalise_fun( name, opts, *fs ):- opts.extra_normaliser = join_normalisers(opts.extra_normaliser, fs)-- def normalise_errmsg_fun( *fs ):- return lambda name, opts: _normalise_errmsg_fun(name, opts, fs)-- def _normalise_errmsg_fun( name, opts, *fs ):- opts.extra_errmsg_normaliser = join_normalisers(opts.extra_errmsg_normaliser, fs)-- def normalise_version_( *pkgs ):- def normalise_version__( str ):- return re.sub('(' + '|'.join(map(re.escape,pkgs)) + ')-[0-9.]+',- '\\1-<VERSION>', str)- return normalise_version__-- def normalise_version( *pkgs ):- def normalise_version__( name, opts ):- _normalise_fun(name, opts, normalise_version_(*pkgs))- _normalise_errmsg_fun(name, opts, normalise_version_(*pkgs))- return normalise_version__-- def join_normalisers(*a):- """- Compose functions, flattening sequences.-- join_normalisers(f1,[f2,f3],f4)-- is the same as-- lambda x: f1(f2(f3(f4(x))))- """-- def flatten(l):- """- Taken from http://stackoverflow.com/a/2158532/946226- """- for el in l:- if isinstance(el, collections.Iterable) and not isinstance(el, basestring):- for sub in flatten(el):- yield sub- else:- yield el-- a = flatten(a)-- fn = lambda x:x # identity function- for f in a:- assert callable(f)- fn = lambda x,f=f,fn=fn: fn(f(x))- return fn-- # ----- # Function for composing two opt-fns together-- def executeSetups(fs, name, opts):- if type(fs) is list:- # If we have a list of setups, then execute each one- for f in fs:- executeSetups(f, name, opts)- else:- # fs is a single function, so just apply it- fs(name, opts)-- # ------------------------------------------------------------------------------ # The current directory of tests-- def newTestDir( dir ):- global thisdir_settings- # reset the options for this test directory- thisdir_settings = lambda name, opts, dir=dir: _newTestDir( name, opts, dir )-- def _newTestDir( name, opts, dir ):- opts.testdir = dir- opts.compiler_always_flags = config.compiler_always_flags-- # ------------------------------------------------------------------------------ # Actually doing tests-- parallelTests = []- aloneTests = []- allTestNames = set([])-- def runTest (opts, name, func, args):- ok = 0-- if config.use_threads:- t.thread_pool.acquire()- try:- while config.threads<(t.running_threads+1):- t.thread_pool.wait()- t.running_threads = t.running_threads+1- ok=1- t.thread_pool.release()- thread.start_new_thread(test_common_thread, (name, opts, func, args))- except:- if not ok:- t.thread_pool.release()- else:- test_common_work (name, opts, func, args)-- # name :: String- # setup :: TestOpts -> IO ()- def test (name, setup, func, args):- global aloneTests- global parallelTests- global allTestNames- global thisdir_settings- if name in allTestNames:- framework_fail(name, 'duplicate', 'There are multiple tests with this name')- if not re.match('^[0-9]*[a-zA-Z][a-zA-Z0-9._-]*$', name):- framework_fail(name, 'bad_name', 'This test has an invalid name')-- # Make a deep copy of the default_testopts, as we need our own copy- # of any dictionaries etc inside it. Otherwise, if one test modifies- # them, all tests will see the modified version!- myTestOpts = copy.deepcopy(default_testopts)-- executeSetups([thisdir_settings, setup], name, myTestOpts)-- thisTest = lambda : runTest(myTestOpts, name, func, args)- if myTestOpts.alone:- aloneTests.append(thisTest)- else:- parallelTests.append(thisTest)- allTestNames.add(name)-- if config.use_threads:- def test_common_thread(name, opts, func, args):- t.lock.acquire()- try:- test_common_work(name,opts,func,args)- finally:- t.lock.release()- t.thread_pool.acquire()- t.running_threads = t.running_threads - 1- t.thread_pool.notify()- t.thread_pool.release()-- def get_package_cache_timestamp():- if config.package_conf_cache_file == '':- return 0.0- else:- try:- return os.stat(config.package_conf_cache_file).st_mtime- except:- return 0.0--- def test_common_work (name, opts, func, args):- try:- t.total_tests = t.total_tests+1- setLocalTestOpts(opts)-- package_conf_cache_file_start_timestamp = get_package_cache_timestamp()-- # All the ways we might run this test- if func == compile or func == multimod_compile:- all_ways = config.compile_ways- elif func == compile_and_run or func == multimod_compile_and_run:- all_ways = config.run_ways- elif func == ghci_script:- if 'ghci' in config.run_ways:- all_ways = ['ghci']- else:- all_ways = []- else:- all_ways = ['normal']-- # A test itself can request extra ways by setting opts.extra_ways- all_ways = all_ways + [way for way in opts.extra_ways if way not in all_ways]-- t.total_test_cases = t.total_test_cases + len(all_ways)-- ok_way = lambda way: \- not getTestOpts().skip \- and (config.only == [] or name in config.only) \- and (getTestOpts().only_ways == None or way in getTestOpts().only_ways) \- and (config.cmdline_ways == [] or way in config.cmdline_ways) \- and (not (config.skip_perf_tests and isStatsTest())) \- and way not in getTestOpts().omit_ways-- # Which ways we are asked to skip- do_ways = list(filter (ok_way,all_ways))-- # In fast mode, we skip all but one way- if config.fast and len(do_ways) > 0:- do_ways = [do_ways[0]]-- if not config.clean_only:- # Run the required tests...- for way in do_ways:- if stopping():- break- do_test (name, way, func, args)-- for way in all_ways:- if way not in do_ways:- skiptest (name,way)-- if getTestOpts().cleanup != '' and (config.clean_only or do_ways != []):- pretest_cleanup(name)- clean([name + suff for suff in [- '', '.exe', '.exe.manifest', '.genscript',- '.stderr.normalised', '.stdout.normalised',- '.run.stderr.normalised', '.run.stdout.normalised',- '.comp.stderr.normalised', '.comp.stdout.normalised',- '.interp.stderr.normalised', '.interp.stdout.normalised',- '.stats', '.comp.stats',- '.hi', '.o', '.prof', '.exe.prof', '.hc',- '_stub.h', '_stub.c', '_stub.o',- '.hp', '.exe.hp', '.ps', '.aux', '.hcr', '.eventlog']])-- if func == multi_compile or func == multi_compile_fail:- extra_mods = args[1]- clean([replace_suffix(fx[0],'o') for fx in extra_mods])- clean([replace_suffix(fx[0], 'hi') for fx in extra_mods])--- clean(getTestOpts().clean_files)-- if getTestOpts().outputdir != None:- odir = in_testdir(getTestOpts().outputdir)- try:- shutil.rmtree(odir)- except:- pass-- try:- shutil.rmtree(in_testdir('.hpc.' + name))- except:- pass-- try:- cleanCmd = getTestOpts().clean_cmd- if cleanCmd != None:- result = runCmdFor(name, 'cd ' + getTestOpts().testdir + ' && ' + cleanCmd)- if result != 0:- framework_fail(name, 'cleaning', 'clean-command failed: ' + str(result))- except:- framework_fail(name, 'cleaning', 'clean-command exception')-- package_conf_cache_file_end_timestamp = get_package_cache_timestamp();-- if package_conf_cache_file_start_timestamp != package_conf_cache_file_end_timestamp:- framework_fail(name, 'whole-test', 'Package cache timestamps do not match: ' + str(package_conf_cache_file_start_timestamp) + ' ' + str(package_conf_cache_file_end_timestamp))-- try:- for f in files_written[name]:- if os.path.exists(f):- try:- if not f in files_written_not_removed[name]:- files_written_not_removed[name].append(f)- except:- files_written_not_removed[name] = [f]- except:- pass- except Exception as e:- framework_fail(name, 'runTest', 'Unhandled exception: ' + str(e))-- def clean(strs):- for str in strs:- for name in glob.glob(in_testdir(str)):- clean_full_path(name)-- def clean_full_path(name):- try:- # Remove files...- os.remove(name)- except OSError as e1:- try:- # ... and empty directories- os.rmdir(name)- except OSError as e2:- # We don't want to fail here, but we do want to know- # what went wrong, so print out the exceptions.- # ENOENT isn't a problem, though, as we clean files- # that don't necessarily exist.- if e1.errno != errno.ENOENT:- print(e1)- if e2.errno != errno.ENOENT:- print(e2)-- def do_test(name, way, func, args):- full_name = name + '(' + way + ')'-- try:- if_verbose(2, "=====> %s %d of %d %s " % \- (full_name, t.total_tests, len(allTestNames), \- [t.n_unexpected_passes, \- t.n_unexpected_failures, \- t.n_framework_failures]))-- if config.use_threads:- t.lock.release()-- try:- preCmd = getTestOpts().pre_cmd- if preCmd != None:- result = runCmdFor(name, 'cd ' + getTestOpts().testdir + ' && ' + preCmd)- if result != 0:- framework_fail(name, way, 'pre-command failed: ' + str(result))- except:- framework_fail(name, way, 'pre-command exception')-- try:- result = func(*[name,way] + args)- finally:- if config.use_threads:- t.lock.acquire()-- if getTestOpts().expect != 'pass' and \- getTestOpts().expect != 'fail' and \- getTestOpts().expect != 'missing-lib':- framework_fail(name, way, 'bad expected ' + getTestOpts().expect)-- try:- passFail = result['passFail']- except:- passFail = 'No passFail found'-- if passFail == 'pass':- if getTestOpts().expect == 'pass' \- and way not in getTestOpts().expect_fail_for:- t.n_expected_passes = t.n_expected_passes + 1- if name in t.expected_passes:- t.expected_passes[name].append(way)- else:- t.expected_passes[name] = [way]- else:- if_verbose(1, '*** unexpected pass for %s' % full_name)- t.n_unexpected_passes = t.n_unexpected_passes + 1- addPassingTestInfo(t.unexpected_passes, getTestOpts().testdir, name, way)- elif passFail == 'fail':- if getTestOpts().expect == 'pass' \- and way not in getTestOpts().expect_fail_for:- reason = result['reason']- tag = result.get('tag')- if tag == 'stat':- if_verbose(1, '*** unexpected stat test failure for %s' % full_name)- t.n_unexpected_stat_failures = t.n_unexpected_stat_failures + 1- addFailingTestInfo(t.unexpected_stat_failures, getTestOpts().testdir, name, reason, way)- else:- if_verbose(1, '*** unexpected failure for %s' % full_name)- t.n_unexpected_failures = t.n_unexpected_failures + 1- addFailingTestInfo(t.unexpected_failures, getTestOpts().testdir, name, reason, way)- else:- if getTestOpts().expect == 'missing-lib':- t.n_missing_libs = t.n_missing_libs + 1- if name in t.missing_libs:- t.missing_libs[name].append(way)- else:- t.missing_libs[name] = [way]- else:- t.n_expected_failures = t.n_expected_failures + 1- if name in t.expected_failures:- t.expected_failures[name].append(way)- else:- t.expected_failures[name] = [way]- else:- framework_fail(name, way, 'bad result ' + passFail)- except KeyboardInterrupt:- stopNow()- except:- framework_fail(name, way, 'do_test exception')- traceback.print_exc()-- def addPassingTestInfo (testInfos, directory, name, way):- directory = re.sub('^\\.[/\\\\]', '', directory)-- if not directory in testInfos:- testInfos[directory] = {}-- if not name in testInfos[directory]:- testInfos[directory][name] = []-- testInfos[directory][name].append(way)-- def addFailingTestInfo (testInfos, directory, name, reason, way):- directory = re.sub('^\\.[/\\\\]', '', directory)-- if not directory in testInfos:- testInfos[directory] = {}-- if not name in testInfos[directory]:- testInfos[directory][name] = {}-- if not reason in testInfos[directory][name]:- testInfos[directory][name][reason] = []-- testInfos[directory][name][reason].append(way)-- def skiptest (name, way):- # print 'Skipping test \"', name, '\"'- t.n_tests_skipped = t.n_tests_skipped + 1- if name in t.tests_skipped:- t.tests_skipped[name].append(way)- else:- t.tests_skipped[name] = [way]-- def framework_fail( name, way, reason ):- full_name = name + '(' + way + ')'- if_verbose(1, '*** framework failure for %s %s ' % (full_name, reason))- t.n_framework_failures = t.n_framework_failures + 1- if name in t.framework_failures:- t.framework_failures[name].append(way)- else:- t.framework_failures[name] = [way]-- def badResult(result):- try:- if result['passFail'] == 'pass':- return False- return True- except:- return True-- def passed():- return {'passFail': 'pass'}-- def failBecause(reason, tag=None):- return {'passFail': 'fail', 'reason': reason, 'tag': tag}-- # ------------------------------------------------------------------------------ # Generic command tests-- # A generic command test is expected to run and exit successfully.- #- # The expected exit code can be changed via exit_code() as normal, and- # the expected stdout/stderr are stored in <testname>.stdout and- # <testname>.stderr. The output of the command can be ignored- # altogether by using run_command_ignore_output instead of- # run_command.-- def run_command( name, way, cmd ):- return simple_run( name, '', cmd, '' )-- # ------------------------------------------------------------------------------ # GHCi tests-- def ghci_script_without_flag(flag):- def apply(name, way, script):- overrides = [f for f in getTestOpts().compiler_always_flags if f != flag]- return ghci_script_override_default_flags(overrides)(name, way, script)-- return apply-- def ghci_script_override_default_flags(overrides):- def apply(name, way, script):- return ghci_script(name, way, script, overrides)-- return apply-- def ghci_script( name, way, script, override_flags = None ):- # filter out -fforce-recomp from compiler_always_flags, because we're- # actually testing the recompilation behaviour in the GHCi tests.- flags = ' '.join(get_compiler_flags(override_flags, noforce=True))-- way_flags = ' '.join(config.way_flags(name)['ghci'])-- # We pass HC and HC_OPTS as environment variables, so that the- # script can invoke the correct compiler by using ':! $HC $HC_OPTS'- cmd = ('HC={{compiler}} HC_OPTS="{flags}" {{compiler}} {flags} {way_flags}'- ).format(flags=flags, way_flags=way_flags)-- getTestOpts().stdin = script- return simple_run( name, way, cmd, getTestOpts().extra_run_opts )-- # ------------------------------------------------------------------------------ # Compile-only tests-- def compile_override_default_flags(overrides):- def apply(name, way, extra_opts):- return do_compile(name, way, 0, '', [], extra_opts, overrides)-- return apply-- def compile_fail_override_default_flags(overrides):- def apply(name, way, extra_opts):- return do_compile(name, way, 1, '', [], extra_opts, overrides)-- return apply-- def compile_without_flag(flag):- def apply(name, way, extra_opts):- overrides = [f for f in getTestOpts().compiler_always_flags if f != flag]- return compile_override_default_flags(overrides)(name, way, extra_opts)-- return apply-- def compile_fail_without_flag(flag):- def apply(name, way, extra_opts):- overrides = [f for f in getTestOpts.compiler_always_flags if f != flag]- return compile_fail_override_default_flags(overrides)(name, way, extra_opts)-- return apply-- def compile( name, way, extra_hc_opts ):- return do_compile( name, way, 0, '', [], extra_hc_opts )-- def compile_fail( name, way, extra_hc_opts ):- return do_compile( name, way, 1, '', [], extra_hc_opts )-- def multimod_compile( name, way, top_mod, extra_hc_opts ):- return do_compile( name, way, 0, top_mod, [], extra_hc_opts )-- def multimod_compile_fail( name, way, top_mod, extra_hc_opts ):- return do_compile( name, way, 1, top_mod, [], extra_hc_opts )-- def multi_compile( name, way, top_mod, extra_mods, extra_hc_opts ):- return do_compile( name, way, 0, top_mod, extra_mods, extra_hc_opts)-- def multi_compile_fail( name, way, top_mod, extra_mods, extra_hc_opts ):- return do_compile( name, way, 1, top_mod, extra_mods, extra_hc_opts)-- def do_compile( name, way, should_fail, top_mod, extra_mods, extra_hc_opts, override_flags = None ):- # print 'Compile only, extra args = ', extra_hc_opts- pretest_cleanup(name)-- result = extras_build( way, extra_mods, extra_hc_opts )- if badResult(result):- return result- extra_hc_opts = result['hc_opts']-- force = 0- if extra_mods:- force = 1- result = simple_build( name, way, extra_hc_opts, should_fail, top_mod, 0, 1, force, override_flags )-- if badResult(result):- return result-- # the actual stderr should always match the expected, regardless- # of whether we expected the compilation to fail or not (successful- # compilations may generate warnings).-- if getTestOpts().with_namebase == None:- namebase = name- else:- namebase = getTestOpts().with_namebase-- (platform_specific, expected_stderr_file) = platform_wordsize_qualify(namebase, 'stderr')- actual_stderr_file = qualify(name, 'comp.stderr')-- if not compare_outputs(way, 'stderr',- join_normalisers(getTestOpts().extra_errmsg_normaliser,- normalise_errmsg,- normalise_whitespace),- expected_stderr_file, actual_stderr_file):- return failBecause('stderr mismatch')-- # no problems found, this test passed- return passed()-- def compile_cmp_asm( name, way, extra_hc_opts ):- print('Compile only, extra args = ', extra_hc_opts)- pretest_cleanup(name)- result = simple_build( name + '.cmm', way, '-keep-s-files -O ' + extra_hc_opts, 0, '', 0, 0, 0)-- if badResult(result):- return result-- # the actual stderr should always match the expected, regardless- # of whether we expected the compilation to fail or not (successful- # compilations may generate warnings).-- if getTestOpts().with_namebase == None:- namebase = name- else:- namebase = getTestOpts().with_namebase-- (platform_specific, expected_asm_file) = platform_wordsize_qualify(namebase, 'asm')- actual_asm_file = qualify(name, 's')-- if not compare_outputs(way, 'asm',- join_normalisers(normalise_errmsg, normalise_asm),- expected_asm_file, actual_asm_file):- return failBecause('asm mismatch')-- # no problems found, this test passed- return passed()-- # ------------------------------------------------------------------------------ # Compile-and-run tests-- def compile_and_run__( name, way, top_mod, extra_mods, extra_hc_opts ):- # print 'Compile and run, extra args = ', extra_hc_opts- pretest_cleanup(name)-- result = extras_build( way, extra_mods, extra_hc_opts )- if badResult(result):- return result- extra_hc_opts = result['hc_opts']-- if way == 'ghci': # interpreted...- return interpreter_run( name, way, extra_hc_opts, 0, top_mod )- else: # compiled...- force = 0- if extra_mods:- force = 1-- result = simple_build( name, way, extra_hc_opts, 0, top_mod, 1, 1, force)- if badResult(result):- return result-- cmd = './' + name;-- # we don't check the compiler's stderr for a compile-and-run test- return simple_run( name, way, cmd, getTestOpts().extra_run_opts )-- def compile_and_run( name, way, extra_hc_opts ):- return compile_and_run__( name, way, '', [], extra_hc_opts)-- def multimod_compile_and_run( name, way, top_mod, extra_hc_opts ):- return compile_and_run__( name, way, top_mod, [], extra_hc_opts)-- def multi_compile_and_run( name, way, top_mod, extra_mods, extra_hc_opts ):- return compile_and_run__( name, way, top_mod, extra_mods, extra_hc_opts)-- def stats( name, way, stats_file ):- opts = getTestOpts()- return checkStats(name, way, stats_file, opts.stats_range_fields)-- # ------------------------------------------------------------------------------ # Check -t stats info-- def checkStats(name, way, stats_file, range_fields):- full_name = name + '(' + way + ')'-- result = passed()- if len(range_fields) > 0:- f = open(in_testdir(stats_file))- contents = f.read()- f.close()-- for (field, (expected, dev)) in range_fields.items():- m = re.search('\("' + field + '", "([0-9]+)"\)', contents)- if m == None:- print('Failed to find field: ', field)- result = failBecause('no such stats field')- val = int(m.group(1))-- lowerBound = trunc( expected * ((100 - float(dev))/100))- upperBound = trunc(0.5 + ceil(expected * ((100 + float(dev))/100)))-- deviation = round(((float(val) * 100)/ expected) - 100, 1)-- if val < lowerBound:- print(field, 'value is too low:')- print('(If this is because you have improved GHC, please')- print('update the test so that GHC doesn\'t regress again)')- result = failBecause('stat too good', tag='stat')- if val > upperBound:- print(field, 'value is too high:')- result = failBecause('stat not good enough', tag='stat')-- if val < lowerBound or val > upperBound or config.verbose >= 4:- valStr = str(val)- valLen = len(valStr)- expectedStr = str(expected)- expectedLen = len(expectedStr)- length = max(len(str(x)) for x in [expected, lowerBound, upperBound, val])-- def display(descr, val, extra):- print(descr, str(val).rjust(length), extra)-- display(' Expected ' + full_name + ' ' + field + ':', expected, '+/-' + str(dev) + '%')- display(' Lower bound ' + full_name + ' ' + field + ':', lowerBound, '')- display(' Upper bound ' + full_name + ' ' + field + ':', upperBound, '')- display(' Actual ' + full_name + ' ' + field + ':', val, '')- if val != expected:- display(' Deviation ' + full_name + ' ' + field + ':', deviation, '%')- - return result-- # ------------------------------------------------------------------------------ # Build a single-module program-- def extras_build( way, extra_mods, extra_hc_opts ):- for modopts in extra_mods:- mod, opts = modopts- result = simple_build( mod, way, opts + ' ' + extra_hc_opts, 0, '', 0, 0, 0)- if not (mod.endswith('.hs') or mod.endswith('.lhs')):- extra_hc_opts += ' ' + replace_suffix(mod, 'o')- if badResult(result):- return result-- return {'passFail' : 'pass', 'hc_opts' : extra_hc_opts}--- def simple_build( name, way, extra_hc_opts, should_fail, top_mod, link, addsuf, noforce, override_flags = None ):- opts = getTestOpts()- errname = add_suffix(name, 'comp.stderr')- rm_no_fail( qualify(errname, '') )-- if top_mod != '':- srcname = top_mod- rm_no_fail( qualify(name, '') )- base, suf = os.path.splitext(top_mod)- rm_no_fail( qualify(base, '') )- rm_no_fail( qualify(base, 'exe') )- elif addsuf:- srcname = add_hs_lhs_suffix(name)- rm_no_fail( qualify(name, '') )- else:- srcname = name- rm_no_fail( qualify(name, 'o') )-- rm_no_fail( qualify(replace_suffix(srcname, "o"), '') )-- to_do = ''- if top_mod != '':- to_do = '--make '- if link:- to_do = to_do + '-o ' + name- elif link:- to_do = '-o ' + name- elif opts.compile_to_hc:- to_do = '-C'- else:- to_do = '-c' # just compile-- stats_file = name + '.comp.stats'- if len(opts.compiler_stats_range_fields) > 0:- extra_hc_opts += ' +RTS -V0 -t' + stats_file + ' --machine-readable -RTS'-- # Required by GHC 7.3+, harmless for earlier versions:- if (getTestOpts().c_src or- getTestOpts().objc_src or- getTestOpts().objcpp_src or- getTestOpts().cmm_src):- extra_hc_opts += ' -no-hs-main '-- if getTestOpts().compile_cmd_prefix == '':- cmd_prefix = ''- else:- cmd_prefix = getTestOpts().compile_cmd_prefix + ' '-- flags = ' '.join(get_compiler_flags(override_flags, noforce) +- config.way_flags(name)[way])-- cmd = ('cd {opts.testdir} && {cmd_prefix} '- '{{compiler}} {to_do} {srcname} {flags} {extra_hc_opts} '- '> {errname} 2>&1'- ).format(**locals())-- result = runCmdFor(name, cmd)-- if result != 0 and not should_fail:- actual_stderr = qualify(name, 'comp.stderr')- if_verbose(1,'Compile failed (status ' + repr(result) + ') errors were:')- if_verbose_dump(1,actual_stderr)-- # ToDo: if the sub-shell was killed by ^C, then exit-- statsResult = checkStats(name, way, stats_file, opts.compiler_stats_range_fields)-- if badResult(statsResult):- return statsResult-- if should_fail:- if result == 0:- return failBecause('exit code 0')- else:- if result != 0:- return failBecause('exit code non-0')-- return passed()-- # ------------------------------------------------------------------------------ # Run a program and check its output- #- # If testname.stdin exists, route input from that, else- # from /dev/null. Route output to testname.run.stdout and- # testname.run.stderr. Returns the exit code of the run.-- def simple_run( name, way, prog, args ):- opts = getTestOpts()-- # figure out what to use for stdin- if opts.stdin != '':- use_stdin = opts.stdin- else:- stdin_file = add_suffix(name, 'stdin')- if os.path.exists(in_testdir(stdin_file)):- use_stdin = stdin_file- else:- use_stdin = '/dev/null'-- run_stdout = add_suffix(name,'run.stdout')- run_stderr = add_suffix(name,'run.stderr')-- rm_no_fail(qualify(name,'run.stdout'))- rm_no_fail(qualify(name,'run.stderr'))- rm_no_fail(qualify(name, 'hp'))- rm_no_fail(qualify(name,'ps'))- rm_no_fail(qualify(name, 'prof'))-- my_rts_flags = rts_flags(way)-- stats_file = name + '.stats'- if len(opts.stats_range_fields) > 0:- args += ' +RTS -V0 -t' + stats_file + ' --machine-readable -RTS'-- if opts.no_stdin:- stdin_comes_from = ''- else:- stdin_comes_from = ' <' + use_stdin-- if opts.combined_output:- redirection = ' > {0} 2>&1'.format(run_stdout)- redirection_append = ' >> {0} 2>&1'.format(run_stdout)- else:- redirection = ' > {0} 2> {1}'.format(run_stdout, run_stderr)- redirection_append = ' >> {0} 2>> {1}'.format(run_stdout, run_stderr)-- cmd = prog + ' ' + args + ' ' \- + my_rts_flags + ' ' \- + stdin_comes_from \- + redirection-- if opts.cmd_wrapper != None:- cmd = opts.cmd_wrapper(cmd) + redirection_append-- cmd = 'cd ' + opts.testdir + ' && ' + cmd-- # run the command- result = runCmdFor(name, cmd, timeout_multiplier=opts.timeout_multiplier)-- exit_code = result >> 8- signal = result & 0xff-- # check the exit code- if exit_code != opts.exit_code:- print('Wrong exit code (expected', opts.exit_code, ', actual', exit_code, ')')- dump_stdout(name)- dump_stderr(name)- return failBecause('bad exit code')-- check_hp = my_rts_flags.find("-h") != -1- check_prof = my_rts_flags.find("-p") != -1-- if not opts.ignore_output:- bad_stderr = not opts.combined_output and not check_stderr_ok(name, way)- bad_stdout = not check_stdout_ok(name, way)- if bad_stderr:- return failBecause('bad stderr')- if bad_stdout:- return failBecause('bad stdout')- # exit_code > 127 probably indicates a crash, so don't try to run hp2ps.- if check_hp and (exit_code <= 127 or exit_code == 251) and not check_hp_ok(name):- return failBecause('bad heap profile')- if check_prof and not check_prof_ok(name, way):- return failBecause('bad profile')-- return checkStats(name, way, stats_file, opts.stats_range_fields)-- def rts_flags(way):- if (way == ''):- return ''- else:- args = config.way_rts_flags[way]-- if args == []:- return ''- else:- return '+RTS ' + ' '.join(args) + ' -RTS'-- # ------------------------------------------------------------------------------ # Run a program in the interpreter and check its output-- def interpreter_run( name, way, extra_hc_opts, compile_only, top_mod ):- outname = add_suffix(name, 'interp.stdout')- errname = add_suffix(name, 'interp.stderr')- rm_no_fail(outname)- rm_no_fail(errname)- rm_no_fail(name)-- if (top_mod == ''):- srcname = add_hs_lhs_suffix(name)- else:- srcname = top_mod-- scriptname = add_suffix(name, 'genscript')- qscriptname = in_testdir(scriptname)- rm_no_fail(qscriptname)-- delimiter = '===== program output begins here\n'-- script = open(qscriptname, 'w')- if not compile_only:- # set the prog name and command-line args to match the compiled- # environment.- script.write(':set prog ' + name + '\n')- script.write(':set args ' + getTestOpts().extra_run_opts + '\n')- # Add marker lines to the stdout and stderr output files, so we- # can separate GHCi's output from the program's.- script.write(':! echo ' + delimiter)- script.write(':! echo 1>&2 ' + delimiter)- # Set stdout to be line-buffered to match the compiled environment.- script.write('System.IO.hSetBuffering System.IO.stdout System.IO.LineBuffering\n')- # wrapping in GHC.TopHandler.runIO ensures we get the same output- # in the event of an exception as for the compiled program.- script.write('GHC.TopHandler.runIOFastExit Main.main Prelude.>> Prelude.return ()\n')- script.close()-- # figure out what to use for stdin- if getTestOpts().stdin != '':- stdin_file = in_testdir(getTestOpts().stdin)- else:- stdin_file = qualify(name, 'stdin')-- if os.path.exists(stdin_file):- stdin = open(stdin_file, 'r')- os.system('cat ' + stdin_file + ' >>' + qscriptname)-- script.close()-- flags = ' '.join(get_compiler_flags(override_flags=None, noforce=False) +- config.way_flags(name)[way])-- if getTestOpts().combined_output:- redirection = ' > {0} 2>&1'.format(outname)- redirection_append = ' >> {0} 2>&1'.format(outname)- else:- redirection = ' > {0} 2> {1}'.format(outname, errname)- redirection_append = ' >> {0} 2>> {1}'.format(outname, errname)-- cmd = ('{{compiler}} {srcname} {flags} {extra_hc_opts} '- '< {scriptname} {redirection}'- ).format(**locals())-- if getTestOpts().cmd_wrapper != None:- cmd = getTestOpts().cmd_wrapper(cmd) + redirection_append;-- cmd = 'cd ' + getTestOpts().testdir + " && " + cmd-- result = runCmdFor(name, cmd, timeout_multiplier=getTestOpts().timeout_multiplier)-- exit_code = result >> 8- signal = result & 0xff-- # split the stdout into compilation/program output- split_file(in_testdir(outname), delimiter,- qualify(name, 'comp.stdout'),- qualify(name, 'run.stdout'))- split_file(in_testdir(errname), delimiter,- qualify(name, 'comp.stderr'),- qualify(name, 'run.stderr'))-- # check the exit code- if exit_code != getTestOpts().exit_code:- print('Wrong exit code (expected', getTestOpts().exit_code, ', actual', exit_code, ')')- dump_stdout(name)- dump_stderr(name)- return failBecause('bad exit code')-- # ToDo: if the sub-shell was killed by ^C, then exit-- if getTestOpts().ignore_output or (check_stderr_ok(name, way) and- check_stdout_ok(name, way)):- return passed()- else:- return failBecause('bad stdout or stderr')--- def split_file(in_fn, delimiter, out1_fn, out2_fn):- infile = open(in_fn)- out1 = open(out1_fn, 'w')- out2 = open(out2_fn, 'w')-- line = infile.readline()- line = re.sub('\r', '', line) # ignore Windows EOL- while (re.sub('^\s*','',line) != delimiter and line != ''):- out1.write(line)- line = infile.readline()- line = re.sub('\r', '', line)- out1.close()-- line = infile.readline()- while (line != ''):- out2.write(line)- line = infile.readline()- out2.close()-- # ------------------------------------------------------------------------------ # Utils- def get_compiler_flags(override_flags, noforce):- opts = getTestOpts()-- if override_flags is not None:- flags = copy.copy(override_flags)- else:- flags = copy.copy(opts.compiler_always_flags)-- if noforce:- flags = [f for f in flags if f != '-fforce-recomp']-- flags.append(opts.extra_hc_opts)-- if opts.outputdir != None:- flags.extend(["-outputdir", opts.outputdir])-- return flags-- def check_stdout_ok(name, way):- if getTestOpts().with_namebase == None:- namebase = name- else:- namebase = getTestOpts().with_namebase-- actual_stdout_file = qualify(name, 'run.stdout')- (platform_specific, expected_stdout_file) = platform_wordsize_qualify(namebase, 'stdout')-- def norm(str):- if platform_specific:- return str- else:- return normalise_output(str)-- extra_norm = join_normalisers(norm, getTestOpts().extra_normaliser)-- check_stdout = getTestOpts().check_stdout- if check_stdout:- return check_stdout(actual_stdout_file, extra_norm)-- return compare_outputs(way, 'stdout', extra_norm,- expected_stdout_file, actual_stdout_file)-- def dump_stdout( name ):- print('Stdout:')- print(read_no_crs(qualify(name, 'run.stdout')))-- def check_stderr_ok(name, way):- if getTestOpts().with_namebase == None:- namebase = name- else:- namebase = getTestOpts().with_namebase-- actual_stderr_file = qualify(name, 'run.stderr')- (platform_specific, expected_stderr_file) = platform_wordsize_qualify(namebase, 'stderr')-- def norm(str):- if platform_specific:- return str- else:- return normalise_errmsg(str)-- return compare_outputs(way, 'stderr',- join_normalisers(norm, getTestOpts().extra_errmsg_normaliser), \- expected_stderr_file, actual_stderr_file)-- def dump_stderr( name ):- print("Stderr:")- print(read_no_crs(qualify(name, 'run.stderr')))-- def read_no_crs(file):- str = ''- try:- h = open(file)- str = h.read()- h.close- except:- # On Windows, if the program fails very early, it seems the- # files stdout/stderr are redirected to may not get created- pass- return re.sub('\r', '', str)-- def write_file(file, str):- h = open(file, 'w')- h.write(str)- h.close-- def check_hp_ok(name):-- # do not qualify for hp2ps because we should be in the right directory- hp2psCmd = "cd " + getTestOpts().testdir + " && {hp2ps} " + name-- hp2psResult = runCmdExitCode(hp2psCmd)-- actual_ps_file = qualify(name, 'ps')-- if(hp2psResult == 0):- if (os.path.exists(actual_ps_file)):- if gs_working:- gsResult = runCmdExitCode(genGSCmd(actual_ps_file))- if (gsResult == 0):- return (True)- else:- print("hp2ps output for " + name + "is not valid PostScript")- else: return (True) # assume postscript is valid without ghostscript- else:- print("hp2ps did not generate PostScript for " + name)- return (False)- else:- print("hp2ps error when processing heap profile for " + name)- return(False)-- def check_prof_ok(name, way):-- prof_file = qualify(name,'prof')-- if not os.path.exists(prof_file):- print(prof_file + " does not exist")- return(False)-- if os.path.getsize(qualify(name,'prof')) == 0:- print(prof_file + " is empty")- return(False)-- if getTestOpts().with_namebase == None:- namebase = name- else:- namebase = getTestOpts().with_namebase-- (platform_specific, expected_prof_file) = \- platform_wordsize_qualify(namebase, 'prof.sample')-- # sample prof file is not required- if not os.path.exists(expected_prof_file):- return True- else:- return compare_outputs(way, 'prof',- join_normalisers(normalise_whitespace,normalise_prof), \- expected_prof_file, prof_file)-- # Compare expected output to actual output, and optionally accept the- # new output. Returns true if output matched or was accepted, false- # otherwise.- def compare_outputs(way, kind, normaliser, expected_file, actual_file):- if os.path.exists(expected_file):- expected_raw = read_no_crs(expected_file)- # print "norm:", normaliser(expected_raw)- expected_str = normaliser(expected_raw)- expected_file_for_diff = expected_file- else:- expected_str = ''- expected_file_for_diff = '/dev/null'-- actual_raw = read_no_crs(actual_file)- actual_str = normaliser(actual_raw)-- if expected_str == actual_str:- return 1- else:- if_verbose(1, 'Actual ' + kind + ' output differs from expected:')-- if expected_file_for_diff == '/dev/null':- expected_normalised_file = '/dev/null'- else:- expected_normalised_file = expected_file + ".normalised"- write_file(expected_normalised_file, expected_str)-- actual_normalised_file = actual_file + ".normalised"- write_file(actual_normalised_file, actual_str)-- # Ignore whitespace when diffing. We should only get to this- # point if there are non-whitespace differences- #- # Note we are diffing the *actual* output, not the normalised- # output. The normalised output may have whitespace squashed- # (including newlines) so the diff would be hard to read.- # This does mean that the diff might contain changes that- # would be normalised away.- if (config.verbose >= 1):- r = os.system( 'diff -uw ' + expected_file_for_diff + \- ' ' + actual_file )-- # If for some reason there were no non-whitespace differences,- # then do a full diff- if r == 0:- r = os.system( 'diff -u ' + expected_file_for_diff + \- ' ' + actual_file )-- if config.accept and (getTestOpts().expect == 'fail' or- way in getTestOpts().expect_fail_for):- if_verbose(1, 'Test is expected to fail. Not accepting new output.')- return 0- elif config.accept:- if_verbose(1, 'Accepting new output.')- write_file(expected_file, actual_raw)- return 1- else:- return 0--- def normalise_whitespace( str ):- # Merge contiguous whitespace characters into a single space.- str = re.sub('[ \t\n]+', ' ', str)- return str-- def normalise_errmsg( str ):- # If somefile ends in ".exe" or ".exe:", zap ".exe" (for Windows)- # the colon is there because it appears in error messages; this- # hacky solution is used in place of more sophisticated filename- # mangling- str = re.sub('([^\\s])\\.exe', '\\1', str)- # normalise slashes, minimise Windows/Unix filename differences- str = re.sub('\\\\', '/', str)- # The inplace ghc's are called ghc-stage[123] to avoid filename- # collisions, so we need to normalise that to just "ghc"- str = re.sub('ghc-stage[123]', 'ghc', str)- # Error messages simetimes contain integer implementation package- str = re.sub('integer-(gmp|simple)-[0-9.]+', 'integer-<IMPL>-<VERSION>', str)- return str-- # normalise a .prof file, so that we can reasonably compare it against- # a sample. This doesn't compare any of the actual profiling data,- # only the shape of the profile and the number of entries.- def normalise_prof (str):- # strip everything up to the line beginning "COST CENTRE"- str = re.sub('^(.*\n)*COST CENTRE[^\n]*\n','',str)-- # strip results for CAFs, these tend to change unpredictably- str = re.sub('[ \t]*(CAF|IDLE).*\n','',str)-- # XXX Ignore Main.main. Sometimes this appears under CAF, and- # sometimes under MAIN.- str = re.sub('[ \t]*main[ \t]+Main.*\n','',str)-- # We have somthing like this:-- # MAIN MAIN 101 0 0.0 0.0 100.0 100.0- # k Main 204 1 0.0 0.0 0.0 0.0- # foo Main 205 1 0.0 0.0 0.0 0.0- # foo.bar Main 207 1 0.0 0.0 0.0 0.0-- # then we remove all the specific profiling data, leaving only the- # cost centre name, module, and entries, to end up with this:-- # MAIN MAIN 0- # k Main 1- # foo Main 1- # foo.bar Main 1-- str = re.sub('\n([ \t]*[^ \t]+)([ \t]+[^ \t]+)([ \t]+\\d+)([ \t]+\\d+)[ \t]+([\\d\\.]+)[ \t]+([\\d\\.]+)[ \t]+([\\d\\.]+)[ \t]+([\\d\\.]+)','\n\\1 \\2 \\4',str)- return str-- def normalise_slashes_( str ):- str = re.sub('\\\\', '/', str)- return str-- def normalise_exe_( str ):- str = re.sub('\.exe', '', str)- return str-- def normalise_output( str ):- # Remove a .exe extension (for Windows)- # This can occur in error messages generated by the program.- str = re.sub('([^\\s])\\.exe', '\\1', str)- return str-- def normalise_asm( str ):- lines = str.split('\n')- # Only keep instructions and labels not starting with a dot.- metadata = re.compile('^[ \t]*\\..*$')- out = []- for line in lines:- # Drop metadata directives (e.g. ".type")- if not metadata.match(line):- line = re.sub('@plt', '', line)- instr = line.lstrip().split()- # Drop empty lines.- if not instr:- continue- # Drop operands, except for call instructions.- elif instr[0] == 'call':- out.append(instr[0] + ' ' + instr[1])- else:- out.append(instr[0])- out = '\n'.join(out)- return out-- def if_verbose( n, s ):- if config.verbose >= n:- print(s)-- def if_verbose_dump( n, f ):- if config.verbose >= n:- try:- print(open(f).read())- except:- print('')-- def rawSystem(cmd_and_args):- # We prefer subprocess.call to os.spawnv as the latter- # seems to send its arguments through a shell or something- # with the Windows (non-cygwin) python. An argument "a b c"- # turns into three arguments ["a", "b", "c"].-- # However, subprocess is new in python 2.4, so fall back to- # using spawnv if we don't have it- cmd = cmd_and_args[0]- if have_subprocess:- return subprocess.call([strip_quotes(cmd)] + cmd_and_args[1:])- else:- return os.spawnv(os.P_WAIT, cmd, cmd_and_args)-- # When running under native msys Python, any invocations of non-msys binaries,- # including timeout.exe, will have their arguments munged according to some- # heuristics, which leads to malformed command lines (#9626). The easiest way- # to avoid problems is to invoke through /usr/bin/cmd which sidesteps argument- # munging because it is a native msys application.- def passThroughCmd(cmd_and_args):- args = []- # cmd needs a Windows-style path for its first argument.- args.append(cmd_and_args[0].replace('/', '\\'))- # Other arguments need to be quoted to deal with spaces.- args.extend(['"%s"' % arg for arg in cmd_and_args[1:]])- return ["cmd", "/c", " ".join(args)]-- # Note that this doesn't handle the timeout itself; it is just used for- # commands that have timeout handling built-in.- def rawSystemWithTimeout(cmd_and_args):- if config.os == 'mingw32' and sys.executable.startswith('/usr'):- # This is only needed when running under msys python.- cmd_and_args = passThroughCmd(cmd_and_args)- r = rawSystem(cmd_and_args)- if r == 98:- # The python timeout program uses 98 to signal that ^C was pressed- stopNow()- return r-- # cmd is a complex command in Bourne-shell syntax- # e.g (cd . && 'c:/users/simonpj/darcs/HEAD/compiler/stage1/ghc-inplace' ...etc)- # Hence it must ultimately be run by a Bourne shell- #- # Mostly it invokes the command wrapped in 'timeout' thus- # timeout 300 'cd . && ...blah blah'- # so it's timeout's job to invoke the Bourne shell- #- # But watch out for the case when there is no timeout program!- # Then, when using the native Python, os.system will invoke the cmd shell-- def runCmd( cmd ):- # Format cmd using config. Example: cmd='{hpc} report A.tix'- cmd = cmd.format(**config.__dict__)-- if_verbose( 3, cmd )- r = 0- if config.os == 'mingw32':- # On MinGW, we will always have timeout- assert config.timeout_prog!=''-- if config.timeout_prog != '':- r = rawSystemWithTimeout([config.timeout_prog, str(config.timeout), cmd])- else:- r = os.system(cmd)- return r << 8-- def runCmdFor( name, cmd, timeout_multiplier=1.0 ):- # Format cmd using config. Example: cmd='{hpc} report A.tix'- cmd = cmd.format(**config.__dict__)-- if_verbose( 3, cmd )- r = 0- if config.os == 'mingw32':- # On MinGW, we will always have timeout- assert config.timeout_prog!=''- timeout = int(ceil(config.timeout * timeout_multiplier))-- if config.timeout_prog != '':- if config.check_files_written:- fn = name + ".strace"- r = rawSystemWithTimeout(- ["strace", "-o", fn, "-fF",- "-e", "creat,open,chdir,clone,vfork",- config.timeout_prog, str(timeout), cmd])- addTestFilesWritten(name, fn)- rm_no_fail(fn)- else:- r = rawSystemWithTimeout([config.timeout_prog, str(timeout), cmd])- else:- r = os.system(cmd)- return r << 8-- def runCmdExitCode( cmd ):- return (runCmd(cmd) >> 8);--- # ------------------------------------------------------------------------------ # checking for files being written to by multiple tests-- re_strace_call_end = '(\) += ([0-9]+|-1 E.*)| <unfinished ...>)$'- re_strace_unavailable = re.compile('^\) += \? <unavailable>$')- re_strace_pid = re.compile('^([0-9]+) +(.*)')- re_strace_clone = re.compile('^(clone\(|<... clone resumed> ).*\) = ([0-9]+)$')- re_strace_clone_unfinished = re.compile('^clone\( <unfinished \.\.\.>$')- re_strace_vfork = re.compile('^(vfork\(\)|<\.\.\. vfork resumed> \)) += ([0-9]+)$')- re_strace_vfork_unfinished = re.compile('^vfork\( <unfinished \.\.\.>$')- re_strace_chdir = re.compile('^chdir\("([^"]*)"(\) += 0| <unfinished ...>)$')- re_strace_chdir_resumed = re.compile('^<\.\.\. chdir resumed> \) += 0$')- re_strace_open = re.compile('^open\("([^"]*)", ([A-Z_|]*)(, [0-9]+)?' + re_strace_call_end)- re_strace_open_resumed = re.compile('^<... open resumed> ' + re_strace_call_end)- re_strace_ignore_sigchild = re.compile('^--- SIGCHLD \(Child exited\) @ 0 \(0\) ---$')- re_strace_ignore_sigvtalarm = re.compile('^--- SIGVTALRM \(Virtual timer expired\) @ 0 \(0\) ---$')- re_strace_ignore_sigint = re.compile('^--- SIGINT \(Interrupt\) @ 0 \(0\) ---$')- re_strace_ignore_sigfpe = re.compile('^--- SIGFPE \(Floating point exception\) @ 0 \(0\) ---$')- re_strace_ignore_sigsegv = re.compile('^--- SIGSEGV \(Segmentation fault\) @ 0 \(0\) ---$')- re_strace_ignore_sigpipe = re.compile('^--- SIGPIPE \(Broken pipe\) @ 0 \(0\) ---$')-- # Files that are read or written but shouldn't be:- # * ghci_history shouldn't be read or written by tests- # * things under package.conf.d shouldn't be written by tests- bad_file_usages = {}-- # Mapping from tests to the list of files that they write- files_written = {}-- # Mapping from tests to the list of files that they write but don't clean- files_written_not_removed = {}-- def add_bad_file_usage(name, file):- try:- if not file in bad_file_usages[name]:- bad_file_usages[name].append(file)- except:- bad_file_usages[name] = [file]-- def mkPath(curdir, path):- # Given the current full directory is 'curdir', what is the full- # path to 'path'?- return os.path.realpath(os.path.join(curdir, path))-- def addTestFilesWritten(name, fn):- if config.use_threads:- with t.lockFilesWritten:- addTestFilesWrittenHelper(name, fn)- else:- addTestFilesWrittenHelper(name, fn)-- def addTestFilesWrittenHelper(name, fn):- started = False- working_directories = {}-- with open(fn, 'r') as f:- for line in f:- m_pid = re_strace_pid.match(line)- if m_pid:- pid = m_pid.group(1)- content = m_pid.group(2)- elif re_strace_unavailable.match(line):- next- else:- framework_fail(name, 'strace', "Can't find pid in strace line: " + line)-- m_open = re_strace_open.match(content)- m_chdir = re_strace_chdir.match(content)- m_clone = re_strace_clone.match(content)- m_vfork = re_strace_vfork.match(content)-- if not started:- working_directories[pid] = os.getcwd()- started = True-- if m_open:- file = m_open.group(1)- file = mkPath(working_directories[pid], file)- if file.endswith("ghci_history"):- add_bad_file_usage(name, file)- elif not file in ['/dev/tty', '/dev/null'] and not file.startswith("/tmp/ghc"):- flags = m_open.group(2).split('|')- if 'O_WRONLY' in flags or 'O_RDWR' in flags:- if re.match('package\.conf\.d', file):- add_bad_file_usage(name, file)- else:- try:- if not file in files_written[name]:- files_written[name].append(file)- except:- files_written[name] = [file]- elif 'O_RDONLY' in flags:- pass- else:- framework_fail(name, 'strace', "Can't understand flags in open strace line: " + line)- elif m_chdir:- # We optimistically assume that unfinished chdir's are going to succeed- dir = m_chdir.group(1)- working_directories[pid] = mkPath(working_directories[pid], dir)- elif m_clone:- working_directories[m_clone.group(2)] = working_directories[pid]- elif m_vfork:- working_directories[m_vfork.group(2)] = working_directories[pid]- elif re_strace_open_resumed.match(content):- pass- elif re_strace_chdir_resumed.match(content):- pass- elif re_strace_vfork_unfinished.match(content):- pass- elif re_strace_clone_unfinished.match(content):- pass- elif re_strace_ignore_sigchild.match(content):- pass- elif re_strace_ignore_sigvtalarm.match(content):- pass- elif re_strace_ignore_sigint.match(content):- pass- elif re_strace_ignore_sigfpe.match(content):- pass- elif re_strace_ignore_sigsegv.match(content):- pass- elif re_strace_ignore_sigpipe.match(content):- pass- else:- framework_fail(name, 'strace', "Can't understand strace line: " + line)- - def checkForFilesWrittenProblems(file):- foundProblem = False-- files_written_inverted = {}- for t in files_written.keys():- for f in files_written[t]:- try:- files_written_inverted[f].append(t)- except:- files_written_inverted[f] = [t]-- for f in files_written_inverted.keys():- if len(files_written_inverted[f]) > 1:- if not foundProblem:- foundProblem = True- file.write("\n")- file.write("\nSome files are written by multiple tests:\n")- file.write(" " + f + " (" + str(files_written_inverted[f]) + ")\n")- if foundProblem:- file.write("\n")-- # ------- if len(files_written_not_removed) > 0:- file.write("\n")- file.write("\nSome files written but not removed:\n")- tests = list(files_written_not_removed.keys())- tests.sort()- for t in tests:- for f in files_written_not_removed[t]:- file.write(" " + t + ": " + f + "\n")- file.write("\n")-- # ------- if len(bad_file_usages) > 0:- file.write("\n")- file.write("\nSome bad file usages:\n")- tests = list(bad_file_usages.keys())- tests.sort()- for t in tests:- for f in bad_file_usages[t]:- file.write(" " + t + ": " + f + "\n")- file.write("\n")-- # ------------------------------------------------------------------------------ # checking if ghostscript is available for checking the output of hp2ps-- def genGSCmd(psfile):- return (config.gs + ' -dNODISPLAY -dBATCH -dQUIET -dNOPAUSE ' + psfile);-- def gsNotWorking():- global gs_working- print("GhostScript not available for hp2ps tests")-- global gs_working- gs_working = 0- if config.have_profiling:- if config.gs != '':- resultGood = runCmdExitCode(genGSCmd(config.confdir + '/good.ps'));- if resultGood == 0:- resultBad = runCmdExitCode(genGSCmd(config.confdir + '/bad.ps') +- ' >/dev/null 2>&1')- if resultBad != 0:- print("GhostScript available for hp2ps tests")- gs_working = 1;- else:- gsNotWorking();- else:- gsNotWorking();- else:- gsNotWorking();-- def rm_no_fail( file ):- try:- os.remove( file )- finally:- return-- def add_suffix( name, suffix ):- if suffix == '':- return name- else:- return name + '.' + suffix-- def add_hs_lhs_suffix(name):- if getTestOpts().c_src:- return add_suffix(name, 'c')- elif getTestOpts().cmm_src:- return add_suffix(name, 'cmm')- elif getTestOpts().objc_src:- return add_suffix(name, 'm')- elif getTestOpts().objcpp_src:- return add_suffix(name, 'mm')- elif getTestOpts().literate:- return add_suffix(name, 'lhs')- else:- return add_suffix(name, 'hs')-- def replace_suffix( name, suffix ):- base, suf = os.path.splitext(name)- return base + '.' + suffix-- def in_testdir( name ):- return (getTestOpts().testdir + '/' + name)-- def qualify( name, suff ):- return in_testdir(add_suffix(name, suff))--- # Finding the sample output. The filename is of the form- #- # <test>.stdout[-<compiler>][-<version>][-ws-<wordsize>][-<platform>]- #- # and we pick the most specific version available. The <version> is- # the major version of the compiler (e.g. 6.8.2 would be "6.8"). For- # more fine-grained control use if_compiler_lt().- #- def platform_wordsize_qualify( name, suff ):-- basepath = qualify(name, suff)-- paths = [(platformSpecific, basepath + comp + vers + ws + plat)- for (platformSpecific, plat) in [(1, '-' + config.platform),- (1, '-' + config.os),- (0, '')]- for ws in ['-ws-' + config.wordsize, '']- for comp in ['-' + config.compiler_type, '']- for vers in ['-' + config.compiler_maj_version, '']]-- dir = glob.glob(basepath + '*')- dir = [normalise_slashes_(d) for d in dir]-- for (platformSpecific, f) in paths:- if f in dir:- return (platformSpecific,f)-- return (0, basepath)-- # Clean up prior to the test, so that we can't spuriously conclude- # that it passed on the basis of old run outputs.- def pretest_cleanup(name):- if getTestOpts().outputdir != None:- odir = in_testdir(getTestOpts().outputdir)- try:- shutil.rmtree(odir)- except:- pass- os.mkdir(odir)-- rm_no_fail(qualify(name,'interp.stderr'))- rm_no_fail(qualify(name,'interp.stdout'))- rm_no_fail(qualify(name,'comp.stderr'))- rm_no_fail(qualify(name,'comp.stdout'))- rm_no_fail(qualify(name,'run.stderr'))- rm_no_fail(qualify(name,'run.stdout'))- rm_no_fail(qualify(name,'tix'))- rm_no_fail(qualify(name,'exe.tix'))- # simple_build zaps the following:- # rm_nofail(qualify("o"))- # rm_nofail(qualify(""))- # not interested in the return code-- # ------------------------------------------------------------------------------ # Return a list of all the files ending in '.T' below directories roots.-- def findTFiles(roots):- # It would be better to use os.walk, but that- # gives backslashes on Windows, which trip the- # testsuite later :-(- return [filename for root in roots for filename in findTFiles_(root)]-- def findTFiles_(path):- if os.path.isdir(path):- paths = [path + '/' + x for x in os.listdir(path)]- return findTFiles(paths)- elif path[-2:] == '.T':- return [path]- else:- return []-- # ------------------------------------------------------------------------------ # Output a test summary to the specified file object-- def summary(t, file):-- file.write('\n')- printUnexpectedTests(file, [t.unexpected_passes, t.unexpected_failures, t.unexpected_stat_failures])- file.write('OVERALL SUMMARY for test run started at '- + time.strftime("%c %Z", t.start_time) + '\n'- + str(datetime.timedelta(seconds=- round(time.time() - time.mktime(t.start_time)))).rjust(8)- + ' spent to go through\n'- + repr(t.total_tests).rjust(8)- + ' total tests, which gave rise to\n'- + repr(t.total_test_cases).rjust(8)- + ' test cases, of which\n'- + repr(t.n_tests_skipped).rjust(8)- + ' were skipped\n'- + '\n'- + repr(t.n_missing_libs).rjust(8)- + ' had missing libraries\n'- + repr(t.n_expected_passes).rjust(8)- + ' expected passes\n'- + repr(t.n_expected_failures).rjust(8)- + ' expected failures\n'- + '\n'- + repr(t.n_framework_failures).rjust(8)- + ' caused framework failures\n'- + repr(t.n_unexpected_passes).rjust(8)- + ' unexpected passes\n'- + repr(t.n_unexpected_failures).rjust(8)- + ' unexpected failures\n'- + repr(t.n_unexpected_stat_failures).rjust(8)- + ' unexpected stat failures\n'- + '\n')-- if t.n_unexpected_passes > 0:- file.write('Unexpected passes:\n')- printPassingTestInfosSummary(file, t.unexpected_passes)-- if t.n_unexpected_failures > 0:- file.write('Unexpected failures:\n')- printFailingTestInfosSummary(file, t.unexpected_failures)-- if t.n_unexpected_stat_failures > 0:- file.write('Unexpected stat failures:\n')- printFailingTestInfosSummary(file, t.unexpected_stat_failures)-- if config.check_files_written:- checkForFilesWrittenProblems(file)-- if stopping():- file.write('WARNING: Testsuite run was terminated early\n')-- def printUnexpectedTests(file, testInfoss):- unexpected = []- for testInfos in testInfoss:- directories = testInfos.keys()- for directory in directories:- tests = list(testInfos[directory].keys())- unexpected += tests- if unexpected != []:- file.write('Unexpected results from:\n')- file.write('TEST="' + ' '.join(unexpected) + '"\n')- file.write('\n')-- def printPassingTestInfosSummary(file, testInfos):- directories = list(testInfos.keys())- directories.sort()- maxDirLen = max(len(x) for x in directories)- for directory in directories:- tests = list(testInfos[directory].keys())- tests.sort()- for test in tests:- file.write(' ' + directory.ljust(maxDirLen + 2) + test + \- ' (' + ','.join(testInfos[directory][test]) + ')\n')- file.write('\n')-- def printFailingTestInfosSummary(file, testInfos):- directories = list(testInfos.keys())- directories.sort()- maxDirLen = max(len(d) for d in directories)- for directory in directories:- tests = list(testInfos[directory].keys())- tests.sort()- for test in tests:- reasons = testInfos[directory][test].keys()- for reason in reasons:- file.write(' ' + directory.ljust(maxDirLen + 2) + test + \- ' [' + reason + ']' + \- ' (' + ','.join(testInfos[directory][test][reason]) + ')\n')- file.write('\n')-- def getStdout(cmd_and_args):- if have_subprocess:- p = subprocess.Popen([strip_quotes(cmd_and_args[0])] + cmd_and_args[1:],- stdout=subprocess.PIPE,- stderr=subprocess.PIPE)- (stdout, stderr) = p.communicate()- r = p.wait()- if r != 0:- raise Exception("Command failed: " + str(cmd_and_args))- if stderr != '':- raise Exception("stderr from command: " + str(cmd_and_args))- return stdout- else:- raise Exception("Need subprocess to get stdout, but don't have it")-EOF-chmod 644 'ghc-test-framework/driver/testlib.py'--mkdir -p 'ghc-test-framework/driver'-sed "s/^ //" <<"EOF" >'ghc-test-framework/driver/testutil.py'- # ------------------------------------------------------------------------------ # Utils- def version_to_ints(v):- return [ int(x) for x in v.split('.') ]-- def version_lt(x, y):- return version_to_ints(x) < version_to_ints(y)-- def version_le(x, y):- return version_to_ints(x) <= version_to_ints(y)-- def version_gt(x, y):- return version_to_ints(x) > version_to_ints(y)-- def version_ge(x, y):- return version_to_ints(x) >= version_to_ints(y)-- def strip_quotes(s):- # Don't wrap commands to subprocess.call/Popen in quotes.- return s.strip('\'"')-EOF-chmod 644 'ghc-test-framework/driver/testutil.py'--mkdir -p 'ghc-test-framework/mk'-sed "s/^ //" <<"EOF" >'ghc-test-framework/mk/boilerplate.mk'-- default: all-- HAVE_EVAL := NO- $(eval HAVE_EVAL := YES)-- ifeq "$(HAVE_EVAL)" "NO"- $(error Your make does not support eval. You need GNU make >= 3.81)- endif-- ifeq "$(abspath /)" ""- $(error Your make does not support abspath. You need GNU make >= 3.81)- endif-- show:- @echo '$(VALUE)="$($(VALUE))"'-- define canonicalise- # $1 = path variable- $1_CYGPATH := $$(shell $(SHELL) -c "cygpath -m '$$($1)'" 2> /dev/null)- ifneq "$$($1_CYGPATH)" ""- # We use 'override' in case we are trying to update a value given on- # the commandline (e.g. TEST_HC)- override $1 := $$($1_CYGPATH)- endif- endef-- define canonicaliseExecutable- # $1 = program path variable- ifneq "$$(shell test -x '$$($1).exe' && echo exists)" ""- # We use 'override' in case we are trying to update a value given on- # the commandline (e.g. TEST_HC)- override $1 := $$($1).exe- endif- $(call canonicalise,$1)- endef-- ifeq "$(TEST_HC)" ""-- STAGE1_GHC := $(abspath $(TOP)/../inplace/bin/ghc-stage1)- STAGE2_GHC := $(abspath $(TOP)/../inplace/bin/ghc-stage2)- STAGE3_GHC := $(abspath $(TOP)/../inplace/bin/ghc-stage3)-- ifneq "$(wildcard $(STAGE1_GHC) $(STAGE1_GHC).exe)" ""-- IMPLICIT_COMPILER = NO- IN_TREE_COMPILER = YES- ifeq "$(BINDIST)" "YES"- TEST_HC := $(abspath $(TOP)/../)/bindisttest/install dir/bin/ghc- else ifeq "$(stage)" "1"- TEST_HC := $(STAGE1_GHC)- else ifeq "$(stage)" "3"- TEST_HC := $(STAGE3_GHC)- else- # use stage2 by default- TEST_HC := $(STAGE2_GHC)- endif-- else- IMPLICIT_COMPILER = YES- IN_TREE_COMPILER = NO- TEST_HC := $(shell which ghc)- endif-- else- ifeq "$(TEST_HC)" "ghc"- IMPLICIT_COMPILER = YES- else- IMPLICIT_COMPILER = NO- endif- IN_TREE_COMPILER = NO- # We want to support both "ghc" and "/usr/bin/ghc" as values of TEST_HC- # passed in by the user, but- # which ghc == /usr/bin/ghc- # which /usr/bin/ghc == /usr/bin/ghc- # so on unix-like platforms we can just always 'which' it.- # However, on cygwin, we can't just use which:- # $ which c:/ghc/ghc-7.4.1/bin/ghc.exe- # which: no ghc.exe in (./c:/ghc/ghc-7.4.1/bin)- # so we start off by using realpath, and if that succeeds then we use- # that value. Otherwise we fall back on 'which'.- #- # Note also that we need to use 'override' in order to override a- # value given on the commandline.- TEST_HC_REALPATH := $(realpath $(TEST_HC))- ifeq "$(TEST_HC_REALPATH)" ""- override TEST_HC := $(shell which '$(TEST_HC)')- else- override TEST_HC := $(TEST_HC_REALPATH)- endif- endif-- # We can't use $(dir ...) here as TEST_HC might be in a path- # containing spaces- BIN_ROOT = $(shell dirname '$(TEST_HC)')-- ifeq "$(IMPLICIT_COMPILER)" "YES"- find_tool = $(shell which $(1))- else- find_tool = $(BIN_ROOT)/$(1)- endif-- ifeq "$(GHC_PKG)" ""- GHC_PKG := $(call find_tool,ghc-pkg)- endif-- ifeq "$(RUNGHC)" ""- RUNGHC := $(call find_tool,runghc)- endif-- ifeq "$(HSC2HS)" ""- HSC2HS := $(call find_tool,hsc2hs)- endif-- ifeq "$(HP2PS_ABS)" ""- HP2PS_ABS := $(call find_tool,hp2ps)- endif-- ifeq "$(HPC)" ""- HPC := $(call find_tool,hpc)- endif-- $(eval $(call canonicaliseExecutable,TEST_HC))- ifeq "$(shell test -x '$(TEST_HC)' && echo exists)" ""- $(error Cannot find ghc: $(TEST_HC))- endif-- $(eval $(call canonicaliseExecutable,GHC_PKG))- ifeq "$(shell test -x '$(GHC_PKG)' && echo exists)" ""- $(error Cannot find ghc-pkg: $(GHC_PKG))- endif-- $(eval $(call canonicaliseExecutable,HSC2HS))- ifeq "$(shell test -x '$(HSC2HS)' && echo exists)" ""- $(error Cannot find hsc2hs: $(HSC2HS))- endif-- $(eval $(call canonicaliseExecutable,HP2PS_ABS))- ifeq "$(shell test -x '$(HP2PS_ABS)' && echo exists)" ""- $(error Cannot find hp2ps: $(HP2PS_ABS))- endif-- $(eval $(call canonicaliseExecutable,HPC))- ifeq "$(shell test -x '$(HPC)' && echo exists)" ""- $(error Cannot find hpc: $(HPC))- endif-- # Be careful when using this. On Windows it ends up looking like- # c:/foo/bar which confuses make, as make thinks that the : is Makefile- # syntax- TOP_ABS := $(abspath $(TOP))- $(eval $(call canonicalise,TOP_ABS))-- GS = gs- CP = cp- RM = rm -f- PYTHON = python- ifeq "$(shell $(SHELL) -c 'python2 -c 0' 2> /dev/null && echo exists)" "exists"- PYTHON = python2- endif-- # ------------------------------------------------------------------------------ # configuration of TEST_HC-- # ghc-config.hs is a short Haskell program that runs ghc --info, parses- # the results, and emits a little .mk file with make bindings for the values.- # This way we cache the results for different values of $(TEST_HC)-- $(TOP)/mk/ghc-config : $(TOP)/mk/ghc-config.hs- "$(TEST_HC)" --make -o $@ $<-- empty=- space=$(empty) $(empty)- ghc-config-mk = $(TOP)/mk/ghcconfig$(subst $(space),_,$(subst :,_,$(subst /,_,$(subst \,_,$(TEST_HC))))).mk-- $(ghc-config-mk) : $(TOP)/mk/ghc-config- $(TOP)/mk/ghc-config "$(TEST_HC)" >"$@"; if [ $$? != 0 ]; then $(RM) "$@"; exit 1; fi- # If the ghc-config fails, remove $@, and fail-- ifeq "$(findstring clean,$(MAKECMDGOALS))" ""- include $(ghc-config-mk)- endif-- ifeq "$(GhcDynamic)" "YES"- ghcThWayFlags = -dynamic- ghciWayFlags = -dynamic- ghcPluginWayFlags = -dynamic- else- ghcThWayFlags = -static- ghciWayFlags = -static- ghcPluginWayFlags = -static- endif-- # ------------------------------------------------------------------------------- ifeq "$(HostOS)" "mingw32"- WINDOWS = YES- else- WINDOWS = NO- endif- ifeq "$(HostOS)" "darwin"- DARWIN = YES- else- DARWIN = NO- endif--EOF-chmod 644 'ghc-test-framework/mk/boilerplate.mk'--mkdir -p 'ghc-test-framework/mk'-sed "s/^ //" <<"EOF" >'ghc-test-framework/mk/ghc-config.hs'- import System.Environment- import System.Process- import Data.Maybe-- main = do- [ghc] <- getArgs-- info <- readProcess ghc ["+RTS", "--info"] ""- let fields = read info :: [(String,String)]- getGhcFieldOrFail fields "HostOS" "Host OS"- getGhcFieldOrFail fields "WORDSIZE" "Word size"- getGhcFieldOrFail fields "TARGETPLATFORM" "Target platform"- getGhcFieldOrFail fields "TargetOS_CPP" "Target OS"- getGhcFieldOrFail fields "TargetARCH_CPP" "Target architecture"-- info <- readProcess ghc ["--info"] ""- let fields = read info :: [(String,String)]-- getGhcFieldOrFail fields "GhcStage" "Stage"- getGhcFieldOrFail fields "GhcDebugged" "Debug on"- getGhcFieldOrFail fields "GhcWithNativeCodeGen" "Have native code generator"- getGhcFieldOrFail fields "GhcWithInterpreter" "Have interpreter"- getGhcFieldOrFail fields "GhcUnregisterised" "Unregisterised"- getGhcFieldOrFail fields "GhcWithSMP" "Support SMP"- getGhcFieldOrFail fields "GhcRTSWays" "RTS ways"- getGhcFieldOrDefault fields "GhcDynamicByDefault" "Dynamic by default" "NO"- getGhcFieldOrDefault fields "GhcDynamic" "GHC Dynamic" "NO"- getGhcFieldProgWithDefault fields "AR" "ar command" "ar"- getGhcFieldProgWithDefault fields "LLC" "LLVM llc command" "llc"-- let pkgdb_flag = case lookup "Project version" fields of- Just v- | parseVersion v >= [7,5] -> "package-db"- _ -> "package-conf"- putStrLn $ "GhcPackageDbFlag" ++ '=':pkgdb_flag--- getGhcFieldOrFail :: [(String,String)] -> String -> String -> IO ()- getGhcFieldOrFail fields mkvar key- = getGhcField fields mkvar key id (fail ("No field: " ++ key))-- getGhcFieldOrDefault :: [(String,String)] -> String -> String -> String -> IO ()- getGhcFieldOrDefault fields mkvar key deflt- = getGhcField fields mkvar key id on_fail- where- on_fail = putStrLn (mkvar ++ '=' : deflt)-- getGhcFieldProgWithDefault- :: [(String,String)]- -> String -> String -> String- -> IO ()- getGhcFieldProgWithDefault fields mkvar key deflt- = getGhcField fields mkvar key fix on_fail- where- fix val = fixSlashes (fixTopdir topdir val)- topdir = fromMaybe "" (lookup "LibDir" fields)- on_fail = putStrLn (mkvar ++ '=' : deflt)-- getGhcField- :: [(String,String)] -> String -> String- -> (String -> String)- -> IO ()- -> IO ()- getGhcField fields mkvar key fix on_fail =- case lookup key fields of- Nothing -> on_fail- Just val -> putStrLn (mkvar ++ '=' : fix val)-- fixTopdir :: String -> String -> String- fixTopdir t "" = ""- fixTopdir t ('$':'t':'o':'p':'d':'i':'r':s) = t ++ s- fixTopdir t (c:s) = c : fixTopdir t s-- fixSlashes :: FilePath -> FilePath- fixSlashes = map f- where f '\\' = '/'- f c = c-- parseVersion :: String -> [Int]- parseVersion v = case break (== '.') v of- (n, rest) -> read n : case rest of- [] -> []- ('.':v') -> parseVersion v'- _ -> error "bug in parseVersion"-EOF-chmod 644 'ghc-test-framework/mk/ghc-config.hs'--mkdir -p 'ghc-test-framework/mk'-sed "s/^ //" <<"EOF" >'ghc-test-framework/mk/test.mk'- # ------------------------------------------------------------------------------ # Examples of use:- #- # make -- run all the tests in the current directory- # make verbose -- as make test, but up the verbosity- # make accept -- run the tests, accepting the current output- #- # The following variables may be set on the make command line:- #- # TEST -- specific test to run- # TESTS -- specific tests to run (same as $TEST really)- # EXTRA_HC_OPTS -- extra flags to send to the Haskell compiler- # EXTRA_RUNTEST_OPTS -- extra flags to give the test driver- # CONFIG -- use a different configuration file- # COMPILER -- select a configuration file from config/- # THREADS -- run n tests at once- #- # ------------------------------------------------------------------------------- # export the value of $MAKE for invocation in tests/driver/- export MAKE-- RUNTESTS = $(TOP)/driver/runtests.py- COMPILER = ghc- CONFIGDIR = $(TOP)/config- CONFIG = $(CONFIGDIR)/$(COMPILER)-- ifeq "$(GhcUnregisterised)" "YES"- # Otherwise C backend generates many warnings about- # imcompatible proto casts for GCC's buitins:- # memcpy, printf, strlen.- EXTRA_HC_OPTS += -optc-fno-builtin- endif-- # TEST_HC_OPTS is passed to every invocation of TEST_HC - # in nested Makefiles- TEST_HC_OPTS = -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-$(GhcPackageDbFlag) -rtsopts $(EXTRA_HC_OPTS)-- # The warning suppression flag below is a temporary kludge. While working with- # tests that contain tabs, please de-tab them so this flag can be eventually- # removed. See- # http://ghc.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces- # for details- #- TEST_HC_OPTS += -fno-warn-tabs-- RUNTEST_OPTS =-- ifeq "$(filter $(TargetOS_CPP), cygwin32 mingw32)" ""- exeext =- else- exeext = .exe- endif-- ifneq "$(filter $(TargetOS_CPP),cygwin32 mingw32)" ""- dllext = .dll- else ifeq "$(TargetOS_CPP)" "darwin"- dllext = .dylib- else- dllext = .so- endif-- RUNTEST_OPTS += -e ghc_compiler_always_flags="'$(TEST_HC_OPTS)'"-- RUNTEST_OPTS += -e ghc_debugged=$(GhcDebugged)-- ifeq "$(GhcWithNativeCodeGen)" "YES"- RUNTEST_OPTS += -e ghc_with_native_codegen=1- else- RUNTEST_OPTS += -e ghc_with_native_codegen=0- endif-- GHC_PRIM_LIBDIR := $(subst library-dirs: ,,$(shell "$(GHC_PKG)" field ghc-prim library-dirs --simple-output))- HAVE_VANILLA := $(shell if [ -f $(subst \,/,$(GHC_PRIM_LIBDIR))/GHC/PrimopWrappers.hi ]; then echo YES; else echo NO; fi)- HAVE_DYNAMIC := $(shell if [ -f $(subst \,/,$(GHC_PRIM_LIBDIR))/GHC/PrimopWrappers.dyn_hi ]; then echo YES; else echo NO; fi)- HAVE_PROFILING := $(shell if [ -f $(subst \,/,$(GHC_PRIM_LIBDIR))/GHC/PrimopWrappers.p_hi ]; then echo YES; else echo NO; fi)-- ifeq "$(HAVE_VANILLA)" "YES"- RUNTEST_OPTS += -e ghc_with_vanilla=1- else- RUNTEST_OPTS += -e ghc_with_vanilla=0- endif-- ifeq "$(HAVE_DYNAMIC)" "YES"- RUNTEST_OPTS += -e ghc_with_dynamic=1- else- RUNTEST_OPTS += -e ghc_with_dynamic=0- endif-- ifeq "$(HAVE_PROFILING)" "YES"- RUNTEST_OPTS += -e ghc_with_profiling=1- else- RUNTEST_OPTS += -e ghc_with_profiling=0- endif-- ifeq "$(filter thr, $(GhcRTSWays))" "thr"- RUNTEST_OPTS += -e ghc_with_threaded_rts=1- else- RUNTEST_OPTS += -e ghc_with_threaded_rts=0- endif-- ifeq "$(filter dyn, $(GhcRTSWays))" "dyn"- RUNTEST_OPTS += -e ghc_with_dynamic_rts=1- else- RUNTEST_OPTS += -e ghc_with_dynamic_rts=0- endif-- ifeq "$(GhcWithInterpreter)" "NO"- RUNTEST_OPTS += -e ghc_with_interpreter=0- else ifeq "$(GhcStage)" "1"- RUNTEST_OPTS += -e ghc_with_interpreter=0- else- RUNTEST_OPTS += -e ghc_with_interpreter=1- endif-- ifeq "$(GhcUnregisterised)" "YES"- RUNTEST_OPTS += -e ghc_unregisterised=1- else- RUNTEST_OPTS += -e ghc_unregisterised=0- endif-- ifeq "$(GhcDynamicByDefault)" "YES"- RUNTEST_OPTS += -e ghc_dynamic_by_default=True- CABAL_MINIMAL_BUILD = --enable-shared --disable-library-vanilla- else- RUNTEST_OPTS += -e ghc_dynamic_by_default=False- CABAL_MINIMAL_BUILD = --enable-library-vanilla --disable-shared- endif-- ifeq "$(GhcDynamic)" "YES"- RUNTEST_OPTS += -e ghc_dynamic=True- CABAL_PLUGIN_BUILD = --enable-shared --disable-library-vanilla- else- RUNTEST_OPTS += -e ghc_dynamic=False- CABAL_PLUGIN_BUILD = --enable-library-vanilla --disable-shared- endif-- ifeq "$(GhcWithSMP)" "YES"- RUNTEST_OPTS += -e ghc_with_smp=1- else- RUNTEST_OPTS += -e ghc_with_smp=0- endif-- ifeq "$(LLC)" ""- RUNTEST_OPTS += -e ghc_with_llvm=0- else ifneq "$(LLC)" "llc"- # If we have a real detected value for LLVM, then it really ought to work- RUNTEST_OPTS += -e ghc_with_llvm=1- else ifneq "$(shell $(SHELL) -c 'llc --version | grep version' 2> /dev/null)" ""- RUNTEST_OPTS += -e ghc_with_llvm=1- else- RUNTEST_OPTS += -e ghc_with_llvm=0- endif-- ifeq "$(WINDOWS)" "YES"- RUNTEST_OPTS += -e windows=True- else- RUNTEST_OPTS += -e windows=False- endif-- ifeq "$(DARWIN)" "YES"- RUNTEST_OPTS += -e darwin=True- else- RUNTEST_OPTS += -e darwin=False- endif-- ifeq "$(IN_TREE_COMPILER)" "YES"- RUNTEST_OPTS += -e in_tree_compiler=True- else- RUNTEST_OPTS += -e in_tree_compiler=False- endif-- ifneq "$(THREADS)" ""- RUNTEST_OPTS += --threads=$(THREADS)- endif-- ifneq "$(VERBOSE)" ""- RUNTEST_OPTS += --verbose=$(VERBOSE)- endif-- ifeq "$(SKIP_PERF_TESTS)" "YES"- RUNTEST_OPTS += --skip-perf-tests- endif-- ifneq "$(CLEAN_ONLY)" ""- RUNTEST_OPTS += -e clean_only=True- else- RUNTEST_OPTS += -e clean_only=False- endif-- ifneq "$(CHECK_FILES_WRITTEN)" ""- RUNTEST_OPTS += --check-files-written- endif-- RUNTEST_OPTS += \- --rootdir=. \- --config=$(CONFIG) \- -e 'config.confdir="$(CONFIGDIR)"' \- -e 'config.platform="$(TARGETPLATFORM)"' \- -e 'config.os="$(TargetOS_CPP)"' \- -e 'config.arch="$(TargetARCH_CPP)"' \- -e 'config.wordsize="$(WORDSIZE)"' \- -e 'default_testopts.cleanup="$(CLEANUP)"' \- -e 'config.timeout=int($(TIMEOUT)) or config.timeout' \- -e 'config.exeext="$(exeext)"' \- -e 'config.top="$(TOP_ABS)"'-- # Put an extra pair of quotes around program paths,- # so we don't have to in .T scripts or driver/testlib.py.- RUNTEST_OPTS += \- -e 'config.compiler="\"$(TEST_HC)\""' \- -e 'config.ghc_pkg="\"$(GHC_PKG)\""' \- -e 'config.hp2ps="\"$(HP2PS_ABS)\""' \- -e 'config.hpc="\"$(HPC)\""' \- -e 'config.gs="\"$(GS)\""' \- -e 'config.timeout_prog="\"$(TIMEOUT_PROGRAM)\""'-- ifneq "$(OUTPUT_SUMMARY)" ""- RUNTEST_OPTS += \- --output-summary "$(OUTPUT_SUMMARY)"- endif-- RUNTEST_OPTS += \- $(EXTRA_RUNTEST_OPTS)-- ifeq "$(list_broken)" "YES"- set_list_broken = -e config.list_broken=True- else- set_list_broken = - endif-- ifeq "$(fast)" "YES"- setfast = -e config.fast=1- else- setfast = - endif-- ifeq "$(accept)" "YES"- setaccept = -e config.accept=1- else- setaccept = - endif-- TESTS = - TEST = - WAY =-- .PHONY: all boot test verbose accept fast list_broken-- all: test-- TIMEOUT_PROGRAM = $(TOP)/timeout/install-inplace/bin/timeout$(exeext)-- boot: $(TIMEOUT_PROGRAM)-- $(TIMEOUT_PROGRAM) :- @echo "Looks like you don't have timeout, building it first..."- $(MAKE) -C $(TOP)/timeout all-- test: $(TIMEOUT_PROGRAM)- $(PYTHON) $(RUNTESTS) $(RUNTEST_OPTS) \- $(patsubst %, --only=%, $(TEST)) \- $(patsubst %, --only=%, $(TESTS)) \- $(patsubst %, --way=%, $(WAY)) \- $(patsubst %, --skipway=%, $(SKIPWAY)) \- $(set_list_broken) \- $(setfast) \- $(setaccept)-- verbose: test-- accept:- $(MAKE) accept=YES-- fast:- $(MAKE) fast=YES-- list_broken:- $(MAKE) list_broken=YES--EOF-chmod 644 'ghc-test-framework/mk/test.mk'--mkdir -p 'ghc-test-framework/timeout'-sed "s/^ //" <<"EOF" >'ghc-test-framework/timeout/Makefile'- TOP = ..-- # If we're cleaning then we don't want to do all the GHC detection hardwork,- # and we certainly don't want to fail if GHC etc can't be found!- # However, we can't just put this conditional in boilerplate.mk, as- # some of the tests have a "clean" makefile target that relies on GHC_PKG- # being defined.- ifneq "$(MAKECMDGOALS)" "clean"- ifneq "$(MAKECMDGOALS)" "distclean"- ifneq "$(MAKECMDGOALS)" "maintainer-clean"-- include $(TOP)/mk/boilerplate.mk-- TIMEOUT_PROGRAM = install-inplace/bin/timeout$(exeext)-- PREFIX := $(abspath install-inplace)- $(eval $(call canonicalise,PREFIX))-- ifneq "$(GCC)" ""- WITH_GCC = --with-gcc='$(GCC)'- endif-- ifeq "$(WINDOWS)" "NO"- # Use a python timeout program, so that we don't have to worry about- # whether or not the compiler we're testing has built the timeout- # program correctly- $(TIMEOUT_PROGRAM): timeout.py- rm -rf install-inplace- mkdir install-inplace- mkdir install-inplace/bin- cp $< $@.py- echo '#!/bin/sh' > $@- echo 'exec "${PYTHON}" $$0.py "$$@"' >> $@- chmod +x $@- else- # The python timeout program doesn't work on mingw, so we still use the- # Haskell program on Windows- $(TIMEOUT_PROGRAM): timeout.hs- rm -rf install-inplace- '$(TEST_HC)' --make Setup- ./Setup configure --with-compiler='$(TEST_HC)' \- --with-hc-pkg='$(GHC_PKG)' \- --with-hsc2hs='$(HSC2HS)' \- $(WITH_GCC) \- --ghc-option=-threaded --prefix='$(PREFIX)'- ./Setup build- ./Setup install- endif-- boot all :: calibrate.out $(TIMEOUT_PROGRAM)-- calibrate.out:- $(RM) -f TimeMe.o TimeMe.hi TimeMe TimeMe.exe- $(PYTHON) calibrate '$(GHC_STAGE1)' > $@- # We use stage 1 to do the calibration, as stage 2 may not exist.- # This isn't necessarily the compiler we'll be running the testsuite- # with, but it's really the performance of the machine that we're- # interested in-- endif- endif- endif-- clean distclean maintainer-clean:- -./Setup clean- $(RM) -rf install-inplace- $(RM) -f calibrate.out- $(RM) -f Setup Setup.exe Setup.hi Setup.o--EOF-chmod 644 'ghc-test-framework/timeout/Makefile'--mkdir -p 'ghc-test-framework/timeout'-sed "s/^ //" <<"EOF" >'ghc-test-framework/timeout/Setup.hs'- module Main (main) where-- import Distribution.Simple-- main :: IO ()- main = defaultMain-EOF-chmod 644 'ghc-test-framework/timeout/Setup.hs'--mkdir -p 'ghc-test-framework/timeout'-sed "s/^ //" <<"EOF" >'ghc-test-framework/timeout/TimeMe.hs'- module Main (main) where-- import System.IO-- main = hPutStr stderr ""--EOF-chmod 644 'ghc-test-framework/timeout/TimeMe.hs'--mkdir -p 'ghc-test-framework/timeout'-sed "s/^ //" <<"EOF" >'ghc-test-framework/timeout/WinCBindings.hsc'- {-# LANGUAGE CPP, ForeignFunctionInterface #-}- module WinCBindings where-- #if defined(mingw32_HOST_OS)-- import Foreign- import System.Win32.File- import System.Win32.Types-- #include <windows.h>-- type LPPROCESS_INFORMATION = Ptr PROCESS_INFORMATION- data PROCESS_INFORMATION = PROCESS_INFORMATION- { piProcess :: HANDLE- , piThread :: HANDLE- , piProcessId :: DWORD- , piThreadId :: DWORD- } deriving Show-- instance Storable PROCESS_INFORMATION where- sizeOf = const #size PROCESS_INFORMATION- alignment = sizeOf- poke buf pi = do- (#poke PROCESS_INFORMATION, hProcess) buf (piProcess pi)- (#poke PROCESS_INFORMATION, hThread) buf (piThread pi)- (#poke PROCESS_INFORMATION, dwProcessId) buf (piProcessId pi)- (#poke PROCESS_INFORMATION, dwThreadId) buf (piThreadId pi)-- peek buf = do- vhProcess <- (#peek PROCESS_INFORMATION, hProcess) buf- vhThread <- (#peek PROCESS_INFORMATION, hThread) buf- vdwProcessId <- (#peek PROCESS_INFORMATION, dwProcessId) buf- vdwThreadId <- (#peek PROCESS_INFORMATION, dwThreadId) buf- return $ PROCESS_INFORMATION {- piProcess = vhProcess,- piThread = vhThread,- piProcessId = vdwProcessId,- piThreadId = vdwThreadId}-- type LPSTARTUPINFO = Ptr STARTUPINFO- data STARTUPINFO = STARTUPINFO- { siCb :: DWORD- , siDesktop :: LPTSTR- , siTitle :: LPTSTR- , siX :: DWORD- , siY :: DWORD- , siXSize :: DWORD- , siYSize :: DWORD- , siXCountChars :: DWORD- , siYCountChars :: DWORD- , siFillAttribute :: DWORD- , siFlags :: DWORD- , siShowWindow :: WORD- , siStdInput :: HANDLE- , siStdOutput :: HANDLE- , siStdError :: HANDLE- } deriving Show-- instance Storable STARTUPINFO where- sizeOf = const #size STARTUPINFO- alignment = sizeOf- poke buf si = do- (#poke STARTUPINFO, cb) buf (siCb si)- (#poke STARTUPINFO, lpDesktop) buf (siDesktop si)- (#poke STARTUPINFO, lpTitle) buf (siTitle si)- (#poke STARTUPINFO, dwX) buf (siX si)- (#poke STARTUPINFO, dwY) buf (siY si)- (#poke STARTUPINFO, dwXSize) buf (siXSize si)- (#poke STARTUPINFO, dwYSize) buf (siYSize si)- (#poke STARTUPINFO, dwXCountChars) buf (siXCountChars si)- (#poke STARTUPINFO, dwYCountChars) buf (siYCountChars si)- (#poke STARTUPINFO, dwFillAttribute) buf (siFillAttribute si)- (#poke STARTUPINFO, dwFlags) buf (siFlags si)- (#poke STARTUPINFO, wShowWindow) buf (siShowWindow si)- (#poke STARTUPINFO, hStdInput) buf (siStdInput si)- (#poke STARTUPINFO, hStdOutput) buf (siStdOutput si)- (#poke STARTUPINFO, hStdError) buf (siStdError si)-- peek buf = do- vcb <- (#peek STARTUPINFO, cb) buf- vlpDesktop <- (#peek STARTUPINFO, lpDesktop) buf- vlpTitle <- (#peek STARTUPINFO, lpTitle) buf- vdwX <- (#peek STARTUPINFO, dwX) buf- vdwY <- (#peek STARTUPINFO, dwY) buf- vdwXSize <- (#peek STARTUPINFO, dwXSize) buf- vdwYSize <- (#peek STARTUPINFO, dwYSize) buf- vdwXCountChars <- (#peek STARTUPINFO, dwXCountChars) buf- vdwYCountChars <- (#peek STARTUPINFO, dwYCountChars) buf- vdwFillAttribute <- (#peek STARTUPINFO, dwFillAttribute) buf- vdwFlags <- (#peek STARTUPINFO, dwFlags) buf- vwShowWindow <- (#peek STARTUPINFO, wShowWindow) buf- vhStdInput <- (#peek STARTUPINFO, hStdInput) buf- vhStdOutput <- (#peek STARTUPINFO, hStdOutput) buf- vhStdError <- (#peek STARTUPINFO, hStdError) buf- return $ STARTUPINFO {- siCb = vcb,- siDesktop = vlpDesktop,- siTitle = vlpTitle,- siX = vdwX,- siY = vdwY,- siXSize = vdwXSize,- siYSize = vdwYSize,- siXCountChars = vdwXCountChars,- siYCountChars = vdwYCountChars,- siFillAttribute = vdwFillAttribute,- siFlags = vdwFlags,- siShowWindow = vwShowWindow,- siStdInput = vhStdInput,- siStdOutput = vhStdOutput,- siStdError = vhStdError}-- foreign import stdcall unsafe "windows.h WaitForSingleObject"- waitForSingleObject :: HANDLE -> DWORD -> IO DWORD-- cWAIT_ABANDONED :: DWORD- cWAIT_ABANDONED = #const WAIT_ABANDONED-- cWAIT_OBJECT_0 :: DWORD- cWAIT_OBJECT_0 = #const WAIT_OBJECT_0-- cWAIT_TIMEOUT :: DWORD- cWAIT_TIMEOUT = #const WAIT_TIMEOUT-- foreign import stdcall unsafe "windows.h GetExitCodeProcess"- getExitCodeProcess :: HANDLE -> LPDWORD -> IO BOOL-- foreign import stdcall unsafe "windows.h TerminateJobObject"- terminateJobObject :: HANDLE -> UINT -> IO BOOL-- foreign import stdcall unsafe "windows.h AssignProcessToJobObject"- assignProcessToJobObject :: HANDLE -> HANDLE -> IO BOOL-- foreign import stdcall unsafe "windows.h CreateJobObjectW"- createJobObjectW :: LPSECURITY_ATTRIBUTES -> LPCTSTR -> IO HANDLE-- foreign import stdcall unsafe "windows.h CreateProcessW"- createProcessW :: LPCTSTR -> LPTSTR- -> LPSECURITY_ATTRIBUTES -> LPSECURITY_ATTRIBUTES- -> BOOL -> DWORD -> LPVOID -> LPCTSTR -> LPSTARTUPINFO- -> LPPROCESS_INFORMATION -> IO BOOL-- #endif--EOF-chmod 644 'ghc-test-framework/timeout/WinCBindings.hsc'--mkdir -p 'ghc-test-framework/timeout'-sed "s/^ //" <<"EOF" >'ghc-test-framework/timeout/calibrate'- #!/usr/bin/env python-- import math- import os- from os import *- from sys import *- try:- from resource import *- except:- # We don't have resource, so this is a non-UNIX machine.- # It's probably a reasonable modern x86/x86_64 machines, so we'd- # probably calibrate to 300 anyway; thus just print 300.- print(300)- exit(0)-- compiler = argv[1]- compiler_name = os.path.basename(compiler)-- spawnl(os.P_WAIT, compiler,- compiler_name, 'TimeMe.hs', '-o', 'TimeMe', '-O2')- spawnl(os.P_WAIT, './TimeMe', 'TimeMe')-- xs = getrusage(RUSAGE_CHILDREN);- x = int(math.ceil(xs[0] + xs[1]))- if x < 1:- x = 1- print (300*x)--EOF-chmod 644 'ghc-test-framework/timeout/calibrate'--mkdir -p 'ghc-test-framework/timeout'-sed "s/^ //" <<"EOF" >'ghc-test-framework/timeout/timeout.cabal'- Name: timeout- Version: 1- Copyright: GHC Team- License: BSD3- Author: GHC Team <cvs-ghc@haskell.org>- Maintainer: GHC Team <cvs-ghc@haskell.org>- Synopsis: timout utility- Description: timeout utility- Category: Development- build-type: Simple- cabal-version: >=1.2-- Executable timeout- Main-Is: timeout.hs- Other-Modules: WinCBindings- Extensions: CPP- Build-Depends: base, process- if os(windows)- Build-Depends: Win32- else- Build-Depends: unix--EOF-chmod 644 'ghc-test-framework/timeout/timeout.cabal'--mkdir -p 'ghc-test-framework/timeout'-sed "s/^ //" <<"EOF" >'ghc-test-framework/timeout/timeout.hs'- {-# OPTIONS -cpp #-}- module Main where-- import Control.Concurrent (forkIO, threadDelay)- import Control.Concurrent.MVar (putMVar, takeMVar, newEmptyMVar)- import Control.Monad- import Control.Exception- import Data.Maybe (isNothing)- import System.Environment (getArgs)- import System.Exit- import System.IO (hPutStrLn, stderr)-- #if !defined(mingw32_HOST_OS)- import System.Posix hiding (killProcess)- import System.IO.Error hiding (try,catch)- #endif-- #if defined(mingw32_HOST_OS)- import System.Process- import WinCBindings- import Foreign- import System.Win32.DebugApi- import System.Win32.Types- #endif-- main :: IO ()- main = do- args <- getArgs- case args of- [secs,cmd] ->- case reads secs of- [(secs', "")] -> run secs' cmd- _ -> ((>> exitFailure) . hPutStrLn stderr) ("Can't parse " ++ show secs ++ " as a number of seconds")- _ -> ((>> exitFailure) . hPutStrLn stderr) ("Bad arguments " ++ show args)-- timeoutMsg :: String- timeoutMsg = "Timeout happened...killing process..."-- run :: Int -> String -> IO ()- #if !defined(mingw32_HOST_OS)- run secs cmd = do- m <- newEmptyMVar- mp <- newEmptyMVar- installHandler sigINT (Catch (putMVar m Nothing)) Nothing- forkIO $ do threadDelay (secs * 1000000)- putMVar m Nothing- forkIO $ do ei <- try $ do pid <- systemSession cmd- return pid- putMVar mp ei- case ei of- Left _ -> return ()- Right pid -> do- r <- getProcessStatus True False pid- putMVar m r- ei_pid_ph <- takeMVar mp- case ei_pid_ph of- Left e -> do hPutStrLn stderr- ("Timeout:\n" ++ show (e :: IOException))- exitWith (ExitFailure 98)- Right pid -> do- r <- takeMVar m- case r of- Nothing -> do- hPutStrLn stderr timeoutMsg- killProcess pid- exitWith (ExitFailure 99)- Just (Exited r) -> exitWith r- Just (Terminated s) -> raiseSignal s- Just _ -> exitWith (ExitFailure 1)-- systemSession cmd =- forkProcess $ do- createSession- executeFile "/bin/sh" False ["-c", cmd] Nothing- -- need to use exec() directly here, rather than something like- -- System.Process.system, because we are in a forked child and some- -- pthread libraries get all upset if you start doing certain- -- things in a forked child of a pthread process, such as forking- -- more threads.-- killProcess pid = do- ignoreIOExceptions (signalProcessGroup sigTERM pid)- checkReallyDead 10- where- checkReallyDead 0 = hPutStrLn stderr "checkReallyDead: Giving up"- checkReallyDead (n+1) =- do threadDelay (3*100000) -- 3/10 sec- m <- tryJust (guard . isDoesNotExistError) $- getProcessStatus False False pid- case m of- Right Nothing -> return ()- Left _ -> return ()- _ -> do- ignoreIOExceptions (signalProcessGroup sigKILL pid)- checkReallyDead n-- ignoreIOExceptions :: IO () -> IO ()- ignoreIOExceptions io = io `catch` ((\_ -> return ()) :: IOException -> IO ())-- #else- run secs cmd =- let escape '\\' = "\\\\"- escape '"' = "\\\""- escape c = [c]- cmd' = "sh -c \"" ++ concatMap escape cmd ++ "\"" in- alloca $ \p_startupinfo ->- alloca $ \p_pi ->- withTString cmd' $ \cmd'' ->- do job <- createJobObjectW nullPtr nullPtr- let creationflags = 0- b <- createProcessW nullPtr cmd'' nullPtr nullPtr True- creationflags- nullPtr nullPtr p_startupinfo p_pi- unless b $ errorWin "createProcessW"- pi <- peek p_pi- assignProcessToJobObject job (piProcess pi)- resumeThread (piThread pi)-- -- The program is now running-- let handle = piProcess pi- let millisecs = secs * 1000- rc <- waitForSingleObject handle (fromIntegral millisecs)- if rc == cWAIT_TIMEOUT- then do hPutStrLn stderr timeoutMsg- terminateJobObject job 99- exitWith (ExitFailure 99)- else alloca $ \p_exitCode ->- do r <- getExitCodeProcess handle p_exitCode- if r then do ec <- peek p_exitCode- let ec' = if ec == 0- then ExitSuccess- else ExitFailure $ fromIntegral ec- exitWith ec'- else errorWin "getExitCodeProcess"- #endif--EOF-chmod 644 'ghc-test-framework/timeout/timeout.hs'--mkdir -p 'ghc-test-framework/timeout'-sed "s/^ //" <<"EOF" >'ghc-test-framework/timeout/timeout.py'- #!/usr/bin/env python-- try:-- import errno- import os- import signal- import sys- import time-- secs = int(sys.argv[1])- cmd = sys.argv[2]-- def killProcess(pid):- os.killpg(pid, signal.SIGKILL)- for x in range(10):- try:- time.sleep(0.3)- r = os.waitpid(pid, os.WNOHANG)- if r == (0, 0):- os.killpg(pid, signal.SIGKILL)- else:- return- except OSError as e:- if e.errno == errno.ECHILD:- return- else:- raise e-- pid = os.fork()- if pid == 0:- # child- os.setpgrp()- os.execvp('/bin/sh', ['/bin/sh', '-c', cmd])- else:- # parent- def handler(signum, frame):- sys.stderr.write('Timeout happened...killing process...\n')- killProcess(pid)- sys.exit(99)- old = signal.signal(signal.SIGALRM, handler)- signal.alarm(secs)- (pid2, res) = os.waitpid(pid, 0)- if (os.WIFEXITED(res)):- sys.exit(os.WEXITSTATUS(res))- else:- sys.exit(res)-- except KeyboardInterrupt:- sys.exit(98)- except:- raise--EOF-chmod 644 'ghc-test-framework/timeout/timeout.py'
− tools/run-tests
@@ -1,52 +0,0 @@-#!/bin/sh-# run all of the tests under the `tests` directory using the GHC test-# framework; for more info about this framework, see:-# https://ghc.haskell.org/trac/ghc/wiki/Building/RunningTests-#-# arguments received by this script are passed as arguments to the `make`-# invocation that initiates the tests-set -e--# check if `-package-db` is supported (didn't exist until 1.20)-# note that we don't use `-package-db` directly because older versions will-# interpret it as `-package -db`-if ghc 2>&1 -no-user-package-db |- grep >/dev/null 2>&1 "ghc: unrecognised flags: -no-user-package-db"-then db=conf-else db=db-fi--[ -z "$HSFLAGS" ] || HSFLAGS=\ $HSFLAGS-HSFLAGS="-package-$db ../dist/package.conf.inplace$HSFLAGS"-HSFLAGS="-optP-include -optP../dist/build/autogen/cabal_macros.h $HSFLAGS"-export HSFLAGS--# extract the test framework if needed-[ -f dist/testsuite/ghc-test-framework.ok ] || (- set -e- mkdir -p dist/testsuite- cd dist/testsuite- rm -fr ghc-test-framework- sh- touch ghc-test-framework.ok-) <tools/ghc-test-framework.shar--# we can't just specify `TOP` as an argument for `make` because it will-# override `TOP` for *every* included makefile-sed >dist/testsuite/Makefile \- "s|^TOP=.*$|TOP=../dist/testsuite/ghc-test-framework|" \- tests/Makefile--cd tests-make -f ../dist/testsuite/Makefile WAY=normal EXTRA_HC_OPTS="$HSFLAGS" "$@" |- tee ../dist/testsuite/test.out--# since the test framework doesn't report an exit status, we need to manually-# find out whether the test had any failures>-{- grep '^ *0 had missing libraries$' ../dist/testsuite/test.out- grep '^ *0 caused framework failures$' ../dist/testsuite/test.out- grep '^ *0 unexpected passes$' ../dist/testsuite/test.out- grep '^ *0 unexpected failures$' ../dist/testsuite/test.out- grep '^ *0 unexpected stat failures$' ../dist/testsuite/test.out-} >/dev/null 2>/dev/null