! Copyright (C) 2007, 2009 Slava Pestov, Daniel Ehrenberg. ! See http://factorcode.org/license.txt for BSD license. USING: sequences io.pathnames kernel regexp.combinators strings splitting system unicode.case peg.ebnf regexp arrays ; IN: globs : not-path-separator ( -- sep ) os windows? R! [^/\\]! R! [^/]! ? ; foldable EBNF: Character = "\\" .:c => [[ c 1string ]] | !(","|"}") . => [[ 1string ]] RangeCharacter = !("]") . Range = RangeCharacter:a "-" RangeCharacter:b => [[ a b ]] | RangeCharacter => [[ 1string ]] StartRange = .:a "-" RangeCharacter:b => [[ a b ]] | . => [[ 1string ]] Ranges = StartRange:s Range*:r => [[ r s prefix ]] CharClass = "^"?:n Ranges:e => [[ e n [ ] when ]] AlternationBody = Concatenation:c "," AlternationBody:a => [[ a c prefix ]] | Concatenation => [[ 1array ]] Element = "*" => [[ not-path-separator ]] | "?" => [[ not-path-separator ]] | "[" CharClass:c "]" => [[ c ]] | "{" AlternationBody:b "}" => [[ b ]] | Character Concatenation = Element* => [[ ]] End = !(.) Main = Concatenation End ;EBNF : glob-matches? ( input glob -- ? ) [ >case-fold ] bi@ matches? ; : glob-pattern? ( string -- ? ) [ "\\*?[{" member? ] any? ; : glob-parent-directory ( glob -- parent-directory ) path-separator split harvest dup [ glob-pattern? ] find drop head path-separator join ;