• 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

74.38
/libs/core/program_options/include/hpx/program_options/errors.hpp
1
// Copyright Vladimir Prus 2002-2004.
2
//  SPDX-License-Identifier: BSL-1.0
3
// Distributed under the Boost Software License, Version 1.0.
4
// (See accompanying file LICENSE_1_0.txt
5
// or copy at http://www.boost.org/LICENSE_1_0.txt)
6

7
#pragma once
8

9
#include <hpx/program_options/config.hpp>
10

11
#include <map>
12
#include <stdexcept>
13
#include <string>
14
#include <utility>
15
#include <vector>
16

17
#include <hpx/config/warnings_prefix.hpp>
18

19
namespace hpx::program_options {
20

21
    /** Base class for all errors in the library. */
22
    class HPX_ALWAYS_EXPORT error : public std::logic_error
38✔
23
    {
24
    public:
25
        explicit error(std::string const& xwhat)
38✔
26
          : std::logic_error(xwhat)
38✔
27
        {
76✔
28
        }
38✔
29
    };
30

31
    /** Class thrown when there are too many positional options.
32
        This is a programming error.
33
    */
34
    class HPX_ALWAYS_EXPORT too_many_positional_options_error : public error
1✔
35
    {
36
    public:
37
        too_many_positional_options_error()
1✔
38
          : error("too many positional options have been specified on the "
1✔
39
                  "command line")
40
        {
2✔
41
        }
1✔
42
    };
43

44
    /** Class thrown when there are programming error related to style */
45
    class HPX_ALWAYS_EXPORT invalid_command_line_style : public error
×
46
    {
47
    public:
48
        explicit invalid_command_line_style(std::string const& msg)
×
49
          : error(msg)
×
50
        {
×
51
        }
×
52
    };
53

54
    /** Class thrown if config file can not be read */
55
    class HPX_ALWAYS_EXPORT reading_file : public error
×
56
    {
57
    public:
58
        explicit reading_file(char const* filename)
×
59
          : error(std::string("can not read options configuration file '")
×
60
                      .append(filename)
×
61
                      .append("'"))
×
62
        {
×
63
        }
×
64
    };
65

66
    /** Base class for most exceptions in the library.
67
     *
68
     *  Substitutes the values for the parameter name
69
     *      placeholders in the template to create the human
70
     *      readable error message
71
     *
72
     *  Placeholders are surrounded by % signs: %example%
73
     *      Poor man's version of boost::format
74
     *
75
     *  If a parameter name is absent, perform default substitutions
76
     *      instead so ugly placeholders are never left in-place.
77
     *
78
     *  Options are displayed in "canonical" form
79
     *      This is the most unambiguous form of the
80
     *      *parsed* option name and would correspond to
81
     *      option_description::format_name()
82
     *      i.e. what is shown by print_usage()
83
     *
84
     *  The "canonical" form depends on whether the option is
85
     *      specified in short or long form, using dashes or slashes
86
     *      or without a prefix (from a configuration file)
87
     *
88
     *   */
89
    class HPX_ALWAYS_EXPORT error_with_option_name : public error
37✔
90
    {
91
    protected:
92
        /** can be
93
         *      0 = no prefix (config file options)
94
         *      allow_long
95
         *      allow_dash_for_short
96
         *      allow_slash_for_short
97
         *      allow_long_disguise */
98
        int m_option_style;
99

100
        /** substitutions
101
         *  from placeholders to values */
102
        std::map<std::string, std::string> m_substitutions;
103
        using string_pair = std::pair<std::string, std::string>;
104
        std::map<std::string, string_pair> m_substitution_defaults;
105

106
    public:
107
        /** template with placeholders */
108
        std::string m_error_template;
109

110
        explicit error_with_option_name(std::string const& template_,
111
            std::string const& option_name = "",
112
            std::string const& original_token = "", int option_style = 0);
113

114
        /** Substitute
115
         *      parameter_name->value to create the error message from
116
         *      the error template */
117
        void set_substitute(
54✔
118
            std::string const& parameter_name, std::string const& value)
119
        {
120
            m_substitutions[parameter_name] = value;
54✔
121
        }
54✔
122

123
        /** If the parameter is missing, then make the
124
         *      from->to substitution instead */
125
        void set_substitute_default(std::string const& parameter_name,
111✔
126
            std::string const& from, std::string const& to)
127
        {
128
            m_substitution_defaults[parameter_name] = std::make_pair(from, to);
111✔
129
        }
111✔
130

131
        /** Add context to an exception */
132
        void add_context(std::string const& option_name,
35✔
133
            std::string const& original_token, int option_style)
134
        {
135
            set_option_name(option_name);
35✔
136
            set_original_token(original_token);
35✔
137
            set_prefix(option_style);
35✔
138
        }
35✔
139

140
        void set_prefix(int option_style) noexcept
35✔
141
        {
142
            m_option_style = option_style;
35✔
143
        }
35✔
144

145
        /** Overridden in error_with_no_option_name */
146
        virtual void set_option_name(std::string const& option_name)
18✔
147
        {
148
            set_substitute("option", option_name);
18✔
149
        }
18✔
150

151
        std::string get_option_name() const
9✔
152
        {
153
            return get_canonical_option_name();
9✔
154
        }
155

156
        void set_original_token(std::string const& original_token)
35✔
157
        {
158
            set_substitute("original_token", original_token);
35✔
159
        }
35✔
160

161
        /** Creates the error_message on the fly
162
         *      Currently a thin wrapper for substitute_placeholders() */
163
        char const* what() const noexcept override;
164

165
    protected:
166
        /** Used to hold the error text returned by what() */
167
        mutable std::string m_message;    // For on-demand formatting in 'what'
168

169
        /** Makes all substitutions using the template */
170
        virtual void substitute_placeholders(
171
            std::string const& error_template) const;
172

173
        // helper function for substitute_placeholders
174
        void replace_token(
175
            std::string const& from, std::string const& to) const;
176

177
        /** Construct option name in accordance with the appropriate
178
         *  prefix style: i.e. long dash or short slash etc */
179
        std::string get_canonical_option_name() const;
180
        std::string get_canonical_option_prefix() const;
181
    };
182

183
    /** Class thrown when there are several option values, but
184
        user called a method which cannot return them all. */
185
    class HPX_ALWAYS_EXPORT multiple_values : public error_with_option_name
×
186
    {
187
    public:
188
        multiple_values()
×
189
          : error_with_option_name(
×
190
                "option '%canonical_option%' only takes a single argument")
×
191
        {
×
192
        }
×
193
    };
194

195
    /** Class thrown when there are several occurrences of an
196
        option, but user called a method which cannot return
197
        them all. */
198
    class HPX_ALWAYS_EXPORT multiple_occurrences : public error_with_option_name
4✔
199
    {
200
    public:
201
        multiple_occurrences()
4✔
202
          : error_with_option_name("option '%canonical_option%' cannot be "
4✔
203
                                   "specified more than once")
204
        {
8✔
205
        }
4✔
206
    };
207

208
    /** Class thrown when a required/mandatory option is missing */
209
    class HPX_ALWAYS_EXPORT required_option : public error_with_option_name
1✔
210
    {
211
    public:
212
        // option name is constructed by the option_descriptor and never on the fly
213
        explicit required_option(std::string const& option_name)
1✔
214
          : error_with_option_name(
1✔
215
                "the option '%canonical_option%' is required but missing", "",
1✔
216
                option_name)
1✔
217
        {
2✔
218
        }
1✔
219
    };
220

221
    /** Base class of un-parsable options,
222
     *  when the desired option cannot be identified.
223
     *
224
     *
225
     *  It makes no sense to have an option name, when we can't match an option to the
226
     *      parameter
227
     *
228
     *  Having this a part of the error_with_option_name hierarchy makes error
229
     *      handling a lot easier, even if the name indicates some sort of
230
     *      conceptual dissonance!
231
     *
232
     *   */
233
    class HPX_ALWAYS_EXPORT error_with_no_option_name
17✔
234
      : public error_with_option_name
235
    {
236
    public:
237
        explicit error_with_no_option_name(std::string const& template_,
17✔
238
            std::string const& original_token = "")
239
          : error_with_option_name(template_, "", original_token)
17✔
240
        {
34✔
241
        }
17✔
242

243
        /** Does NOT set option name, because no option name makes sense */
244
        void set_option_name(std::string const&) override {}
17✔
245
    };
246

247
    /** Class thrown when option name is not recognized. */
248
    class HPX_ALWAYS_EXPORT unknown_option : public error_with_no_option_name
10✔
249
    {
250
    public:
251
        explicit unknown_option(std::string const& original_token = "")
10✔
252
          : error_with_no_option_name(
10✔
253
                "unrecognised option '%canonical_option%'", original_token)
10✔
254
        {
20✔
255
        }
10✔
256
    };
257

258
    /** Class thrown when there's ambiguity among several possible options. */
259
    class HPX_ALWAYS_EXPORT ambiguous_option : public error_with_no_option_name
7✔
260
    {
261
    public:
262
        explicit ambiguous_option(std::vector<std::string> const& xalternatives)
7✔
263
          : error_with_no_option_name(
7✔
264
                "option '%canonical_option%' is ambiguous")
7✔
265
          , m_alternatives(xalternatives)
7✔
266
        {
14✔
267
        }
7✔
268

269
        std::vector<std::string> const& alternatives() const noexcept
9✔
270
        {
271
            return m_alternatives;
9✔
272
        }
273

274
    protected:
275
        /** Makes all substitutions using the template */
276
        void substitute_placeholders(
277
            std::string const& error_template) const override;
278

279
    private:
280
        // TODO: copy ctor might throw
281
        std::vector<std::string> m_alternatives;
282
    };
283

284
    /** Class thrown when there's syntax error either for command
285
     *  line or config file options. See derived children for
286
     *  concrete classes. */
287
    class HPX_ALWAYS_EXPORT invalid_syntax : public error_with_option_name
13✔
288
    {
289
    public:
290
        enum kind_t
291
        {
292
            long_not_allowed = 30,
293
            long_adjacent_not_allowed,
294
            short_adjacent_not_allowed,
295
            empty_adjacent_parameter,
296
            missing_parameter,
297
            extra_parameter,
298
            unrecognized_line
299
        };
300

301
        explicit invalid_syntax(kind_t kind,
13✔
302
            std::string const& option_name = "",
303
            std::string const& original_token = "", int option_style = 0)
304
          : error_with_option_name(
13✔
305
                get_template(kind), option_name, original_token, option_style)
13✔
306
          , m_kind(kind)
13✔
307
        {
13✔
308
        }
13✔
309

310
        constexpr kind_t kind() const noexcept
13✔
311
        {
312
            return m_kind;
13✔
313
        }
314

315
        /** Convenience functions for backwards compatibility */
316
        virtual std::string tokens() const
1✔
317
        {
318
            return get_option_name();
1✔
319
        }
320

321
    protected:
322
        /** Used to convert kind_t to a related error text */
323
        std::string get_template(kind_t kind);
324
        kind_t m_kind;
325
    };
326

327
    class HPX_ALWAYS_EXPORT invalid_config_file_syntax : public invalid_syntax
×
328
    {
329
    public:
330
        invalid_config_file_syntax(std::string const& invalid_line, kind_t kind)
×
331
          : invalid_syntax(kind)
×
332
        {
×
333
            m_substitutions["invalid_line"] = invalid_line;
×
334
        }
×
335

336
        /** Convenience functions for backwards compatibility */
337
        std::string tokens() const override
×
338
        {
339
            auto it = m_substitutions.find("invalid_line");
×
340
            if (it != m_substitutions.end())
×
341
            {
342
                return it->second;
×
343
            }
344
            return "<unknown>";
×
345
        }
×
346
    };
347

348
    /** Class thrown when there are syntax errors in given command line */
349
    class HPX_ALWAYS_EXPORT invalid_command_line_syntax : public invalid_syntax
13✔
350
    {
351
    public:
352
        explicit invalid_command_line_syntax(kind_t kind,
13✔
353
            std::string const& option_name = "",
354
            std::string const& original_token = "", int option_style = 0)
355
          : invalid_syntax(kind, option_name, original_token, option_style)
13✔
356
        {
26✔
357
        }
13✔
358
    };
359

360
    /** Class thrown when value of option is incorrect. */
361
    class HPX_ALWAYS_EXPORT validation_error : public error_with_option_name
2✔
362
    {
363
    public:
364
        enum kind_t
365
        {
366
            multiple_values_not_allowed = 30,
367
            at_least_one_value_required,
368
            invalid_bool_value,
369
            invalid_option_value,
370
            invalid_option
371
        };
372

373
    public:
374
        explicit validation_error(kind_t kind,
2✔
375
            std::string const& option_name = "",
376
            std::string const& original_token = "", int option_style = 0)
377
          : error_with_option_name(
2✔
378
                get_template(kind), option_name, original_token, option_style)
2✔
379
          , m_kind(kind)
2✔
380
        {
2✔
381
        }
2✔
382

383
        constexpr kind_t kind() const noexcept
384
        {
385
            return m_kind;
386
        }
387

388
    protected:
389
        /** Used to convert kind_t to a related error text */
390
        std::string get_template(kind_t kind);
391
        kind_t m_kind;
392
    };
393

394
    /** Class thrown if there is an invalid option value given */
395
    class HPX_ALWAYS_EXPORT invalid_option_value : public validation_error
1✔
396
    {
397
    public:
398
        explicit invalid_option_value(std::string const& value);
399
        explicit invalid_option_value(std::wstring const& value);
400
    };
401

402
    /** Class thrown if there is an invalid bool value given */
403
    class HPX_ALWAYS_EXPORT invalid_bool_value : public validation_error
×
404
    {
405
    public:
406
        explicit invalid_bool_value(std::string const& value);
407
    };
408
}    // namespace hpx::program_options
409

410
#include <hpx/config/warnings_suffix.hpp>
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

© 2026 Coveralls, Inc