From 94c3574492b6db6ae8d5fbef717f8e6f92f1d402 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 2 Sep 2015 17:09:57 +0200 Subject: Command line options/commands/help infrastructure --- bpkg/bpkg.cxx | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 143 insertions(+), 13 deletions(-) (limited to 'bpkg/bpkg.cxx') diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx index d95d005..849a386 100644 --- a/bpkg/bpkg.cxx +++ b/bpkg/bpkg.cxx @@ -2,35 +2,165 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file +#include #include #include #include #include +#include + +#include +#include + +//#include +#include + using namespace std; using namespace bpkg; +// Initialize the command option class O with the common options +// and then parse the rest of the arguments. Once this is done, +// use the "final" values of the common options to do global +// initializations (verbosity level, etc). +// +template +static O +parse (const common_options& co, cli::scanner& s) +{ + O o; + static_cast (o) = co; + o.parse (s); + + // Global initializations. + // + + // Trace verbosity. + // + verb = o.verbose () > 0 ? o.verbose () : (o.v () ? 1 : 0); + + return o; +} + int -main () +main (int argc, char* argv[]) +try { - tracer trace ("main"); + using namespace cli; + + argv_file_scanner args (argc, argv, "--options-file"); + + // First parse common options and --version/--help. + // + bpkg_options bo; + bo.parse (args, unknown_mode::stop); + + if (bo.version ()) + { + cout << "bpkg 0.0.0" << endl + << "Copyright (c) 2014-2015 Code Synthesis Ltd" << endl + << "This is free software released under the MIT license." << endl; + return 0; + } + + if (bo.help ()) + { + help (help_options (), "", nullptr); + return 0; + } + + const common_options& co (bo); + + // The next argument should be a command. + // + if (!args.more ()) + fail << "bpkg command expected" << + info << "run 'bpkg help' for more information"; - try + int cmd_argc (2); + char* cmd_argv[] {argv[0], const_cast (args.next ())}; + bpkg_commands cmd; + cmd.parse (cmd_argc, cmd_argv, true, unknown_mode::stop); + + if (cmd_argc != 1) + fail << "unknown bpkg command/option '" << cmd_argv[1] << "'" << + info << "run 'bpkg help' for more information"; + + // If the command is 'help', then what's coming next is another + // command. Parse it into cmd so that we only need to check for + // each command in one place. + // + bool h (cmd.help ()); + help_options ho; + + if (h) { - // Trace verbosity. - // - verb = 0; + ho = parse (co, args); + + if (args.more ()) + { + cmd_argc = 2; + cmd_argv[1] = const_cast (args.next ()); + + // First see if this is a command. + // + cmd = bpkg_commands (); // Clear help option. + cmd.parse (cmd_argc, cmd_argv, true, unknown_mode::stop); + + // If not, then it got to be a help topic. + // + if (cmd_argc != 1) + return help (ho, cmd_argv[1], nullptr); + } + else + return help (ho, "", nullptr); } - catch (const failed&) + + // Handle commands. + // + + // help + // + if (cmd.help ()) { - return 1; // Diagnostics has already been issued. + assert (h); + return help (ho, "help", help_options::print_usage); } - /* - catch (const std::exception& e) + + // rep-create + // + if (cmd.rep_create ()) { - error << e.what (); - return 1; + if (h) + return help (ho, "rep-create", rep_create_options::print_usage); + + auto o (parse (co, args)); + + if (verb) + text << "rep-create"; + + return 0; } - */ + + assert (false); // Unhandled command. + return 1; +} +catch (const failed&) +{ + return 1; // Diagnostics has already been issued. +} +catch (const cli::exception& e) +{ + *diag_stream << "error: "; + e.print (*diag_stream); + *diag_stream << endl; + return 1; +} +/* +catch (const std::exception& e) +{ + error << e.what (); + return 1; } +*/ -- cgit v1.1