hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 347529391e4198744e984f99d148fa6a1aefc962
parent d632dedb4dd7fcc273249a94dd610da0f277b879
Author: Sebastian <sebastian@sebsite.pw>
Date:   Fri, 29 Sep 2023 22:19:31 -0400

glob: recognize escapes in last path component

So `\*` only matches `*` rather than being treated as a wildcard.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mglob/+test.ha | 27++++++++++++++-------------
Mglob/glob.ha | 6++++++
2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/glob/+test.ha b/glob/+test.ha @@ -18,6 +18,7 @@ use strings; ("//", flag::NONE), (".", flag::NONE), ("..", flag::NONE), + ("\\*", flag::NONE), ]; for (let i = 0z; i < len(cases); i += 1) { let gen = glob(cases[i].0, cases[i].1); @@ -46,18 +47,18 @@ use strings; @test fn pattern_parse() void = { const cases: [_](str, bool, str, str, str) = [ - ("foo/bar/baz", true, "foo/bar/", "baz", ""), - ("foo/b\\ar/baz", true, "foo/b\\ar/", "baz", ""), - ("foo/b\\ar/baz", false, "foo/bar/", "baz", ""), - ("/foo/bar/baz", true, "/foo/bar/", "baz", ""), - ("/foo\\/bar/baz", true, "/foo\\/bar/", "baz", ""), - ("/foo\\/bar/baz", false, "/foo/bar/", "baz", ""), - ("/foo/bar\\/baz", true, "/foo/bar\\/", "baz", ""), - ("/foo/bar\\/baz", false, "/foo/bar/", "baz", ""), - ("/foobarbaz", true, "/", "foobarbaz", ""), + ("foo/bar/baz", true, "foo/bar/baz", "", ""), + ("foo/b\\ar/baz", true, "foo/b\\ar/baz", "", ""), + ("foo/b\\ar/baz", false, "foo/bar/baz", "", ""), + ("/foo/bar/baz", true, "/foo/bar/baz", "", ""), + ("/foo\\/bar/baz", true, "/foo\\/bar/baz", "", ""), + ("/foo\\/bar/baz", false, "/foo/bar/baz", "", ""), + ("/foo/bar\\/baz", true, "/foo/bar\\/baz", "", ""), + ("/foo/bar\\/baz", false, "/foo/bar/baz", "", ""), + ("/foobarbaz", true, "/foobarbaz", "", ""), ("foo/bar/baz/", true, "foo/bar/baz/", "", ""), ("foobarbaz/", true, "foobarbaz/", "", ""), - ("foobarbaz", true, "", "foobarbaz", ""), + ("foobarbaz", true, "foobarbaz", "", ""), ("foo/b?r/baz", true, "foo/", "b?r/", "baz"), ("foo/b?r\\/baz", true, "foo/", "b?r\\/", "baz"), ("foo/b?r\\/baz", false, "foo/", "b?r/", "baz"), @@ -70,9 +71,9 @@ use strings; ("foo/b[ar]/baz\\/", false, "foo/", "b[ar]/", "baz\\/"), ("foo/b\\[ar]/baz\\/", true, "foo/", "b\\[ar]/", "baz\\/"), ("foo/b\\[ar]/baz\\/", false, "foo/b[ar]/baz/", "", ""), - ("fo[o/ba[r/baz", true, "fo[o/ba[r/", "baz", ""), - ("fo]o/bar/b[az", false, "fo]o/bar/", "b[az", ""), - ("foo/ba]r/b]az", true, "foo/ba]r/", "b]az", ""), + ("fo[o/ba[r/baz", true, "fo[o/ba[r/baz", "", ""), + ("fo]o/bar/b[az", false, "fo]o/bar/b[az", "", ""), + ("foo/ba]r/b]az", true, "foo/ba]r/b]az", "", ""), ("foo/ba[r/b]az", false, "foo/ba[r/", "b]az", ""), ("fo[o/bar/b]az", true, "fo[o/bar/", "b]az", ""), ]; diff --git a/glob/glob.ha b/glob/glob.ha @@ -111,6 +111,10 @@ fn next_match(gen: *generator) (str | void | failure) = { const dir = pattern_dir(&gen.tmpp); let pat = pattern_pat(&gen.tmpp); + if (pat == "") { + assert(pattern_rem(&gen.tmpp) == ""); + return if (os::exists(dir)) dir else void; + }; const patm = strings::hassuffix(pat, '/'); if (patm) { pat = strings::sub(pat, 0, len(pat) - 1); @@ -217,6 +221,8 @@ fn pattern_parse(p: *pattern, pstr: str, noesc: bool) void = { for (let brk = false, esc = false; true) { const r = match (strings::next(&itdir)) { case void => + memio::concat(&p.dir, memio::string(&p.pat)!)!; + memio::reset(&p.pat); return; case let r: rune => yield r;