Commit 4067f55cb87824360655f4d0e55967fdb32610ad
1 parent
7ba1e84b
Changing the exit method to a more reasonable system
Showing
4 changed files
with
45 additions
and
18 deletions
examples/try.cpp
| ... | ... | @@ -11,7 +11,9 @@ int main (int argc, char** argv) { |
| 11 | 11 | int count; |
| 12 | 12 | app.add_flag("c,count", count, "File name"); |
| 13 | 13 | |
| 14 | - app.start(argc, argv); | |
| 14 | + CLI::Return ret = app.start(argc, argv); | |
| 15 | + if(ret != CLI::Return::Continue) | |
| 16 | + return (int) ret; | |
| 15 | 17 | |
| 16 | 18 | std::cout << "Working on file: " << file << ", direct count: " << app.count("file") << std::endl; |
| 17 | 19 | std::cout << "Working on count: " << count << ", direct count: " << app.count("count") << std::endl; | ... | ... |
examples/try1.cpp
| ... | ... | @@ -14,7 +14,9 @@ int main (int argc, char** argv) { |
| 14 | 14 | int count; |
| 15 | 15 | stop->add_flag("c,count", count, "File name"); |
| 16 | 16 | |
| 17 | - app.start(argc, argv); | |
| 17 | + CLI::Return ret = app.start(argc, argv); | |
| 18 | + if(ret != CLI::Return::Continue) | |
| 19 | + return (int) ret; | |
| 18 | 20 | |
| 19 | 21 | std::cout << "Working on file: " << file << ", direct count: " << start->count("file") << std::endl; |
| 20 | 22 | std::cout << "Working on count: " << count << ", direct count: " << stop->count("count") << std::endl; | ... | ... |
include/CLI.hpp
| ... | ... | @@ -62,6 +62,15 @@ using std::enable_if_t; |
| 62 | 62 | #endif |
| 63 | 63 | // If your compiler supports C++14, you can use that definition instead |
| 64 | 64 | |
| 65 | +enum class Return { | |
| 66 | + Continue = -1, | |
| 67 | + Success = 0, | |
| 68 | + ParseError = 1, | |
| 69 | + PositionalError = 2, | |
| 70 | + RequiredError = 3, | |
| 71 | + GeneralError = 4 | |
| 72 | +}; | |
| 73 | + | |
| 65 | 74 | struct Combiner { |
| 66 | 75 | int num; |
| 67 | 76 | bool positional; |
| ... | ... | @@ -147,8 +156,8 @@ struct RequiredError : public Error { |
| 147 | 156 | RequiredError(std::string name) : Error("RequiredError", name) {} |
| 148 | 157 | }; |
| 149 | 158 | |
| 150 | -struct ExtraPositionalsError : public Error { | |
| 151 | - ExtraPositionalsError(std::string name) : Error("ExtraPositionalsError", name) {} | |
| 159 | +struct PositionalError : public Error { | |
| 160 | + PositionalError(std::string name) : Error("PositionalError", name) {} | |
| 152 | 161 | }; |
| 153 | 162 | |
| 154 | 163 | struct HorribleError : public Error { |
| ... | ... | @@ -617,7 +626,7 @@ public: |
| 617 | 626 | |
| 618 | 627 | } |
| 619 | 628 | if(positionals.size()>0) |
| 620 | - throw ExtraPositionalsError("[" + join(positionals) + "]"); | |
| 629 | + throw PositionalError("[" + join(positionals) + "]"); | |
| 621 | 630 | } |
| 622 | 631 | |
| 623 | 632 | void _parse_subcommand(std::vector<std::string> &args) { |
| ... | ... | @@ -762,21 +771,32 @@ public: |
| 762 | 771 | } |
| 763 | 772 | |
| 764 | 773 | /// This must be called after the options are in but before the rest of the program. |
| 765 | - /** Instead of throwing erros, causes the program to exit | |
| 766 | - * if -h or an invalid option is passed. */ | |
| 767 | - void start(int argc, char** argv) { | |
| 774 | + /** Instead of throwing erros, this gives an error code | |
| 775 | + * if -h or an invalid option is passed. Continue with your program if returns -1 */ | |
| 776 | + Return start(int argc, char** argv) { | |
| 777 | + | |
| 778 | + std::function<void(const Error&)> msg_fun{[this](const Error &e){ | |
| 779 | + std::cerr << "ERROR: "; | |
| 780 | + std::cerr << e.what() << std::endl; | |
| 781 | + std::cerr << help() << std::endl; | |
| 782 | + }}; | |
| 783 | + | |
| 768 | 784 | try { |
| 769 | 785 | parse(argc, argv); |
| 786 | + return Return::Continue; | |
| 770 | 787 | } catch(const CallForHelp &e) { |
| 771 | 788 | std::cout << help() << std::endl; |
| 772 | - exit(0); | |
| 789 | + return Return::Success; | |
| 790 | + } catch(const ParseError &e) { | |
| 791 | + msg_fun(e); | |
| 792 | + return Return::ParseError; | |
| 793 | + } catch(const PositionalError &e) { | |
| 794 | + msg_fun(e); | |
| 795 | + return Return::RequiredError; | |
| 773 | 796 | } catch(const Error &e) { |
| 774 | - std::cerr << "ERROR: "; | |
| 775 | - std::cerr << e.what() << std::endl; | |
| 776 | - std::cerr << help() << std::endl; | |
| 777 | - exit(1); | |
| 797 | + msg_fun(e); | |
| 798 | + return Return::GeneralError; | |
| 778 | 799 | } |
| 779 | - | |
| 780 | 800 | } |
| 781 | 801 | |
| 782 | 802 | /// Counts the number of times the given option was passed. | ... | ... |
tests/CLITest.cpp
| ... | ... | @@ -15,7 +15,7 @@ TEST(Basic, Empty) { |
| 15 | 15 | { |
| 16 | 16 | CLI::App app; |
| 17 | 17 | input_t spare = {"spare"}; |
| 18 | - EXPECT_THROW(app.parse(spare), CLI::ExtraPositionalsError); | |
| 18 | + EXPECT_THROW(app.parse(spare), CLI::PositionalError); | |
| 19 | 19 | } |
| 20 | 20 | { |
| 21 | 21 | CLI::App app; |
| ... | ... | @@ -248,6 +248,10 @@ TEST_F(TApp, FileExists) { |
| 248 | 248 | std::remove(myfile.c_str()); |
| 249 | 249 | EXPECT_FALSE(CLI::_ExistingFile(myfile)); |
| 250 | 250 | } |
| 251 | + | |
| 252 | + | |
| 253 | +// TODO: Add directory test | |
| 254 | + | |
| 251 | 255 | TEST_F(TApp, Basic) { |
| 252 | 256 | auto sub1 = app.add_subcommand("sub1"); |
| 253 | 257 | auto sub2 = app.add_subcommand("sub2"); |
| ... | ... | @@ -302,16 +306,15 @@ TEST_F(SubcommandProgram, Working) { |
| 302 | 306 | TEST_F(SubcommandProgram, Spare) { |
| 303 | 307 | args = {"extra", "-d", "start", "-ffilename"}; |
| 304 | 308 | |
| 305 | - EXPECT_THROW(run(), CLI::ExtraPositionalsError); | |
| 309 | + EXPECT_THROW(run(), CLI::PositionalError); | |
| 306 | 310 | } |
| 307 | 311 | |
| 308 | 312 | TEST_F(SubcommandProgram, SpareSub) { |
| 309 | 313 | args = {"-d", "start", "spare", "-ffilename"}; |
| 310 | 314 | |
| 311 | - EXPECT_THROW(run(), CLI::ExtraPositionalsError); | |
| 315 | + EXPECT_THROW(run(), CLI::PositionalError); | |
| 312 | 316 | } |
| 313 | 317 | |
| 314 | -// TODO: Add positionals | |
| 315 | 318 | // TODO: Add vector arguments |
| 316 | 319 | // TODO: Maybe add function to call on subcommand parse? |
| 317 | 320 | // TODO: Check help output | ... | ... |