From a7a3cf206851b5896d938efa34a142aa1f0649b0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 21 Feb 2022 06:24:27 +0200 Subject: Factor additional logic to parse_cmdline() --- build2/b.cxx | 92 ++++++++++----------------------------------------- libbuild2/cmdline.cxx | 76 ++++++++++++++++++++++++++++++++++++++++-- libbuild2/cmdline.hxx | 19 +++++++++-- 3 files changed, 107 insertions(+), 80 deletions(-) diff --git a/build2/b.cxx b/build2/b.cxx index 95be718..304b58e 100644 --- a/build2/b.cxx +++ b/build2/b.cxx @@ -231,15 +231,7 @@ main (int argc, char* argv[]) { // Parse the command line. // - strings cmd_vars; - string args; - uint16_t verbosity; - { - cmdline r (parse_cmdline (trace, argc, argv, ops)); - cmd_vars = move (r.cmd_vars); - args = move (r.buildspec); - verbosity = r.verbosity; - } + cmdline cmdl (parse_cmdline (trace, argc, argv, ops)); // Handle --build2-metadata (see also buildfile). // @@ -289,10 +281,9 @@ main (int argc, char* argv[]) // Initialize the diagnostics state. // - init_diag (verbosity, + init_diag (cmdl.verbosity, ops.silent (), - (ops.progress () ? optional (true) : - ops.no_progress () ? optional (false) : nullopt), + cmdl.progress, ops.no_line (), ops.no_column (), fdterm (stderr_fd ())); @@ -335,14 +326,9 @@ main (int argc, char* argv[]) // init (&::terminate, argv[0], - (ops.mtime_check () ? optional (true) : - ops.no_mtime_check () ? optional (false) : nullopt), - (ops.config_sub_specified () - ? optional (ops.config_sub ()) - : nullopt), - (ops.config_guess_specified () - ? optional (ops.config_guess ()) - : nullopt)); + cmdl.mtime_check, + cmdl.config_sub, + cmdl.config_guess); #ifdef _WIN32 // On Windows disable displaying error reporting dialog box for the @@ -375,58 +361,14 @@ main (int argc, char* argv[]) // Start up the scheduler and allocate lock shards. // - size_t jobs (0); - - if (ops.jobs_specified ()) - jobs = ops.jobs (); - else if (ops.serial_stop ()) - jobs = 1; - - if (jobs == 0) - jobs = scheduler::hardware_concurrency (); - - if (jobs == 0) - { - warn << "unable to determine the number of hardware threads" << - info << "falling back to serial execution" << - info << "use --jobs|-j to override"; - - jobs = 1; - } - - size_t max_jobs (0); - - if (ops.max_jobs_specified ()) - { - max_jobs = ops.max_jobs (); - - if (max_jobs != 0 && max_jobs < jobs) - fail << "invalid --max-jobs|-J value"; - } - - sched.startup (jobs, - 1, - max_jobs, - jobs * ops.queue_depth (), - (ops.max_stack_specified () - ? optional (ops.max_stack () * 1024) - : nullopt)); + sched.startup (cmdl.jobs, + 1 /* init_active */, + cmdl.max_jobs, + cmdl.jobs * ops.queue_depth (), + cmdl.max_stack); global_mutexes mutexes (sched.shard_size ()); - - bool fcache_comp (true); - if (ops.file_cache_specified ()) - { - const string& v (ops.file_cache ()); - if (v == "noop" || v == "none") - fcache_comp = false; - else if (v == "sync-lz4") - fcache_comp = true; - else - fail << "invalid --file-cache value '" << v << "'"; - } - - file_cache fcache (fcache_comp); + file_cache fcache (cmdl.fcache_compress); // Trace some overall environment information. // @@ -438,7 +380,7 @@ main (int argc, char* argv[]) trace << "home: " << home; trace << "path: " << (p ? *p : ""); trace << "type: " << (build_installed ? "installed" : "development"); - trace << "jobs: " << jobs; + trace << "jobs: " << cmdl.jobs; } // Set the build context before parsing the buildspec since it relies on @@ -446,7 +388,7 @@ main (int argc, char* argv[]) // below). // unique_ptr pctx; - auto new_context = [&ops, &pctx, &sched, &mutexes, &fcache, &cmd_vars] + auto new_context = [&ops, &cmdl, &pctx, &sched, &mutexes, &fcache] { pctx = nullptr; // Free first. pctx.reset (new context (sched, @@ -456,7 +398,7 @@ main (int argc, char* argv[]) ops.no_external_modules (), ops.dry_run (), !ops.serial_stop () /* keep_going */, - cmd_vars)); + cmdl.cmd_vars)); }; new_context (); @@ -466,7 +408,7 @@ main (int argc, char* argv[]) buildspec bspec; try { - istringstream is (args); + istringstream is (cmdl.buildspec); is.exceptions (istringstream::failbit | istringstream::badbit); parser p (*pctx); @@ -474,7 +416,7 @@ main (int argc, char* argv[]) } catch (const io_error&) { - fail << "unable to parse buildspec '" << args << "'"; + fail << "unable to parse buildspec '" << cmdl.buildspec << "'"; } l5 ([&]{trace << "buildspec: " << bspec;}); diff --git a/libbuild2/cmdline.cxx b/libbuild2/cmdline.cxx index a5f9616..e022762 100644 --- a/libbuild2/cmdline.cxx +++ b/libbuild2/cmdline.cxx @@ -9,6 +9,7 @@ #include #include +#include #include using namespace std; @@ -19,18 +20,24 @@ namespace cli = build2::build::cli; namespace build2 { cmdline - parse_cmdline (tracer& trace, int argc, char* argv[], options& ops) + parse_cmdline (tracer& trace, + int argc, char* argv[], + options& ops, + uint16_t def_verb, + size_t def_jobs) { // Note that the diagnostics verbosity level can only be calculated after // default options are loaded and merged (see below). Thus, until then we // refer to the verbosity level specified on the command line. // - auto verbosity = [&ops] () + auto verbosity = [&ops, def_verb] () { uint16_t v ( ops.verbose_specified () ? ops.verbose () - : ops.V () ? 3 : ops.v () ? 2 : ops.quiet () || ops.silent () ? 0 : 1); + : (ops.V () ? 3 : + ops.v () ? 2 : + ops.quiet () || ops.silent () ? 0 : def_verb)); return v; }; @@ -397,12 +404,75 @@ namespace build2 fail << e; } + if (ops.help () || ops.version ()) + return r; + r.verbosity = verbosity (); if (ops.silent () && r.verbosity != 0) fail << "specified with -v, -V, or --verbose verbosity level " << r.verbosity << " is incompatible with --silent"; + r.progress = (ops.progress () ? optional (true) : + ops.no_progress () ? optional (false) : nullopt); + + r.mtime_check = (ops.mtime_check () ? optional (true) : + ops.no_mtime_check () ? optional (false) : nullopt); + + + r.config_sub = (ops.config_sub_specified () + ? optional (ops.config_sub ()) + : nullopt); + + r.config_guess = (ops.config_guess_specified () + ? optional (ops.config_guess ()) + : nullopt); + + if (ops.jobs_specified ()) + r.jobs = ops.jobs (); + else if (ops.serial_stop ()) + r.jobs = 1; + + if (def_jobs != 0) + r.jobs = def_jobs; + else + { + if (r.jobs == 0) + r.jobs = scheduler::hardware_concurrency (); + + if (r.jobs == 0) + { + warn << "unable to determine the number of hardware threads" << + info << "falling back to serial execution" << + info << "use --jobs|-j to override"; + + r.jobs = 1; + } + } + + if (ops.max_jobs_specified ()) + { + r.max_jobs = ops.max_jobs (); + + if (r.max_jobs != 0 && r.max_jobs < r.jobs) + fail << "invalid --max-jobs|-J value"; + } + + r.max_stack = (ops.max_stack_specified () + ? optional (ops.max_stack () * 1024) + : nullopt); + + if (ops.file_cache_specified ()) + { + const string& v (ops.file_cache ()); + if (v == "noop" || v == "none") + r.fcache_compress = false; + else if (v == "sync-lz4") + r.fcache_compress = true; + else + fail << "invalid --file-cache value '" << v << "'"; + } + return r; } } diff --git a/libbuild2/cmdline.hxx b/libbuild2/cmdline.hxx index 7bf41c2..56e9510 100644 --- a/libbuild2/cmdline.hxx +++ b/libbuild2/cmdline.hxx @@ -19,11 +19,26 @@ namespace build2 { strings cmd_vars; string buildspec; - uint16_t verbosity; + + // Processed/meged option values (unless --help or --version specified). + // + uint16_t verbosity = 1; + optional progress; + optional mtime_check; + optional config_sub; + optional config_guess; + size_t jobs = 0; + size_t max_jobs = 0; + optional max_stack; + bool fcache_compress = true; }; LIBBUILD2_SYMEXPORT cmdline - parse_cmdline (tracer&, int argc, char* argv[], options&); + parse_cmdline (tracer&, + int argc, char* argv[], + options&, + uint16_t default_verbosity = 1, + size_t default_jobs = 0); } #endif // LIBBUILD2_CMDLINE_HXX -- cgit v1.1