aboutsummaryrefslogtreecommitdiff
path: root/tests/builtin/driver.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tests/builtin/driver.cxx')
-rw-r--r--tests/builtin/driver.cxx159
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 ();
+}