globs: implement glob-directory.
It looks too complicated, and maybe it is. Some tests pass.locals-and-roots
parent
c1010144e5
commit
1441d66553
|
@ -1,4 +1,5 @@
|
||||||
USING: globs io.pathnames literals sequences tools.test ;
|
USING: globs io.directories io.files.temp io.files.unique
|
||||||
|
io.pathnames literals sequences tools.test ;
|
||||||
IN: globs.tests
|
IN: globs.tests
|
||||||
|
|
||||||
{ f } [ "abd" "fdf" glob-matches? ] unit-test
|
{ f } [ "abd" "fdf" glob-matches? ] unit-test
|
||||||
|
@ -30,6 +31,57 @@ IN: globs.tests
|
||||||
{ t } [ "fo\\*" glob-pattern? ] unit-test
|
{ t } [ "fo\\*" glob-pattern? ] unit-test
|
||||||
{ t } [ "fo{o,bro}" glob-pattern? ] unit-test
|
{ t } [ "fo{o,bro}" glob-pattern? ] unit-test
|
||||||
|
|
||||||
|
{
|
||||||
|
{ "a" }
|
||||||
|
{ "a" "a/b" "a/b/c" "a/b/c/d" "a/b/h" "a/e" "a/e/g" }
|
||||||
|
{
|
||||||
|
"a" "a/b" "a/b/c" "a/b/c/d" "a/b/c/d/e" "a/b/c/f"
|
||||||
|
"a/b/g" "a/b/h" "a/b/h/e" "a/e" "a/e/f" "a/e/g"
|
||||||
|
"a/e/g/e"
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"a" "a/b" "a/b/c" "a/b/c/d" "a/b/c/d/e" "a/b/c/f"
|
||||||
|
"a/b/g" "a/b/h" "a/b/h/e" "a/e" "a/e/f" "a/e/g"
|
||||||
|
"a/e/g/e"
|
||||||
|
}
|
||||||
|
{ "a/b" }
|
||||||
|
{ "a/b/c/d/e" "a/b/h/e" "a/e" "a/e/g/e" }
|
||||||
|
! { "a/b/c/d/e" "a/b/h/e" "a/e" "a/e/g/e" }
|
||||||
|
! { "a/b/c/d/e" "a/b/h/e" "a/e" "a/e/g/e" }
|
||||||
|
{ "a/e/f" "a/e/g" }
|
||||||
|
{ "a/b" "a/e" }
|
||||||
|
} [
|
||||||
|
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"a" make-directory
|
||||||
|
"a/b" make-directory
|
||||||
|
"a/b/c" make-directory
|
||||||
|
"a/b/c/d" make-directory
|
||||||
|
"a/b/c/d/e" touch-file
|
||||||
|
"a/b/c/f" touch-file
|
||||||
|
"a/b/g" touch-file
|
||||||
|
"a/b/h" make-directory
|
||||||
|
"a/b/h/e" touch-file
|
||||||
|
"a/e" make-directory
|
||||||
|
"a/e/f" touch-file
|
||||||
|
"a/e/g" make-directory
|
||||||
|
"a/e/g/e" touch-file
|
||||||
|
|
||||||
|
"**" glob-directory
|
||||||
|
"**/" glob-directory
|
||||||
|
"**/*" glob-directory
|
||||||
|
"**/**" glob-directory
|
||||||
|
"**/b" glob-directory
|
||||||
|
"**/e" glob-directory
|
||||||
|
! "**//e" glob-directory
|
||||||
|
! "**/**/e" glob-directory
|
||||||
|
"**/e/**" glob-directory
|
||||||
|
"a/**" glob-directory
|
||||||
|
] cleanup-unique-directory
|
||||||
|
] with-temp-directory
|
||||||
|
] unit-test
|
||||||
|
|
||||||
${ { "foo" "bar" } path-separator join }
|
${ { "foo" "bar" } path-separator join }
|
||||||
[ { "foo" "bar" "ba?" } path-separator join glob-parent-directory ] unit-test
|
[ { "foo" "bar" "ba?" } path-separator join glob-parent-directory ] unit-test
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
! Copyright (C) 2007, 2009 Slava Pestov, Daniel Ehrenberg.
|
! Copyright (C) 2007, 2009 Slava Pestov, Daniel Ehrenberg.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: sequences io.pathnames kernel regexp.combinators
|
USING: accessors arrays combinators combinators.short-circuit
|
||||||
strings splitting system unicode.case peg.ebnf regexp arrays ;
|
io.directories io.files io.files.info io.pathnames kernel locals
|
||||||
|
make peg.ebnf regexp regexp.combinators sequences splitting
|
||||||
|
strings system unicode.case ;
|
||||||
IN: globs
|
IN: globs
|
||||||
|
|
||||||
: not-path-separator ( -- sep )
|
: not-path-separator ( -- sep )
|
||||||
|
@ -47,6 +49,103 @@ Main = Concatenation End
|
||||||
: glob-pattern? ( string -- ? )
|
: glob-pattern? ( string -- ? )
|
||||||
[ "\\*?[{" member? ] any? ;
|
[ "\\*?[{" member? ] any? ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
DEFER: glob-directory%
|
||||||
|
|
||||||
|
: ?glob-directory% ( root remaining entry -- )
|
||||||
|
directory? [
|
||||||
|
glob-directory%
|
||||||
|
] [
|
||||||
|
empty? [ , ] [ drop ] if
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
:: glob-wildcard% ( root globs -- )
|
||||||
|
globs ?second :> next-glob
|
||||||
|
next-glob dup pair? [ second ] [ drop f ] if :> next-glob-regexp
|
||||||
|
|
||||||
|
root directory-entries [| entry |
|
||||||
|
root entry name>> append-path
|
||||||
|
{
|
||||||
|
{ [ next-glob not ] [ dup , ] }
|
||||||
|
{ [ next-glob empty? ] [ entry directory? [ dup , ] when ] }
|
||||||
|
[
|
||||||
|
next-glob-regexp [
|
||||||
|
entry name>> >case-fold next-glob-regexp matches?
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
[ next-glob "**" = ]
|
||||||
|
[ entry name>> next-glob = ]
|
||||||
|
} 0||
|
||||||
|
] if [
|
||||||
|
globs 2 tail [
|
||||||
|
dup ,
|
||||||
|
] [
|
||||||
|
entry directory? [
|
||||||
|
dupd glob-directory%
|
||||||
|
] [
|
||||||
|
drop
|
||||||
|
] if
|
||||||
|
] if-empty
|
||||||
|
] when
|
||||||
|
]
|
||||||
|
} cond
|
||||||
|
|
||||||
|
{ [ entry directory? ] [ next-glob ] } 0&& [
|
||||||
|
globs glob-directory%
|
||||||
|
] [
|
||||||
|
drop
|
||||||
|
] if
|
||||||
|
] each ;
|
||||||
|
|
||||||
|
:: glob-pattern% ( root globs -- )
|
||||||
|
globs unclip second :> ( remaining glob )
|
||||||
|
|
||||||
|
root directory-entries [| entry |
|
||||||
|
entry name>> >case-fold glob matches? [
|
||||||
|
root entry name>> append-path
|
||||||
|
remaining entry ?glob-directory%
|
||||||
|
] when
|
||||||
|
] each ;
|
||||||
|
|
||||||
|
:: glob-literal% ( root globs -- )
|
||||||
|
globs unclip :> ( remaining glob )
|
||||||
|
|
||||||
|
root glob append-path dup exists? [
|
||||||
|
remaining over file-info ?glob-directory%
|
||||||
|
] [
|
||||||
|
drop
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
: glob-directory% ( root globs -- )
|
||||||
|
dup ?first {
|
||||||
|
{ f [ 2drop ] }
|
||||||
|
{ "**" [ glob-wildcard% ] }
|
||||||
|
[ pair? [ glob-pattern% ] [ glob-literal% ] if ]
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
: split-glob ( glob -- path globs )
|
||||||
|
{ } [
|
||||||
|
over glob-pattern?
|
||||||
|
] [
|
||||||
|
[
|
||||||
|
path-separator first over last-index
|
||||||
|
[ cut rest ] [ "" swap ] if*
|
||||||
|
] dip swap prefix
|
||||||
|
] while ;
|
||||||
|
|
||||||
|
: glob-path ( glob -- path globs )
|
||||||
|
split-glob [
|
||||||
|
dup { [ "**" = not ] [ glob-pattern? ] } 1&& [
|
||||||
|
dup >case-fold <glob> 2array
|
||||||
|
] when
|
||||||
|
] map ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: glob-directory ( glob -- files )
|
||||||
|
glob-path [ glob-directory% ] { } make ;
|
||||||
|
|
||||||
: glob-parent-directory ( glob -- parent-directory )
|
: glob-parent-directory ( glob -- parent-directory )
|
||||||
path-separator split harvest dup [ glob-pattern? ] find drop head
|
path-separator split harvest dup [ glob-pattern? ] find drop head
|
||||||
path-separator join ;
|
path-separator join ;
|
||||||
|
|
Loading…
Reference in New Issue