rippled
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 <ripple/basics/BasicConfig.h>
21 #include <ripple/basics/StringUtilities.h>
22 #include <boost/regex.hpp>
23 #include <algorithm>
24 
25 namespace ripple {
26 
28  : name_(name)
29 {
30 }
31 
32 void
33 Section::set (std::string const& key, std::string const& value)
34 {
35  auto const result = cont().emplace (key, value);
36  if (! result.second)
37  result.first->second = value;
38 }
39 
40 void
42 {
43  // <key> '=' <value>
44  static boost::regex const re1 (
45  "^" // start of line
46  "(?:\\s*)" // whitespace (optonal)
47  "([a-zA-Z][_a-zA-Z0-9]*)" // <key>
48  "(?:\\s*)" // whitespace (optional)
49  "(?:=)" // '='
50  "(?:\\s*)" // whitespace (optional)
51  "(.*\\S+)" // <value>
52  "(?:\\s*)" // whitespace (optional)
53  , boost::regex_constants::optimize
54  );
55 
57  for (auto line : lines)
58  {
59  auto remove_comment = [](std::string& val)->bool
60  {
61  bool removed_trailing = false;
62  auto comment = val.find('#');
63  while(comment != std::string::npos)
64  {
65  if (comment == 0)
66  {
67  // entire value is a comment. In most cases, this
68  // would have already been handled by the file reader
69  val = "";
70  break;
71  }
72  else if (val.at(comment-1) == '\\')
73  {
74  // we have an escaped comment char. Erase the escape char
75  // and keep looking
76  val.erase(comment-1,1);
77  }
78  else
79  {
80  // this must be a real comment. Extract the value
81  // as a substring and stop looking.
82  val = trim_whitespace(val.substr(0, comment));
83  removed_trailing = true;
84  break;
85  }
86 
87  comment = val.find('#', comment);
88  }
89  return removed_trailing;
90  };
91 
92  if (remove_comment(line) && !line.empty())
94 
95  if (line.empty())
96  continue;
97 
98  boost::smatch match;
99  if (boost::regex_match (line, match, re1))
100  set (match[1], match[2]);
101  else
102  values_.push_back (line);
103 
104  lines_.push_back (std::move(line));
105  }
106 }
107 
108 bool
109 Section::exists (std::string const& name) const
110 {
111  return cont().find (name) != cont().end();
112 }
113 
115 Section::find (std::string const& name) const
116 {
117  auto const iter = cont().find (name);
118  if (iter == cont().end())
119  return {{}, false};
120  return {iter->second, true};
121 }
122 
124 operator<< (std::ostream& os, Section const& section)
125 {
126  for (auto const& [k, v] : section.cont())
127  os << k << "=" << v << "\n";
128  return os;
129 }
130 
131 //------------------------------------------------------------------------------
132 
133 bool
134 BasicConfig::exists (std::string const& name) const
135 {
136  return map_.find(name) != map_.end();
137 }
138 
139 Section&
141 {
142  return map_[name];
143 }
144 
145 Section const&
147 {
148  static Section none("");
149  auto const iter = map_.find (name);
150  if (iter == map_.end())
151  return none;
152  return iter->second;
153 }
154 
155 void
156 BasicConfig::overwrite (std::string const& section, std::string const& key,
157  std::string const& value)
158 {
159  auto const result = map_.emplace (std::piecewise_construct,
161  result.first->second.set (key, value);
162 }
163 
164 void
166 {
167  auto i = map_.find(section);
168  if (i != map_.end())
169  i->second = Section(section);
170 }
171 
172 void
174 {
175  map_[section].legacy(std::move(value));
176 }
177 
179 BasicConfig::legacy(std::string const& sectionName) const
180 {
181  return section (sectionName).legacy ();
182 }
183 
184 void
186 {
187  for (auto const& entry : ifs)
188  {
189  auto const result = map_.emplace (std::piecewise_construct,
190  std::make_tuple(entry.first), std::make_tuple(entry.first));
191  result.first->second.append (entry.second);
192  }
193 }
194 
197 {
198  for (auto const& [k, v] : c.map_)
199  ss << "[" << k << "]\n" << v;
200  return ss;
201 }
202 
203 } // ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:43
ripple::Section::values_
std::vector< std::string > values_
Definition: BasicConfig.h:50
ripple::Section::legacy
void legacy(std::string value)
Set the legacy value for this section.
Definition: BasicConfig.h:87
std::make_tuple
T make_tuple(T... args)
std::string
STL class.
std::pair
std::vector::reserve
T reserve(T... args)
std::vector< std::string >
std::string::find
T find(T... args)
std::vector::size
T size(T... args)
ripple::CashFilter::none
@ none
ripple::Section::Section
Section(std::string const &name="")
Create an empty section.
Definition: BasicConfig.cpp:27
ripple::Section::exists
bool exists(std::string const &name) const
Returns true if a key with the given name exists.
Definition: BasicConfig.cpp:109
ripple::trim_whitespace
std::string trim_whitespace(std::string str)
ripple::operator<<
std::ostream & operator<<(std::ostream &os, TOffer< TIn, TOut > const &offer)
Definition: Offer.h:237
algorithm
ripple::Section::append
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
Definition: BasicConfig.cpp:41
std::vector::push_back
T push_back(T... args)
ripple::Section::name
std::string const & name() const
Returns the name of this section.
Definition: BasicConfig.h:60
ripple::BasicConfig::deprecatedClearSection
void deprecatedClearSection(std::string const &section)
Remove all the key/value pairs from the section.
Definition: BasicConfig.cpp:165
std::ostream
STL class.
ripple::BasicConfig::build
void build(IniFileSections const &ifs)
Definition: BasicConfig.cpp:185
ripple::BasicConfig::legacy
void legacy(std::string const &section, std::string value)
Set a value that is not a key/value pair.
Definition: BasicConfig.cpp:173
ripple::Section::lines
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition: BasicConfig.h:69
std::map
STL class.
ripple::Section::had_trailing_comments_
bool had_trailing_comments_
Definition: BasicConfig.h:51
ripple::BasicConfig::overwrite
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.
Definition: BasicConfig.cpp:156
ripple::Section::find
std::pair< std::string, bool > find(std::string const &name) const
Retrieve a key/value pair.
Definition: BasicConfig.cpp:115
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Section::set
void set(std::string const &key, std::string const &value)
Set a key/value pair.
Definition: BasicConfig.cpp:33
ripple::Section::lines_
std::vector< std::string > lines_
Definition: BasicConfig.h:49
ripple::BasicConfig::map_
std::map< std::string, Section, boost::beast::iless > map_
Definition: BasicConfig.h:180
ripple::BasicConfig
Holds unparsed configuration information.
Definition: BasicConfig.h:177
ripple::BasicConfig::exists
bool exists(std::string const &name) const
Returns true if a section with the given name exists.
Definition: BasicConfig.cpp:134
ripple::BasicConfig::section
Section & section(std::string const &name)
Returns the section with the given name.
Definition: BasicConfig.cpp:140