> module Filter (filterdots, filterbackups, basename, filter_patterns) where > import Type_Data > import Library > import Opts Get the last pathname component of a FilePath argument, e.g. Main> basename "/foo/bar/quux.txt" "quux.txt" Main> basename "/foo/bar/quux" "quux" Main> basename "/foo/bar/quux/" "quux" Main> basename "" "" Main> > basename :: FilePath -> FilePath > basename "" = "" > basename f = if head rev_f == '/' > then lastpath $ tail rev_f > else lastpath rev_f > where rev_f = reverse f > lastpath fp = reverse $ takeUntil ((==) '/') fp Filter either nothing, all strings with basename beginning with a '.' or all strings with a basename of "." or ".." depending on the options. Main> filterdots [] ["foo", ".bar", "..", ".", ".quux", "wibble"] ["foo","wibble"] Main> filterdots [ShowAll] ["foo", ".bar", "..", ".", ".quux", "wibble"] ["foo",".bar","..",".",".quux","wibble"] Main> filterdots [ShowMost] ["foo", ".bar", "..", ".", ".quux", "wibble"] ["foo",".bar",".quux","wibble"] Main> filterdots [ShowMost] $ map (\f -> "qq/" ++ f) ["foo", ".bar", "..", ".", ".quux", "wibble"] ["qq/foo","qq/.bar","qq/.quux","qq/wibble"] Main> > filterdots :: MyOptions -> [String] -> [String] > filterdots opts fs = if show_all_dots > then fs > else if show_most_dots > then filter filter_some_dots fs > else filter filter_all_dots fs > where show_all_dots = or (map ((==) ShowAll) opts) > show_most_dots = or (map ((==) ShowMost) opts) > filter_some_dots f = ((basename f) /= ".") && ((basename f) /= "..") > filter_all_dots f = head (basename f) /= '.' Remove any strings ending in '~' if that option is set, e.g. Main> filterbackups [] ["foo", "bar~"] ["foo","bar~"] Main> filterbackups [FilterBackups] ["foo", "bar~"] ["foo"] Main> > filterbackups :: MyOptions -> [String] -> [String] > filterbackups opts fs = if filter_backups opts then filter not_is_backup fs > else fs > where not_is_backup f = last f /= '~' Remove any strings matching any of the patterns, which treat '*' as matching any number (including 0) of any character and '?' as matching any single character. > filter_patterns :: [Pattern] -> String -> Bool > filter_patterns ps s = or $ map (filter_pattern bs) ps > where bs = basename s The obvious child to the above function > filter_pattern :: String -> Pattern -> Bool > filter_pattern [] [] = True > filter_pattern [] "*" = True > filter_pattern [] _ = False > filter_pattern _ [] = False > filter_pattern (s:ss) (p:ps) > = case p of > '?' -> filter_pattern ss ps > '*' -> filter_pattern ss ps || filter_pattern ss (p:ps) > _ -> (s == p) && filter_pattern ss ps