Commit f1d805badc1ea09998fea9427687456717936ff7
1 parent
c3e9b64e
Add QPDFArgParser::copyFromOtherTable
Showing
8 changed files
with
66 additions
and
2 deletions
include/qpdf/QPDFArgParser.hh
| @@ -117,6 +117,14 @@ class QPDFArgParser | @@ -117,6 +117,14 @@ class QPDFArgParser | ||
| 117 | QPDF_DLL | 117 | QPDF_DLL |
| 118 | void addRequiredChoices( | 118 | void addRequiredChoices( |
| 119 | std::string const& arg, param_arg_handler_t, char const** choices); | 119 | std::string const& arg, param_arg_handler_t, char const** choices); |
| 120 | + QPDF_DLL | ||
| 121 | + | ||
| 122 | + // If an option is shared among multiple tables and uses identical | ||
| 123 | + // handlers, you can just copy it instead of repeating the | ||
| 124 | + // registration call. | ||
| 125 | + void copyFromOtherTable(std::string const& arg, | ||
| 126 | + std::string const& other_table); | ||
| 127 | + | ||
| 120 | // The final check handler is called at the very end of argument | 128 | // The final check handler is called at the very end of argument |
| 121 | // parsing. | 129 | // parsing. |
| 122 | QPDF_DLL | 130 | QPDF_DLL |
libqpdf/QPDFArgParser.cc
| @@ -154,6 +154,29 @@ QPDFArgParser::addRequiredChoices( | @@ -154,6 +154,29 @@ QPDFArgParser::addRequiredChoices( | ||
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | void | 156 | void |
| 157 | +QPDFArgParser::copyFromOtherTable(std::string const& arg, | ||
| 158 | + std::string const& other_table) | ||
| 159 | +{ | ||
| 160 | + if (! this->m->option_tables.count(other_table)) | ||
| 161 | + { | ||
| 162 | + QTC::TC("libtests", "QPDFArgParser copy from unknown"); | ||
| 163 | + throw std::logic_error( | ||
| 164 | + "QPDFArgParser: attempt to copy from unknown table " + | ||
| 165 | + other_table); | ||
| 166 | + } | ||
| 167 | + auto& ot = this->m->option_tables[other_table]; | ||
| 168 | + if (! ot.count(arg)) | ||
| 169 | + { | ||
| 170 | + QTC::TC("libtests", "QPDFArgParser copy unknown"); | ||
| 171 | + throw std::logic_error( | ||
| 172 | + "QPDFArgParser: attempt to copy unknown argument " + arg + | ||
| 173 | + " from table " + other_table); | ||
| 174 | + } | ||
| 175 | + OptionEntry& oe = registerArg(arg); | ||
| 176 | + oe = ot[arg]; | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +void | ||
| 157 | QPDFArgParser::addFinalCheck(bare_arg_handler_t handler) | 180 | QPDFArgParser::addFinalCheck(bare_arg_handler_t handler) |
| 158 | { | 181 | { |
| 159 | this->m->final_check_handler = handler; | 182 | this->m->final_check_handler = handler; |
| @@ -533,7 +556,8 @@ QPDFArgParser::parseArgs() | @@ -533,7 +556,8 @@ QPDFArgParser::parseArgs() | ||
| 533 | if (oep == this->m->option_table->end()) | 556 | if (oep == this->m->option_table->end()) |
| 534 | { | 557 | { |
| 535 | // This is registered automatically, so this can't happen. | 558 | // This is registered automatically, so this can't happen. |
| 536 | - throw std::logic_error("ArgParser: -- handler not registered"); | 559 | + throw std::logic_error( |
| 560 | + "QPDFArgParser: -- handler not registered"); | ||
| 537 | } | 561 | } |
| 538 | } | 562 | } |
| 539 | else if ((arg[0] == '-') && (strcmp(arg, "-") != 0)) | 563 | else if ((arg[0] == '-') && (strcmp(arg, "-") != 0)) |
libtests/arg_parser.cc
| @@ -64,6 +64,10 @@ ArgParser::initOptions() | @@ -64,6 +64,10 @@ ArgParser::initOptions() | ||
| 64 | ap.registerOptionTable("baaa", nullptr); | 64 | ap.registerOptionTable("baaa", nullptr); |
| 65 | ap.addBare("ewe", [this](){ output("you"); }); | 65 | ap.addBare("ewe", [this](){ output("you"); }); |
| 66 | ap.addBare("ram", [this](){ output("ram"); }); | 66 | ap.addBare("ram", [this](){ output("ram"); }); |
| 67 | + ap.selectMainOptionTable(); | ||
| 68 | + ap.addBare("sheep", [this](){ this->ap.selectOptionTable("sheep"); }); | ||
| 69 | + ap.registerOptionTable("sheep", nullptr); | ||
| 70 | + ap.copyFromOtherTable("ewe", "baaa"); | ||
| 67 | } | 71 | } |
| 68 | 72 | ||
| 69 | void | 73 | void |
| @@ -186,11 +190,28 @@ ArgParser::test_exceptions() | @@ -186,11 +190,28 @@ ArgParser::test_exceptions() | ||
| 186 | { | 190 | { |
| 187 | std::cout << "unknown table: " << e.what() << std::endl; | 191 | std::cout << "unknown table: " << e.what() << std::endl; |
| 188 | } | 192 | } |
| 193 | + try | ||
| 194 | + { | ||
| 195 | + ap.copyFromOtherTable("one", "two"); | ||
| 196 | + assert(false); | ||
| 197 | + } | ||
| 198 | + catch (std::exception& e) | ||
| 199 | + { | ||
| 200 | + std::cout << "copy from unknown table: " << e.what() << std::endl; | ||
| 201 | + } | ||
| 202 | + try | ||
| 203 | + { | ||
| 204 | + ap.copyFromOtherTable("two", "baaa"); | ||
| 205 | + assert(false); | ||
| 206 | + } | ||
| 207 | + catch (std::exception& e) | ||
| 208 | + { | ||
| 209 | + std::cout << "copy unknown from other table: " << e.what() << std::endl; | ||
| 210 | + } | ||
| 189 | } | 211 | } |
| 190 | 212 | ||
| 191 | int main(int argc, char* argv[]) | 213 | int main(int argc, char* argv[]) |
| 192 | { | 214 | { |
| 193 | - | ||
| 194 | ArgParser ap(argc, argv); | 215 | ArgParser ap(argc, argv); |
| 195 | if ((argc == 2) && (strcmp(argv[1], "exceptions") == 0)) | 216 | if ((argc == 2) && (strcmp(argv[1], "exceptions") == 0)) |
| 196 | { | 217 | { |
libtests/libtests.testcov
| @@ -52,3 +52,5 @@ QPDFArgParser help option 0 | @@ -52,3 +52,5 @@ QPDFArgParser help option 0 | ||
| 52 | QPDFArgParser positional 0 | 52 | QPDFArgParser positional 0 |
| 53 | QPDFArgParser unrecognized 0 | 53 | QPDFArgParser unrecognized 0 |
| 54 | QPDFArgParser complete choices 0 | 54 | QPDFArgParser complete choices 0 |
| 55 | +QPDFArgParser copy from unknown 0 | ||
| 56 | +QPDFArgParser copy unknown 0 |
libtests/qtest/arg_parser.test
| @@ -32,6 +32,7 @@ my @completion_tests = ( | @@ -32,6 +32,7 @@ my @completion_tests = ( | ||
| 32 | ['arg_parser --quack "user password" ', undef, 'quack-x'], | 32 | ['arg_parser --quack "user password" ', undef, 'quack-x'], |
| 33 | ['arg_parser --quack "user pass\'word" ', undef, 'quack-x'], | 33 | ['arg_parser --quack "user pass\'word" ', undef, 'quack-x'], |
| 34 | ['arg_parser --quack user\ password ', undef, 'quack-x'], | 34 | ['arg_parser --quack user\ password ', undef, 'quack-x'], |
| 35 | + ['arg_parser --sheep --', undef, 'sheep'], | ||
| 35 | ); | 36 | ); |
| 36 | 37 | ||
| 37 | foreach my $c (@completion_tests) | 38 | foreach my $c (@completion_tests) |
| @@ -78,6 +79,7 @@ my @arg_tests = ( | @@ -78,6 +79,7 @@ my @arg_tests = ( | ||
| 78 | ['@quack-xyz --', 0], # 15 | 79 | ['@quack-xyz --', 0], # 15 |
| 79 | ['--salad', 2], # 16 | 80 | ['--salad', 2], # 16 |
| 80 | ['--salad=spinach', 0], # 17 | 81 | ['--salad=spinach', 0], # 17 |
| 82 | + ['--sheep --ewe --', 0], # 18 | ||
| 81 | ); | 83 | ); |
| 82 | 84 | ||
| 83 | for (my $i = 0; $i < scalar(@arg_tests); ++$i) | 85 | for (my $i = 0; $i < scalar(@arg_tests); ++$i) |
libtests/qtest/arg_parser/args-18.out
0 → 100644
libtests/qtest/arg_parser/completion-sheep.out
0 → 100644
libtests/qtest/arg_parser/exceptions.out
| @@ -2,3 +2,5 @@ duplicate handler: QPDFArgParser: adding a duplicate handler for option potato i | @@ -2,3 +2,5 @@ duplicate handler: QPDFArgParser: adding a duplicate handler for option potato i | ||
| 2 | duplicate handler: QPDFArgParser: adding a duplicate handler for option ram in baaa option table | 2 | duplicate handler: QPDFArgParser: adding a duplicate handler for option ram in baaa option table |
| 3 | duplicate table: QPDFArgParser: registering already registered option table baaa | 3 | duplicate table: QPDFArgParser: registering already registered option table baaa |
| 4 | unknown table: QPDFArgParser: selecting unregistered option table aardvark | 4 | unknown table: QPDFArgParser: selecting unregistered option table aardvark |
| 5 | +copy from unknown table: QPDFArgParser: attempt to copy from unknown table two | ||
| 6 | +copy unknown from other table: QPDFArgParser: attempt to copy unknown argument two from table baaa |