File: Simplify.hs

package info (click to toggle)
haskell-glob 0.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 192 kB
  • sloc: haskell: 1,193; makefile: 2
file content (42 lines) | stat: -rw-r--r-- 1,477 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
-- File created: 2009-01-30 14:54:14

module System.FilePath.Glob.Simplify (simplify) where

import System.FilePath.Glob.Base (Pattern(..), Token(..), liftP)

-- |Simplifies a 'Pattern' object: removes redundant @\"./\"@, for instance.
-- The resulting 'Pattern' matches the exact same input as the original one,
-- with some differences:
--
-- * The output of 'globDir' will differ: for example, globbing for @\"./\*\"@
--   gives @\"./foo\"@, but after simplification this'll be only @\"foo\"@.
--
-- * Decompiling the simplified 'Pattern' will obviously not give the original.
--
-- * The simplified 'Pattern' is a bit faster to match with and uses less
--   memory, since some redundant data is removed.
--
-- For the last of the above reasons, if you're performance-conscious and not
-- using 'globDir', you should always 'simplify' after calling 'compile'.
simplify :: Pattern -> Pattern
simplify = liftP (go . pre)
 where
   -- ./ at beginning -> nothing (any number of /'s)
   pre (ExtSeparator:PathSeparator:xs) = pre (dropWhile isSlash xs)
   pre                             xs  = xs

   go [] = []

   -- /./ -> /
   go (PathSeparator:ExtSeparator:xs@(PathSeparator:_)) = go xs

   go (x:xs) =
      if isSlash x
         then let (compressed,ys) = span isSlash xs
               in if null compressed
                     then x : go ys
                     else go (x : ys)
         else x : go xs

   isSlash PathSeparator = True
   isSlash _             = False