packages feed

Glob 0.6 → 0.6.1

raw patch · 3 files changed

+70/−14 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGELOG.txt view
@@ -1,3 +1,10 @@+0.6.1, 2011-09-14:+	Bug fix: globDir should now ignore the given directory when given an+	         absolute path on Windows.++	Doc fix: noted that globDir doesn't actually fully ignore the given+	         directory if the Pattern starts with a path separator.+ 0.6, 2011-09-12: 	New functions: 		System.FilePath.Glob.glob :: Pattern -> IO [FilePath]
Glob.cabal view
@@ -1,7 +1,7 @@ Cabal-Version: >= 1.6  Name:        Glob-Version:     0.6+Version:     0.6.1 Homepage:    http://iki.fi/matti.niemenmaa/glob/ Synopsis:    Globbing library Category:    System
System/FilePath/Glob/Directory.hs view
@@ -10,15 +10,15 @@ import qualified Data.DList as DL import Data.DList       (DList) import Data.List        ((\\))-import Data.Maybe       (listToMaybe) import System.Directory ( doesDirectoryExist, getDirectoryContents                         , getCurrentDirectory                         )-import System.FilePath  ( (</>), extSeparator, isExtSeparator, pathSeparator-                        , takeDrive+import System.FilePath  ( (</>), takeDrive, splitDrive+                        , extSeparator, isExtSeparator+                        , pathSeparator, isPathSeparator                         ) -import System.FilePath.Glob.Base  ( Pattern(..), Token(..), liftP+import System.FilePath.Glob.Base  ( Pattern(..), Token(..)                                   , MatchOptions, matchDefault                                   ) import System.FilePath.Glob.Match (matchWith)@@ -67,8 +67,15 @@ -- -- If the given 'FilePath' is @[]@, 'getCurrentDirectory' will be used. ----- If the given 'Pattern' starts with a path separator, it is not relative to--- the given directory and the @dir@ parameter is completely ignored!+-- If the given 'Pattern' starts with a drive (as defined by+-- 'System.FilePath'), it is not relative to the given directory and the+-- 'FilePath' parameter is completely ignored! Similarly, if the given+-- 'Pattern' starts with a path separator, only the drive part of the+-- 'FilePath' is used. On Posix systems these behaviours are equivalent:+-- 'Pattern's starting with @\/@ work relative to @\/@. On Windows, 'Pattern's+-- starting with @\/@ or @\\@ work relative only to the drive part of+-- 'FilePath' and 'Pattern's starting with absolute paths ignore the+-- 'FilePath'. -- -- Note that in some cases results outside the given directory may be returned: -- for instance the @.*@ pattern matches the @..@ directory.@@ -114,13 +121,11 @@ globDir'0 :: MatchOptions -> Pattern -> FilePath           -> IO (DList FilePath, DList FilePath) globDir'0 opts pat dir = do-   (dir',pat') <--      if maybe False (==PathSeparator) . listToMaybe . unPattern $ pat-         then do-            curDir <- getCurrentDirectory-            return (takeDrive curDir, liftP (dropWhile (==PathSeparator)) pat)-         else fmap (flip (,) pat) $-                 if null dir then getCurrentDirectory else return dir+   let (pat', drive) = driveSplit pat+   dir' <- case drive of+                Just "" -> fmap takeDrive getCurrentDirectory+                Just d  -> return d+                Nothing -> if null dir then getCurrentDirectory else return dir    globDir' opts (separate pat') dir'  globDir' :: MatchOptions -> [TypedPattern] -> FilePath@@ -219,6 +224,50 @@    f (Any      p) ts = u p ++ ts     u = unPattern++-- Note that we consider "/foo" to specify a drive on Windows, even though it's+-- relative to the current drive.+--+-- Returns the [TypedPattern] of the Pattern (with the drive dropped if+-- appropriate) and, if the Pattern specified a drive, a Maybe representing the+-- drive to use. If it's a Just "", use the drive of the current working+-- directory.+driveSplit :: Pattern -> (Pattern, Maybe FilePath)+driveSplit = check . split . unPattern+ where+   -- We can't just use something like commonDirectory because of Windows+   -- drives being possibly longer than one "directory", like "//?/foo/bar/".+   -- So just take as much as possible.+   split (LongLiteral _ l : xs) = first (l++) (split xs)+   split (    Literal   l : xs) = first (l:) (split xs)+   split (PathSeparator   : xs) = first (pathSeparator:) (split xs)+   split ( ExtSeparator   : xs) = first ( extSeparator:) (split xs)+   split xs                     = ([],xs)++   -- The isPathSeparator check is interesting in two ways:+   --+   -- 1. It's correct to return simply Just "" because there can't be more than+   --    one path separator if splitDrive gave a null drive: "//x" is a shared+   --    "drive" in Windows and starts with the root "drive" in Posix.+   --+   -- 2. The 'head' is safe because we have not (null d) && null drive.+   check (d,ps)+      | null d                      = (Pattern     ps, Nothing)+      | not (null drive)            = (dirify rest ps, Just drive)+      | isPathSeparator (head rest) = (Pattern     ps, Just "")+      | otherwise                   = (dirify d    ps, Nothing)+    where+      (drive, rest) = splitDrive d++   dirify path = Pattern . (comp path++)++   comp s = let (p,l) = foldr f ([],[]) s in if null l then p else ll l p+    where+      f c (p,l) | isExtSeparator  c = (ExtSeparator  : ll l p, [])+                | isPathSeparator c = (PathSeparator : ll l p, [])+                | otherwise         = (p, c:l)++      ll l p = if null l then p else LongLiteral (length l) l : p  -- |Factors out the directory component of a 'Pattern'. Useful in conjunction -- with 'globDir'.