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