PrintAllowedConfiguration.cc
Go to the documentation of this file.
4 #include "cetlib/trim.h"
10 
11 #include <regex>
12 
13 using namespace fhicl::detail;
14 
15 namespace {
16 
17  std::regex const reNewLine{"\n"};
18 
19  inline bool
21  {
22  auto pos = k.find_last_of("]");
23  return pos != std::string::npos && pos == k.size() - 1;
24  }
25 
26  struct maybeName {
27 
28  maybeName(ParameterBase const& p, std::string const& ind)
29  : is_seq_elem{is_sequence_element(p.key())}, name{p.name()}, indent{ind}
30  {}
31 
32  bool is_seq_elem;
35  };
36 
37  std::ostream&
38  operator<<(std::ostream& os, maybeName&& mn)
39  {
40  if (!mn.is_seq_elem) {
41  os << mn.indent << mn.name << ": ";
42  } else {
43  os << mn.indent;
44  }
45  return os;
46  }
47 
49  suffix(std::unordered_set<std::string>& keysWithCommas_,
50  std::unordered_set<std::string>& keysWithEllipses_,
51  std::string const& key,
52  std::string const& indent)
53  {
55  if (cet::search_all(keysWithCommas_, key)) {
56  keysWithCommas_.erase(key);
57  result += ",";
58  }
59  if (cet::search_all(keysWithEllipses_, key)) {
60  keysWithEllipses_.erase(key);
61  result.append("\n").append(indent).append("...");
62  }
63  return result;
64  }
65 
67  non_whitespace(std::string const& s, std::size_t const sz)
68  {
69 
70  // To support denoting optional tables, we sometimes print an
71  // indentation string that has only one character in it. But we
72  // don't want to print any extra whitespace. So we remove it
73  // here.
74  //
75  // We also ignore indents if the size is one -- i.e. the current
76  // state of the indent stack does not include any nested
77  // parameters, so there's no reason to include any prefixes that
78  // might be on the lowest-level indent (corresponding to sz == 1).
79 
80  return sz > 1 ? cet::trim_right_copy(s, " ") : "";
81  }
82 
83  auto
84  string_repeat(std::size_t const n, std::string const& s)
85  {
87  for (std::size_t i{}; i != n; ++i)
88  result += s;
89  return result;
90  }
91 }
92 
93 using namespace fhicl::detail;
94 
95 //======================================================================
96 
98  bool const showParents,
99  std::string const& prefix,
100  bool const stlf)
101  : buffer_{os}
102  , indent_{prefix}
104  , showParentsForFirstParam_{showParents}
105 {}
106 
107 bool
109 {
110 
113 
114  if (!suppressFormat(p)) {
115 
116  if (p.is_conditional()) {
117  buffer_ << '\n';
118  indent_.modify_top("┌" + string_repeat(30, "─"));
119  buffer_ << non_whitespace(indent_(), indent_.size()) << '\n';
120  indent_.modify_top("│ ");
121  }
122 
123  if (!p.comment().empty()) {
124  if (!p.is_conditional())
125  buffer_ << non_whitespace(indent_(), indent_.size()) << '\n';
126  for (auto const& line : cet::split_by_regex(p.comment(), reNewLine))
127  buffer_ << indent_() << "## " << line << '\n';
128  }
129  }
130 
131  if (!is_sequence_element(p.key())) {
132  buffer_ << non_whitespace(indent_(), indent_.size()) << '\n';
133 
134  // In general, optional parameters cannot be template arguments to
135  // sequences. However, the implementation for 'TupleAs' uses
136  // OptionalTuple<...> as the holding type of the sequence
137  // elements. In the case where we have Sequence< TupleAs<> >, the
138  // TupleAs entries will be prefaced with '#', and we don't want
139  // that. Therefore, we modify the top indentation fragment only
140  // if the parameter is not a sequence element.
141 
142  if (p.is_optional()) {
143  if (p.is_conditional())
144  indent_.modify_top("│# ");
145  else
146  indent_.modify_top(" # ");
147  }
148  }
149 
152 
153  buffer_ << mps_.top().parent_names();
154 
155  return true;
156 }
157 
158 void
160 {
161  buffer_ << suffix(keysWithCommas_, keysWithEllipses_, p.key(), indent_());
162 
163  if (p.has_default() && p.parameter_type() == par_type::ATOM)
164  buffer_ << " # default";
165 
166  if (!suppressFormat(p)) {
167  if (p.is_conditional()) {
168  indent_.modify_top("└" + string_repeat(30, "─"));
169  buffer_ << '\n' << indent_();
170  indent_.modify_top(std::string(3, ' '));
171  } else if (p.is_optional()) {
172  indent_.modify_top(std::string(3, ' '));
173  }
174  }
175 
177  buffer_ << '\n' << mps_.top().closing_braces();
178  mps_.pop();
179 }
180 
181 //======================================================================
182 
183 void
185 {
186  buffer_ << maybeName{t, indent_()} << "{\n";
187  indent_.push();
188 }
189 
190 void
192 {
193  indent_.pop();
194  buffer_ << indent_() << "}";
195 }
196 
197 //======================================================================
198 
199 void
201 {
202  buffer_ << maybeName{s, indent_()} << "[\n";
203 
204  indent_.push();
205 
206  if (s.empty())
207  return;
208 
209  // We want the printout to look like this for sequences with
210  // defaults:
211  //
212  // list1: [
213  // 1, # default
214  // 2 # default
215  // ]
216  //
217  // And like this for vectors w/o defaults (has length 1):
218  //
219  // list2: [
220  // <int>,
221  // ...
222  // ]
223 
224  if (s.has_default() || (s.parameter_type() != par_type::SEQ_VECTOR)) {
225  for (std::size_t i{}; i != s.size() - 1; ++i)
226  keysWithCommas_.emplace(s.key() + "[" + std::to_string(i) + "]");
227  return;
228  }
229 
230  keysWithCommas_.emplace(s.key() + "[0]");
231  keysWithEllipses_.emplace(s.key() + "[0]");
232 }
233 
234 void
236 {
237  indent_.pop();
238  buffer_ << indent_() << "]";
239 }
240 
241 //======================================================================
242 
243 void
245 {
246  buffer_ << maybeName{a, indent_()} << a.stringified_value();
247 }
248 
249 //======================================================================
250 
251 void
253 {
254  buffer_ << maybeName{dp, indent_()} << "<< delegated >>";
255 }
static QCString name
Definition: declinfo.cpp:673
bool empty() const noexcept
Definition: SequenceBase.h:28
bool is_sequence_element(std::string const &key)
std::string const & name() const
Definition: ParameterBase.h:43
std::size_t size() const noexcept
Definition: SequenceBase.h:33
static QCString result
void exit_sequence(SequenceBase const &) override
PrintAllowedConfiguration(std::ostream &os, bool const showParents=false, std::string const &prefix=std::string(3, ' '), bool const stlf=false)
std::string string
Definition: nybbler.cc:12
void after_action(ParameterBase const &) override
std::vector< std::string > split_by_regex(std::string const &str, std::regex const &reDelimSet)
std::string trim_right_copy(std::string source, std::string const &t=" ")
Definition: trim.h:54
void maybeReleaseTopLevelParameter(ParameterBase const &p)
void modify_top(std::string const &s)
Definition: Indentation.h:36
bool search_all(FwdCont const &, Datum const &)
bool before_action(ParameterBase const &) override
def key(type, name=None)
Definition: graph.py:13
std::string stringified_value() const
Definition: AtomBase.h:18
std::void_t< T > n
const double a
par_type parameter_type() const
Definition: ParameterBase.h:68
p
Definition: test.py:223
void enter_sequence(SequenceBase const &) override
std::string const & key() const
Definition: ParameterBase.h:38
void delegated_parameter(DelegateBase const &) override
void line(double t, double *p, double &x, double &y, double &z)
std::string const & comment() const
Definition: ParameterBase.h:48
void cacheTopLevelParameter(ParameterBase const &p)
std::ostream & operator<<(std::ostream &, ParameterSetID const &)
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
static QCString * s
Definition: config.cpp:1042