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

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

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

0.0
/libs/core/program_options/src/config_file.cpp
1
//  Copyright Vladimir Prus 2002-2004.
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/program_options/config.hpp>
8
#include <hpx/assert.hpp>
9
#include <hpx/program_options/detail/config_file.hpp>
10
#include <hpx/program_options/detail/convert.hpp>
11
#include <hpx/program_options/errors.hpp>
12

13
#include <fstream>
14
#include <set>
15
#include <string>
16

17
namespace hpx::program_options::detail {
18

19
    common_config_file_iterator::common_config_file_iterator(
×
20
        std::set<std::string> const& allowed_options, bool allow_unregistered)
×
21
      : allowed_options(allowed_options)
22
      , m_allow_unregistered(allow_unregistered)
×
23
    {
24
        for (auto const& allowed_option : allowed_options)
×
25
        {
26
            add_option(allowed_option.c_str());
×
27
        }
28
    }
×
29

30
    void common_config_file_iterator::add_option(char const* name)
×
31
    {
32
        std::string s(name);
×
33
        HPX_ASSERT(!s.empty());
34
        if (*s.rbegin() == '*')
×
35
        {
36
            s.resize(s.size() - 1);
×
37
            bool bad_prefixes(false);
38

39
            // If 's' is a prefix of one of allowed suffix, then
40
            // lower_bound will return that element.
41
            // If some element is prefix of 's', then lower_bound will
42
            // return the next element.
43
            auto i = allowed_prefixes.lower_bound(s);
44
            if (i != allowed_prefixes.end())
×
45
            {
46
                if (i->find(s) == 0)
×
47
                    bad_prefixes = true;
48
            }
49
            if (i != allowed_prefixes.begin())
×
50
            {
51
                --i;
52
                if (s.find(*i) == 0)
×
53
                    bad_prefixes = true;
54
            }
55
            if (bad_prefixes)
×
56
            {
57
                throw error("options '" + std::string(name) + "' and '" + *i +
×
58
                    "*' will both match the same arguments from the "
59
                    "configuration file");
×
60
            }
61
            allowed_prefixes.insert(s);
62
        }
63
    }
×
64

65
    namespace {
66

67
        std::string trim_ws(std::string const& s)
×
68
        {
69
            std::string::size_type const n = s.find_first_not_of(" \t\r\n");
70
            if (n == std::string::npos)
×
71
                return std::string();
72

73
            std::string::size_type const n2 = s.find_last_not_of(" \t\r\n");
74
            return s.substr(n, n2 - n + 1);
×
75
        }
76
    }    // namespace
77

78
    void common_config_file_iterator::get()
×
79
    {
80
        std::string s;
81
        bool found = false;
82

83
        while (this->getline(s))
84
        {
×
85
            // strip '#' comments and whitespace
86
            std::string::size_type n = s.find('#');
87
            if (n != std::string::npos)
×
88
                s = s.substr(0, n);
×
89
            s = trim_ws(s);
×
90

91
            if (!s.empty())
×
92
            {
93
                // Handle section name
94
                if (*s.begin() == '[' && *s.rbegin() == ']')
×
95
                {
96
                    m_prefix = s.substr(1, s.size() - 2);
×
97
                    if (*m_prefix.rbegin() != '.')
×
98
                        m_prefix += '.';
99
                }
100
                // NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
×
101
                else if ((n = s.find('=')) != std::string::npos)
102
                {
×
103
                    std::string name = m_prefix + trim_ws(s.substr(0, n));
×
104
                    std::string value = trim_ws(s.substr(n + 1));
105

×
106
                    bool const registered = allowed_option(name);
×
107
                    if (!registered && !m_allow_unregistered)
×
108
                        throw unknown_option(name);
109

110
                    found = true;
111

112
                    auto& v = this->value();
×
113
                    v.string_key = name;
×
114
                    v.value.clear();
×
115
                    v.value.push_back(value);
×
116
                    v.unregistered = !registered;
×
117
                    v.original_tokens.clear();
118
                    v.original_tokens.push_back(HPX_MOVE(name));
119
                    v.original_tokens.push_back(HPX_MOVE(value));
120
                    break;
121
                }
122
                else
123
                {
×
124
                    throw invalid_config_file_syntax(
×
125
                        s, invalid_syntax::unrecognized_line);
126
                }
127
            }
128
        }
129
        if (!found)
130
            found_eof();
×
131
    }
132

×
133
    bool common_config_file_iterator::allowed_option(std::string const& s) const
134
    {
135
        std::set<std::string>::const_iterator i = allowed_options.find(s);
×
136
        if (i != allowed_options.end())
137
            return true;
138
        // If s is "pa" where "p" is allowed prefix then
139
        // lower_bound should find the element after "p".
140
        // This depends on 'allowed_prefixes' invariant.
141
        i = allowed_prefixes.lower_bound(s);
×
142
        // NOLINTNEXTLINE(bugprone-inc-dec-in-conditions)
143
        if (i != allowed_prefixes.begin() && s.find(*--i) == 0)
144
            return true;
145
        return false;
146
    }
147

148
#if defined(__COMO_VERSION__) && __COMO_VERSION__ >= 4303 ||                   \
149
    (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION >= 741)
150
    template <>
151
    bool basic_config_file_iterator<wchar_t>::getline(std::string& s)
152
    {
153
        std::wstring ws;
154

155
        // On Comeau, using two-argument version causes call to some internal
156
        // function with std::wstring, and '\n' (not L'\n') and compile can't
157
        // resolve that call.
158

159
        if (std::getline(*is, ws, L'\n'))
160
        {
161
            s = to_utf8(ws);
162
            return true;
163
        }
164
        else
165
        {
166
            return false;
167
        }
168
    }
169
#endif
170
}    // namespace hpx::program_options::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