From 78910e3cb0b9cc215e53142c28f8b9f52c30af60 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 3 Feb 2017 14:57:03 +0200 Subject: Implement path_match() and path_search() --- tests/buildfile | 3 +- tests/wildcard/buildfile | 7 + tests/wildcard/driver.cxx | 105 +++++++++++++ tests/wildcard/testscript | 378 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 492 insertions(+), 1 deletion(-) create mode 100644 tests/wildcard/buildfile create mode 100644 tests/wildcard/driver.cxx create mode 100644 tests/wildcard/testscript (limited to 'tests') diff --git a/tests/buildfile b/tests/buildfile index 8608ed9..6f5dd03 100644 --- a/tests/buildfile +++ b/tests/buildfile @@ -4,7 +4,8 @@ d = base64/ cpfile/ dir-iterator/ fdstream/ link/ manifest-parser/ \ manifest-serializer/ manifest-roundtrip/ pager/ path/ prefix-map/ \ - process/ sha256/ small-vector/ strcase/ timestamp/ target-triplet/ + process/ sha256/ small-vector/ strcase/ timestamp/ target-triplet/ \ + wildcard/ ./: $d include $d diff --git a/tests/wildcard/buildfile b/tests/wildcard/buildfile new file mode 100644 index 0000000..7de67f4 --- /dev/null +++ b/tests/wildcard/buildfile @@ -0,0 +1,7 @@ +# file : tests/wildcard/buildfile +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +exe{driver}: cxx{driver} ../../butl/lib{butl} test{testscript} + +include ../../butl/ diff --git a/tests/wildcard/driver.cxx b/tests/wildcard/driver.cxx new file mode 100644 index 0000000..7df5556 --- /dev/null +++ b/tests/wildcard/driver.cxx @@ -0,0 +1,105 @@ +// file : tests/wildcard/driver.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include +#include +#include +#include +#include // sort() +#include + +#include +#include // operator<<(ostream, exception) +#include + +using namespace std; +using namespace butl; + +// Usage: argv[0] (-m | -s [-n] []) +// +// Execute actions specified by -m or -s options. Exit with code 0 if succeed, +// 1 if fail, 2 on the underlying OS error (print error description to STDERR). +// +// -m +// Match a name against the pattern. +// +// -s +// Search for paths matching the pattern in the directory specified (absent +// directory means the current one). Print the matching canonicalized paths +// to STDOUT in the ascending order. Succeed if at least one matching path +// is found. Note that this option must go first in the command line, +// +// -n +// Do not sort paths found. +// +int +main (int argc, const char* argv[]) +try +{ + assert (argc >= 2); + + string op (argv[1]); + bool match (op == "-m"); + assert (match || op == "-s"); + + if (match) + { + assert (argc == 4); + + string pattern (argv[2]); + string name (argv[3]); + return path_match (pattern, name) ? 0 : 1; + } + else + { + assert (argc >= 3); + + bool sort (true); + int i (2); + for (; i != argc; ++i) + { + string o (argv[i]); + if (o == "-n") + sort = false; + else + break; // End of options. + } + + assert (i != argc); // Still need pattern. + path pattern (argv[i++]); + + dir_path start; + if (i != argc) + start = dir_path (argv[i++]); + + assert (i == argc); // All args parsed, + + vector paths; + auto add = [&paths] (path&& p) -> bool + { + paths.emplace_back (move (p.canonicalize ())); + return true; + }; + + path_search (pattern, add, start); + + if (sort) + std::sort (paths.begin (), paths.end ()); + + for (const auto& p: paths) + cout << p.representation () << endl; + + return paths.empty () ? 1 : 0; + } +} +catch (const invalid_path& e) +{ + cerr << e << ": " << e.path << endl; + return 2; +} +catch (const exception& e) +{ + cerr << e << endl; + return 2; +} diff --git a/tests/wildcard/testscript b/tests/wildcard/testscript new file mode 100644 index 0000000..bcd618f --- /dev/null +++ b/tests/wildcard/testscript @@ -0,0 +1,378 @@ +# file : tests/wildcard/testscript +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +: path-match +: +{ + test.options = -m + + $* foo/ foo == 1 : dir-vs-file + $* foo foo/ == 1 : file-vs-dir + + : no-star + : + { + : match + : + { + $* foo/ foo/ : dir + $* foo foo : file + $* f?o foo : qmark + $* '' '' : empty + } + + : no-match + : + { + $* oo foo == 1 : name-char + $* foo oo == 1 : pattern-char + } + } + + : with-star + : + { + : no-backtracking + : + { + : match + : + { + $* * '' : empty + $* *.txt foo.txt : suffix-only + $* foo* foo.txt : prefix-only + $* f*.txt foo.txt : prefix-suffix + } + + : no-match + : + { + $* fox* foo.txt == 1 : pattern-prefix-char + $* foo* fo == 1 : short-name + } + } + + : backtracking + : + { + : match + : + { + $* ** '' : empty1 + $* *** '' : empty2 + $* f*.* f.txt : empty3 + $* f**.* f.txt : empty4 + $* f*.* foo.txt : non-empty + $* f*?* foo-txt : qmark + } + + : no-match + : + { + $* f*.* foo-txt == 1 + } + } + } +} + +: path-search +: +{ + test.options = -s + + : start + : + { + : empty + : + $* * >>/EOO + stderr + stdout + EOO + + : relative + : + mkdir -p foo/fox/bar; + $* ba*/ foo/fox >>/EOO + bar/ + EOO + + : absolute + : + : When cross-testing we can't guarantee that host absolute paths are + : recognized by the target process. + : + if ($test.target == $build.host) + { + wd = $~ + +mkdir -p foo/bar + + : dir + : + $* ba*/ "$wd/foo" >>/EOO + bar/ + EOO + + : pattern + : + $* "$wd/foo/ba*/" >>/"EOO" + $wd/foo/bar/ + EOO + } + } + + : pattern + : + { + : simple + : + { + : file + : + { + +mkdir -p foo/bar + +touch foo/baz foo/box foo/bar/bar foo/bar/fox + + : immediate + : + $* b* ../foo >>EOO + baz + box + EOO + + : recursive + : + $* ba** ../foo >>/EOO + bar/bar + baz + EOO + + : self-recursive + : + { + : start + : + $* f*** ../../foo >>/EOO + bar/fox + EOO + + : current + : + mkdir -p bar/fox; + touch bar/fox/cox; + $* c*** >>/EOO + bar/fox/cox + EOO + } + } + + : dir + : + { + +mkdir -p foo/bar/bar foo/bar/fox/ + +touch foo/baz + + : immediate + : + $* b*/ ../foo >>/EOO + bar/ + EOO + + : recursive + : + $* -n b**/ ../foo >>/EOO + bar/bar/ + bar/ + EOO + + : self-recursive + : + { + : start + : + : Note that the start dir is represented as an empty path being + : found. + : + $* f***/ ../../foo >>/EOO + + bar/fox/ + EOO + + : current + : + mkdir -p bar/cox/box/; + $* c***/ >>/EOO + + bar/cox/ + EOO + } + } + } + + : compound + : + { + : file + : + { + +mkdir -p foo fox fix/bar baz/foo/zab baz/foo/zab/baz + +touch foo/bar foo/fox fox/baz baz/foo/zab/bar + + : immediate + : + $* f*/b* .. >>/EOO + foo/bar + fox/baz + EOO + + : recursive + : + $* f**/b** .. >>/EOO + baz/foo/zab/bar + foo/bar + fox/baz + EOO + + : self-recursive + : + { + : pattern + : + $* foo/f*** ../.. >>/EOO + foo/fox + EOO + + : start + : + $* f*** ../../foo >>/EOO + fox + EOO + + : current + : + mkdir -p bar; + touch bar/cox; + $* c*** >>/EOO + bar/cox + EOO + } + } + + : dir + : + { + +mkdir -p foo/bar foo/fox/box fox/baz fix baz/foo/zab/baz + +touch fix/bar baz/foo/zab/bar + + : immediate + : + $* f*/b*/ .. >>/EOO + foo/bar/ + fox/baz/ + EOO + + : recursive + : + $* f**/b**/ .. >>/EOO + baz/foo/zab/baz/ + foo/bar/ + foo/fox/box/ + foo/fox/box/ + fox/baz/ + EOO + + : self-recursive + : + { + : pattern + : + $* foo/f***/b**/ ../.. >>/EOO + foo/bar/ + foo/fox/box/ + foo/fox/box/ + EOO + + : start + : + $* f***/b**/ ../../foo >>/EOO + bar/ + fox/box/ + fox/box/ + EOO + + : current + : + mkdir -p bar/cox/box/; + $* c***/b**/ >>/EOO + bar/ + bar/cox/box/ + bar/cox/box/ + EOO + } + } + } + + : fast-forward + : + { + +mkdir -p foo/bar/baz foo/box + +touch foo/bar/baz/fox + + : partial + : + { + wd = ../.. + + : file + : + $* foo/ba*/baz/f* $wd >>/EOO + foo/bar/baz/fox + EOO + + : dir + : + $* foo/b*/baz/ $wd >>/EOO + foo/bar/baz/ + EOO + } + + : reduce + : + { + wd = ../../.. + + : exists + : + { + : file + : + $* fo?/bar/baz/fox $wd >>/EOO + foo/bar/baz/fox + EOO + + : dir + : + $* fo?/bar/baz/ $wd >>/EOO + foo/bar/baz/ + EOO + + : parent + : + $* fo?/box/../bar/baz/fox $wd >>/EOO + foo/box/../bar/baz/fox + EOO + } + + : not-exists + : + { + $* fo?/bar/baz/foz $wd == 1 : file + $* fo?/bar/bax/ $wd == 1 : dir + $* fo?/bar/baz/fox/ $wd == 1 : not-dir + $* fo?/bix/../bar/baz/foz $wd == 1 : parent + } + } + } + } +} -- cgit v1.1