From 0426335af0e7577148903be7a2534c4ced06cd3b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 3 Aug 2021 14:11:17 +0200 Subject: Add support for tracking argument/option position The scanner interface now provides the position() function that returns a monotonically-increasing number which, if stored, can later be used to determine the relative position of the arguments. There is also now a parser implementation for std::pair which parses the value T into the first half of the pair and stores the option position in the second half. Together, this can be used to establish the relative position of different options, for example: class options { std::vector> --config-id; std::vector> --config-name; }; cli::argv_scanner scan (argc, argv); options ops (scan); // Iterate over --config-id and --config-name options in the order // specified by the user. // auto ii (ops.config_id ().begin ()); auto ni (ops.config_name ().begin ()); for (size_t i (0), n (scan.position ()); i != n; ++i) { if (ii != ops.config_id ().end () && ii->second == i) { // Handle *ii. ++ii; } if (ni != ops.config_name ().end () && ni->second == i) { // Handle *ni. ++ni; } } --- cli-tests/position/buildfile | 9 +++++++++ cli-tests/position/driver.cxx | 38 ++++++++++++++++++++++++++++++++++++++ cli-tests/position/test.cli | 13 +++++++++++++ cli-tests/position/testscript | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 cli-tests/position/buildfile create mode 100644 cli-tests/position/driver.cxx create mode 100644 cli-tests/position/test.cli create mode 100644 cli-tests/position/testscript (limited to 'cli-tests/position') diff --git a/cli-tests/position/buildfile b/cli-tests/position/buildfile new file mode 100644 index 0000000..371cc54 --- /dev/null +++ b/cli-tests/position/buildfile @@ -0,0 +1,9 @@ +# file : position/buildfile +# license : MIT; see accompanying LICENSE file + +exe{driver}: {hxx cxx}{* -test} cli.cxx{test} testscript + +cxx.poptions =+ "-I$out_base" + +cli.cxx{test}: cli{test} +cli.options = --generate-file-scanner --generate-specifier diff --git a/cli-tests/position/driver.cxx b/cli-tests/position/driver.cxx new file mode 100644 index 0000000..77b9a8d --- /dev/null +++ b/cli-tests/position/driver.cxx @@ -0,0 +1,38 @@ +// file : position/driver.cxx +// author : Boris Kolpackov +// license : MIT; see accompanying LICENSE file + +// Test argument/option position. +// +#include + +#include "test.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ + try + { + cli::argv_file_scanner scan (argc, argv, "--file"); + options ops (scan); + + if (ops.a_specified ()) + cout << ops.a ().second << ": " << "-a " << ops.a ().first << endl; + + for (const pair& b: ops.b ()) + { + cout << b.second << ": " << "-b " << b.first << endl; + } + + while (scan.more ()) + cout << scan.position () << ": " << scan.next () << endl; + + cout << "max: " << scan.position () << endl; + } + catch (const cli::exception& e) + { + cerr << e << endl; + } +} diff --git a/cli-tests/position/test.cli b/cli-tests/position/test.cli new file mode 100644 index 0000000..7fc8655 --- /dev/null +++ b/cli-tests/position/test.cli @@ -0,0 +1,13 @@ +// file : position/test.cli +// author : Boris Kolpackov +// license : MIT; see accompanying LICENSE file + +include ; +include ; +include ; + +class options +{ + std::pair -a; + std::vector > -b; +}; diff --git a/cli-tests/position/testscript b/cli-tests/position/testscript new file mode 100644 index 0000000..568e571 --- /dev/null +++ b/cli-tests/position/testscript @@ -0,0 +1,36 @@ +# file : position/testscript +# license : MIT; see accompanying LICENSE file + +: basics +: +$* -b 1 -a 2 -b 3 foo bar baz >>EOO +3: -a 2 +1: -b 1 +5: -b 3 +7: foo +8: bar +9: baz +max: 10 +EOO + +: override +: +$* -a 1 -a 2 >>EOO +3: -a 2 +max: 5 +EOO + +: file +: +cat <=test.ops; +-a 2 +EOI +$* -b 1 --file test.ops -b 2 foo bar baz >>EOO +5: -a 2 +1: -b 1 +7: -b 2 +9: foo +10: bar +11: baz +max: 12 +EOO -- cgit v1.1