aboutsummaryrefslogtreecommitdiff
path: root/tests/default-options/driver.cxx
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/driver.cxx
parent800bf1b9f67aae867ffe900a545444dfe8aa46c9 (diff)
Add default options loading and merging API
Diffstat (limited to 'tests/default-options/driver.cxx')
-rw-r--r--tests/default-options/driver.cxx186
1 files changed, 186 insertions, 0 deletions
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;
+}