• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #856

28 Dec 2022 02:00AM UTC coverage: 86.602% (+0.05%) from 86.55%
#856

push

StellarBot
Merge #6119

6119: Update CMakeLists.txt r=hkaiser a=khuck

updating the default APEX version


Co-authored-by: Kevin Huck <khuck@cs.uoregon.edu>

174566 of 201573 relevant lines covered (86.6%)

1876093.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.07
/libs/core/command_line_handling_local/src/parse_command_line_local.cpp
1
//  Copyright (c) 2007-2022 Hartmut Kaiser
2
//
3
//  SPDX-License-Identifier: BSL-1.0
4
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6

7
#include <hpx/command_line_handling_local/parse_command_line_local.hpp>
8
#include <hpx/datastructures/any.hpp>
9
#include <hpx/ini/ini.hpp>
10
#include <hpx/modules/errors.hpp>
11
#include <hpx/modules/filesystem.hpp>
12
#include <hpx/util/from_string.hpp>
13

14
#include <cctype>
15
#include <cstddef>
16
#include <fstream>
17
#include <iostream>
18
#include <stdexcept>
19
#include <string>
20
#include <utility>
21
#include <vector>
22

23
///////////////////////////////////////////////////////////////////////////////
24
namespace hpx { namespace local { namespace detail {
25

26
    ///////////////////////////////////////////////////////////////////////
27
    std::string trim_whitespace(std::string const& s)
14,666✔
28
    {
29
        using size_type = std::string::size_type;
30

31
        size_type first = s.find_first_not_of(" \t");
14,666✔
32
        if (std::string::npos == first)
14,666✔
33
            return std::string();
6,601✔
34

35
        size_type last = s.find_last_not_of(" \t");
8,065✔
36
        return s.substr(first, last - first + 1);
8,065✔
37
    }
14,666✔
38

39
    ///////////////////////////////////////////////////////////////////////
40
    // Handle aliasing of command line options based on information stored
41
    // in the ini-configuration
42
    std::pair<std::string, std::string> handle_aliasing(
8,060✔
43
        util::section const& ini, std::string const& option)
44
    {
45
        std::pair<std::string, std::string> result;
8,060✔
46

47
        std::string opt(trim_whitespace(option));
8,060✔
48
        if (opt.size() < 2 || opt[0] != '-')
8,060✔
49
            return result;
1,454✔
50

51
        util::section const* sec = ini.get_section("hpx.commandline.aliases");
6,606✔
52
        if (nullptr == sec)
6,606✔
53
            return result;    // no alias mappings are defined
×
54

55
        // we found shortcut option definitions, try to find mapping
56
        std::string expand_to;
6,606✔
57
        std::string::size_type start_at = 2;
6,606✔
58
        bool long_option = false;
6,606✔
59
        if (opt.size() > 2 && opt[1] != '-')
6,606✔
60
        {
61
            // short option with value: first two letters have to match
62
            expand_to =
5✔
63
                trim_whitespace(sec->get_entry(opt.substr(0, start_at), ""));
5✔
64
        }
5✔
65
        else
66
        {
67
            // short option (no value) or long option
68
            if (opt[1] == '-')
6,601✔
69
            {
70
                start_at = opt.find_last_of('=');
6,601✔
71
                long_option = true;
6,601✔
72
            }
6,601✔
73

74
            if (start_at != std::string::npos)
6,601✔
75
            {
76
                expand_to = trim_whitespace(
6,572✔
77
                    sec->get_entry(opt.substr(0, start_at), ""));
6,572✔
78
            }
6,572✔
79
            else
80
            {
81
                expand_to = trim_whitespace(sec->get_entry(opt, ""));
29✔
82
            }
83
        }
84

85
        if (expand_to.size() < 2 || expand_to.substr(0, 2) != "--")
6,606✔
86
            return result;    // no sensible alias is defined for this option
6,601✔
87
        expand_to.erase(0, 2);
5✔
88

89
        std::string::size_type p = expand_to.find_first_of('=');
5✔
90
        if (p != std::string::npos)
5✔
91
        {
92
            // the option alias defines its own value
93
            std::string o(trim_whitespace(expand_to.substr(0, p)));
×
94
            std::string v(trim_whitespace(expand_to.substr(p + 1)));
×
95
            result = std::make_pair(o, v);
×
96
        }
×
97
        else if (start_at != std::string::npos && start_at < opt.size())
5✔
98
        {
99
            // extract value from original option
100
            result = std::make_pair(
5✔
101
                expand_to, opt.substr(start_at + (long_option ? 1 : 0)));
5✔
102
        }
5✔
103
        else
104
        {
105
            // no value
106
            result = std::make_pair(expand_to, std::string());
×
107
        }
108

109
        return result;
5✔
110
    }
8,060✔
111

112
    ///////////////////////////////////////////////////////////////////////
113
    // Additional command line parser which interprets '@something' as an
114
    // option "options-file" with the value "something". Additionally we
115
    // resolve defined command line option aliases.
116
    option_parser::option_parser(
4,260✔
117
        util::section const& ini, bool ignore_aliases) noexcept
118
      : ini_(ini)
4,260✔
119
      , ignore_aliases_(ignore_aliases)
4,260✔
120
    {
121
    }
4,260✔
122

123
    std::pair<std::string, std::string> option_parser::operator()(
14,901✔
124
        std::string const& s) const
125
    {
126
        // handle special syntax for configuration files @filename
127
        if ('@' == s[0])
14,901✔
128
        {
129
            return std::make_pair(std::string("hpx:options-file"), s.substr(1));
×
130
        }
131

132
        // handle aliasing, if enabled
133
        if (ini_.get_entry("hpx.commandline.aliasing", "0") == "0" ||
14,901✔
134
            ignore_aliases_)
10,937✔
135
        {
136
            return std::make_pair(std::string(), std::string());
6,841✔
137
        }
138

139
        return handle_aliasing(ini_, s);
8,060✔
140
    }
14,901✔
141

142
    ///////////////////////////////////////////////////////////////////////
143
    hpx::program_options::basic_command_line_parser<char>&
144
    get_commandline_parser(
4,260✔
145
        hpx::program_options::basic_command_line_parser<char>& p,
146
        util::commandline_error_mode mode)
147
    {
148
        if ((mode &
12,780✔
149
                ~(util::commandline_error_mode::report_missing_config_file |
4,260✔
150
                    util::commandline_error_mode::ignore_aliases)) ==
4,260✔
151
            util::commandline_error_mode::allow_unregistered)
152
        {
153
            return p.allow_unregistered();
4,256✔
154
        }
155
        return p;
4✔
156
    }
4,260✔
157

158
    ///////////////////////////////////////////////////////////////////////
159
    // Read all options from a given config file
160
    std::vector<std::string> read_config_file_options(
28,577✔
161
        std::string const& filename, util::commandline_error_mode error_mode)
162
    {
163
        std::vector<std::string> options;
28,577✔
164

165
        std::ifstream ifs(filename.c_str());
28,577✔
166
        if (!ifs.is_open())
28,577✔
167
        {
168
            if (as_bool(error_mode &
28,577✔
169
                    util::commandline_error_mode::report_missing_config_file))
170
            {
171
                std::cerr << "hpx::init: command line warning: command line "
×
172
                             "options file not found ("
173
                          << filename << ")" << std::endl;
×
174
            }
×
175
            return options;
28,577✔
176
        }
177

178
        std::string line;
×
179
        while (std::getline(ifs, line))
×
180
        {
181
            using hpx::local::detail::trim_whitespace;
182

183
            // skip empty lines
184
            std::string::size_type pos = line.find_first_not_of(" \t");
×
185
            if (pos == std::string::npos)
×
186
                continue;
×
187

188
            // strip leading and trailing whitespace
189
            line = trim_whitespace(line);
×
190

191
            // skip comment lines
192
            if ('#' != line[0])
×
193
            {
194
                std::string::size_type p1 = line.find_first_of(" \t");
×
195
                if (p1 != std::string::npos)
×
196
                {
197
                    // rebuild the line connecting the parts with a '='
198
                    line = trim_whitespace(line.substr(0, p1)) + '=' +
×
199
                        trim_whitespace(line.substr(p1));
×
200
                }
×
201
                options.push_back(line);
×
202
            }
×
203
        }
204

205
        return options;
×
206
    }
28,577✔
207

208
    ///////////////////////////////////////////////////////////////////////////
209
    // Handle all options from a given config file, parse and add them to the
210
    // given variables_map
211
    bool handle_config_file_options(std::vector<std::string> const& options,
17,272✔
212
        hpx::program_options::options_description const& desc,
213
        hpx::program_options::variables_map& vm, util::section const& rtcfg,
214
        util::commandline_error_mode error_mode)
215
    {
216
        // add options to parsed settings
217
        if (!options.empty())
17,272✔
218
        {
219
            using hpx::program_options::command_line_parser;
220
            using hpx::program_options::store;
221
            using hpx::program_options::command_line_style::unix_style;
222

223
            util::commandline_error_mode mode =
×
224
                error_mode & util::commandline_error_mode::ignore_aliases;
×
225
            util::commandline_error_mode notmode =
×
226
                error_mode & util::commandline_error_mode::ignore_aliases;
×
227

228
            store(get_commandline_parser(
×
229
                      command_line_parser(options)
×
230
                          .options(desc)
×
231
                          .style(unix_style)
×
232
                          .extra_parser(option_parser(rtcfg, as_bool(mode))),
×
233
                      notmode)
×
234
                      .run(),
×
235
                vm);
×
236
            notify(vm);
×
237
            return true;
×
238
        }
239
        return false;
17,272✔
240
    }
17,272✔
241

242
    // try to find a config file somewhere up the filesystem hierarchy starting
243
    // with the input file path. This allows to use a general <app_name>.cfg
244
    // file for all executables in a certain project.
245
    void handle_generic_config_options(std::string appname,
2,468✔
246
        hpx::program_options::variables_map& vm,
247
        hpx::program_options::options_description const& desc_cfgfile,
248
        util::section const& ini, util::commandline_error_mode error_mode)
249
    {
250
        if (appname.empty())
2,468✔
251
            return;
×
252

253
        filesystem::path dir(filesystem::initial_path());
2,468✔
254
        filesystem::path app(appname);
2,468✔
255
        appname = filesystem::basename(app.filename());
2,468✔
256

257
        // walk up the hierarchy, trying to find a file <appname>.cfg
258
        while (!dir.empty())
17,272✔
259
        {
260
            filesystem::path filename = dir / (appname + ".cfg");
17,272✔
261
            util::commandline_error_mode mode = error_mode &
34,544✔
262
                ~util::commandline_error_mode::report_missing_config_file;
17,272✔
263

264
            std::vector<std::string> options =
265
                read_config_file_options(filename.string(), mode);
17,272✔
266

267
            bool result = handle_config_file_options(
17,272✔
268
                options, desc_cfgfile, vm, ini, mode);
17,272✔
269
            if (result)
17,272✔
270
            {
271
                break;    // break on the first options file found
×
272
            }
273

274
            // Boost filesystem and C++17 filesystem behave differently
275
            // here. Boost filesystem returns an empty path for
276
            // "/".parent_path() whereas C++17 filesystem will keep
277
            // returning "/".
278
#if !defined(HPX_FILESYSTEM_HAVE_BOOST_FILESYSTEM_COMPATIBILITY)
279
            auto dir_prev = dir;
17,272✔
280
            dir = dir.parent_path();    // chop off last directory part
17,272✔
281
            if (dir_prev == dir)
17,272✔
282
                break;
2,468✔
283
#else
284
            dir = dir.parent_path();    // chop off last directory part
285
#endif
286
        }
17,272✔
287
    }
2,468✔
288

289
    // handle all --options-config found on the command line
290
    void handle_config_options(hpx::program_options::variables_map& vm,
2,468✔
291
        hpx::program_options::options_description const& desc_cfgfile,
292
        util::section const& ini, util::commandline_error_mode error_mode)
293
    {
294
        using hpx::program_options::options_description;
295
        if (vm.count("hpx:options-file"))
2,468✔
296
        {
297
            std::vector<std::string> const& cfg_files =
×
298
                vm["hpx:options-file"].as<std::vector<std::string>>();
×
299

300
            for (std::string const& cfg_file : cfg_files)
×
301
            {
302
                // parse a single config file and store the results
303
                std::vector<std::string> options =
304
                    read_config_file_options(cfg_file, error_mode);
×
305

306
                handle_config_file_options(
×
307
                    options, desc_cfgfile, vm, ini, error_mode);
×
308
            }
×
309
        }
×
310
    }
2,468✔
311

312
    void verify_unknown_options(std::vector<std::string> const& opts)
1,226✔
313
    {
314
        for (auto const& opt : opts)
1,235✔
315
        {
316
            std::string::size_type p = opt.find("--hpx:");
9✔
317
            if (p != std::string::npos)
9✔
318
            {
319
                throw hpx::detail::command_line_error(
×
320
                    "Unknown/misspelled HPX command line option found: " + opt);
×
321
            }
322
        }
323
    }
1,226✔
324

325
    ///////////////////////////////////////////////////////////////////////////
326
    // parse the command line
327
    bool parse_commandline(util::section const& rtcfg, options_map& all_options,
4,260✔
328
        hpx::program_options::options_description const& app_options,
329
        std::vector<std::string> const& args,
330
        hpx::program_options::variables_map& vm,
331
        util::commandline_error_mode error_mode,
332
        hpx::program_options::options_description* visible,
333
        std::vector<std::string>* unregistered_options)
334
    {
335
        using hpx::program_options::command_line_parser;
336
        using hpx::program_options::options_description;
337
        using hpx::program_options::parsed_options;
338
        using hpx::program_options::positional_options_description;
339
        using hpx::program_options::store;
340
        using hpx::program_options::value;
341
        using namespace hpx::program_options::command_line_style;
342

343
        if (rtcfg.get_entry("hpx.commandline.allow_unknown", "0") == "0")
4,260✔
344
        {
345
            // clang-format off
346
            options_description positional_options;
3,444✔
347
            positional_options.add_options()
3,444✔
348
                ("hpx:positional",
349
                  value<std::vector<std::string>>(), "positional options")
3,444✔
350
                ;
351
            // clang-format on
352

353
            all_options[options_type::desc_cmdline].add(positional_options);
3,444✔
354
            all_options[options_type::desc_cfgfile].add(positional_options);
3,444✔
355

356
            // move all positional options into the hpx:positional option
357
            // group
358
            positional_options_description pd;
3,444✔
359
            pd.add("hpx:positional", -1);
3,444✔
360

361
            // parse command line, allow for unregistered options this point
362
            util::commandline_error_mode mode =
3,444✔
363
                error_mode & util::commandline_error_mode::ignore_aliases;
3,444✔
364
            util::commandline_error_mode notmode =
3,444✔
365
                error_mode & ~util::commandline_error_mode::ignore_aliases;
3,444✔
366

367
            parsed_options opts(get_commandline_parser(
6,888✔
368
                command_line_parser(args)
3,444✔
369
                    .options(all_options[options_type::desc_cmdline])
3,444✔
370
                    .positional(pd)
3,444✔
371
                    .style(unix_style)
3,444✔
372
                    .extra_parser(option_parser(rtcfg, as_bool(mode))),
3,444✔
373
                notmode)
3,444✔
374
                                    .run());
3,444✔
375

376
            // collect unregistered options, if needed
377
            if (unregistered_options)
3,444✔
378
            {
379
                using hpx::program_options::collect_unrecognized;
380
                using hpx::program_options::exclude_positional;
381
                *unregistered_options =
1,019✔
382
                    collect_unrecognized(opts.options, exclude_positional);
1,019✔
383

384
                verify_unknown_options(*unregistered_options);
1,019✔
385
            }
1,019✔
386

387
            store(opts, vm);
3,444✔
388
        }
3,444✔
389
        else
390
        {
391
            // parse command line, allow for unregistered options this point
392
            util::commandline_error_mode mode =
816✔
393
                error_mode & util::commandline_error_mode::ignore_aliases;
816✔
394
            util::commandline_error_mode notmode =
816✔
395
                error_mode & ~util::commandline_error_mode::ignore_aliases;
816✔
396

397
            parsed_options opts(get_commandline_parser(
1,632✔
398
                command_line_parser(args)
816✔
399
                    .options(all_options[options_type::desc_cmdline])
816✔
400
                    .style(unix_style)
816✔
401
                    .extra_parser(option_parser(rtcfg, as_bool(mode))),
816✔
402
                notmode)
816✔
403
                                    .run());
816✔
404

405
            // collect unregistered options, if needed
406
            if (unregistered_options)
816✔
407
            {
408
                using hpx::program_options::collect_unrecognized;
409
                using hpx::program_options::include_positional;
410
                *unregistered_options =
207✔
411
                    collect_unrecognized(opts.options, include_positional);
207✔
412

413
                verify_unknown_options(*unregistered_options);
207✔
414
            }
207✔
415

416
            store(opts, vm);
816✔
417
        }
816✔
418

419
        if (vm.count("hpx:help"))
4,260✔
420
        {
421
            // collect help information
422
            if (visible != nullptr)
6✔
423
            {
424
                (*visible)
3✔
425
                    .add(app_options)
3✔
426
                    .add(all_options[options_type::commandline_options])
3✔
427
                    .add(all_options[options_type::hpx_options])
3✔
428
                    .add(all_options[options_type::debugging_options])
3✔
429
                    .add(all_options[options_type::config_options]);
3✔
430
            }
3✔
431
            return true;
6✔
432
        }
433

434
        notify(vm);
4,254✔
435

436
        return true;
4,254✔
437
    }
4,260✔
438

439
    options_map compose_local_options()
4,260✔
440
    {
441
        using hpx::program_options::value;
442

443
        options_map all_options;
4,260✔
444

445
        // clang-format off
446
        all_options.emplace(options_type::commandline_options,
4,260✔
447
            "HPX options (allowed on command line only)");
448

449
        all_options[options_type::commandline_options].add_options()
12,780✔
450
            ("hpx:help", value<std::string>()->implicit_value("minimal"),
4,260✔
451
                "print out program usage (default: this message), possible "
452
                "values: 'full' (additionally prints options from components)")
453
            ("hpx:version", "print out HPX version and copyright information")
454
            ("hpx:info", "print out HPX configuration information")
455
            ("hpx:options-file", value<std::vector<std::string> >()->composing(),
4,260✔
456
                "specify a file containing command line options "
457
                "(alternatively: @filepath)")
458
        ;
459
        // clang-format on
460

461
        all_options.emplace(options_type::hpx_options,
4,260✔
462
            "HPX options (additionally allowed in an options file)");
463
        all_options.emplace(options_type::hidden_options, "Hidden options");
4,260✔
464

465
        // general options definitions
466
        // clang-format off
467
        all_options[options_type::hpx_options].add_options()
38,340✔
468
            ("hpx:pu-offset", value<std::size_t>(),
4,260✔
469
                "the first processing unit this instance of HPX should be "
470
                "run on (default: 0), valid for "
471
                "--hpx:queuing=local, --hpx:queuing=abp-priority, "
472
                "--hpx:queuing=static, --hpx:queuing=static-priority, "
473
                "and --hpx:queuing=local-priority only")
474
            ("hpx:pu-step", value<std::size_t>(),
4,260✔
475
                "the step between used processing unit numbers for this "
476
                "instance of HPX (default: 1), valid for "
477
                "--hpx:queuing=local, --hpx:queuing=abp-priority, "
478
                "--hpx:queuing=static, --hpx:queuing=static-priority "
479
                "and --hpx:queuing=local-priority only")
480
            ("hpx:affinity", value<std::string>(),
4,260✔
481
                "the affinity domain the OS threads will be confined to, "
482
                "possible values: pu, core, numa, machine (default: pu), valid for "
483
                "--hpx:queuing=local, --hpx:queuing=abp-priority, "
484
                "--hpx:queuing=static, --hpx:queuing=static-priority "
485
                " and --hpx:queuing=local-priority only")
486
            ("hpx:bind", value<std::vector<std::string> >()->composing(),
4,260✔
487
                "the detailed affinity description for the OS threads, see "
488
                "the documentation for a detailed description of possible "
489
                "values. Do not use with --hpx:pu-step, --hpx:pu-offset, or "
490
                "--hpx:affinity options. Implies --hpx:numa-sensitive=1"
491
                "(--hpx:bind=none disables defining thread affinities).")
492
            ("hpx:use-process-mask", "use the process mask to restrict "
493
                "available hardware resources (implies "
494
                "--hpx:ignore-batch-env)")
495
            ("hpx:print-bind",
496
                "print to the console the bit masks calculated from the "
497
                "arguments specified to all --hpx:bind options.")
498
            ("hpx:threads", value<std::string>(),
4,260✔
499
                "the number of operating system threads to spawn for this HPX "
500
                "locality (default: 1, using 'all' will spawn one thread for "
501
                "each processing unit")
502
            ("hpx:cores", value<std::string>(),
4,260✔
503
                "the number of cores to utilize for this HPX "
504
                "locality (default: 'all', i.e. the number of cores is based on "
505
                "the number of total cores in the system)")
506
            ("hpx:queuing", value<std::string>(),
4,260✔
507
                "the queue scheduling policy to use, options are "
508
                "'local', 'local-priority-fifo','local-priority-lifo', "
509
                "'abp-priority-fifo', 'abp-priority-lifo', 'static', and "
510
                "'static-priority' (default: 'local-priority'; "
511
                "all option values can be abbreviated)")
512
            ("hpx:high-priority-threads", value<std::size_t>(),
4,260✔
513
                "the number of operating system threads maintaining a high "
514
                "priority queue (default: number of OS threads), valid for "
515
                "--hpx:queuing=local-priority,--hpx:queuing=static-priority, "
516
                " and --hpx:queuing=abp-priority only)")
517
            ("hpx:numa-sensitive", value<std::size_t>()->implicit_value(0),
4,260✔
518
                "makes the local-priority scheduler NUMA sensitive ("
519
                "allowed values: 0 - no NUMA sensitivity, 1 - allow only for "
520
                "boundary cores to steal across NUMA domains, 2 - "
521
                "no cross boundary stealing is allowed (default value: 0)")
522
        ;
523

524
        all_options.emplace(options_type::config_options,
4,260✔
525
            "HPX configuration options");
526
        all_options[options_type::config_options].add_options()
12,780✔
527
            ("hpx:app-config", value<std::string>(),
4,260✔
528
                "load the specified application configuration (ini) file")
529
            ("hpx:config", value<std::string>()->default_value(""),
4,260✔
530
                "load the specified hpx configuration (ini) file")
531
            ("hpx:ini", value<std::vector<std::string> >()->composing(),
4,260✔
532
                "add a configuration definition to the default runtime "
533
                "configuration")
534
            ("hpx:exit", "exit after configuring the runtime")
535
        ;
536

537
        all_options.emplace(options_type::debugging_options,
4,260✔
538
            "HPX debugging options");
539
        all_options[options_type::debugging_options].add_options()
21,300✔
540
            ("hpx:dump-config-initial", "print the initial runtime configuration")
541
            ("hpx:dump-config", "print the final runtime configuration")
542
            // enable debug output from command line handling
543
            ("hpx:debug-clp", "debug command line processing")
544
#if defined(_POSIX_VERSION) || defined(HPX_WINDOWS)
545
            ("hpx:attach-debugger",
546
                value<std::string>()->implicit_value("startup"),
4,260✔
547
                "wait for a debugger to be attached, possible values: "
548
                "off, startup, exception or test-failure (default: startup)")
549
#endif
550
            ("hpx:debug-hpx-log", value<std::string>()->implicit_value("cout"),
4,260✔
551
                "enable all messages on the HPX log channel and send all "
552
                "HPX logs to the target destination")
553
            ("hpx:debug-timing-log", value<std::string>()->implicit_value("cout"),
4,260✔
554
                "enable all messages on the timing log channel and send all "
555
                "timing logs to the target destination")
556
            ("hpx:debug-app-log", value<std::string>()->implicit_value("cout"),
4,260✔
557
                "enable all messages on the application log channel and send all "
558
                "application logs to the target destination")
559
        ;
560

561
        all_options[options_type::hidden_options].add_options()
4,260✔
562
            ("hpx:ignore", "this option will be silently ignored")
563
        ;
564
        // clang-format on
565

566
        return all_options;
4,260✔
567
    }
4,260✔
568

569
    void compose_all_options(
4,260✔
570
        hpx::program_options::options_description const& app_options,
571
        options_map& all_options)
572
    {
573
        // construct the overall options description and parse the command line
574
        all_options.emplace(options_type::desc_cmdline,
4,260✔
575
            "All HPX options allowed on the command line");
576

577
        all_options[options_type::desc_cmdline]
4,260✔
578
            .add(app_options)
4,260✔
579
            .add(all_options[options_type::commandline_options])
4,260✔
580
            .add(all_options[options_type::hpx_options])
4,260✔
581
            .add(all_options[options_type::config_options])
4,260✔
582
            .add(all_options[options_type::debugging_options])
4,260✔
583
            .add(all_options[options_type::hidden_options]);
4,260✔
584

585
        all_options.emplace(options_type::desc_cfgfile,
4,260✔
586
            "All HPX options allowed in configuration files");
587

588
        all_options[options_type::desc_cfgfile]
4,260✔
589
            .add(app_options)
4,260✔
590
            .add(all_options[options_type::hpx_options])
4,260✔
591
            .add(all_options[options_type::config_options])
4,260✔
592
            .add(all_options[options_type::debugging_options])
4,260✔
593
            .add(all_options[options_type::hidden_options]);
4,260✔
594
    }
4,260✔
595

596
    bool parse_commandline(util::section const& rtcfg,
2,468✔
597
        hpx::program_options::options_description const& app_options,
598
        std::string const& arg0, std::vector<std::string> const& args,
599
        hpx::program_options::variables_map& vm,
600
        util::commandline_error_mode error_mode,
601
        hpx::program_options::options_description* visible,
602
        std::vector<std::string>* unregistered_options)
603
    {
604
        try
605
        {
606
            options_map all_options = compose_local_options();
2,468✔
607

608
            compose_all_options(app_options, all_options);
2,468✔
609

610
            bool result = parse_commandline(rtcfg, all_options, app_options,
4,936✔
611
                args, vm, error_mode, visible, unregistered_options);
2,468✔
612

613
            handle_generic_config_options(arg0, vm,
2,468✔
614
                all_options[options_type::desc_cfgfile], rtcfg, error_mode);
2,468✔
615
            handle_config_options(
2,468✔
616
                vm, all_options[options_type::desc_cfgfile], rtcfg, error_mode);
2,468✔
617

618
            return result;
2,468✔
619
        }
2,468✔
620
        catch (std::exception const& e)
621
        {
622
            if (as_bool(error_mode &
×
623
                    util::commandline_error_mode::rethrow_on_error))
624
                throw;
×
625

626
            std::cerr << "hpx::init: exception caught: " << e.what()
×
627
                      << std::endl;
×
628
        }
×
629
        return false;
×
630
    }
2,468✔
631

632
    ///////////////////////////////////////////////////////////////////////////
633
    namespace detail {
634

635
        std::string extract_arg0(std::string const& cmdline)
1,222✔
636
        {
637
            std::string::size_type p = cmdline.find_first_of(" \t");
1,222✔
638
            if (p != std::string::npos)
1,222✔
639
            {
640
                return cmdline.substr(0, p);
1,222✔
641
            }
642
            return cmdline;
×
643
        }
1,222✔
644
    }    // namespace detail
645

646
    bool parse_commandline(util::section const& rtcfg,
1,222✔
647
        hpx::program_options::options_description const& app_options,
648
        std::string const& cmdline, hpx::program_options::variables_map& vm,
649
        util::commandline_error_mode error_mode,
650
        hpx::program_options::options_description* visible,
651
        std::vector<std::string>* unregistered_options)
652
    {
653
        using namespace hpx::program_options;
654
#if defined(HPX_WINDOWS)
655
        std::vector<std::string> args = split_winmain(cmdline);
656
#else
657
        std::vector<std::string> args = split_unix(cmdline);
1,222✔
658
#endif
659
        return parse_commandline(rtcfg, app_options,
1,222✔
660
            detail::extract_arg0(cmdline), args, vm, error_mode, visible,
1,222✔
661
            unregistered_options);
1,222✔
662
    }
1,222✔
663

664
    ///////////////////////////////////////////////////////////////////////////
665
    std::string embed_in_quotes(std::string const& s)
4,261✔
666
    {
667
        char quote = (s.find_first_of('"') != std::string::npos) ? '\'' : '"';
4,261✔
668

669
        if (s.find_first_of("\t ") != std::string::npos)
4,261✔
670
            return quote + s + quote;
×
671
        return s;
4,261✔
672
    }
4,261✔
673

674
    void add_as_option(
4,361✔
675
        std::string& command_line, std::string const& k, std::string const& v)
676
    {
677
        command_line += "--" + k;
4,361✔
678
        if (!v.empty())
4,361✔
679
            command_line += "=" + v;
3,132✔
680
    }
4,361✔
681

682
    std::string reconstruct_command_line(
1,221✔
683
        hpx::program_options::variables_map const& vm)
684
    {
685
        std::string command_line;
1,221✔
686
        for (auto const& v : vm)
6,355✔
687
        {
688
            hpx::program_options::any const& value = v.second.value();
5,134✔
689
            if (hpx::program_options::any_cast<std::string>(&value))
5,134✔
690
            {
691
                add_as_option(command_line, v.first,
7,346✔
692
                    embed_in_quotes(v.second.as<std::string>()));
3,673✔
693
                if (!command_line.empty())
3,673✔
694
                    command_line += " ";
3,673✔
695
            }
3,673✔
696
            else if (hpx::program_options::any_cast<double>(&value))
1,461✔
697
            {
698
                add_as_option(command_line, v.first,
102✔
699
                    std::to_string(v.second.as<double>()));
51✔
700
                if (!command_line.empty())
51✔
701
                    command_line += " ";
51✔
702
            }
51✔
703
            else if (hpx::program_options::any_cast<int>(&value))
1,410✔
704
            {
705
                add_as_option(
49✔
706
                    command_line, v.first, std::to_string(v.second.as<int>()));
49✔
707
                if (!command_line.empty())
49✔
708
                    command_line += " ";
49✔
709
            }
49✔
710
            else if (hpx::program_options::any_cast<std::vector<std::string>>(
1,361✔
711
                         &value))
1,361✔
712
            {
713
                auto const& vec = v.second.as<std::vector<std::string>>();
294✔
714
                for (std::string const& e : vec)
882✔
715
                {
716
                    add_as_option(command_line, v.first, embed_in_quotes(e));
588✔
717
                    if (!command_line.empty())
588✔
718
                        command_line += " ";
588✔
719
                }
720
            }
294✔
721
        }
722
        return command_line;
1,221✔
723
    }
1,221✔
724
}}}    // namespace hpx::local::detail
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc