packages feed

pathtype 0.5.5 → 0.6

raw patch · 8 files changed

+951/−496 lines, 8 files

Files

pathtype.cabal view
@@ -1,5 +1,5 @@ Name:                pathtype-Version:             0.5.5+Version:             0.6 Synopsis:            Type-safe replacement for System.FilePath etc Description:         This package provides type-safe access to filepath manipulations. 		     .@@ -73,7 +73,15 @@ 		     The basic API (and properties satisfied) are heavily influenced 		     by Neil Mitchell's "System.FilePath" module.                      .+                     Related packages:                      .+                     * @path@: Provides a wrapper type around 'FilePath'+                       and maps to functions from @filepath@ package.+                       This warrants consistency with @filepath@ functions.+                       Requires Template Haskell.+                     .+                     * @data-filepath@:+                       Requires 'Typeable' and Template Haskell. Stability:           experimental License:             BSD3 Category:            System@@ -94,7 +102,7 @@   Location: http://hub.darcs.net/thielema/pathtype/  Source-Repository this-  Tag:      0.5.5+  Tag:      0.6   Type:     darcs   Location: http://hub.darcs.net/thielema/pathtype/ 
src/System/Path/Directory.hs view
@@ -166,11 +166,14 @@ copyFile :: (AbsRelClass ar1, AbsRelClass ar2) => FilePath ar1 -> FilePath ar2 -> IO () copyFile p1 p2 = SD.copyFile (getPathString p1) (getPathString p2) -canonicalizePath :: AbsRelClass ar => Path ar fd -> IO (AbsPath fd)+canonicalizePath ::+    (AbsRelClass ar, FileDirClass fd) => Path ar fd -> IO (AbsPath fd) canonicalizePath p = asPath <$> SD.canonicalizePath (getPathString p) -makeRelativeToCurrentDirectory :: AbsRelClass ar => Path ar fd -> IO (RelPath fd)-makeRelativeToCurrentDirectory p = asPath <$> SD.makeRelativeToCurrentDirectory (getPathString p)+makeRelativeToCurrentDirectory ::+    (AbsRelClass ar, FileDirClass fd) => Path ar fd -> IO (RelPath fd)+makeRelativeToCurrentDirectory p =+    asPath <$> SD.makeRelativeToCurrentDirectory (getPathString p)  findExecutable :: String -> IO (Maybe AbsFile) findExecutable s = fmap asPath <$> SD.findExecutable s@@ -189,15 +192,18 @@ ------------------------------------------------------------------------ -- Permissions -getPermissions :: AbsRelClass ar => Path ar fd -> IO Permissions+getPermissions ::+    (AbsRelClass ar, FileDirClass fd) => Path ar fd -> IO Permissions getPermissions p = SD.getPermissions (getPathString p) -setPermissions :: AbsRelClass ar => Path ar fd -> Permissions -> IO ()+setPermissions ::+    (AbsRelClass ar, FileDirClass fd) => Path ar fd -> Permissions -> IO () setPermissions p perms = SD.setPermissions (getPathString p) perms   ------------------------------------------------------------------------ -- Timestamps -getModificationTime :: AbsRelClass ar => Path ar fd -> IO UTCTime+getModificationTime ::+    (AbsRelClass ar, FileDirClass fd) => Path ar fd -> IO UTCTime getModificationTime p = convertTime <$> SD.getModificationTime (getPathString p)
src/System/Path/Internal.hs view
@@ -116,12 +116,14 @@  import qualified System.Directory as SD -import Control.Arrow (first, (|||), (***))+import Control.Arrow (first, second, (|||), (***))+import Control.Monad (guard, mplus) import Control.Applicative ((<$>)) import Control.DeepSeq (NFData(rnf))-import Data.List (isSuffixOf, isPrefixOf, stripPrefix, intercalate)+import Data.List (isSuffixOf, isPrefixOf, stripPrefix, intersperse) import Data.String (IsString(fromString))-import Data.Char (isSpace)+import Data.Maybe (fromMaybe, maybeToList)+import Data.Char (toLower, isAlpha, isSpace)  import Text.Printf (printf) @@ -136,29 +138,75 @@ ------------------------------------------------------------------------ -- Types -data Abs-data Rel-data File-data Dir+newtype Abs = Abs String deriving (Eq, Ord)+data Rel = Rel deriving (Eq, Ord) +newtype File = File PathComponent deriving (Eq, Ord)+data Dir  = Dir deriving (Eq, Ord)+ -- | This is the main filepath abstract datatype-data Path ar fd = PathRoot -- ^ Invariant - this should always have type :: DirPath ar-                | FileDir !(DirPath ar) !PathComponent -- The fact that we recurse binding fd to Dir-                                                       -- makes this a "nested datatype"-                  deriving (Eq, Ord)+data Path ar fd = Path ar [PathComponent] fd --- Possible GADT version...------ data Path ar fd where---   AbsRoot :: Path Abs Dir---   RelRoot :: Path Rel Dir---   File    :: Path ar Dir -> PathComponent -> Path ar File---   Dir     :: Path ar Dir -> PathComponent -> Path ar Dir------ ... doesn't presently seem to add much value over non-GADT.+instance (AbsRelClass ar, FileDirClass fd) => Eq (Path ar fd) where+    Path ar0 pcs0 fd0 == Path ar1 pcs1 fd1  =+        (WrapAbsRel ar0, pcs0, WrapFileDir fd0)+        ==+        (WrapAbsRel ar1, pcs1, WrapFileDir fd1) -newtype PathComponent = PathComponent String deriving (Eq,Ord)+instance (AbsRelClass ar, FileDirClass fd) => Ord (Path ar fd) where+    compare (Path ar0 pcs0 fd0) (Path ar1 pcs1 fd1)  =+        compare+            (WrapAbsRel ar0, pcs0, WrapFileDir fd0)+            (WrapAbsRel ar1, pcs1, WrapFileDir fd1) ++newtype WrapAbsRel ar = WrapAbsRel {unwrapAbsRel :: ar}++instance (AbsRelClass ar) => Eq (WrapAbsRel ar) where+    (==) = switchRelation switchAbsRel unwrapAbsRel (==) (==)++instance (AbsRelClass ar) => Ord (WrapAbsRel ar) where+    compare = switchRelation switchAbsRel unwrapAbsRel compare compare+++newtype WrapFileDir fd = WrapFileDir {unwrapFileDir :: fd}++instance (FileDirClass fd) => Eq (WrapFileDir fd) where+    (==) = switchRelation switchFileDir unwrapFileDir (==) (==)++instance (FileDirClass fd) => Ord (WrapFileDir fd) where+    compare = switchRelation switchFileDir unwrapFileDir compare compare+++newtype Relation res a = Relation {runRelation :: a -> a -> res}++switchRelation ::+    (Relation res a -> Relation res b -> Relation res c) ->+    (wrapped -> c) ->+    (a -> a -> res) ->+    (b -> b -> res) ->+    wrapped -> wrapped -> res+switchRelation switch unwrap fFile fDir ar0 ar1 =+    runRelation+        (switch (Relation fFile) (Relation fDir))+        (unwrap ar0) (unwrap ar1)+++newtype PathComponent = PathComponent String++instance Eq PathComponent where+    PathComponent x == PathComponent y  =+        if isPosix+          then x==y+          else map toLower x == map toLower y++instance Ord PathComponent where+    compare (PathComponent x) (PathComponent y) =+        if isPosix+          then compare x y+          else compare (map toLower x) (map toLower y)++ type AbsFile = Path Abs File type RelFile = Path Rel File type AbsDir  = Path Abs Dir@@ -172,10 +220,32 @@ instance NFData PathComponent where     rnf (PathComponent pc) = rnf pc -instance NFData (Path ar fd) where-    rnf PathRoot = ()-    rnf (FileDir d pc) = rnf (d, pc)+instance NFData Abs where+    rnf (Abs drive) = rnf drive +instance NFData Rel where+    rnf Rel = ()++instance NFData File where+    rnf (File pc) = rnf pc++instance NFData Dir where+    rnf Dir = ()++instance (AbsRelClass ar, FileDirClass fd) => NFData (Path ar fd) where+    rnf (Path ar pcs fd) =+        rnf (absRelPlain rnf rnf ar, pcs, fileDirPlain rnf rnf fd)++absRelPlain :: (AbsRelClass ar) => (Abs -> a) -> (Rel -> a) -> ar -> a+absRelPlain fAbs fRel =+    runFuncArg $ switchAbsRel (FuncArg fAbs) (FuncArg fRel)++fileDirPlain :: (FileDirClass fd) => (File -> a) -> (Dir -> a) -> fd -> a+fileDirPlain fFile fDir =+    runFuncArg $ switchFileDir (FuncArg fFile) (FuncArg fDir)++newtype FuncArg b a = FuncArg {runFuncArg :: a -> b}+ -- I don't think this basic type of fold is appropriate for a nested datatype -- pathFold :: a -> (a -> String -> a) -> Path ar fd -> a -- pathFold pr f PathRoot = pr@@ -183,12 +253,17 @@  -- | Map over the components of the path. ----- >> pathMap (map toLower) "/tmp/Reports/SpreadSheets" == "/tmp/reports/spreadsheets"-pathMap :: (String -> String) -> Path ar fd -> Path ar fd-pathMap _ PathRoot = PathRoot-pathMap f (FileDir d pc) = FileDir (pathMap f d) (pcMap f pc)+-- >> Posix.pathMap (map toLower) "/tmp/Reports/SpreadSheets" == Posix.asAbsDir "/tmp/reports/spreadsheets"+pathMap :: (FileDirClass fd) => (String -> String) -> Path ar fd -> Path ar fd+pathMap f (Path ar pcs fd) = Path ar (map (pcMap f) pcs) (fdMap f fd) --- Private fn+newtype FDMap ar fd = FDMap {runFDMap :: fd -> fd}++fdMap :: (FileDirClass fd) => (String -> String) -> fd -> fd+fdMap f =+    runFDMap $+    switchFileDir (FDMap $ \(File pc) -> File $ pcMap f pc) (FDMap id)+ pcMap :: (String -> String) -> PathComponent -> PathComponent pcMap f (PathComponent s) = PathComponent (f s) @@ -226,9 +301,9 @@     switchFileDir :: f File -> f Dir -> f fd     -- | Will become a top-level function in future     fileDir :: (FilePath ar -> a) -> (DirPath ar -> a) -> Path ar fd -> a-    fileDir f g = runFileDir $ switchFileDir (FileDirFunc f) (FileDirFunc g)+    fileDir f g = runFileDir $ switchFileDir (FileDir f) (FileDir g) -newtype FileDir ar a fd = FileDirFunc {runFileDir :: Path ar fd -> a}+newtype FileDir ar a fd = FileDir {runFileDir :: Path ar fd -> a}  instance FileDirClass File where switchFileDir f _g = f instance FileDirClass Dir  where switchFileDir _f g = g@@ -245,62 +320,86 @@ ------------------------------------------------------------------------ -- Read & Show instances --- >> show (rootDir </> "bla" </> "blub") == "rootDir </> \"bla\" </> \"blub\""--- >> show (Just (rootDir </> "bla" </> "blub")) == "Just (rootDir </> \"bla\" </> \"blub\")"--- >> show (currentDir </> "bla" </> "blub") == "currentDir </> \"bla\" </> \"blub\""--- >> show (Just (currentDir </> "bla" </> "blub")) == "Just (currentDir </> \"bla\" </> \"blub\")"-instance AbsRelClass ar => Show (Path ar fd) where-    showsPrec d =-        let go :: AbsRelClass ar => Path ar fd -> ShowS-            go x@PathRoot =-                absRel (const $ showString rootName) (const $ showString currentName) x-            go (FileDir p (PathComponent pc)) =-                go p . showChar ' ' .-                showString combineOperator . showChar ' ' . shows pc-        in  showParen (d>9) . go+-- >> show (Posix.rootDir </> "bla" </> Posix.asRelFile "blub") == "rootDir </> \"bla\" </> \"blub\""+-- >> show (Just (Posix.rootDir </> "bla" </> Posix.asRelFile "blub")) == "Just (rootDir </> \"bla\" </> \"blub\")"+-- >> show (Posix.currentDir </> "bla" </> Posix.asRelFile "blub") == "currentDir </> \"bla\" </> \"blub\""+-- >> show (Just (Posix.currentDir </> "bla" </> Posix.asRelFile "blub")) == "Just (currentDir </> \"bla\" </> \"blub\")"+-- >> show (Windows.asAbsDir "c:" Windows.</> "bla" Windows.</> Windows.asRelFile "blub") == "asAbsDir \"c:\" </> \"bla\" </> \"blub\""+-- >> show (Just (Windows.asAbsDir "c:\\" Windows.</> "bla" Windows.</> Windows.asRelFile "blub")) == "Just (asAbsDir \"c:\" </> \"bla\" </> \"blub\")"+instance (AbsRelClass ar, FileDirClass fd) => Show (Path ar fd) where+    showsPrec d x =+        case pathComponents x of+            (ar, pcs) ->+                showParen (d>9) $+                foldr (.) id $+                intersperse+                    (showChar ' ' .+                     showString combineOperator . showChar ' ') $+                absRelPlain+                    (\(Abs drive) ->+                        if null drive+                          then showString rootName+                          else showString absDirName .+                               showString drive .+                               showChar '"')+                    (const $ showString currentName)+                    ar :+                map (\(PathComponent pc) -> shows pc) pcs --- >> read (show (rootDir </> "bla" </> "blub")) == rootDir </> "bla" </> "blub"--- >> read (show (Just (rootDir </> "bla" </> "blub"))) == Just (rootDir </> "bla" </> "blub")--- >> read (show (currentDir </> "bla" </> "blub")) == currentDir </> "bla" </> "blub"--- >> read (show (Just (currentDir </> "bla" </> "blub"))) == Just (currentDir </> "bla" </> "blub")-instance AbsRelClass ar => Read (Path ar fd) where+-- >> let path = Posix.rootDir </> "bla" </> Posix.asRelFile "blub" in read (show path) == path+-- >> let path = Just (Posix.rootDir </> "bla" </> Posix.asRelFile "blub") in read (show path) == path+-- >> let path = Posix.currentDir </> "bla" </> Posix.asRelFile "blub" in read (show path) == path+-- >> let path = Just (Posix.currentDir </> "bla" </> Posix.asRelFile "blub") in read (show path) == path+-- >> let path = Windows.rootDir Windows.</> "bla" Windows.</> Windows.asRelFile "blub" in read (show path) == path+-- >> let path = Just (Windows.rootDir Windows.</> "bla" Windows.</> Windows.asRelFile "blub") in read (show path) == path+instance (AbsRelClass ar, FileDirClass fd) => Read (Path ar fd) where     readsPrec d = readParen (d>9) $ \str ->-        let go :: AbsRelClass ar => Path ar Dir -> ReadS (Path ar fd)-            go path s0 =+        let go :: ReadS [PathComponent]+            go s0 =                 case stripPrefix combineOperator $ dropWhile isSpace s0 of-                    Nothing -> [(relaxDir path, s0)]+                    Nothing -> [([], s0)]                     Just s1 -> do                         (pc, s2) <- reads s1-                        go (FileDir path (PathComponent pc)) s2-            result = do-                let required = absRel (const rootName) (const currentName) $ fst $ head result-                maybe [] (go PathRoot) $-                    stripPrefix required $ dropWhile isSpace str-        in  result+                        (pcs, s3) <- go s2+                        return (PathComponent pc : pcs, s3)+        in  do+                (ar, s0) <- maybeToList $ readsSplitDrive $ dropWhile isSpace str+                (pcs, s1) <- go s0+                path <- maybeToList $ maybePathFromComponents ar pcs+                return (path, s1) -relaxDir :: Path ar Dir -> Path ar fd-relaxDir PathRoot = PathRoot-relaxDir (FileDir p pc) = FileDir p pc+newtype+    ReadsSplitDrive ar =+        ReadsSplitDrive {runReadsSplitDrive :: Maybe (ar, String)} +readsSplitDrive :: (AbsRelClass ar) => String -> Maybe (ar, String)+readsSplitDrive str0 =+    runReadsSplitDrive $+    switchAbsRel+        (ReadsSplitDrive $+            (fmap ((,) (Abs "")) $ stripPrefix rootName str0)+            `mplus`+            do  str1 <- stripPrefix absDirName str0+                (drive, '"':str2) <- Just $ break ('"'==) str1+                return (Abs drive, str2))+        (ReadsSplitDrive $+            fmap ((,) Rel) $ stripPrefix currentName str0)+ -- | Convert the 'Path' into a plain 'String' as required for OS calls.-getPathString :: AbsRelClass ar => Path ar fd -> String+getPathString :: (AbsRelClass ar, FileDirClass fd) => Path ar fd -> String getPathString = flip getPathStringS "" -getPathStringS :: AbsRelClass ar => Path ar fd -> ShowS-getPathStringS =-    let go :: AbsRelClass ar => Path ar fd -> ShowS-        go x@PathRoot =-            absRel-                (const $ showChar pathSeparator)-                (const $ showString currentDirComponent) x-        -- we need the clause below so that we don't duplicate the pathSeparator after an abs-        -- root and we don't want to display a "./" prefix on relative paths-        go (FileDir p@PathRoot (PathComponent pc)) =-            absRel (const $ showChar pathSeparator) (const id) p .-            showString pc-        go (FileDir p (PathComponent pc)) =-            go p . showChar pathSeparator . showString pc-    in  go+getPathStringS :: (AbsRelClass ar, FileDirClass fd) => Path ar fd -> ShowS+getPathStringS x =+    case pathComponents x of+        (ar, []) ->+            absRelPlain+                (\(Abs drive) -> showString drive . showChar pathSeparator)+                (const $ showString currentDirComponent) ar+        (ar, pcs) ->+            foldr (.) id $ intersperse (showChar pathSeparator) $+            absRelPlain (\(Abs drive) -> (showString drive :)) (const id) ar $+            map (\(PathComponent pc) -> showString pc) pcs  prop_asPath_getPathString :: AbsFile -> Property prop_asPath_getPathString p = property $ p == asPath (getPathString p)@@ -309,8 +408,8 @@ ------------------------------------------------------------------------ -- Windows / Posix -_isPosix :: Bool-_isPosix = not isWindows+isPosix :: Bool+isPosix = not isWindows  isWindows :: Bool isWindows = IS_WINDOWS@@ -319,10 +418,10 @@ -- Constants  rootDir :: AbsDir-rootDir = PathRoot+rootDir = Path (Abs "") [] Dir  currentDir :: RelDir-currentDir = PathRoot+currentDir = Path Rel [] Dir  rootName :: String rootName = "rootDir"@@ -333,6 +432,8 @@ currentDirComponent :: String currentDirComponent = "." +absDirName :: String+absDirName = "asAbsDir \""  ------------------------------------------------------------------------ -- Unchecked Construction Functions@@ -341,70 +442,82 @@ -- | Use a 'String' as a 'Path' whose type is determined --   by its context. ----- >> asPath "/tmp" == "/tmp"--- >> asPath "file.txt" == "file.txt"--- >> isAbsolute (asPath "/tmp" :: AbsDir) == True--- >> isAbsolute (asPath "/tmp" :: RelDir) == False--- >> getPathString (asPath "/tmp" :: AbsDir) == "/tmp"--- >> getPathString (asPath "/tmp" :: RelDir) == "tmp"-asPath :: String -> Path ar fd-asPath = mkPathFromComponents . mkPathComponents+-- >> Posix.asPath "/tmp" == Posix.asAbsDir "/tmp"+-- >> Posix.asPath "file.txt" == Posix.asRelFile "file.txt"+-- >> Posix.isAbsolute (Posix.asAbsDir "/tmp")+-- >> Posix.isRelative (Posix.asRelDir "/tmp")+-- >> Posix.getPathString (Posix.asPath "/tmp" :: Posix.AbsDir) == "/tmp"+-- >> Posix.getPathString (Posix.asPath "/tmp" :: Posix.RelDir) == "tmp"+-- >> Windows.getPathString (Windows.asPath "\\tmp" :: Windows.AbsDir) == "\\tmp"+-- >> Windows.getPathString (Windows.asPath "a:\\tmp" :: Windows.AbsDir) == "a:\\tmp"+-- >> Windows.getPathString (Windows.asPath "tmp" :: Windows.RelDir) == "tmp"+asPath :: (AbsRelClass ar, FileDirClass fd) => String -> Path ar fd+asPath = uncurry mkPathFromComponents . mkPathComponents +newtype AbsRelDefault ar = AbsRelDefault {getAbsRelDefault :: ar}++absRelDefault :: (AbsRelClass ar) => ar+absRelDefault =+    getAbsRelDefault $ switchAbsRel (AbsRelDefault $ Abs "") (AbsRelDefault Rel)++ -- | Use a 'String' as a 'RelFile'. No checking is done. ----- >> getPathString (asRelFile "file.txt") == "file.txt"--- >> getPathString (asRelFile "/file.txt") == "file.txt"--- >> getPathString (asRelFile "tmp") == "tmp"--- >> getPathString (asRelFile "/tmp") == "tmp"+-- >> Posix.getPathString (Posix.asRelFile "file.txt") == "file.txt"+-- >> Posix.getPathString (Posix.asRelFile "/file.txt") == "file.txt"+-- >> Posix.getPathString (Posix.asRelFile "tmp") == "tmp"+-- >> Posix.getPathString (Posix.asRelFile "/tmp") == "tmp" asRelFile :: String -> RelFile asRelFile = asPath  -- | Use a 'String' as a 'RelDir'. No checking is done. ----- >> getPathString (asRelDir ".") == "."--- >> getPathString (asRelDir "file.txt") == "file.txt"--- >> getPathString (asRelDir "/file.txt") == "file.txt"--- >> getPathString (asRelDir "tmp") == "tmp"--- >> getPathString (asRelDir "/tmp") == "tmp"+-- >> Posix.getPathString (Posix.asRelDir ".") == "."+-- >> Posix.getPathString (Posix.asRelDir "file.txt") == "file.txt"+-- >> Posix.getPathString (Posix.asRelDir "/file.txt") == "file.txt"+-- >> Posix.getPathString (Posix.asRelDir "tmp") == "tmp"+-- >> Posix.getPathString (Posix.asRelDir "/tmp") == "tmp" asRelDir :: String -> RelDir asRelDir = asPath  -- | Use a 'String' as an 'AbsFile'. No checking is done. ----- >> getPathString (asAbsFile "file.txt") == "/file.txt"--- >> getPathString (asAbsFile "/file.txt") == "/file.txt"--- >> getPathString (asAbsFile "tmp") == "/tmp"--- >> getPathString (asAbsFile "/tmp") == "/tmp"+-- >> Posix.getPathString (Posix.asAbsFile "file.txt") == "/file.txt"+-- >> Posix.getPathString (Posix.asAbsFile "/file.txt") == "/file.txt"+-- >> Posix.getPathString (Posix.asAbsFile "tmp") == "/tmp"+-- >> Posix.getPathString (Posix.asAbsFile "/tmp") == "/tmp" asAbsFile :: String -> AbsFile asAbsFile = asPath  -- | Use a 'String' as an 'AbsDir'. No checking is done. ----- >> getPathString (asAbsDir "file.txt") == "/file.txt"--- >> getPathString (asAbsDir "/file.txt") == "/file.txt"--- >> getPathString (asAbsDir "tmp") == "/tmp"--- >> getPathString (asAbsDir "/tmp") == "/tmp"+-- >> Posix.getPathString (Posix.asAbsDir "file.txt") == "/file.txt"+-- >> Posix.getPathString (Posix.asAbsDir "/file.txt") == "/file.txt"+-- >> Posix.getPathString (Posix.asAbsDir "tmp") == "/tmp"+-- >> Posix.getPathString (Posix.asAbsDir "/tmp") == "/tmp" asAbsDir :: String -> AbsDir asAbsDir = asPath  -- | Use a 'String' as a 'RelPath fd'. No checking is done.-asRelPath :: String -> RelPath fd+asRelPath :: (FileDirClass fd) => String -> RelPath fd asRelPath = asPath  -- | Use a 'String' as an 'AbsPath fd'. No checking is done.-asAbsPath :: String -> AbsPath fd+asAbsPath :: (FileDirClass fd) => String -> AbsPath fd asAbsPath = asPath  -- | Use a 'String' as a 'FilePath ar'. No checking is done.-asFilePath :: String -> FilePath ar+asFilePath :: (AbsRelClass ar) => String -> FilePath ar asFilePath = asPath  -- | Use a 'String' as a 'DirPath ar'. No checking is done.-asDirPath :: String -> DirPath ar+asDirPath :: (AbsRelClass ar) => String -> DirPath ar asDirPath = asPath  -- | Allow use of OverloadedStrings if desired-instance IsString (Path ar fd) where fromString = asPath+instance+    (AbsRelClass ar, FileDirClass fd) =>+        IsString (Path ar fd) where fromString = asPath  ------------------------------------------------------------------------ -- Checked Construction Functions@@ -412,9 +525,13 @@ -- | Examines the supplied string and constructs an absolute or -- relative path as appropriate. ----- >> mkPathAbsOrRel "/tmp" == Left (asAbsDir "/tmp")--- >> mkPathAbsOrRel  "tmp" == Right (asRelDir "tmp")-mkPathAbsOrRel :: String -> Either (AbsPath fd) (RelPath fd)+-- >> Posix.mkPathAbsOrRel "/tmp" == Left (Posix.asAbsDir "/tmp")+-- >> Posix.mkPathAbsOrRel  "tmp" == Right (Posix.asRelDir "tmp")+-- >> Windows.mkPathAbsOrRel "\\tmp" == Left (Windows.asAbsDir "\\tmp")+-- >> Windows.mkPathAbsOrRel "d:\\tmp" == Left (Windows.asAbsDir "d:\\tmp")+-- >> Windows.mkPathAbsOrRel "tmp" == Right (Windows.asRelDir "tmp")+mkPathAbsOrRel ::+    (FileDirClass fd) => String -> Either (AbsPath fd) (RelPath fd) mkPathAbsOrRel s =     if isAbsoluteString s       then Left $ asAbsPath s@@ -437,39 +554,88 @@ -- | Convert a 'String' into an 'AbsPath' by interpreting it as --   relative to the supplied directory if necessary. ----- >> mkAbsPath "/tmp" "foo.txt" == "/tmp/foo.txt"--- >> mkAbsPath "/tmp" "/etc/foo.txt" == "/etc/foo.txt"-mkAbsPath :: AbsDir -> String -> AbsPath fd+-- >> Posix.mkAbsPath "/tmp" "foo.txt" == Posix.asAbsFile "/tmp/foo.txt"+-- >> Posix.mkAbsPath "/tmp" "/etc/foo.txt" == Posix.asAbsFile "/etc/foo.txt"+mkAbsPath :: (FileDirClass fd) => AbsDir -> String -> AbsPath fd mkAbsPath d = (id ||| makeAbsolute d) . mkPathAbsOrRel  -- | Convert a 'String' into an 'AbsPath' by interpreting it as --   relative to the cwd if necessary.-mkAbsPathFromCwd :: String -> IO (AbsPath fd)+mkAbsPathFromCwd :: (FileDirClass fd) => String -> IO (AbsPath fd) mkAbsPathFromCwd = (return ||| makeAbsoluteFromCwd) . mkPathAbsOrRel   ------------------------------------------------------------------------ -- Internal Functions for PathComponent manipulation -mkPathFromComponents :: [PathComponent] -> Path ar fd-mkPathFromComponents pcs =-    case reverse pcs of-      [] -> PathRoot-      p:ps -> FileDir (foldr (flip FileDir) PathRoot ps) p+mkPathFromComponents :: (FileDirClass fd) => ar -> [PathComponent] -> Path ar fd+mkPathFromComponents ar pcs =+    switchFileDir+        (fromMaybe (Path ar [] $ File $ PathComponent "") $+         mkFilePathFromComponents ar pcs)+        (mkDirPathFromComponents ar pcs) -mkPathComponents :: String -> [PathComponent]-mkPathComponents xs =-    case break isPathSeparator (dropWhile isPathSeparator xs) of-      ("","")  -> []-      (s,rest) -> PathComponent s : mkPathComponents rest+maybePathFromComponents ::+    (FileDirClass fd) => ar -> [PathComponent] -> Maybe (Path ar fd)+maybePathFromComponents ar pcs =+    getFunctorPath $+    switchFileDir+        (FunctorPath $ mkFilePathFromComponents ar pcs)+        (FunctorPath $ Just $ mkDirPathFromComponents ar pcs) -pathComponents :: Path ar fd -> [PathComponent]-pathComponents PathRoot = []-pathComponents (FileDir p pc) = pathComponents p ++ [pc]+newtype+    FunctorPath f ar fd =+        FunctorPath {getFunctorPath :: f (Path ar fd)} -prop_mkPathFromComponents_pathComponents :: AbsFile -> Property+mkDirPathFromComponents :: ar -> [PathComponent] -> Path ar Dir+mkDirPathFromComponents ar pcs = Path ar pcs Dir++mkFilePathFromComponents :: ar -> [PathComponent] -> Maybe (Path ar File)+mkFilePathFromComponents _ [] = Nothing+mkFilePathFromComponents ar0 (q:qs) =+    let mapPathDirs f ~(Path ar pcs fd) = Path ar (f pcs) fd+        go p [] = Path ar0 [] (File p)+        go p0 (p1:ps) = mapPathDirs (p0:) $ go p1 ps+    in  Just $ go q qs++mkPathComponents :: (AbsRelClass ar) => String -> (ar, [PathComponent])+mkPathComponents =+    let go xs =+            case break isPathSeparator $ dropWhile isPathSeparator xs of+                ("","") -> []+                (s,rest) -> s : go rest+        split [] = (absRelDefault, [])+        split (pc:pcs) =+            second (map PathComponent) $+            case splitDrive pc of+                (drive, "") -> (drive, pcs)+                (drive, pc0) -> (drive, pc0:pcs)+    in  split . go++newtype SplitDrive ar = SplitDrive {runSplitDrive :: (ar, String)}++splitDrive :: (AbsRelClass ar) => String -> (ar, String)+splitDrive str =+    runSplitDrive $+    switchAbsRel+        (SplitDrive $ first Abs $+         if isPosix+           then ("", str)+           else+               case break (':'==) str of+                   (drive, ':':rest) -> (drive++":", rest)+                   _ -> ("", str))+        (SplitDrive (Rel, str))++pathComponents :: (FileDirClass fd) => Path ar fd -> (ar, [PathComponent])+pathComponents (Path ar pcs fd) = (ar, pcs ++ fileDirComponent fd)++fileDirComponent :: (FileDirClass fd) => fd -> [PathComponent]+fileDirComponent = fileDirPlain (\(File pc) -> [pc]) (\Dir -> [])++prop_mkPathFromComponents_pathComponents :: AbsDir -> Property prop_mkPathFromComponents_pathComponents p =-    property $ mkPathFromComponents (pathComponents p) == p+    property $ uncurry mkPathFromComponents (pathComponents p) == p   @@ -480,10 +646,16 @@ combineOperator = "</>"  -- | Infix variant of 'combine'.+--+-- >> Posix.getPathString (Posix.asAbsDir "/tmp" </> Posix.asRelFile "file.txt") == "/tmp/file.txt"+-- >> Posix.getPathString (Posix.asAbsDir "/tmp" </> Posix.asRelDir "dir" </> Posix.asRelFile "file.txt") == "/tmp/dir/file.txt"+-- >> Posix.getPathString (Posix.asRelDir "dir" </> Posix.asRelFile "file.txt") == "dir/file.txt"+-- >> Windows.getPathString (Windows.asAbsDir "\\tmp" Windows.</> Windows.asRelFile "file.txt") == "\\tmp\\file.txt"+-- >> Windows.getPathString (Windows.asAbsDir "c:\\tmp" Windows.</> Windows.asRelFile "file.txt") == "c:\\tmp\\file.txt"+-- >> Windows.getPathString (Windows.asAbsDir "c:" Windows.</> Windows.asRelDir "tmp" Windows.</> Windows.asRelFile "file.txt") == "c:\\tmp\\file.txt"+-- >> Windows.getPathString (Windows.asRelDir "dir" Windows.</> Windows.asRelFile "file.txt") == "dir\\file.txt" (</>) :: DirPath ar -> RelPath fd -> Path ar fd-PathRoot         </> PathRoot       = PathRoot-(FileDir dp dpc) </> PathRoot       = FileDir dp dpc-d                </> (FileDir p pc) = FileDir (d </> p) pc+(Path ar pcs0 Dir) </> (Path Rel pcs1 fd) = Path ar (pcs0 ++ pcs1) fd  -- | Infix variant of 'addExtension'. --   We only allow files (and not directories) to have extensions added@@ -494,17 +666,17 @@ --   directories, and so we provide a function that is more flexible: --   'genericAddExtension'. (<.>) :: FilePath ar -> String -> FilePath ar-(<.>) = genericAddExtension+Path ar pcs (File pc) <.> ext = Path ar pcs (File $ addExtensionPC pc ext)  -- | Add an extension, even if there is already one there. --   E.g. @addExtension \"foo.txt\" \"bat\" -> \"foo.txt.bat\"@. ----- >> addExtension "file.txt" "bib" == "file.txt.bib"--- >> addExtension "file." ".bib" == "file..bib"--- >> addExtension "file" ".bib" == "file.bib"--- >> addExtension "" "bib" == ".bib"--- >> addExtension "" ".bib" == ".bib"--- >> takeFileName (addExtension "" "ext") == ".ext"+-- >> Posix.addExtension (Posix.asRelFile "file.txt") "bib" == "file.txt.bib"+-- >> Posix.addExtension (Posix.asRelFile "file.") ".bib" == "file..bib"+-- >> Posix.addExtension (Posix.asRelFile "file") ".bib" == "file.bib"+-- >> Posix.addExtension (Posix.asRelFile "") "bib" == ".bib"+-- >> Posix.addExtension (Posix.asRelFile "") ".bib" == ".bib"+-- >> Posix.takeFileName (Posix.addExtension (Posix.asRelFile "") "ext") == ".ext" addExtension :: FilePath ar -> String -> FilePath ar addExtension = (<.>) @@ -516,67 +688,69 @@  -- | Remove last extension, and the \".\" preceding it. ----- >> dropExtension x == fst (splitExtension x)+-- >> Posix.dropExtension x == fst (Posix.splitExtension x) dropExtension :: FilePath ar -> FilePath ar dropExtension = fst . splitExtension  -- | Drop all extensions ----- >> not $ hasAnExtension (dropExtensions x)+-- >> not $ Posix.hasAnExtension (Posix.dropExtensions x) dropExtensions :: FilePath ar -> FilePath ar dropExtensions = fst . splitExtensions  -- | Synonym for 'takeDirectory'-dropFileName :: Path ar fd -> DirPath ar+dropFileName :: FilePath ar -> DirPath ar dropFileName = fst . splitFileName   -- | Set the extension of a file, overwriting one if already present. ----- >> replaceExtension "file.txt" ".bob" == "file.bob"--- >> replaceExtension "file.txt" "bob" == "file.bob"--- >> replaceExtension "file" ".bob" == "file.bob"--- >> replaceExtension "file.txt" "" == "file"--- >> replaceExtension "file.fred.bob" "txt" == "file.fred.txt"+-- >> Posix.replaceExtension (Posix.asRelFile "file.txt") ".bob" == "file.bob"+-- >> Posix.replaceExtension (Posix.asRelFile "file.txt") "bob" == "file.bob"+-- >> Posix.replaceExtension (Posix.asRelFile "file") ".bob" == "file.bob"+-- >> Posix.replaceExtension (Posix.asRelFile "file.txt") "" == "file"+-- >> Posix.replaceExtension (Posix.asRelFile "file.fred.bob") "txt" == "file.fred.txt" replaceExtension :: FilePath ar -> String -> FilePath ar replaceExtension p ext = dropExtension p <.> ext -replaceBaseName :: Path ar fd -> String -> Path ar fd-replaceBaseName p bn = takeDirectory p </> (asPath bn `genericAddExtension` genericTakeExtension p)+replaceBaseName :: FilePath ar -> String -> FilePath ar+replaceBaseName (Path ar pcs (File pc)) bn =+    Path ar pcs $ File $+    addExtensionPC (PathComponent bn) $ snd $ splitExtensionPC pc -replaceDirectory :: Path ar1 fd -> DirPath ar2 -> Path ar2 fd-replaceDirectory p d = d </> takeFileName p+replaceDirectory :: FilePath ar1 -> DirPath ar2 -> FilePath ar2+replaceDirectory (Path _ _ fd) (Path ar pcs _) = Path ar pcs fd -replaceFileName :: Path ar fd -> String -> Path ar fd-replaceFileName p fn = takeDirectory p </> asPath fn+replaceFileName :: FilePath ar -> String -> FilePath ar+replaceFileName (Path ar pcs _) fn = Path ar pcs (File (PathComponent fn))   -- | Split on the extension. 'addExtension' is the inverse. ----- >> uncurry (<.>) (splitExtension x) == x--- >> uncurry addExtension (splitExtension x) == x--- >> splitExtension "file.txt" == ("file",".txt")--- >> splitExtension "file" == ("file","")--- >> splitExtension "file/file.txt" == ("file/file",".txt")--- >> splitExtension "file.txt/boris" == ("file.txt/boris","")--- >> splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")--- >> splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")+-- >> uncurry (<.>) (Posix.splitExtension x) == x+-- >> uncurry Posix.addExtension (Posix.splitExtension x) == x+-- >> Posix.splitExtension (Posix.asRelFile "file.txt") == ("file",".txt")+-- >> Posix.splitExtension (Posix.asRelFile "file") == ("file","")+-- >> Posix.splitExtension (Posix.asRelFile "file/file.txt") == ("file/file",".txt")+-- >> Posix.splitExtension (Posix.asRelFile "file.txt/boris") == ("file.txt/boris","")+-- >> Posix.splitExtension (Posix.asRelFile "file.txt/boris.ext") == ("file.txt/boris",".ext")+-- >> Posix.splitExtension (Posix.asRelFile "file/path.txt.bob.fred") == ("file/path.txt.bob",".fred") splitExtension :: FilePath ar -> (FilePath ar, String)-splitExtension = genericSplitExtension+splitExtension (Path ar pcs (File pc)) =+    first (Path ar pcs . File) $ splitExtensionPC pc  -- | Split on all extensions ----- >> splitExtensions "file.tar.gz" == ("file",".tar.gz")+-- >> Posix.splitExtensions (Posix.asRelFile "file.tar.gz") == ("file",".tar.gz") splitExtensions :: FilePath ar -> (FilePath ar, String)-splitExtensions = genericSplitExtensions+splitExtensions (Path ar pcs (File pc)) =+    first (Path ar pcs . File) $ splitExtensionsPC pc  prop_split_combineExt :: AbsFile -> Property prop_split_combineExt p = property $ p == uncurry (<.>) (splitExtension p) --- | Path must not be empty-splitFileName :: Path ar fd -> (DirPath ar, RelPath fd)-splitFileName (FileDir p pc) = (p, mkPathFromComponents [pc])-splitFileName PathRoot = error "splitFileName: empty path"+splitFileName :: FilePath ar -> (DirPath ar, RelFile)+splitFileName (Path ar pcs fd) = (Path ar pcs Dir, Path Rel [] fd)  prop_split_combine :: AbsFile -> Property prop_split_combine p = property $ uncurry combine (splitFileName p) == p@@ -584,37 +758,36 @@  -- | Get the basename of a file ----- >> takeBaseName "/tmp/somedir/myfile.txt" == "myfile"--- >> takeBaseName "./myfile.txt" == "myfile"--- >> takeBaseName "myfile.txt" == "myfile"-takeBaseName :: Path ar fd -> RelPath fd-takeBaseName = takeFileName . genericDropExtension+-- >> Posix.takeBaseName (Posix.asAbsFile "/tmp/somedir/myfile.txt") == "myfile"+-- >> Posix.takeBaseName (Posix.asRelFile "./myfile.txt") == "myfile"+-- >> Posix.takeBaseName (Posix.asRelFile "myfile.txt") == "myfile"+takeBaseName :: FilePath ar -> RelFile+takeBaseName = takeFileName . dropExtension -takeDirectory :: Path ar fd -> DirPath ar+takeDirectory :: FilePath ar -> DirPath ar takeDirectory = fst . splitFileName  -- | Get the extension of a file, returns @\"\"@ for no extension, @.ext@ otherwise. ----- >> takeExtension x == snd (splitExtension x)--- >> takeExtension (addExtension x "ext") == ".ext"--- >> takeExtension (replaceExtension x "ext") == ".ext"+-- >> Posix.takeExtension x == snd (Posix.splitExtension x)+-- >> Posix.takeExtension (Posix.addExtension x "ext") == ".ext"+-- >> Posix.takeExtension (Posix.replaceExtension x "ext") == ".ext" takeExtension :: FilePath ar -> String takeExtension = snd . splitExtension  -- | Get all extensions ----- >> takeExtensions "file.tar.gz" == ".tar.gz"+-- >> Posix.takeExtensions (Posix.asRelFile "file.tar.gz") == ".tar.gz" takeExtensions :: FilePath ar -> String takeExtensions = snd . splitExtensions  -- | Get the filename component of a file path (ie stripping all parent dirs) ----- >> takeFileName "/tmp/somedir/myfile.txt" == "myfile.txt"--- >> takeFileName "./myfile.txt" == "myfile.txt"--- >> takeFileName "myfile.txt" == "myfile.txt"-takeFileName :: Path ar fd -> RelPath fd-takeFileName PathRoot = PathRoot -- becomes a relative root-takeFileName (FileDir _ pc) = FileDir PathRoot pc+-- >> Posix.takeFileName (Posix.asAbsFile "/tmp/somedir/myfile.txt") == "myfile.txt"+-- >> Posix.takeFileName (Posix.asRelFile "./myfile.txt") == "myfile.txt"+-- >> Posix.takeFileName (Posix.asRelFile "myfile.txt") == "myfile.txt"+takeFileName :: FilePath ar -> RelFile+takeFileName (Path _ _ fd) = Path Rel [] fd  prop_takeFileName_end :: AbsFile -> Property prop_takeFileName_end p = property $ show (takeFileName p) `isSuffixOf` show p@@ -625,51 +798,65 @@  -- | Check whether two strings are equal as file paths. ----- >> equalFilePath "/tmp/" "/tmp" == True--- >> equalFilePath "/tmp"  "tmp"  == False+-- >>       Posix.equalFilePath "/tmp/" "/tmp"+-- >> not $ Posix.equalFilePath "/tmp" "tmp"+-- >>       Windows.equalFilePath "file" "File"+-- >> not $ Windows.equalFilePath "file" "dir" equalFilePath :: String -> String -> Bool equalFilePath s1 s2 =-    isAbsoluteString s1 == isAbsoluteString s2 && asPath s1 == asPath s2+    let abs1 = isAbsoluteString s1+        abs2 = isAbsoluteString s2+    in  abs1 == abs2 &&+        if abs1+          then asAbsDir s1 == asAbsDir s2+          else asRelDir s1 == asRelDir s2 --- | Constructs a 'Path' from a list of components.+-- | Constructs a 'RelPath' from a list of components.+--   It is an unchecked error if the path components contain path separators.+--   It is an unchecked error if a 'RelFile' path is empty. ----- >> joinPath ["/tmp","someDir","file.txt"] == "/tmp/someDir/file.txt"--- >> joinPath ["/tmp","someDir","file.txt"] == asRelFile "tmp/someDir/file.txt"-joinPath :: [String] -> Path ar fd-joinPath = asPath . intercalate [pathSeparator]+-- >> Posix.joinPath ["tmp","someDir","dir"] == Posix.asRelDir "tmp/someDir/dir"+-- >> Posix.joinPath ["tmp","someDir","file.txt"] == Posix.asRelFile "tmp/someDir/file.txt"+joinPath :: (FileDirClass fd) => [String] -> RelPath fd+joinPath = mkPathFromComponents Rel . map PathComponent  -- | Currently just transforms: ----- >> normalise "/tmp/fred/./jim/./file" == "/tmp/fred/jim/file"+-- >> Posix.normalise "/tmp/fred/./jim/./file" == Posix.asAbsFile "/tmp/fred/jim/file" normalise :: Path ar fd -> Path ar fd-normalise =-    mkPathFromComponents .-    filter (/= PathComponent currentDirComponent) .-    pathComponents+normalise (Path ar pcs fd) =+    Path ar (filter (PathComponent currentDirComponent /=) pcs) fd  -- | Deconstructs a path into its components. ----- >> splitPath (asAbsDir "/tmp/someDir/mydir.dir") == (["tmp","someDir","mydir.dir"], Nothing)--- >> splitPath (asAbsFile "/tmp/someDir/myfile.txt") == (["tmp","someDir"], Just "myfile.txt")-splitPath :: FileDirClass fd => Path ar fd -> ([RelDir], Maybe RelFile)-splitPath PathRoot = ([],Nothing)-splitPath p@(FileDir d pc) =-    first (map (FileDir PathRoot)) $-    fileDir-        (\ _ -> (pathComponents d, Just (FileDir PathRoot pc)))-        (\ _ -> (pathComponents p, Nothing))-        p+-- >> Posix.splitPath (Posix.asAbsDir "/tmp/someDir/mydir.dir") == (True, ["tmp","someDir","mydir.dir"], Nothing)+-- >> Posix.splitPath (Posix.asAbsFile "/tmp/someDir/myfile.txt") == (True, ["tmp","someDir"], Just "myfile.txt")+splitPath ::+    (AbsRelClass ar, FileDirClass fd) =>+    Path ar fd -> (Bool, [RelDir], Maybe RelFile)+splitPath (Path ar pcs fd) =+    (isAbsolutePlain ar,+     map (\pc -> Path Rel [pc] Dir) pcs,+     maybeFileDir fd) +isAbsolutePlain :: (AbsRelClass ar) => ar -> Bool+isAbsolutePlain = absRelPlain (const True) (const False)++maybeFileDir :: (FileDirClass fd) => fd -> Maybe RelFile+maybeFileDir = fileDirPlain (Just . Path Rel []) (\Dir -> Nothing)+ -- | This function can be used to construct a relative path by removing --   the supplied 'AbsDir' from the front. It is a runtime 'error' if the --   supplied 'AbsPath' doesn't start with the 'AbsDir'. ----- >> makeRelative "/tmp/somedir" "/tmp/somedir/anotherdir/file.txt" == asRelFile "anotherdir/file.txt"--- >> makeRelative "/tmp/somedir" "/tmp/somedir/anotherdir/dir" == asRelDir "anotherdir/dir"-makeRelative :: AbsDir -> AbsPath fd -> RelPath fd-makeRelative relTo orig =-    maybe (error msg) mkPathFromComponents $-    stripPrefix (pathComponents relTo) (pathComponents orig)+-- >> Posix.makeRelative "/tmp/somedir" "/tmp/somedir/anotherdir/file.txt" == Posix.asRelFile "anotherdir/file.txt"+-- >> Posix.makeRelative "/tmp/somedir" "/tmp/somedir/anotherdir/dir" == Posix.asRelDir "anotherdir/dir"+-- >> Windows.makeRelative "c:\\tmp\\somedir" "c:\\Tmp\\SomeDir\\AnotherDir\\File.txt" == Windows.asRelFile "AnotherDir\\File.txt"+-- >> Windows.makeRelative "c:\\tmp\\somedir" "c:\\tmp\\somedir\\anotherdir\\dir" == Windows.asRelDir "anotherdir\\dir"+makeRelative :: (FileDirClass fd) => AbsDir -> AbsPath fd -> RelPath fd+makeRelative relTo@(Path relToAR relToPCs Dir) orig@(Path origAR origPCs fd) =+    maybe (error msg) (flip (Path Rel) fd) $+    guard (relToAR == origAR) >> stripPrefix relToPCs origPCs   where     msg =         printf "System.Path can't make (%s) relative to (%s)"@@ -678,9 +865,9 @@ -- | Joins an absolute directory with a relative path to construct a --   new absolute path. ----- >> makeAbsolute "/tmp" "file.txt"      == asAbsFile "/tmp/file.txt"--- >> makeAbsolute "/tmp" "adir/file.txt" == asAbsFile "/tmp/adir/file.txt"--- >> makeAbsolute "/tmp" "adir/dir"      == asAbsDir "/tmp/adir/dir"+-- >> Posix.makeAbsolute "/tmp" "file.txt"      == Posix.asAbsFile "/tmp/file.txt"+-- >> Posix.makeAbsolute "/tmp" "adir/file.txt" == Posix.asAbsFile "/tmp/adir/file.txt"+-- >> Posix.makeAbsolute "/tmp" "adir/dir"      == Posix.asAbsDir "/tmp/adir/dir" makeAbsolute :: AbsDir -> RelPath fd -> AbsPath fd makeAbsolute = genericMakeAbsolute @@ -692,10 +879,10 @@ -- | As for 'makeAbsolute', but for use when the path may already be --   absolute (in which case it is left unchanged). ----- >> genericMakeAbsolute "/tmp" (asRelFile "file.txt")       == "/tmp/file.txt"--- >> genericMakeAbsolute "/tmp" (asRelFile "adir/file.txt")  == "/tmp/adir/file.txt"--- >> genericMakeAbsolute "/tmp" (asAbsFile "adir/file.txt")  == "/adir/file.txt"--- >> genericMakeAbsolute "/tmp" (asAbsFile "/adir/file.txt") == "/adir/file.txt"+-- >> Posix.genericMakeAbsolute "/tmp" (Posix.asRelFile "file.txt")       == "/tmp/file.txt"+-- >> Posix.genericMakeAbsolute "/tmp" (Posix.asRelFile "adir/file.txt")  == "/tmp/adir/file.txt"+-- >> Posix.genericMakeAbsolute "/tmp" (Posix.asAbsFile "adir/file.txt")  == "/adir/file.txt"+-- >> Posix.genericMakeAbsolute "/tmp" (Posix.asAbsFile "/adir/file.txt") == "/adir/file.txt" genericMakeAbsolute :: AbsRelClass ar => AbsDir -> Path ar fd -> AbsPath fd genericMakeAbsolute base p = absRel id (base </>) p @@ -740,10 +927,10 @@  -- | Test whether a @'Path' ar fd@ is absolute. ----- >> isAbsolute (asAbsFile "fred")  == True--- >> isAbsolute (asRelFile "fred")  == False--- >> isAbsolute (asAbsFile "/fred") == True--- >> isAbsolute (asRelFile "/fred") == False+-- >> Posix.isAbsolute (Posix.asAbsFile "fred")+-- >> Posix.isAbsolute (Posix.asAbsFile "/fred")+-- >> Windows.isAbsolute (Windows.asAbsFile "\\fred")+-- >> Windows.isAbsolute (Windows.asAbsFile "c:\\fred") isAbsolute :: AbsRelClass ar => Path ar fd -> Bool isAbsolute = absRel (const True) (const False) @@ -751,11 +938,17 @@ --   if interpreted as a 'Path'. isAbsoluteString :: String -> Bool isAbsoluteString [] = False -- Treat the empty string as relative because it doesn't start with 'pathSeparators'-isAbsoluteString (x:_) = isPathSeparator x -- Absolute if first char is a path separator+isAbsoluteString (x:xs) =+    isPathSeparator x -- Absolute if first char is a path separator+    ||+    isWindows && isAlpha x && isPrefixOf ":" xs  -- | Invariant - this should return True iff arg is of type @'Path' Rel _@ -- -- > isRelative = not . isAbsolute+-- >> Posix.isRelative (Posix.asRelFile "fred")+-- >> Posix.isRelative (Posix.asRelFile "/fred")+-- >> Windows.isRelative (Windows.asRelFile "fred") isRelative :: AbsRelClass ar => Path ar fd -> Bool isRelative = not . isAbsolute @@ -769,15 +962,15 @@  -- | Does the given filename have an extension? ----- >> null (takeExtension x) == not (hasAnExtension x)+-- >> null (Posix.takeExtension x) == not (Posix.hasAnExtension x) hasAnExtension :: FilePath ar -> Bool hasAnExtension = not . null . snd . splitExtension  -- | Does the given filename have the given extension? ----- >> hasExtension ".hs" "MyCode.hs" == True--- >> hasExtension ".hs" "MyCode.hs.bak" == False--- >> hasExtension ".hs" "MyCode.bak.hs" == True+-- >> Posix.hasExtension ".hs" (Posix.asRelFile "MyCode.hs")+-- >> Posix.hasExtension ".hs" (Posix.asRelFile "MyCode.bak.hs")+-- >> not $ Posix.hasExtension ".hs" (Posix.asRelFile "MyCode.hs.bak") hasExtension :: String -> FilePath ar -> Bool hasExtension ext = (==ext) . snd . splitExtension @@ -795,7 +988,7 @@  -- | File extension character ----- >> extSeparator == '.'+-- >> Posix.extSeparator == '.' extSeparator :: Char extSeparator = '.' @@ -806,14 +999,14 @@ -- | The character that separates directories. In the case where more than --   one character is possible, 'pathSeparator' is the \'ideal\' one. ----- >> isPathSeparator pathSeparator+-- >> Posix.isPathSeparator Posix.pathSeparator pathSeparator :: Char pathSeparator | isWindows = '\\'               | otherwise = '/'  -- | The list of all possible separators. ----- >> pathSeparator `elem` pathSeparators+-- >> Posix.pathSeparator `elem` Posix.pathSeparators pathSeparators :: [Char] pathSeparators = return pathSeparator @@ -824,20 +1017,20 @@  -- | Is the character an extension character? ----- >> isExtSeparator a == (a == extSeparator)+-- >> Posix.isExtSeparator a == (a == Posix.extSeparator) isExtSeparator :: Char -> Bool isExtSeparator = (== extSeparator)  -- | Rather than using @(== 'pathSeparator')@, use this. Test if something --   is a path separator. ----- >> isPathSeparator a == (a `elem` pathSeparators)+-- >> Posix.isPathSeparator a == (a `elem` Posix.pathSeparators) isPathSeparator :: Char -> Bool isPathSeparator = flip elem pathSeparators  -- | Is the character a file separator? ----- >> isSearchPathSeparator a == (a == searchPathSeparator)+-- >> Posix.isSearchPathSeparator a == (a == Posix.searchPathSeparator) isSearchPathSeparator :: Char -> Bool isSearchPathSeparator = (== searchPathSeparator) @@ -853,50 +1046,107 @@ -- | This is a more flexible variant of 'addExtension' / '<.>' which can --   work with files or directories ----- >> genericAddExtension "/" "x" == asAbsDir "/.x"--- >> genericAddExtension "/a" "x" == asAbsDir "/a.x"--- >> genericAddExtension "" "x" == asRelFile ".x"--- >> genericAddExtension "" "" == asRelFile ""-genericAddExtension :: Path ar fd -> String -> Path ar fd+-- >> Posix.genericAddExtension "/" "x" == Posix.asAbsDir "/.x"+-- >> Posix.genericAddExtension "/a" "x" == Posix.asAbsDir "/a.x"+-- >> Posix.genericAddExtension "" "x" == Posix.asRelFile ".x"+-- >> Posix.genericAddExtension "" "" == Posix.asRelFile ""+genericAddExtension :: (FileDirClass fd) => Path ar fd -> String -> Path ar fd genericAddExtension p "" = p genericAddExtension path ext =-    let suffix =-            if [extSeparator] `isPrefixOf` ext-              then ext-              else extSeparator : ext-    in  case path of-            FileDir p (PathComponent pc) ->-                FileDir p (PathComponent (pc ++ suffix))-            PathRoot ->-                FileDir PathRoot (PathComponent suffix)+    runAddExtension+        (switchFileDir+            (AddExtension $+             \(Path ar pcs (File pc)) ->+                Path ar pcs $ File $ addExtensionPC pc ext)+            (AddExtension $+             \(Path ar pcs0 Dir) ->+                let pcs = if null pcs0 then [PathComponent ""] else pcs0+                in  Path ar (mapLast (flip addExtensionPC ext) pcs) Dir))+        path -genericDropExtension :: Path ar fd -> Path ar fd+newtype+    AddExtension ar fd =+        AddExtension {runAddExtension :: Path ar fd -> Path ar fd}++genericDropExtension :: (FileDirClass fd) => Path ar fd -> Path ar fd genericDropExtension = fst . genericSplitExtension -genericDropExtensions :: Path ar fd -> Path ar fd+genericDropExtensions :: (FileDirClass fd) => Path ar fd -> Path ar fd genericDropExtensions = fst . genericSplitExtensions -genericSplitExtension :: Path ar fd -> (Path ar fd, String)-genericSplitExtension (FileDir p (PathComponent s)) = (FileDir p (PathComponent s1), s2)+genericSplitExtension ::+    (FileDirClass fd) => Path ar fd -> (Path ar fd, String)+genericSplitExtension =+    runSplitExtension $+    switchFileDir+        (SplitExtension $+         \(Path ar pcs (File pc)) ->+            first (Path ar pcs . File) $ splitExtensionPC pc)+        (SplitExtension $+         \(Path ar pcs Dir) ->+            first (flip (Path ar) Dir) $+            mapLastPair+                (error "genericSplitExtension: empty path")+                splitExtensionPC pcs)++genericSplitExtensions ::+    (FileDirClass fd) => Path ar fd -> (Path ar fd, String)+genericSplitExtensions =+    runSplitExtension $+    switchFileDir+        (SplitExtension $+         \(Path ar pcs (File pc)) ->+            first (Path ar pcs . File) $ splitExtensionsPC pc)+        (SplitExtension $+         \(Path ar pcs Dir) ->+            first (flip (Path ar) Dir) $+            mapLastPair+                (error "genericSplitExtensions: empty path")+                splitExtensionsPC pcs)++genericTakeExtension :: (FileDirClass fd) => Path ar fd -> String+genericTakeExtension = snd . genericSplitExtension++genericTakeExtensions :: (FileDirClass fd) => Path ar fd -> String+genericTakeExtensions = snd . genericSplitExtension++newtype+    SplitExtension ar fd =+        SplitExtension {runSplitExtension :: Path ar fd -> (Path ar fd, String)}+++-- move to utility-ht+mapLast :: (a -> a) -> [a] -> [a]+mapLast f xs = zipWith id (drop 1 $ map (const id) xs ++ [f]) xs++mapLastPair :: b -> (a -> (a,b)) -> [a] -> ([a], b)+mapLastPair b0 f xs =+    case reverse xs of+        [] -> (xs, b0)+        y:ys ->+            let (a, b) = f y+            in  (reverse ys ++ [a], b)++addExtensionPC :: PathComponent -> String -> PathComponent+addExtensionPC p "" = p+addExtensionPC (PathComponent pc) ext =+    PathComponent $ pc +++        if [extSeparator] `isPrefixOf` ext+          then ext+          else extSeparator : ext++splitExtensionPC :: PathComponent -> (PathComponent, String)+splitExtensionPC (PathComponent s) = (PathComponent s1, s2)     where (s1,s2) = fixTrailingDot $ rbreak isExtSeparator s           fixTrailingDot ("",r2) = (r2,"")           fixTrailingDot (r1,r2) | [extSeparator] `isSuffixOf` r1 = (init r1, extSeparator:r2)                                  | otherwise = (r1,r2)           swap (x,y) = (y,x)           rbreak q = (reverse *** reverse) . swap . break q . reverse-genericSplitExtension p = (p,"") -genericSplitExtensions :: Path ar fd -> (Path ar fd, String)-genericSplitExtensions (FileDir p (PathComponent s)) = (FileDir p (PathComponent s1), s2)-    where (s1,s2) = break isExtSeparator s-genericSplitExtensions p = (p,"")--genericTakeExtension :: Path ar fd -> String-genericTakeExtension = snd . genericSplitExtension--genericTakeExtensions :: Path ar fd -> String-genericTakeExtensions = snd . genericSplitExtension-+splitExtensionsPC :: PathComponent -> (PathComponent, String)+splitExtensionsPC (PathComponent s) =+    first PathComponent $ break isExtSeparator s  ------------------------------------------------------------------------ -- QuickCheck@@ -937,22 +1187,25 @@     arbitrary = oneof [qcFileComponent, qcDirComponent]  -qcGenPath :: Gen PathComponent -> Gen (Path ar fd)+qcGenPath ::+    (AbsRelClass ar, FileDirClass fd) =>+    Gen PathComponent -> Gen (Path ar fd) qcGenPath qcLastComponent = do+    ar <- switchAbsRel (fmap (Abs . (:":")) $ QC.choose ('a', 'z')) (return Rel)     pcs <- QC.listOf qcDirComponent     pc <- qcLastComponent-    return $ mkPathFromComponents (pcs ++ [pc])+    return $ mkPathFromComponents ar (pcs ++ [pc]) -qcFilePath :: Gen (FilePath ar)+qcFilePath :: (AbsRelClass ar) => Gen (FilePath ar) qcFilePath = qcGenPath qcFileComponent -qcDirPath :: Gen (DirPath ar)+qcDirPath :: (AbsRelClass ar) => Gen (DirPath ar) qcDirPath = qcGenPath qcDirComponent -newtype PathGen ar fd = PathGen {runPathGen :: Gen (Path ar fd)}- qcPath :: (AbsRelClass ar, FileDirClass fd) => Gen (Path ar fd)-qcPath = runPathGen $ switchFileDir (PathGen qcFilePath) (PathGen qcDirPath)+qcPath =+    getFunctorPath $+    switchFileDir (FunctorPath qcFilePath) (FunctorPath qcDirPath)  instance (AbsRelClass ar, FileDirClass fd) => Arbitrary (Path ar fd) where     arbitrary = qcPath
src/System/Path/Posix.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE CPP #-} #define MODULE_NAME     Posix #define IS_WINDOWS      False
src/System/Path/Windows.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE CPP #-} #define MODULE_NAME     Windows #define IS_WINDOWS      True
test/TestResult.hs view
@@ -2,214 +2,390 @@ {-# LANGUAGE OverloadedStrings #-} module TestResult (results) where -import System.Path.Posix as Path+import qualified System.Path.Posix as Posix+import qualified System.Path.Windows as Windows+import System.Path ((</>), (<.>)) import Data.Char (toLower)  -results :: Char -> Path.FilePath ar -> [(String, Bool)]+results :: (Posix.AbsRelClass ar) => Char -> Posix.FilePath ar -> [(String, Bool)] results a x =-  ("pathMap (map toLower) \"/tmp/Reports/SpreadSheets\" == \"/tmp/reports/spreadsheets\"",-    pathMap (map toLower) "/tmp/Reports/SpreadSheets" == "/tmp/reports/spreadsheets") :-  ("show (rootDir </> \"bla\" </> \"blub\") == \"rootDir </> \\\"bla\\\" </> \\\"blub\\\"\"",-    show (rootDir </> "bla" </> "blub") == "rootDir </> \"bla\" </> \"blub\"") :-  ("show (Just (rootDir </> \"bla\" </> \"blub\")) == \"Just (rootDir </> \\\"bla\\\" </> \\\"blub\\\")\"",-    show (Just (rootDir </> "bla" </> "blub")) == "Just (rootDir </> \"bla\" </> \"blub\")") :-  ("show (currentDir </> \"bla\" </> \"blub\") == \"currentDir </> \\\"bla\\\" </> \\\"blub\\\"\"",-    show (currentDir </> "bla" </> "blub") == "currentDir </> \"bla\" </> \"blub\"") :-  ("show (Just (currentDir </> \"bla\" </> \"blub\")) == \"Just (currentDir </> \\\"bla\\\" </> \\\"blub\\\")\"",-    show (Just (currentDir </> "bla" </> "blub")) == "Just (currentDir </> \"bla\" </> \"blub\")") :-  ("read (show (rootDir </> \"bla\" </> \"blub\")) == rootDir </> \"bla\" </> \"blub\"",-    read (show (rootDir </> "bla" </> "blub")) == rootDir </> "bla" </> "blub") :-  ("read (show (Just (rootDir </> \"bla\" </> \"blub\"))) == Just (rootDir </> \"bla\" </> \"blub\")",-    read (show (Just (rootDir </> "bla" </> "blub"))) == Just (rootDir </> "bla" </> "blub")) :-  ("read (show (currentDir </> \"bla\" </> \"blub\")) == currentDir </> \"bla\" </> \"blub\"",-    read (show (currentDir </> "bla" </> "blub")) == currentDir </> "bla" </> "blub") :-  ("read (show (Just (currentDir </> \"bla\" </> \"blub\"))) == Just (currentDir </> \"bla\" </> \"blub\")",-    read (show (Just (currentDir </> "bla" </> "blub"))) == Just (currentDir </> "bla" </> "blub")) :-  ("asPath \"/tmp\" == \"/tmp\"",-    asPath "/tmp" == "/tmp") :-  ("asPath \"file.txt\" == \"file.txt\"",-    asPath "file.txt" == "file.txt") :-  ("isAbsolute (asPath \"/tmp\" :: AbsDir) == True",-    isAbsolute (asPath "/tmp" :: AbsDir) == True) :-  ("isAbsolute (asPath \"/tmp\" :: RelDir) == False",-    isAbsolute (asPath "/tmp" :: RelDir) == False) :-  ("getPathString (asPath \"/tmp\" :: AbsDir) == \"/tmp\"",-    getPathString (asPath "/tmp" :: AbsDir) == "/tmp") :-  ("getPathString (asPath \"/tmp\" :: RelDir) == \"tmp\"",-    getPathString (asPath "/tmp" :: RelDir) == "tmp") :-  ("getPathString (asRelFile \"file.txt\") == \"file.txt\"",-    getPathString (asRelFile "file.txt") == "file.txt") :-  ("getPathString (asRelFile \"/file.txt\") == \"file.txt\"",-    getPathString (asRelFile "/file.txt") == "file.txt") :-  ("getPathString (asRelFile \"tmp\") == \"tmp\"",-    getPathString (asRelFile "tmp") == "tmp") :-  ("getPathString (asRelFile \"/tmp\") == \"tmp\"",-    getPathString (asRelFile "/tmp") == "tmp") :-  ("getPathString (asRelDir \".\") == \".\"",-    getPathString (asRelDir ".") == ".") :-  ("getPathString (asRelDir \"file.txt\") == \"file.txt\"",-    getPathString (asRelDir "file.txt") == "file.txt") :-  ("getPathString (asRelDir \"/file.txt\") == \"file.txt\"",-    getPathString (asRelDir "/file.txt") == "file.txt") :-  ("getPathString (asRelDir \"tmp\") == \"tmp\"",-    getPathString (asRelDir "tmp") == "tmp") :-  ("getPathString (asRelDir \"/tmp\") == \"tmp\"",-    getPathString (asRelDir "/tmp") == "tmp") :-  ("getPathString (asAbsFile \"file.txt\") == \"/file.txt\"",-    getPathString (asAbsFile "file.txt") == "/file.txt") :-  ("getPathString (asAbsFile \"/file.txt\") == \"/file.txt\"",-    getPathString (asAbsFile "/file.txt") == "/file.txt") :-  ("getPathString (asAbsFile \"tmp\") == \"/tmp\"",-    getPathString (asAbsFile "tmp") == "/tmp") :-  ("getPathString (asAbsFile \"/tmp\") == \"/tmp\"",-    getPathString (asAbsFile "/tmp") == "/tmp") :-  ("getPathString (asAbsDir \"file.txt\") == \"/file.txt\"",-    getPathString (asAbsDir "file.txt") == "/file.txt") :-  ("getPathString (asAbsDir \"/file.txt\") == \"/file.txt\"",-    getPathString (asAbsDir "/file.txt") == "/file.txt") :-  ("getPathString (asAbsDir \"tmp\") == \"/tmp\"",-    getPathString (asAbsDir "tmp") == "/tmp") :-  ("getPathString (asAbsDir \"/tmp\") == \"/tmp\"",-    getPathString (asAbsDir "/tmp") == "/tmp") :-  ("mkPathAbsOrRel \"/tmp\" == Left (asAbsDir \"/tmp\")",-    mkPathAbsOrRel "/tmp" == Left (asAbsDir "/tmp")) :-  ("mkPathAbsOrRel  \"tmp\" == Right (asRelDir \"tmp\")",-    mkPathAbsOrRel  "tmp" == Right (asRelDir "tmp")) :-  ("mkAbsPath \"/tmp\" \"foo.txt\" == \"/tmp/foo.txt\"",-    mkAbsPath "/tmp" "foo.txt" == "/tmp/foo.txt") :-  ("mkAbsPath \"/tmp\" \"/etc/foo.txt\" == \"/etc/foo.txt\"",-    mkAbsPath "/tmp" "/etc/foo.txt" == "/etc/foo.txt") :-  ("addExtension \"file.txt\" \"bib\" == \"file.txt.bib\"",-    addExtension "file.txt" "bib" == "file.txt.bib") :-  ("addExtension \"file.\" \".bib\" == \"file..bib\"",-    addExtension "file." ".bib" == "file..bib") :-  ("addExtension \"file\" \".bib\" == \"file.bib\"",-    addExtension "file" ".bib" == "file.bib") :-  ("addExtension \"\" \"bib\" == \".bib\"",-    addExtension "" "bib" == ".bib") :-  ("addExtension \"\" \".bib\" == \".bib\"",-    addExtension "" ".bib" == ".bib") :-  ("takeFileName (addExtension \"\" \"ext\") == \".ext\"",-    takeFileName (addExtension "" "ext") == ".ext") :-  ("dropExtension x == fst (splitExtension x)",-    dropExtension x == fst (splitExtension x)) :-  ("not $ hasAnExtension (dropExtensions x)",-    not $ hasAnExtension (dropExtensions x)) :-  ("replaceExtension \"file.txt\" \".bob\" == \"file.bob\"",-    replaceExtension "file.txt" ".bob" == "file.bob") :-  ("replaceExtension \"file.txt\" \"bob\" == \"file.bob\"",-    replaceExtension "file.txt" "bob" == "file.bob") :-  ("replaceExtension \"file\" \".bob\" == \"file.bob\"",-    replaceExtension "file" ".bob" == "file.bob") :-  ("replaceExtension \"file.txt\" \"\" == \"file\"",-    replaceExtension "file.txt" "" == "file") :-  ("replaceExtension \"file.fred.bob\" \"txt\" == \"file.fred.txt\"",-    replaceExtension "file.fred.bob" "txt" == "file.fred.txt") :-  ("uncurry (<.>) (splitExtension x) == x",-    uncurry (<.>) (splitExtension x) == x) :-  ("uncurry addExtension (splitExtension x) == x",-    uncurry addExtension (splitExtension x) == x) :-  ("splitExtension \"file.txt\" == (\"file\",\".txt\")",-    splitExtension "file.txt" == ("file",".txt")) :-  ("splitExtension \"file\" == (\"file\",\"\")",-    splitExtension "file" == ("file","")) :-  ("splitExtension \"file/file.txt\" == (\"file/file\",\".txt\")",-    splitExtension "file/file.txt" == ("file/file",".txt")) :-  ("splitExtension \"file.txt/boris\" == (\"file.txt/boris\",\"\")",-    splitExtension "file.txt/boris" == ("file.txt/boris","")) :-  ("splitExtension \"file.txt/boris.ext\" == (\"file.txt/boris\",\".ext\")",-    splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")) :-  ("splitExtension \"file/path.txt.bob.fred\" == (\"file/path.txt.bob\",\".fred\")",-    splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")) :-  ("splitExtensions \"file.tar.gz\" == (\"file\",\".tar.gz\")",-    splitExtensions "file.tar.gz" == ("file",".tar.gz")) :-  ("takeBaseName \"/tmp/somedir/myfile.txt\" == \"myfile\"",-    takeBaseName "/tmp/somedir/myfile.txt" == "myfile") :-  ("takeBaseName \"./myfile.txt\" == \"myfile\"",-    takeBaseName "./myfile.txt" == "myfile") :-  ("takeBaseName \"myfile.txt\" == \"myfile\"",-    takeBaseName "myfile.txt" == "myfile") :-  ("takeExtension x == snd (splitExtension x)",-    takeExtension x == snd (splitExtension x)) :-  ("takeExtension (addExtension x \"ext\") == \".ext\"",-    takeExtension (addExtension x "ext") == ".ext") :-  ("takeExtension (replaceExtension x \"ext\") == \".ext\"",-    takeExtension (replaceExtension x "ext") == ".ext") :-  ("takeExtensions \"file.tar.gz\" == \".tar.gz\"",-    takeExtensions "file.tar.gz" == ".tar.gz") :-  ("takeFileName \"/tmp/somedir/myfile.txt\" == \"myfile.txt\"",-    takeFileName "/tmp/somedir/myfile.txt" == "myfile.txt") :-  ("takeFileName \"./myfile.txt\" == \"myfile.txt\"",-    takeFileName "./myfile.txt" == "myfile.txt") :-  ("takeFileName \"myfile.txt\" == \"myfile.txt\"",-    takeFileName "myfile.txt" == "myfile.txt") :-  ("equalFilePath \"/tmp/\" \"/tmp\" == True",-    equalFilePath "/tmp/" "/tmp" == True) :-  ("equalFilePath \"/tmp\"  \"tmp\"  == False",-    equalFilePath "/tmp"  "tmp"  == False) :-  ("joinPath [\"/tmp\",\"someDir\",\"file.txt\"] == \"/tmp/someDir/file.txt\"",-    joinPath ["/tmp","someDir","file.txt"] == "/tmp/someDir/file.txt") :-  ("joinPath [\"/tmp\",\"someDir\",\"file.txt\"] == asRelFile \"tmp/someDir/file.txt\"",-    joinPath ["/tmp","someDir","file.txt"] == asRelFile "tmp/someDir/file.txt") :-  ("normalise \"/tmp/fred/./jim/./file\" == \"/tmp/fred/jim/file\"",-    normalise "/tmp/fred/./jim/./file" == "/tmp/fred/jim/file") :-  ("splitPath (asAbsDir \"/tmp/someDir/mydir.dir\") == ([\"tmp\",\"someDir\",\"mydir.dir\"], Nothing)",-    splitPath (asAbsDir "/tmp/someDir/mydir.dir") == (["tmp","someDir","mydir.dir"], Nothing)) :-  ("splitPath (asAbsFile \"/tmp/someDir/myfile.txt\") == ([\"tmp\",\"someDir\"], Just \"myfile.txt\")",-    splitPath (asAbsFile "/tmp/someDir/myfile.txt") == (["tmp","someDir"], Just "myfile.txt")) :-  ("makeRelative \"/tmp/somedir\" \"/tmp/somedir/anotherdir/file.txt\" == asRelFile \"anotherdir/file.txt\"",-    makeRelative "/tmp/somedir" "/tmp/somedir/anotherdir/file.txt" == asRelFile "anotherdir/file.txt") :-  ("makeRelative \"/tmp/somedir\" \"/tmp/somedir/anotherdir/dir\" == asRelDir \"anotherdir/dir\"",-    makeRelative "/tmp/somedir" "/tmp/somedir/anotherdir/dir" == asRelDir "anotherdir/dir") :-  ("makeAbsolute \"/tmp\" \"file.txt\"      == asAbsFile \"/tmp/file.txt\"",-    makeAbsolute "/tmp" "file.txt"      == asAbsFile "/tmp/file.txt") :-  ("makeAbsolute \"/tmp\" \"adir/file.txt\" == asAbsFile \"/tmp/adir/file.txt\"",-    makeAbsolute "/tmp" "adir/file.txt" == asAbsFile "/tmp/adir/file.txt") :-  ("makeAbsolute \"/tmp\" \"adir/dir\"      == asAbsDir \"/tmp/adir/dir\"",-    makeAbsolute "/tmp" "adir/dir"      == asAbsDir "/tmp/adir/dir") :-  ("genericMakeAbsolute \"/tmp\" (asRelFile \"file.txt\")       == \"/tmp/file.txt\"",-    genericMakeAbsolute "/tmp" (asRelFile "file.txt")       == "/tmp/file.txt") :-  ("genericMakeAbsolute \"/tmp\" (asRelFile \"adir/file.txt\")  == \"/tmp/adir/file.txt\"",-    genericMakeAbsolute "/tmp" (asRelFile "adir/file.txt")  == "/tmp/adir/file.txt") :-  ("genericMakeAbsolute \"/tmp\" (asAbsFile \"adir/file.txt\")  == \"/adir/file.txt\"",-    genericMakeAbsolute "/tmp" (asAbsFile "adir/file.txt")  == "/adir/file.txt") :-  ("genericMakeAbsolute \"/tmp\" (asAbsFile \"/adir/file.txt\") == \"/adir/file.txt\"",-    genericMakeAbsolute "/tmp" (asAbsFile "/adir/file.txt") == "/adir/file.txt") :-  ("isAbsolute (asAbsFile \"fred\")  == True",-    isAbsolute (asAbsFile "fred")  == True) :-  ("isAbsolute (asRelFile \"fred\")  == False",-    isAbsolute (asRelFile "fred")  == False) :-  ("isAbsolute (asAbsFile \"/fred\") == True",-    isAbsolute (asAbsFile "/fred") == True) :-  ("isAbsolute (asRelFile \"/fred\") == False",-    isAbsolute (asRelFile "/fred") == False) :-  ("null (takeExtension x) == not (hasAnExtension x)",-    null (takeExtension x) == not (hasAnExtension x)) :-  ("hasExtension \".hs\" \"MyCode.hs\" == True",-    hasExtension ".hs" "MyCode.hs" == True) :-  ("hasExtension \".hs\" \"MyCode.hs.bak\" == False",-    hasExtension ".hs" "MyCode.hs.bak" == False) :-  ("hasExtension \".hs\" \"MyCode.bak.hs\" == True",-    hasExtension ".hs" "MyCode.bak.hs" == True) :-  ("extSeparator == '.'",-    extSeparator == '.') :-  ("isPathSeparator pathSeparator",-    isPathSeparator pathSeparator) :-  ("pathSeparator `elem` pathSeparators",-    pathSeparator `elem` pathSeparators) :-  ("isExtSeparator a == (a == extSeparator)",-    isExtSeparator a == (a == extSeparator)) :-  ("isPathSeparator a == (a `elem` pathSeparators)",-    isPathSeparator a == (a `elem` pathSeparators)) :-  ("isSearchPathSeparator a == (a == searchPathSeparator)",-    isSearchPathSeparator a == (a == searchPathSeparator)) :-  ("genericAddExtension \"/\" \"x\" == asAbsDir \"/.x\"",-    genericAddExtension "/" "x" == asAbsDir "/.x") :-  ("genericAddExtension \"/a\" \"x\" == asAbsDir \"/a.x\"",-    genericAddExtension "/a" "x" == asAbsDir "/a.x") :-  ("genericAddExtension \"\" \"x\" == asRelFile \".x\"",-    genericAddExtension "" "x" == asRelFile ".x") :-  ("genericAddExtension \"\" \"\" == asRelFile \"\"",-    genericAddExtension "" "" == asRelFile "") :+  {-# LINE 255 "src/System/Path/Internal.hs" #-}+  ("Posix.pathMap (map toLower) \"/tmp/Reports/SpreadSheets\" == Posix.asAbsDir \"/tmp/reports/spreadsheets\"",+      Posix.pathMap (map toLower) "/tmp/Reports/SpreadSheets" == Posix.asAbsDir "/tmp/reports/spreadsheets") :+  {-# LINE 322 "src/System/Path/Internal.hs" #-}+  ("show (Posix.rootDir </> \"bla\" </> Posix.asRelFile \"blub\") == \"rootDir </> \\\"bla\\\" </> \\\"blub\\\"\"",+      show (Posix.rootDir </> "bla" </> Posix.asRelFile "blub") == "rootDir </> \"bla\" </> \"blub\"") :+  {-# LINE 323 "src/System/Path/Internal.hs" #-}+  ("show (Just (Posix.rootDir </> \"bla\" </> Posix.asRelFile \"blub\")) == \"Just (rootDir </> \\\"bla\\\" </> \\\"blub\\\")\"",+      show (Just (Posix.rootDir </> "bla" </> Posix.asRelFile "blub")) == "Just (rootDir </> \"bla\" </> \"blub\")") :+  {-# LINE 324 "src/System/Path/Internal.hs" #-}+  ("show (Posix.currentDir </> \"bla\" </> Posix.asRelFile \"blub\") == \"currentDir </> \\\"bla\\\" </> \\\"blub\\\"\"",+      show (Posix.currentDir </> "bla" </> Posix.asRelFile "blub") == "currentDir </> \"bla\" </> \"blub\"") :+  {-# LINE 325 "src/System/Path/Internal.hs" #-}+  ("show (Just (Posix.currentDir </> \"bla\" </> Posix.asRelFile \"blub\")) == \"Just (currentDir </> \\\"bla\\\" </> \\\"blub\\\")\"",+      show (Just (Posix.currentDir </> "bla" </> Posix.asRelFile "blub")) == "Just (currentDir </> \"bla\" </> \"blub\")") :+  {-# LINE 326 "src/System/Path/Internal.hs" #-}+  ("show (Windows.asAbsDir \"c:\" Windows.</> \"bla\" Windows.</> Windows.asRelFile \"blub\") == \"asAbsDir \\\"c:\\\" </> \\\"bla\\\" </> \\\"blub\\\"\"",+      show (Windows.asAbsDir "c:" Windows.</> "bla" Windows.</> Windows.asRelFile "blub") == "asAbsDir \"c:\" </> \"bla\" </> \"blub\"") :+  {-# LINE 327 "src/System/Path/Internal.hs" #-}+  ("show (Just (Windows.asAbsDir \"c:\\\\\" Windows.</> \"bla\" Windows.</> Windows.asRelFile \"blub\")) == \"Just (asAbsDir \\\"c:\\\" </> \\\"bla\\\" </> \\\"blub\\\")\"",+      show (Just (Windows.asAbsDir "c:\\" Windows.</> "bla" Windows.</> Windows.asRelFile "blub")) == "Just (asAbsDir \"c:\" </> \"bla\" </> \"blub\")") :+  {-# LINE 348 "src/System/Path/Internal.hs" #-}+  ("let path = Posix.rootDir </> \"bla\" </> Posix.asRelFile \"blub\" in read (show path) == path",+      let path = Posix.rootDir </> "bla" </> Posix.asRelFile "blub" in read (show path) == path) :+  {-# LINE 349 "src/System/Path/Internal.hs" #-}+  ("let path = Just (Posix.rootDir </> \"bla\" </> Posix.asRelFile \"blub\") in read (show path) == path",+      let path = Just (Posix.rootDir </> "bla" </> Posix.asRelFile "blub") in read (show path) == path) :+  {-# LINE 350 "src/System/Path/Internal.hs" #-}+  ("let path = Posix.currentDir </> \"bla\" </> Posix.asRelFile \"blub\" in read (show path) == path",+      let path = Posix.currentDir </> "bla" </> Posix.asRelFile "blub" in read (show path) == path) :+  {-# LINE 351 "src/System/Path/Internal.hs" #-}+  ("let path = Just (Posix.currentDir </> \"bla\" </> Posix.asRelFile \"blub\") in read (show path) == path",+      let path = Just (Posix.currentDir </> "bla" </> Posix.asRelFile "blub") in read (show path) == path) :+  {-# LINE 352 "src/System/Path/Internal.hs" #-}+  ("let path = Windows.rootDir Windows.</> \"bla\" Windows.</> Windows.asRelFile \"blub\" in read (show path) == path",+      let path = Windows.rootDir Windows.</> "bla" Windows.</> Windows.asRelFile "blub" in read (show path) == path) :+  {-# LINE 353 "src/System/Path/Internal.hs" #-}+  ("let path = Just (Windows.rootDir Windows.</> \"bla\" Windows.</> Windows.asRelFile \"blub\") in read (show path) == path",+      let path = Just (Windows.rootDir Windows.</> "bla" Windows.</> Windows.asRelFile "blub") in read (show path) == path) :+  {-# LINE 444 "src/System/Path/Internal.hs" #-}+  ("Posix.asPath \"/tmp\" == Posix.asAbsDir \"/tmp\"",+      Posix.asPath "/tmp" == Posix.asAbsDir "/tmp") :+  {-# LINE 445 "src/System/Path/Internal.hs" #-}+  ("Posix.asPath \"file.txt\" == Posix.asRelFile \"file.txt\"",+      Posix.asPath "file.txt" == Posix.asRelFile "file.txt") :+  {-# LINE 446 "src/System/Path/Internal.hs" #-}+  ("Posix.isAbsolute (Posix.asAbsDir \"/tmp\")",+      Posix.isAbsolute (Posix.asAbsDir "/tmp")) :+  {-# LINE 447 "src/System/Path/Internal.hs" #-}+  ("Posix.isRelative (Posix.asRelDir \"/tmp\")",+      Posix.isRelative (Posix.asRelDir "/tmp")) :+  {-# LINE 448 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asPath \"/tmp\" :: Posix.AbsDir) == \"/tmp\"",+      Posix.getPathString (Posix.asPath "/tmp" :: Posix.AbsDir) == "/tmp") :+  {-# LINE 449 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asPath \"/tmp\" :: Posix.RelDir) == \"tmp\"",+      Posix.getPathString (Posix.asPath "/tmp" :: Posix.RelDir) == "tmp") :+  {-# LINE 450 "src/System/Path/Internal.hs" #-}+  ("Windows.getPathString (Windows.asPath \"\\\\tmp\" :: Windows.AbsDir) == \"\\\\tmp\"",+      Windows.getPathString (Windows.asPath "\\tmp" :: Windows.AbsDir) == "\\tmp") :+  {-# LINE 451 "src/System/Path/Internal.hs" #-}+  ("Windows.getPathString (Windows.asPath \"a:\\\\tmp\" :: Windows.AbsDir) == \"a:\\\\tmp\"",+      Windows.getPathString (Windows.asPath "a:\\tmp" :: Windows.AbsDir) == "a:\\tmp") :+  {-# LINE 452 "src/System/Path/Internal.hs" #-}+  ("Windows.getPathString (Windows.asPath \"tmp\" :: Windows.RelDir) == \"tmp\"",+      Windows.getPathString (Windows.asPath "tmp" :: Windows.RelDir) == "tmp") :+  {-# LINE 465 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelFile \"file.txt\") == \"file.txt\"",+      Posix.getPathString (Posix.asRelFile "file.txt") == "file.txt") :+  {-# LINE 466 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelFile \"/file.txt\") == \"file.txt\"",+      Posix.getPathString (Posix.asRelFile "/file.txt") == "file.txt") :+  {-# LINE 467 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelFile \"tmp\") == \"tmp\"",+      Posix.getPathString (Posix.asRelFile "tmp") == "tmp") :+  {-# LINE 468 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelFile \"/tmp\") == \"tmp\"",+      Posix.getPathString (Posix.asRelFile "/tmp") == "tmp") :+  {-# LINE 474 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelDir \".\") == \".\"",+      Posix.getPathString (Posix.asRelDir ".") == ".") :+  {-# LINE 475 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelDir \"file.txt\") == \"file.txt\"",+      Posix.getPathString (Posix.asRelDir "file.txt") == "file.txt") :+  {-# LINE 476 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelDir \"/file.txt\") == \"file.txt\"",+      Posix.getPathString (Posix.asRelDir "/file.txt") == "file.txt") :+  {-# LINE 477 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelDir \"tmp\") == \"tmp\"",+      Posix.getPathString (Posix.asRelDir "tmp") == "tmp") :+  {-# LINE 478 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelDir \"/tmp\") == \"tmp\"",+      Posix.getPathString (Posix.asRelDir "/tmp") == "tmp") :+  {-# LINE 484 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsFile \"file.txt\") == \"/file.txt\"",+      Posix.getPathString (Posix.asAbsFile "file.txt") == "/file.txt") :+  {-# LINE 485 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsFile \"/file.txt\") == \"/file.txt\"",+      Posix.getPathString (Posix.asAbsFile "/file.txt") == "/file.txt") :+  {-# LINE 486 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsFile \"tmp\") == \"/tmp\"",+      Posix.getPathString (Posix.asAbsFile "tmp") == "/tmp") :+  {-# LINE 487 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsFile \"/tmp\") == \"/tmp\"",+      Posix.getPathString (Posix.asAbsFile "/tmp") == "/tmp") :+  {-# LINE 493 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsDir \"file.txt\") == \"/file.txt\"",+      Posix.getPathString (Posix.asAbsDir "file.txt") == "/file.txt") :+  {-# LINE 494 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsDir \"/file.txt\") == \"/file.txt\"",+      Posix.getPathString (Posix.asAbsDir "/file.txt") == "/file.txt") :+  {-# LINE 495 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsDir \"tmp\") == \"/tmp\"",+      Posix.getPathString (Posix.asAbsDir "tmp") == "/tmp") :+  {-# LINE 496 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsDir \"/tmp\") == \"/tmp\"",+      Posix.getPathString (Posix.asAbsDir "/tmp") == "/tmp") :+  {-# LINE 527 "src/System/Path/Internal.hs" #-}+  ("Posix.mkPathAbsOrRel \"/tmp\" == Left (Posix.asAbsDir \"/tmp\")",+      Posix.mkPathAbsOrRel "/tmp" == Left (Posix.asAbsDir "/tmp")) :+  {-# LINE 528 "src/System/Path/Internal.hs" #-}+  ("Posix.mkPathAbsOrRel  \"tmp\" == Right (Posix.asRelDir \"tmp\")",+      Posix.mkPathAbsOrRel  "tmp" == Right (Posix.asRelDir "tmp")) :+  {-# LINE 529 "src/System/Path/Internal.hs" #-}+  ("Windows.mkPathAbsOrRel \"\\\\tmp\" == Left (Windows.asAbsDir \"\\\\tmp\")",+      Windows.mkPathAbsOrRel "\\tmp" == Left (Windows.asAbsDir "\\tmp")) :+  {-# LINE 530 "src/System/Path/Internal.hs" #-}+  ("Windows.mkPathAbsOrRel \"d:\\\\tmp\" == Left (Windows.asAbsDir \"d:\\\\tmp\")",+      Windows.mkPathAbsOrRel "d:\\tmp" == Left (Windows.asAbsDir "d:\\tmp")) :+  {-# LINE 531 "src/System/Path/Internal.hs" #-}+  ("Windows.mkPathAbsOrRel \"tmp\" == Right (Windows.asRelDir \"tmp\")",+      Windows.mkPathAbsOrRel "tmp" == Right (Windows.asRelDir "tmp")) :+  {-# LINE 556 "src/System/Path/Internal.hs" #-}+  ("Posix.mkAbsPath \"/tmp\" \"foo.txt\" == Posix.asAbsFile \"/tmp/foo.txt\"",+      Posix.mkAbsPath "/tmp" "foo.txt" == Posix.asAbsFile "/tmp/foo.txt") :+  {-# LINE 557 "src/System/Path/Internal.hs" #-}+  ("Posix.mkAbsPath \"/tmp\" \"/etc/foo.txt\" == Posix.asAbsFile \"/etc/foo.txt\"",+      Posix.mkAbsPath "/tmp" "/etc/foo.txt" == Posix.asAbsFile "/etc/foo.txt") :+  {-# LINE 649 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsDir \"/tmp\" </> Posix.asRelFile \"file.txt\") == \"/tmp/file.txt\"",+      Posix.getPathString (Posix.asAbsDir "/tmp" </> Posix.asRelFile "file.txt") == "/tmp/file.txt") :+  {-# LINE 650 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asAbsDir \"/tmp\" </> Posix.asRelDir \"dir\" </> Posix.asRelFile \"file.txt\") == \"/tmp/dir/file.txt\"",+      Posix.getPathString (Posix.asAbsDir "/tmp" </> Posix.asRelDir "dir" </> Posix.asRelFile "file.txt") == "/tmp/dir/file.txt") :+  {-# LINE 651 "src/System/Path/Internal.hs" #-}+  ("Posix.getPathString (Posix.asRelDir \"dir\" </> Posix.asRelFile \"file.txt\") == \"dir/file.txt\"",+      Posix.getPathString (Posix.asRelDir "dir" </> Posix.asRelFile "file.txt") == "dir/file.txt") :+  {-# LINE 652 "src/System/Path/Internal.hs" #-}+  ("Windows.getPathString (Windows.asAbsDir \"\\\\tmp\" Windows.</> Windows.asRelFile \"file.txt\") == \"\\\\tmp\\\\file.txt\"",+      Windows.getPathString (Windows.asAbsDir "\\tmp" Windows.</> Windows.asRelFile "file.txt") == "\\tmp\\file.txt") :+  {-# LINE 653 "src/System/Path/Internal.hs" #-}+  ("Windows.getPathString (Windows.asAbsDir \"c:\\\\tmp\" Windows.</> Windows.asRelFile \"file.txt\") == \"c:\\\\tmp\\\\file.txt\"",+      Windows.getPathString (Windows.asAbsDir "c:\\tmp" Windows.</> Windows.asRelFile "file.txt") == "c:\\tmp\\file.txt") :+  {-# LINE 654 "src/System/Path/Internal.hs" #-}+  ("Windows.getPathString (Windows.asAbsDir \"c:\" Windows.</> Windows.asRelDir \"tmp\" Windows.</> Windows.asRelFile \"file.txt\") == \"c:\\\\tmp\\\\file.txt\"",+      Windows.getPathString (Windows.asAbsDir "c:" Windows.</> Windows.asRelDir "tmp" Windows.</> Windows.asRelFile "file.txt") == "c:\\tmp\\file.txt") :+  {-# LINE 655 "src/System/Path/Internal.hs" #-}+  ("Windows.getPathString (Windows.asRelDir \"dir\" Windows.</> Windows.asRelFile \"file.txt\") == \"dir\\\\file.txt\"",+      Windows.getPathString (Windows.asRelDir "dir" Windows.</> Windows.asRelFile "file.txt") == "dir\\file.txt") :+  {-# LINE 673 "src/System/Path/Internal.hs" #-}+  ("Posix.addExtension (Posix.asRelFile \"file.txt\") \"bib\" == \"file.txt.bib\"",+      Posix.addExtension (Posix.asRelFile "file.txt") "bib" == "file.txt.bib") :+  {-# LINE 674 "src/System/Path/Internal.hs" #-}+  ("Posix.addExtension (Posix.asRelFile \"file.\") \".bib\" == \"file..bib\"",+      Posix.addExtension (Posix.asRelFile "file.") ".bib" == "file..bib") :+  {-# LINE 675 "src/System/Path/Internal.hs" #-}+  ("Posix.addExtension (Posix.asRelFile \"file\") \".bib\" == \"file.bib\"",+      Posix.addExtension (Posix.asRelFile "file") ".bib" == "file.bib") :+  {-# LINE 676 "src/System/Path/Internal.hs" #-}+  ("Posix.addExtension (Posix.asRelFile \"\") \"bib\" == \".bib\"",+      Posix.addExtension (Posix.asRelFile "") "bib" == ".bib") :+  {-# LINE 677 "src/System/Path/Internal.hs" #-}+  ("Posix.addExtension (Posix.asRelFile \"\") \".bib\" == \".bib\"",+      Posix.addExtension (Posix.asRelFile "") ".bib" == ".bib") :+  {-# LINE 678 "src/System/Path/Internal.hs" #-}+  ("Posix.takeFileName (Posix.addExtension (Posix.asRelFile \"\") \"ext\") == \".ext\"",+      Posix.takeFileName (Posix.addExtension (Posix.asRelFile "") "ext") == ".ext") :+  {-# LINE 690 "src/System/Path/Internal.hs" #-}+  ("Posix.dropExtension x == fst (Posix.splitExtension x)",+      Posix.dropExtension x == fst (Posix.splitExtension x)) :+  {-# LINE 696 "src/System/Path/Internal.hs" #-}+  ("not $ Posix.hasAnExtension (Posix.dropExtensions x)",+      not $ Posix.hasAnExtension (Posix.dropExtensions x)) :+  {-# LINE 707 "src/System/Path/Internal.hs" #-}+  ("Posix.replaceExtension (Posix.asRelFile \"file.txt\") \".bob\" == \"file.bob\"",+      Posix.replaceExtension (Posix.asRelFile "file.txt") ".bob" == "file.bob") :+  {-# LINE 708 "src/System/Path/Internal.hs" #-}+  ("Posix.replaceExtension (Posix.asRelFile \"file.txt\") \"bob\" == \"file.bob\"",+      Posix.replaceExtension (Posix.asRelFile "file.txt") "bob" == "file.bob") :+  {-# LINE 709 "src/System/Path/Internal.hs" #-}+  ("Posix.replaceExtension (Posix.asRelFile \"file\") \".bob\" == \"file.bob\"",+      Posix.replaceExtension (Posix.asRelFile "file") ".bob" == "file.bob") :+  {-# LINE 710 "src/System/Path/Internal.hs" #-}+  ("Posix.replaceExtension (Posix.asRelFile \"file.txt\") \"\" == \"file\"",+      Posix.replaceExtension (Posix.asRelFile "file.txt") "" == "file") :+  {-# LINE 711 "src/System/Path/Internal.hs" #-}+  ("Posix.replaceExtension (Posix.asRelFile \"file.fred.bob\") \"txt\" == \"file.fred.txt\"",+      Posix.replaceExtension (Posix.asRelFile "file.fred.bob") "txt" == "file.fred.txt") :+  {-# LINE 729 "src/System/Path/Internal.hs" #-}+  ("uncurry (<.>) (Posix.splitExtension x) == x",+      uncurry (<.>) (Posix.splitExtension x) == x) :+  {-# LINE 730 "src/System/Path/Internal.hs" #-}+  ("uncurry Posix.addExtension (Posix.splitExtension x) == x",+      uncurry Posix.addExtension (Posix.splitExtension x) == x) :+  {-# LINE 731 "src/System/Path/Internal.hs" #-}+  ("Posix.splitExtension (Posix.asRelFile \"file.txt\") == (\"file\",\".txt\")",+      Posix.splitExtension (Posix.asRelFile "file.txt") == ("file",".txt")) :+  {-# LINE 732 "src/System/Path/Internal.hs" #-}+  ("Posix.splitExtension (Posix.asRelFile \"file\") == (\"file\",\"\")",+      Posix.splitExtension (Posix.asRelFile "file") == ("file","")) :+  {-# LINE 733 "src/System/Path/Internal.hs" #-}+  ("Posix.splitExtension (Posix.asRelFile \"file/file.txt\") == (\"file/file\",\".txt\")",+      Posix.splitExtension (Posix.asRelFile "file/file.txt") == ("file/file",".txt")) :+  {-# LINE 734 "src/System/Path/Internal.hs" #-}+  ("Posix.splitExtension (Posix.asRelFile \"file.txt/boris\") == (\"file.txt/boris\",\"\")",+      Posix.splitExtension (Posix.asRelFile "file.txt/boris") == ("file.txt/boris","")) :+  {-# LINE 735 "src/System/Path/Internal.hs" #-}+  ("Posix.splitExtension (Posix.asRelFile \"file.txt/boris.ext\") == (\"file.txt/boris\",\".ext\")",+      Posix.splitExtension (Posix.asRelFile "file.txt/boris.ext") == ("file.txt/boris",".ext")) :+  {-# LINE 736 "src/System/Path/Internal.hs" #-}+  ("Posix.splitExtension (Posix.asRelFile \"file/path.txt.bob.fred\") == (\"file/path.txt.bob\",\".fred\")",+      Posix.splitExtension (Posix.asRelFile "file/path.txt.bob.fred") == ("file/path.txt.bob",".fred")) :+  {-# LINE 743 "src/System/Path/Internal.hs" #-}+  ("Posix.splitExtensions (Posix.asRelFile \"file.tar.gz\") == (\"file\",\".tar.gz\")",+      Posix.splitExtensions (Posix.asRelFile "file.tar.gz") == ("file",".tar.gz")) :+  {-# LINE 760 "src/System/Path/Internal.hs" #-}+  ("Posix.takeBaseName (Posix.asAbsFile \"/tmp/somedir/myfile.txt\") == \"myfile\"",+      Posix.takeBaseName (Posix.asAbsFile "/tmp/somedir/myfile.txt") == "myfile") :+  {-# LINE 761 "src/System/Path/Internal.hs" #-}+  ("Posix.takeBaseName (Posix.asRelFile \"./myfile.txt\") == \"myfile\"",+      Posix.takeBaseName (Posix.asRelFile "./myfile.txt") == "myfile") :+  {-# LINE 762 "src/System/Path/Internal.hs" #-}+  ("Posix.takeBaseName (Posix.asRelFile \"myfile.txt\") == \"myfile\"",+      Posix.takeBaseName (Posix.asRelFile "myfile.txt") == "myfile") :+  {-# LINE 771 "src/System/Path/Internal.hs" #-}+  ("Posix.takeExtension x == snd (Posix.splitExtension x)",+      Posix.takeExtension x == snd (Posix.splitExtension x)) :+  {-# LINE 772 "src/System/Path/Internal.hs" #-}+  ("Posix.takeExtension (Posix.addExtension x \"ext\") == \".ext\"",+      Posix.takeExtension (Posix.addExtension x "ext") == ".ext") :+  {-# LINE 773 "src/System/Path/Internal.hs" #-}+  ("Posix.takeExtension (Posix.replaceExtension x \"ext\") == \".ext\"",+      Posix.takeExtension (Posix.replaceExtension x "ext") == ".ext") :+  {-# LINE 779 "src/System/Path/Internal.hs" #-}+  ("Posix.takeExtensions (Posix.asRelFile \"file.tar.gz\") == \".tar.gz\"",+      Posix.takeExtensions (Posix.asRelFile "file.tar.gz") == ".tar.gz") :+  {-# LINE 785 "src/System/Path/Internal.hs" #-}+  ("Posix.takeFileName (Posix.asAbsFile \"/tmp/somedir/myfile.txt\") == \"myfile.txt\"",+      Posix.takeFileName (Posix.asAbsFile "/tmp/somedir/myfile.txt") == "myfile.txt") :+  {-# LINE 786 "src/System/Path/Internal.hs" #-}+  ("Posix.takeFileName (Posix.asRelFile \"./myfile.txt\") == \"myfile.txt\"",+      Posix.takeFileName (Posix.asRelFile "./myfile.txt") == "myfile.txt") :+  {-# LINE 787 "src/System/Path/Internal.hs" #-}+  ("Posix.takeFileName (Posix.asRelFile \"myfile.txt\") == \"myfile.txt\"",+      Posix.takeFileName (Posix.asRelFile "myfile.txt") == "myfile.txt") :+  {-# LINE 800 "src/System/Path/Internal.hs" #-}+  ("      Posix.equalFilePath \"/tmp/\" \"/tmp\"",+            Posix.equalFilePath "/tmp/" "/tmp") :+  {-# LINE 801 "src/System/Path/Internal.hs" #-}+  ("not $ Posix.equalFilePath \"/tmp\" \"tmp\"",+      not $ Posix.equalFilePath "/tmp" "tmp") :+  {-# LINE 802 "src/System/Path/Internal.hs" #-}+  ("      Windows.equalFilePath \"file\" \"File\"",+            Windows.equalFilePath "file" "File") :+  {-# LINE 803 "src/System/Path/Internal.hs" #-}+  ("not $ Windows.equalFilePath \"file\" \"dir\"",+      not $ Windows.equalFilePath "file" "dir") :+  {-# LINE 817 "src/System/Path/Internal.hs" #-}+  ("Posix.joinPath [\"tmp\",\"someDir\",\"dir\"] == Posix.asRelDir \"tmp/someDir/dir\"",+      Posix.joinPath ["tmp","someDir","dir"] == Posix.asRelDir "tmp/someDir/dir") :+  {-# LINE 818 "src/System/Path/Internal.hs" #-}+  ("Posix.joinPath [\"tmp\",\"someDir\",\"file.txt\"] == Posix.asRelFile \"tmp/someDir/file.txt\"",+      Posix.joinPath ["tmp","someDir","file.txt"] == Posix.asRelFile "tmp/someDir/file.txt") :+  {-# LINE 824 "src/System/Path/Internal.hs" #-}+  ("Posix.normalise \"/tmp/fred/./jim/./file\" == Posix.asAbsFile \"/tmp/fred/jim/file\"",+      Posix.normalise "/tmp/fred/./jim/./file" == Posix.asAbsFile "/tmp/fred/jim/file") :+  {-# LINE 831 "src/System/Path/Internal.hs" #-}+  ("Posix.splitPath (Posix.asAbsDir \"/tmp/someDir/mydir.dir\") == (True, [\"tmp\",\"someDir\",\"mydir.dir\"], Nothing)",+      Posix.splitPath (Posix.asAbsDir "/tmp/someDir/mydir.dir") == (True, ["tmp","someDir","mydir.dir"], Nothing)) :+  {-# LINE 832 "src/System/Path/Internal.hs" #-}+  ("Posix.splitPath (Posix.asAbsFile \"/tmp/someDir/myfile.txt\") == (True, [\"tmp\",\"someDir\"], Just \"myfile.txt\")",+      Posix.splitPath (Posix.asAbsFile "/tmp/someDir/myfile.txt") == (True, ["tmp","someDir"], Just "myfile.txt")) :+  {-# LINE 851 "src/System/Path/Internal.hs" #-}+  ("Posix.makeRelative \"/tmp/somedir\" \"/tmp/somedir/anotherdir/file.txt\" == Posix.asRelFile \"anotherdir/file.txt\"",+      Posix.makeRelative "/tmp/somedir" "/tmp/somedir/anotherdir/file.txt" == Posix.asRelFile "anotherdir/file.txt") :+  {-# LINE 852 "src/System/Path/Internal.hs" #-}+  ("Posix.makeRelative \"/tmp/somedir\" \"/tmp/somedir/anotherdir/dir\" == Posix.asRelDir \"anotherdir/dir\"",+      Posix.makeRelative "/tmp/somedir" "/tmp/somedir/anotherdir/dir" == Posix.asRelDir "anotherdir/dir") :+  {-# LINE 853 "src/System/Path/Internal.hs" #-}+  ("Windows.makeRelative \"c:\\\\tmp\\\\somedir\" \"c:\\\\Tmp\\\\SomeDir\\\\AnotherDir\\\\File.txt\" == Windows.asRelFile \"AnotherDir\\\\File.txt\"",+      Windows.makeRelative "c:\\tmp\\somedir" "c:\\Tmp\\SomeDir\\AnotherDir\\File.txt" == Windows.asRelFile "AnotherDir\\File.txt") :+  {-# LINE 854 "src/System/Path/Internal.hs" #-}+  ("Windows.makeRelative \"c:\\\\tmp\\\\somedir\" \"c:\\\\tmp\\\\somedir\\\\anotherdir\\\\dir\" == Windows.asRelDir \"anotherdir\\\\dir\"",+      Windows.makeRelative "c:\\tmp\\somedir" "c:\\tmp\\somedir\\anotherdir\\dir" == Windows.asRelDir "anotherdir\\dir") :+  {-# LINE 867 "src/System/Path/Internal.hs" #-}+  ("Posix.makeAbsolute \"/tmp\" \"file.txt\"      == Posix.asAbsFile \"/tmp/file.txt\"",+      Posix.makeAbsolute "/tmp" "file.txt"      == Posix.asAbsFile "/tmp/file.txt") :+  {-# LINE 868 "src/System/Path/Internal.hs" #-}+  ("Posix.makeAbsolute \"/tmp\" \"adir/file.txt\" == Posix.asAbsFile \"/tmp/adir/file.txt\"",+      Posix.makeAbsolute "/tmp" "adir/file.txt" == Posix.asAbsFile "/tmp/adir/file.txt") :+  {-# LINE 869 "src/System/Path/Internal.hs" #-}+  ("Posix.makeAbsolute \"/tmp\" \"adir/dir\"      == Posix.asAbsDir \"/tmp/adir/dir\"",+      Posix.makeAbsolute "/tmp" "adir/dir"      == Posix.asAbsDir "/tmp/adir/dir") :+  {-# LINE 881 "src/System/Path/Internal.hs" #-}+  ("Posix.genericMakeAbsolute \"/tmp\" (Posix.asRelFile \"file.txt\")       == \"/tmp/file.txt\"",+      Posix.genericMakeAbsolute "/tmp" (Posix.asRelFile "file.txt")       == "/tmp/file.txt") :+  {-# LINE 882 "src/System/Path/Internal.hs" #-}+  ("Posix.genericMakeAbsolute \"/tmp\" (Posix.asRelFile \"adir/file.txt\")  == \"/tmp/adir/file.txt\"",+      Posix.genericMakeAbsolute "/tmp" (Posix.asRelFile "adir/file.txt")  == "/tmp/adir/file.txt") :+  {-# LINE 883 "src/System/Path/Internal.hs" #-}+  ("Posix.genericMakeAbsolute \"/tmp\" (Posix.asAbsFile \"adir/file.txt\")  == \"/adir/file.txt\"",+      Posix.genericMakeAbsolute "/tmp" (Posix.asAbsFile "adir/file.txt")  == "/adir/file.txt") :+  {-# LINE 884 "src/System/Path/Internal.hs" #-}+  ("Posix.genericMakeAbsolute \"/tmp\" (Posix.asAbsFile \"/adir/file.txt\") == \"/adir/file.txt\"",+      Posix.genericMakeAbsolute "/tmp" (Posix.asAbsFile "/adir/file.txt") == "/adir/file.txt") :+  {-# LINE 929 "src/System/Path/Internal.hs" #-}+  ("Posix.isAbsolute (Posix.asAbsFile \"fred\")",+      Posix.isAbsolute (Posix.asAbsFile "fred")) :+  {-# LINE 930 "src/System/Path/Internal.hs" #-}+  ("Posix.isAbsolute (Posix.asAbsFile \"/fred\")",+      Posix.isAbsolute (Posix.asAbsFile "/fred")) :+  {-# LINE 931 "src/System/Path/Internal.hs" #-}+  ("Windows.isAbsolute (Windows.asAbsFile \"\\\\fred\")",+      Windows.isAbsolute (Windows.asAbsFile "\\fred")) :+  {-# LINE 932 "src/System/Path/Internal.hs" #-}+  ("Windows.isAbsolute (Windows.asAbsFile \"c:\\\\fred\")",+      Windows.isAbsolute (Windows.asAbsFile "c:\\fred")) :+  {-# LINE 948 "src/System/Path/Internal.hs" #-}+  ("Posix.isRelative (Posix.asRelFile \"fred\")",+      Posix.isRelative (Posix.asRelFile "fred")) :+  {-# LINE 949 "src/System/Path/Internal.hs" #-}+  ("Posix.isRelative (Posix.asRelFile \"/fred\")",+      Posix.isRelative (Posix.asRelFile "/fred")) :+  {-# LINE 950 "src/System/Path/Internal.hs" #-}+  ("Windows.isRelative (Windows.asRelFile \"fred\")",+      Windows.isRelative (Windows.asRelFile "fred")) :+  {-# LINE 964 "src/System/Path/Internal.hs" #-}+  ("null (Posix.takeExtension x) == not (Posix.hasAnExtension x)",+      null (Posix.takeExtension x) == not (Posix.hasAnExtension x)) :+  {-# LINE 970 "src/System/Path/Internal.hs" #-}+  ("Posix.hasExtension \".hs\" (Posix.asRelFile \"MyCode.hs\")",+      Posix.hasExtension ".hs" (Posix.asRelFile "MyCode.hs")) :+  {-# LINE 971 "src/System/Path/Internal.hs" #-}+  ("Posix.hasExtension \".hs\" (Posix.asRelFile \"MyCode.bak.hs\")",+      Posix.hasExtension ".hs" (Posix.asRelFile "MyCode.bak.hs")) :+  {-# LINE 972 "src/System/Path/Internal.hs" #-}+  ("not $ Posix.hasExtension \".hs\" (Posix.asRelFile \"MyCode.hs.bak\")",+      not $ Posix.hasExtension ".hs" (Posix.asRelFile "MyCode.hs.bak")) :+  {-# LINE 990 "src/System/Path/Internal.hs" #-}+  ("Posix.extSeparator == '.'",+      Posix.extSeparator == '.') :+  {-# LINE 1001 "src/System/Path/Internal.hs" #-}+  ("Posix.isPathSeparator Posix.pathSeparator",+      Posix.isPathSeparator Posix.pathSeparator) :+  {-# LINE 1008 "src/System/Path/Internal.hs" #-}+  ("Posix.pathSeparator `elem` Posix.pathSeparators",+      Posix.pathSeparator `elem` Posix.pathSeparators) :+  {-# LINE 1019 "src/System/Path/Internal.hs" #-}+  ("Posix.isExtSeparator a == (a == Posix.extSeparator)",+      Posix.isExtSeparator a == (a == Posix.extSeparator)) :+  {-# LINE 1026 "src/System/Path/Internal.hs" #-}+  ("Posix.isPathSeparator a == (a `elem` Posix.pathSeparators)",+      Posix.isPathSeparator a == (a `elem` Posix.pathSeparators)) :+  {-# LINE 1032 "src/System/Path/Internal.hs" #-}+  ("Posix.isSearchPathSeparator a == (a == Posix.searchPathSeparator)",+      Posix.isSearchPathSeparator a == (a == Posix.searchPathSeparator)) :+  {-# LINE 1048 "src/System/Path/Internal.hs" #-}+  ("Posix.genericAddExtension \"/\" \"x\" == Posix.asAbsDir \"/.x\"",+      Posix.genericAddExtension "/" "x" == Posix.asAbsDir "/.x") :+  {-# LINE 1049 "src/System/Path/Internal.hs" #-}+  ("Posix.genericAddExtension \"/a\" \"x\" == Posix.asAbsDir \"/a.x\"",+      Posix.genericAddExtension "/a" "x" == Posix.asAbsDir "/a.x") :+  {-# LINE 1050 "src/System/Path/Internal.hs" #-}+  ("Posix.genericAddExtension \"\" \"x\" == Posix.asRelFile \".x\"",+      Posix.genericAddExtension "" "x" == Posix.asRelFile ".x") :+  {-# LINE 1051 "src/System/Path/Internal.hs" #-}+  ("Posix.genericAddExtension \"\" \"\" == Posix.asRelFile \"\"",+      Posix.genericAddExtension "" "" == Posix.asRelFile "") :   []
test/TestTemplate.hs view
@@ -1,11 +1,13 @@ {-# LANGUAGE OverloadedStrings #-} module TestResult (results) where -import System.Path.Posix as Path+import qualified System.Path.Posix as Posix+import qualified System.Path.Windows as Windows+import System.Path ((</>), (<.>)) import Data.Char (toLower)  -results :: Char -> Path.FilePath ar -> [(String, Bool)]+results :: (Posix.AbsRelClass ar) => Char -> Posix.FilePath ar -> [(String, Bool)] results a x =   <TESTS_GO_HERE>   []
tool/CreateTest.hs view
@@ -20,11 +20,23 @@  main :: IO () main = do+  let mapSndF f (a,b) = (,) a <$> f b+  let readFileNumbered path =+        zipWith (\n row -> ((path,n), row)) [(0::Int)..] . lines <$>+        readFile path   testLines <--     mapMaybe (stripPrefix testPrefix) . concatMap lines <$> mapM readFile srcfiles+     mapMaybe (mapSndF $ stripPrefix testPrefix) . concat <$>+        mapM readFileNumbered srcfiles   (templateHead,_:templateTail) <-      break (tok `isInfixOf`) . lines <$> readFile template-  let outLines = (\t -> printf "  (%s,\n    %s) :" (show t) t) <$> testLines+  {-+  Choose the same indentation depth as in the source file,+  such that GHC reports precise source file locations.+  -}+  let outLines =+        (\((src,n),t) ->+           printf "  {-# LINE %d \"%s\" #-}\n  (%s,\n      %s) :"+              n src (show t) t) <$> testLines    writeFile testModule $ unlines $      ("{- Do not edit! Created from " ++ template ++ " -}") :