diff options
Diffstat (limited to 'tests/builtin/driver.cxx')
-rw-r--r-- | tests/builtin/driver.cxx | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/tests/builtin/driver.cxx b/tests/builtin/driver.cxx new file mode 100644 index 0000000..bf171cb --- /dev/null +++ b/tests/builtin/driver.cxx @@ -0,0 +1,159 @@ +// file : tests/builtin/driver.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <cassert> + +#ifndef __cpp_lib_modules_ts +#include <string> +#include <vector> +#include <utility> // move() +#include <ostream> +#include <iostream> +#endif + +// Other includes. + +#ifdef __cpp_modules_ts +#ifdef __cpp_lib_modules_ts +import std.core; +import std.io; +#endif +import butl.path; +import butl.utility; // eof() +import butl.builtin; +import butl.optional; +import butl.timestamp; // to_stream(duration) +#else +#include <libbutl/path.mxx> +#include <libbutl/utility.mxx> +#include <libbutl/builtin.mxx> +#include <libbutl/optional.mxx> +#include <libbutl/timestamp.mxx> +#endif + +using namespace std; +using namespace butl; + +inline ostream& +operator<< (ostream& os, const path& p) +{ + return os << p.representation (); +} + +// Usage: argv[0] [-d <dir>] [-o <opt>] [-c] [-i] <builtin> <builtin-args> +// +// Execute the builtin and exit with its exit status. +// +// -d <dir> use as a current working directory +// -c use callbacks that, in particular, trace calls to stdout +// -o <opt> additional builtin option recognized by the callback +// -i read lines from stdin and append them to the builtin arguments +// +int +main (int argc, char* argv[]) +{ + using butl::optional; + + cin.exceptions (ios::badbit); + cout.exceptions (ios::failbit | ios::badbit); + cerr.exceptions (ios::failbit | ios::badbit); + + bool in (false); + dir_path cwd; + string option; + builtin_callbacks callbacks; + + string name; + vector<string> args; + + auto flag = [] (bool v) {return v ? "true" : "false";}; + + // Parse the driver options and arguments. + // + int i (1); + for (; i != argc; ++i) + { + string a (argv[i]); + + if (a == "-d") + { + ++i; + + assert (i != argc); + cwd = dir_path (argv[i]); + } + else if (a == "-o") + { + ++i; + + assert (i != argc); + option = argv[i]; + } + else if (a == "-c") + { + callbacks = builtin_callbacks ( + [&flag] (const path& p, bool pre) + { + cout << "create " << p << ' ' << flag (pre) << endl; + }, + [&flag] (const path& from, const path& to, bool force, bool pre) + { + cout << "move " << from << ' ' << to << ' ' << flag (force) << ' ' + << flag (pre) << endl; + }, + [&flag] (const path& p, bool force, bool pre) + { + cout << "remove " << p << ' ' << flag (force) << ' ' << flag (pre) + << endl; + }, + [&option] (const vector<string>& args, size_t i) + { + cout << "option " << args[i] << endl; + return !option.empty () && args[i] == option ? 1 : 0; + }, + [] (const duration& d) + { + cout << "sleep "; + to_stream (cout, d, false /* nanoseconds */); + cout << endl; + } + ); + } + else if (a == "-i") + in = true; + else + break; + } + + // Parse the builtin name and arguments. + // + assert (i != argc); + name = argv[i++]; + + for (; i != argc; ++i) + args.push_back (argv[i]); + + // Read out additional arguments from stdin. + // + if (in) + { + string s; + while (!eof (getline (cin, s))) + args.push_back (move (s)); + } + + // Execute the builtin. + // + builtin_function* bf (builtins.find (name)); + + if (bf == nullptr) + { + cerr << "unknown builtin '" << name << "'" << endl; + return 1; + } + + uint8_t r; // Storage. + builtin b (bf (r, args, nullfd, nullfd, nullfd, cwd, callbacks)); + return b.wait (); +} |