Commit 4067f55cb87824360655f4d0e55967fdb32610ad

Authored by Henry Fredrick Schreiner
1 parent 7ba1e84b

Changing the exit method to a more reasonable system

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
... ...