From d20d2a641351b7f9e8c9bd9b841d8de4d824aa82 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 10 Aug 2019 17:14:37 +0300 Subject: Add default options loading and merging API --- tests/default-options/driver.cxx | 186 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 tests/default-options/driver.cxx (limited to 'tests/default-options/driver.cxx') 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 + +#ifndef __cpp_lib_modules_ts +#include +#include +#include +#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 +#include +#include // eof() +#include +#include +#include +#endif + +using namespace std; +using namespace butl; + +// Usage: argv[0] [-f ] [-d ] [-s ] [-h ] +// [-e] +// +// 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: +// +// ,, +// +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 + next () + { + string s; + return !eof (getline (ifs_, s)) ? optional (move (s)) : nullopt; + } + + private: + ifdstream ifs_; + }; + + enum class unknow_mode + { + fail + }; + + class options: public vector + { + public: + bool + parse (scanner& s, unknow_mode, unknow_mode) + { + bool r (false); + while (optional 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 sys_dir; + optional 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 def_ops ( + load_default_options (sys_dir, + home_dir, + fs)); + + if (print_entries) + { + for (const default_options_entry& 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; +} -- cgit v1.1