From 871273b374f75306a6c79c4ec067f2e4ce338172 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 7 Dec 2020 22:13:06 +0300 Subject: Add proper support for option files option to load_default_options() --- tests/default-options/driver.cxx | 64 ++++++++++++++++++++++------------------ tests/default-options/testscript | 33 +++++++++++++++++++++ 2 files changed, 68 insertions(+), 29 deletions(-) (limited to 'tests') diff --git a/tests/default-options/driver.cxx b/tests/default-options/driver.cxx index 574e002..b3f66bf 100644 --- a/tests/default-options/driver.cxx +++ b/tests/default-options/driver.cxx @@ -35,7 +35,7 @@ using namespace std; using namespace butl; // Usage: argv[0] [-f ] [-d ] [-s ] [-h ] -// [-x ] [-e] [-t] +// [-x ] [-a] [-e] [-t] // // 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 @@ -78,56 +78,61 @@ main (int argc, const char* argv[]) class scanner { public: - scanner (const string& f): ifs_ (f, fdopen_mode::in, ifdstream::badbit) {} + scanner (const string& f, const string& option) + : option_ (option) {load (path (f));} bool more () { - if (peeked_) - return true; - - if (!eof_) - eof_ = ifs_.peek () == ifdstream::traits_type::eof (); - - return !eof_; + return i_ < args_.size (); } string peek () { assert (more ()); - - if (peeked_) - return *peeked_; - - string s; - getline (ifs_, s); - - peeked_ = move (s); - return *peeked_; + return args_[i_]; } string next () { assert (more ()); + return args_[i_++]; + } + + private: + void + load (const path& f) + { + ifdstream is (f, fdopen_mode::in, ifdstream::badbit); - string s; - if (peeked_) + for (string l; !eof (getline (is, l)); ) { - s = move (*peeked_); - peeked_ = nullopt; - } - else - getline (ifs_, s); + if (option_ && *option_ == l) + { + assert (!eof (getline (is, l))); - return s; + // If the path of the file being parsed is not simple and the path + // of the file that needs to be loaded is relative, then complete + // the latter using the former as a base. + // + path p (l); + + if (!f.simple () && p.relative ()) + p = f.directory () / p; + + load (p); + } + else + args_.push_back (move (l)); + } } private: - ifdstream ifs_; - bool eof_ = false; - optional peeked_; + optional option_; + vector args_; + size_t i_ = 0; }; enum class unknow_mode @@ -264,6 +269,7 @@ main (int argc, const char* argv[]) cerr << (overwrite ? "overwriting " : "loading ") << (remote ? "remote " : "local ") << f << endl; }, + "--options-file", args); } catch (const invalid_argument& e) diff --git a/tests/default-options/testscript b/tests/default-options/testscript index b168ca9..09bb2ec 100644 --- a/tests/default-options/testscript +++ b/tests/default-options/testscript @@ -345,3 +345,36 @@ EOO } } + +: options-file +: +{ + d = work/.build2; + mkdir -p work/.build2; + + cat <=$d/foo; + --foo + --options-file + bar + --fox + EOI + + cat <=$d/bar; + --bar + --options-file + baz + --box + EOI + + cat <=$d/baz; + --baz + EOI + + $* -d $~/work -f foo >>EOO + --foo + --bar + --baz + --box + --fox + EOO +} -- cgit v1.1