diff options
-rw-r--r-- | include/qpdf/QPDFArgParser.hh | 8 | ||||
-rw-r--r-- | libqpdf/QPDFArgParser.cc | 26 | ||||
-rw-r--r-- | libtests/arg_parser.cc | 23 | ||||
-rw-r--r-- | libtests/libtests.testcov | 2 | ||||
-rw-r--r-- | libtests/qtest/arg_parser.test | 2 | ||||
-rw-r--r-- | libtests/qtest/arg_parser/args-18.out | 2 | ||||
-rw-r--r-- | libtests/qtest/arg_parser/completion-sheep.out | 3 | ||||
-rw-r--r-- | libtests/qtest/arg_parser/exceptions.out | 2 |
8 files changed, 66 insertions, 2 deletions
diff --git a/include/qpdf/QPDFArgParser.hh b/include/qpdf/QPDFArgParser.hh index 24e6ac48..15c17399 100644 --- a/include/qpdf/QPDFArgParser.hh +++ b/include/qpdf/QPDFArgParser.hh @@ -117,6 +117,14 @@ class QPDFArgParser QPDF_DLL void addRequiredChoices( std::string const& arg, param_arg_handler_t, char const** choices); + QPDF_DLL + + // If an option is shared among multiple tables and uses identical + // handlers, you can just copy it instead of repeating the + // registration call. + void copyFromOtherTable(std::string const& arg, + std::string const& other_table); + // The final check handler is called at the very end of argument // parsing. QPDF_DLL diff --git a/libqpdf/QPDFArgParser.cc b/libqpdf/QPDFArgParser.cc index 33dbf2e0..a24b00eb 100644 --- a/libqpdf/QPDFArgParser.cc +++ b/libqpdf/QPDFArgParser.cc @@ -154,6 +154,29 @@ QPDFArgParser::addRequiredChoices( } void +QPDFArgParser::copyFromOtherTable(std::string const& arg, + std::string const& other_table) +{ + if (! this->m->option_tables.count(other_table)) + { + QTC::TC("libtests", "QPDFArgParser copy from unknown"); + throw std::logic_error( + "QPDFArgParser: attempt to copy from unknown table " + + other_table); + } + auto& ot = this->m->option_tables[other_table]; + if (! ot.count(arg)) + { + QTC::TC("libtests", "QPDFArgParser copy unknown"); + throw std::logic_error( + "QPDFArgParser: attempt to copy unknown argument " + arg + + " from table " + other_table); + } + OptionEntry& oe = registerArg(arg); + oe = ot[arg]; +} + +void QPDFArgParser::addFinalCheck(bare_arg_handler_t handler) { this->m->final_check_handler = handler; @@ -533,7 +556,8 @@ QPDFArgParser::parseArgs() if (oep == this->m->option_table->end()) { // This is registered automatically, so this can't happen. - throw std::logic_error("ArgParser: -- handler not registered"); + throw std::logic_error( + "QPDFArgParser: -- handler not registered"); } } else if ((arg[0] == '-') && (strcmp(arg, "-") != 0)) diff --git a/libtests/arg_parser.cc b/libtests/arg_parser.cc index a5a0bf35..a57b9c66 100644 --- a/libtests/arg_parser.cc +++ b/libtests/arg_parser.cc @@ -64,6 +64,10 @@ ArgParser::initOptions() ap.registerOptionTable("baaa", nullptr); ap.addBare("ewe", [this](){ output("you"); }); ap.addBare("ram", [this](){ output("ram"); }); + ap.selectMainOptionTable(); + ap.addBare("sheep", [this](){ this->ap.selectOptionTable("sheep"); }); + ap.registerOptionTable("sheep", nullptr); + ap.copyFromOtherTable("ewe", "baaa"); } void @@ -186,11 +190,28 @@ ArgParser::test_exceptions() { std::cout << "unknown table: " << e.what() << std::endl; } + try + { + ap.copyFromOtherTable("one", "two"); + assert(false); + } + catch (std::exception& e) + { + std::cout << "copy from unknown table: " << e.what() << std::endl; + } + try + { + ap.copyFromOtherTable("two", "baaa"); + assert(false); + } + catch (std::exception& e) + { + std::cout << "copy unknown from other table: " << e.what() << std::endl; + } } int main(int argc, char* argv[]) { - ArgParser ap(argc, argv); if ((argc == 2) && (strcmp(argv[1], "exceptions") == 0)) { diff --git a/libtests/libtests.testcov b/libtests/libtests.testcov index 884d433f..69573ab0 100644 --- a/libtests/libtests.testcov +++ b/libtests/libtests.testcov @@ -52,3 +52,5 @@ QPDFArgParser help option 0 QPDFArgParser positional 0 QPDFArgParser unrecognized 0 QPDFArgParser complete choices 0 +QPDFArgParser copy from unknown 0 +QPDFArgParser copy unknown 0 diff --git a/libtests/qtest/arg_parser.test b/libtests/qtest/arg_parser.test index 42a80531..1d24d507 100644 --- a/libtests/qtest/arg_parser.test +++ b/libtests/qtest/arg_parser.test @@ -32,6 +32,7 @@ my @completion_tests = ( ['arg_parser --quack "user password" ', undef, 'quack-x'], ['arg_parser --quack "user pass\'word" ', undef, 'quack-x'], ['arg_parser --quack user\ password ', undef, 'quack-x'], + ['arg_parser --sheep --', undef, 'sheep'], ); foreach my $c (@completion_tests) @@ -78,6 +79,7 @@ my @arg_tests = ( ['@quack-xyz --', 0], # 15 ['--salad', 2], # 16 ['--salad=spinach', 0], # 17 + ['--sheep --ewe --', 0], # 18 ); for (my $i = 0; $i < scalar(@arg_tests); ++$i) diff --git a/libtests/qtest/arg_parser/args-18.out b/libtests/qtest/arg_parser/args-18.out new file mode 100644 index 00000000..094076f4 --- /dev/null +++ b/libtests/qtest/arg_parser/args-18.out @@ -0,0 +1,2 @@ +you +total quacks: 0 diff --git a/libtests/qtest/arg_parser/completion-sheep.out b/libtests/qtest/arg_parser/completion-sheep.out new file mode 100644 index 00000000..15673934 --- /dev/null +++ b/libtests/qtest/arg_parser/completion-sheep.out @@ -0,0 +1,3 @@ +--ewe +!--potato +!--ram diff --git a/libtests/qtest/arg_parser/exceptions.out b/libtests/qtest/arg_parser/exceptions.out index c71159f8..82eef2a7 100644 --- a/libtests/qtest/arg_parser/exceptions.out +++ b/libtests/qtest/arg_parser/exceptions.out @@ -2,3 +2,5 @@ duplicate handler: QPDFArgParser: adding a duplicate handler for option potato i duplicate handler: QPDFArgParser: adding a duplicate handler for option ram in baaa option table duplicate table: QPDFArgParser: registering already registered option table baaa unknown table: QPDFArgParser: selecting unregistered option table aardvark +copy from unknown table: QPDFArgParser: attempt to copy from unknown table two +copy unknown from other table: QPDFArgParser: attempt to copy unknown argument two from table baaa |