rippled
Loading...
Searching...
No Matches
BasicConfig.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/BasicConfig.h>
21#include <xrpl/basics/StringUtilities.h>
22
23#include <boost/regex/v5/regbase.hpp>
24#include <boost/regex/v5/regex.hpp>
25#include <boost/regex/v5/regex_fwd.hpp>
26#include <boost/regex/v5/regex_match.hpp>
27
28#include <ostream>
29#include <string>
30#include <tuple>
31#include <utility>
32#include <vector>
33
34namespace ripple {
35
36Section::Section(std::string const& name) : name_(name)
37{
38}
39
40void
41Section::set(std::string const& key, std::string const& value)
42{
43 lookup_.insert_or_assign(key, value);
44}
45
46void
48{
49 // <key> '=' <value>
50 static boost::regex const re1(
51 "^" // start of line
52 "(?:\\s*)" // whitespace (optonal)
53 "([a-zA-Z][_a-zA-Z0-9]*)" // <key>
54 "(?:\\s*)" // whitespace (optional)
55 "(?:=)" // '='
56 "(?:\\s*)" // whitespace (optional)
57 "(.*\\S+)" // <value>
58 "(?:\\s*)" // whitespace (optional)
59 ,
60 boost::regex_constants::optimize);
61
63 for (auto line : lines)
64 {
65 auto remove_comment = [](std::string& val) -> bool {
66 bool removed_trailing = false;
67 auto comment = val.find('#');
68 while (comment != std::string::npos)
69 {
70 if (comment == 0)
71 {
72 // entire value is a comment. In most cases, this
73 // would have already been handled by the file reader
74 val = "";
75 break;
76 }
77 else if (val.at(comment - 1) == '\\')
78 {
79 // we have an escaped comment char. Erase the escape char
80 // and keep looking
81 val.erase(comment - 1, 1);
82 }
83 else
84 {
85 // this must be a real comment. Extract the value
86 // as a substring and stop looking.
87 val = trim_whitespace(val.substr(0, comment));
88 removed_trailing = true;
89 break;
90 }
91
92 comment = val.find('#', comment);
93 }
94 return removed_trailing;
95 };
96
97 if (remove_comment(line) && !line.empty())
99
100 if (line.empty())
101 continue;
102
103 boost::smatch match;
104 if (boost::regex_match(line, match, re1))
105 set(match[1], match[2]);
106 else
107 values_.push_back(line);
108
109 lines_.push_back(std::move(line));
110 }
111}
112
113bool
114Section::exists(std::string const& name) const
115{
116 return lookup_.contains(name);
117}
118
120operator<<(std::ostream& os, Section const& section)
121{
122 for (auto const& [k, v] : section.lookup_)
123 os << k << "=" << v << "\n";
124 return os;
125}
126
127//------------------------------------------------------------------------------
128
129bool
131{
132 return map_.contains(name);
133}
134
135Section&
137{
138 return map_.emplace(name, name).first->second;
139}
140
141Section const&
143{
144 static Section none("");
145 auto const iter = map_.find(name);
146 if (iter == map_.end())
147 return none;
148 return iter->second;
149}
150
151void
153 std::string const& section,
154 std::string const& key,
155 std::string const& value)
156{
157 auto const result = map_.emplace(
161 result.first->second.set(key, value);
162}
163
164void
166{
167 auto i = map_.find(section);
168 if (i != map_.end())
169 i->second = Section(section);
170}
171
172void
174{
175 map_.emplace(section, section).first->second.legacy(std::move(value));
176}
177
179BasicConfig::legacy(std::string const& sectionName) const
180{
181 return section(sectionName).legacy();
182}
183
184void
186{
187 for (auto const& entry : ifs)
188 {
189 auto const result = map_.emplace(
191 std::make_tuple(entry.first),
192 std::make_tuple(entry.first));
193 result.first->second.append(entry.second);
194 }
195}
196
199{
200 for (auto const& [k, v] : c.map_)
201 ss << "[" << k << "]\n" << v;
202 return ss;
203}
204
205} // namespace ripple
Holds unparsed configuration information.
bool exists(std::string const &name) const
Returns true if a section with the given name exists.
void deprecatedClearSection(std::string const &section)
Remove all the key/value pairs from the section.
Section & section(std::string const &name)
Returns the section with the given name.
void build(IniFileSections const &ifs)
std::unordered_map< std::string, Section > map_
void overwrite(std::string const &section, std::string const &key, std::string const &value)
Overwrite a key/value pair with a command line argument If the section does not exist it is created.
void legacy(std::string const &section, std::string value)
Set a value that is not a key/value pair.
Holds a collection of configuration values.
Definition BasicConfig.h:45
std::string const & name() const
Returns the name of this section.
Definition BasicConfig.h:61
void set(std::string const &key, std::string const &value)
Set a key/value pair.
std::vector< std::string > lines_
Definition BasicConfig.h:49
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition BasicConfig.h:70
void legacy(std::string value)
Set the legacy value for this section.
Definition BasicConfig.h:88
bool exists(std::string const &name) const
Returns true if a key with the given name exists.
bool had_trailing_comments_
Definition BasicConfig.h:51
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
Section(std::string const &name="")
Create an empty section.
std::unordered_map< std::string, std::string > lookup_
Definition BasicConfig.h:48
std::vector< std::string > values_
Definition BasicConfig.h:50
T contains(T... args)
T find(T... args)
T insert_or_assign(T... args)
T make_tuple(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
std::string trim_whitespace(std::string str)
std::ostream & operator<<(std::ostream &out, base_uint< Bits, Tag > const &u)
Definition base_uint.h:647
T piecewise_construct
T push_back(T... args)
T reserve(T... args)
T size(T... args)