From 377cec303eea81fb18b294eb47a54587643dbd01 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 10 Sep 2020 19:05:23 +0300 Subject: Add support for arguments in default options files helpers --- tests/default-options/driver.cxx | 137 +++++++++++++++++++++++++++++++++------ 1 file changed, 117 insertions(+), 20 deletions(-) (limited to 'tests/default-options/driver.cxx') diff --git a/tests/default-options/driver.cxx b/tests/default-options/driver.cxx index c6ac671..574e002 100644 --- a/tests/default-options/driver.cxx +++ b/tests/default-options/driver.cxx @@ -7,6 +7,7 @@ #include #include #include +#include // invalid_argument #endif // Other includes. @@ -57,6 +58,9 @@ using namespace butl; // -x // Extra directory. // +// -a +// Default arguments are allowed in the options files. +// // -e // Print the default options entries (rather than the merged options) to // STDOUT one per line in the following format: @@ -76,19 +80,59 @@ main (int argc, const char* argv[]) public: scanner (const string& f): ifs_ (f, fdopen_mode::in, ifdstream::badbit) {} - optional + bool + more () + { + if (peeked_) + return true; + + if (!eof_) + eof_ = ifs_.peek () == ifdstream::traits_type::eof (); + + return !eof_; + } + + string + peek () + { + assert (more ()); + + if (peeked_) + return *peeked_; + + string s; + getline (ifs_, s); + + peeked_ = move (s); + return *peeked_; + } + + string next () { + assert (more ()); + string s; - return !eof (getline (ifs_, s)) ? optional (move (s)) : nullopt; + if (peeked_) + { + s = move (*peeked_); + peeked_ = nullopt; + } + else + getline (ifs_, s); + + return s; } private: ifdstream ifs_; + bool eof_ = false; + optional peeked_; }; enum class unknow_mode { + stop, fail }; @@ -96,15 +140,28 @@ main (int argc, const char* argv[]) { public: bool - parse (scanner& s, unknow_mode, unknow_mode) + parse (scanner& s, unknow_mode, unknow_mode m) { bool r (false); - while (optional o = s.next ()) + while (s.more ()) { - if (*o == "--no-default-options") + string a (s.peek ()); + + if (a.compare (0, 2, "--") != 0) + { + switch (m) + { + case unknow_mode::stop: return r; + case unknow_mode::fail: throw invalid_argument (a); + } + } + + s.next (); + + if (a == "--no-default-options") no_default_options_ = true; - push_back (move (*o)); + push_back (move (a)); r = true; } return r; @@ -132,50 +189,58 @@ main (int argc, const char* argv[]) optional sys_dir; optional home_dir; optional extra_dir; + bool args (false); vector dirs; options cmd_ops; + vector cmd_args; bool print_entries (false); bool trace (false); for (int i (1); i != argc; ++i) { - string op (argv[i]); + string a (argv[i]); - if (op == "-f") + if (a == "-f") { assert (++i != argc); fs.files.push_back (path (argv[i])); } - else if (op == "-d") + else if (a == "-d") { assert (++i != argc); dirs.emplace_back (argv[i]); } - else if (op == "-s") + else if (a == "-s") { assert (++i != argc); sys_dir = dir_path (argv[i]); } - else if (op == "-h") + else if (a == "-h") { assert (++i != argc); home_dir = dir_path (argv[i]); } - else if (op == "-x") + else if (a == "-x") { assert (++i != argc); extra_dir = dir_path (argv[i]); } - else if (op == "-e") + else if (a == "-a") + { + args = true; + } + else if (a == "-e") { print_entries = true; } - else if (op == "-t") + else if (a == "-t") { trace = true; } + else if (a.compare (0, 2, "--") == 0) + cmd_ops.push_back (move (a)); else - cmd_ops.push_back (argv[i]); + cmd_args.push_back (move (a)); } // Deduce a common start directory. @@ -184,8 +249,11 @@ main (int argc, const char* argv[]) // Load and print the default options. // - default_options def_ops ( - load_default_options ( + default_options def_ops; + + try + { + def_ops = load_default_options ( sys_dir, home_dir, extra_dir, @@ -195,7 +263,14 @@ main (int argc, const char* argv[]) if (trace) cerr << (overwrite ? "overwriting " : "loading ") << (remote ? "remote " : "local ") << f << endl; - })); + }, + args); + } + catch (const invalid_argument& e) + { + cerr << "error: unexpected argument '" << e.what () << "'" << endl; + return 1; + } if (print_entries) { @@ -211,18 +286,40 @@ main (int argc, const char* argv[]) cout << o; } + if (args) + { + cout << "|"; + + for (const string& a: e.arguments) + { + if (&a != &e.arguments[0]) + cout << ' '; + + cout << a; + } + + } + 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) { + options ops (merge_default_options (def_ops, cmd_ops)); + for (const string& o: ops) cout << o << endl; + + if (args) + { + vector as (merge_default_arguments (def_ops, cmd_args)); + + for (const string& a: as) + cout << a << endl; + } } return 0; -- cgit v1.1