aboutsummaryrefslogtreecommitdiff
path: root/tests/default-options
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-08-10 17:14:37 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-08-12 18:35:37 +0300
commitd20d2a641351b7f9e8c9bd9b841d8de4d824aa82 (patch)
tree8ac63c12a5c45f1e1a8159fc07d76575cb82a147 /tests/default-options
parent800bf1b9f67aae867ffe900a545444dfe8aa46c9 (diff)
Add default options loading and merging API
Diffstat (limited to 'tests/default-options')
-rw-r--r--tests/default-options/buildfile7
-rw-r--r--tests/default-options/driver.cxx186
-rw-r--r--tests/default-options/testscript109
3 files changed, 302 insertions, 0 deletions
diff --git a/tests/default-options/buildfile b/tests/default-options/buildfile
new file mode 100644
index 0000000..5530a10
--- /dev/null
+++ b/tests/default-options/buildfile
@@ -0,0 +1,7 @@
+# file : tests/default-options/buildfile
+# copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+import libs = libbutl%lib{butl}
+
+exe{driver}: {hxx cxx}{*} $libs testscript
diff --git a/tests/default-options/driver.cxx b/tests/default-options/driver.cxx
new file mode 100644
index 0000000..a2ed43d
--- /dev/null
+++ b/tests/default-options/driver.cxx
@@ -0,0 +1,186 @@
+// file : tests/default-options/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 <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.path_io;
+import butl.optional;
+import butl.fdstream;
+import butl.default_options;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/path-io.mxx>
+#include <libbutl/utility.mxx> // eof()
+#include <libbutl/optional.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/default-options.mxx>
+#endif
+
+using namespace std;
+using namespace butl;
+
+// Usage: argv[0] [-f <file>] [-d <start-dir>] [-s <sys-dir>] [-h <home-dir>]
+// [-e] <cmd-options>
+//
+// Parse default options files, merge them with the command line options, and
+// print the resulting options to STDOUT one per line. Note that the options
+// instance is a vector of arbitrary strings.
+//
+// -f
+// Default options file name. Can be specified multiple times.
+//
+// -d
+// Directory to start the default options files search from.
+//
+// -s
+// System directory.
+//
+// -h
+// Home directory.
+//
+// -e
+// Print the default options entries (rather than the merged options) to
+// STDOUT one per line in the following format:
+//
+// <file>,<space-separated-options>,<remote>
+//
+int
+main (int argc, const char* argv[])
+{
+ using butl::optional;
+
+ class scanner
+ {
+ public:
+ scanner (const string& f): ifs_ (f, fdopen_mode::in, ifdstream::badbit) {}
+
+ optional<string>
+ next ()
+ {
+ string s;
+ return !eof (getline (ifs_, s)) ? optional<string> (move (s)) : nullopt;
+ }
+
+ private:
+ ifdstream ifs_;
+ };
+
+ enum class unknow_mode
+ {
+ fail
+ };
+
+ class options: public vector<string>
+ {
+ public:
+ bool
+ parse (scanner& s, unknow_mode, unknow_mode)
+ {
+ bool r (false);
+ while (optional<string> o = s.next ())
+ {
+ push_back (move (*o));
+ r = true;
+ }
+ return r;
+ }
+
+ void
+ merge (const options& o)
+ {
+ insert (end (), o.begin (), o.end ());
+ }
+ };
+
+ // Parse and validate the arguments.
+ //
+ default_options_files fs;
+ optional<dir_path> sys_dir;
+ optional<dir_path> home_dir;
+ options cmd_ops;
+ bool print_entries (false);
+
+ for (int i (1); i != argc; ++i)
+ {
+ string op (argv[i]);
+
+ if (op == "-f")
+ {
+ assert (++i != argc);
+ fs.files.push_back (path (argv[i]));
+ }
+ else if (op == "-d")
+ {
+ assert (++i != argc);
+ fs.start_dir = dir_path (argv[i]);
+ }
+ else if (op == "-s")
+ {
+ assert (++i != argc);
+ sys_dir = dir_path (argv[i]);
+ }
+ else if (op == "-h")
+ {
+ assert (++i != argc);
+ home_dir = dir_path (argv[i]);
+ }
+ else if (op == "-e")
+ {
+ print_entries = true;
+ }
+ else
+ cmd_ops.push_back (argv[i]);
+ }
+
+ // Load and print the default options.
+ //
+ default_options<options> def_ops (
+ load_default_options<options, scanner, unknow_mode> (sys_dir,
+ home_dir,
+ fs));
+
+ if (print_entries)
+ {
+ for (const default_options_entry<options>& e: def_ops)
+ {
+ cout << e.file << ',';
+
+ for (const string& o: e.options)
+ {
+ if (&o != &e.options[0])
+ cout << ' ';
+
+ cout << o;
+ }
+
+ cout << (e.remote ? ",true" : ",false") << endl;
+ }
+ }
+
+ // Merge the options and print the result.
+ //
+ options ops (merge_default_options (def_ops, cmd_ops));
+
+ if (!print_entries)
+ {
+ for (const string& o: ops)
+ cout << o << endl;
+ }
+
+ return 0;
+}
diff --git a/tests/default-options/testscript b/tests/default-options/testscript
new file mode 100644
index 0000000..c0c3816
--- /dev/null
+++ b/tests/default-options/testscript
@@ -0,0 +1,109 @@
+# file : tests/default-options/testscript
+# copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+# Note that when cross-testing the driver may not be able to run the command
+# due to the meaningless program path.
+#
++if ($test.target != $build.host)
+ exit
+end
+
+sys_dir = $canonicalize([dir_path] $~/build2)
++mkdir -p $sys_dir/local
+
++echo 'sys-foo' >=$sys_dir/foo
++echo 'sys-bar' >=$sys_dir/bar
++echo 'sys-local-foo' >=$sys_dir/local/foo
++echo 'sys-local-bar' >=$sys_dir/local/bar
+
+home_dir = $canonicalize([dir_path] $~/home)
++mkdir -p $home_dir/.build2/local/
+
++echo 'home-foo' >=$home_dir/.build2/foo
++echo 'home-bar' >=$home_dir/.build2/bar
++echo 'home-local-foo' >=$home_dir/.build2/local/foo
++echo 'home-local-bar' >=$home_dir/.build2/local/bar
+
+: in-home
+:
+{
+ d = $home_dir/work/.build2
+ +mkdir -p $d/local/
+
+ +echo 'work-foo' >=$d/foo
+ +echo 'work-bar' >=$d/bar
+ +echo 'work-local-foo' >=$d/local/foo
+ +echo 'work-local-bar' >=$d/local/bar
+
+ d = $home_dir/work/project/.build2
+ +mkdir -p $d/local/
+ +touch $home_dir/work/project/.git
+
+ +echo 'project-foo' >=$d/foo
+ +echo 'project-bar' >=$d/bar
+ +echo 'project-local-foo' >=$d/local/foo
+ +echo 'project-local-bar' >=$d/local/bar
+
+ d = $home_dir/work/project/package/.build2
+ +mkdir -p $d/local/
+
+ +echo 'package-foo' >=$d/foo
+ +echo 'package-bar' >=$d/bar
+ +echo 'package-local-foo' >=$d/local/foo
+ +echo 'package-local-bar' >=$d/local/bar
+
+ start_dir = $canonicalize([dir_path] $home_dir/work/project/package)
+
+ : entries
+ :
+ $* -e -f foo -f bar -d $start_dir -s $sys_dir -h $home_dir cmd-foo cmd-bar >>/~%EOO%d
+ %\.+/build2/foo,sys-foo,false%
+ %\.+/build2/bar,sys-bar,false%
+ %\.+/build2/local/foo,sys-local-foo,false%
+ %\.+/build2/local/bar,sys-local-bar,false%
+ %\.+/home/.build2/foo,home-foo,false%
+ %\.+/home/.build2/bar,home-bar,false%
+ %\.+/home/.build2/local/foo,home-local-foo,false%
+ %\.+/home/.build2/local/bar,home-local-bar,false%
+ %\.+/home/work/.build2/foo,work-foo,false%
+ %\.+/home/work/.build2/bar,work-bar,false%
+ %\.+/home/work/.build2/local/foo,work-local-foo,false%
+ %\.+/home/work/.build2/local/bar,work-local-bar,false%
+ %\.+/home/work/project/.build2/foo,project-foo,true%
+ %\.+/home/work/project/.build2/bar,project-bar,true%
+ %\.+/home/work/project/.build2/local/foo,project-local-foo,true%
+ %\.+/home/work/project/.build2/local/bar,project-local-bar,true%
+ %\.+/home/work/project/package/.build2/foo,package-foo,true%
+ %\.+/home/work/project/package/.build2/bar,package-bar,true%
+ %\.+/home/work/project/package/.build2/local/foo,package-local-foo,true%
+ %\.+/home/work/project/package/.build2/local/bar,package-local-bar,true%
+ EOO
+
+ : merged
+ :
+ $* -f foo -f bar -d $start_dir -s $sys_dir -h $home_dir cmd-foo cmd-bar >>EOO
+ sys-foo
+ sys-bar
+ sys-local-foo
+ sys-local-bar
+ home-foo
+ home-bar
+ home-local-foo
+ home-local-bar
+ work-foo
+ work-bar
+ work-local-foo
+ work-local-bar
+ project-foo
+ project-bar
+ project-local-foo
+ project-local-bar
+ package-foo
+ package-bar
+ package-local-foo
+ package-local-bar
+ cmd-foo
+ cmd-bar
+ EOO
+}