ATLAS Offline Software
MiniConfig.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // **********************************************************************
6 // **********************************************************************
7 
8 #include <fstream>
9 #include <iostream>
10 #include <optional>
11 #include <sstream>
12 #include <utility>
13 
14 #include "boost/algorithm/string/case_conv.hpp"
15 #include "boost/algorithm/string/trim.hpp"
16 
18 
19 
20 //Get rid of Root macros that confuse Doxygen
24 
25 
26 namespace dqi {
27 
28 // *********************************************************************
29 // Public Methods
30 // *********************************************************************
31 
33 MiniConfig()
34  : m_tree(0)
35  , m_propagateDown(true)
36 {
37 }
38 
39 
42 {
43  delete m_tree;
44 }
45 
46 
47 void
49 AddKeyword( std::string keyword_ )
50 {
51  const KeySet_t::value_type& keyval( std::move(keyword_) );
52  m_keywords.insert( keyval );
53 }
54 
55 
56 void
58 AddAttributeKeyword( std::string keyword_ )
59 {
60  const KeySet_t::value_type& keyval( std::move(keyword_) );
61  m_attKeywords.insert( keyval );
62 }
63 
64 void
66 SetAttribKeywordPropagateDown( bool propagateDown )
67 {
68  this->m_propagateDown = propagateDown;
69 }
70 
71 bool
73 ReadFile( std::string fileName )
74 {
75  bool success(true);
76 
77  delete m_tree;
78  m_tree = new MiniConfigTreeNode( "global", 0 );
81 
82  std::ifstream file( fileName.c_str() );
83  if( !file ) {
84  std::cerr << "MiniConfig::ReadFile(): "
85  << "cannot read from file: " << fileName << "\n";
86  return false;
87  }
88 
89  std::string line;
90  char c;
91  std::string key;
92  std::string id;
93  std::string sep;
94  std::string att;
95  std::string val;
96  int skipCount(0);
97  int lineNumber = 0;
98 
99  while( getline(file,line) ) {
100  ++lineNumber;
101  std::istringstream linestream(line);
102  c = 0;
103 
104  while( linestream.get(c) ) {
105  // ignore leading whitespace
106  if( !isspace(c) ) {
107  break;
108  }
109  }
110 
111  // ignore empty lines
112  if( c == 0 || isspace(c) ) {
113  continue;
114  }
115 
116  // ignore comments
117  if( c == '#' ) {
118  continue;
119  }
120 
121  linestream.putback(c);
122 
123  // check for: }
124  linestream >> sep;
125  if( !linestream ) {
126  std::cerr << "MiniConfig::ReadFile(): "
127  << "badly formatted line: \"" << line << "\", line number " << lineNumber << "\n";
128  success = false;
129  continue;
130  }
131  if( sep == "}" ) {
132  if( skipCount > 0 ) {
133  --skipCount;
134  }
135  else {
136  node = node->GetParent();
137  if( node == 0 ) {
138  std::cerr << "MiniConfig::ReadFile(): "
139  << "unmatched \"}\", line number " << lineNumber << "\n";
140  success = false;
141  node = m_tree;
142  }
143  }
144  continue;
145  }
146 
147  // check for: <att> = <val>
148  att = sep;
149  linestream >> sep;
150  if( !linestream ) {
151  std::cerr << "MiniConfig::ReadFile(): "
152  << "badly formatted line: \"" << line << "\", line number " << lineNumber << "\n";
153  success = false;
154  continue;
155  }
156  if( sep == "=" ) {
157  val = line.substr(linestream.tellg(), std::string::npos);
158  boost::trim(val);
159  //linestream >> val;
160  if( val.size() == 0 ) {
161  std::cerr << "MiniConfig::ReadFile(): "
162  << "badly formatted line: \"" << line << "\", line number " << lineNumber << "\n";
163  success = false;
164  continue;
165  }
166  if( skipCount == 0 ) {
167  node->SetAttribute( att, val, false );
168  }
169  continue;
170  }
171 
172  // check for: keyword <identifier> {
173  key = att;
174  // Don't use to_lower_copy in order to avoid gcc 13.1 bug
175  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109703
176  // (Should be fixed in 13.2.)
177  //const std::string& lokey = boost::algorithm::to_lower_copy(key);
178  std::string lokey = key;
179  boost::algorithm::to_lower (lokey);
180  id = sep;
181  linestream >> sep;
182  if( !linestream ) {
183  std::cerr << "MiniConfig::ReadFile(): "
184  << "badly formatted line: \"" << line << "\", line number " << lineNumber << "\n";
185  success = false;
186  continue;
187  }
188  if( sep == "{" ) {
189  if( m_keywords.find(key) != m_keywords.end()
190  || m_keywords.find(lokey) != m_keywords.end() ) {
191  node = node->GetNewDaughter( id );
192  }
193  else if( m_attKeywords.find(key) != m_attKeywords.end()
194  || m_attKeywords.find(lokey) != m_attKeywords.end() ) {
195  node->SetAttribute( id, node->GetPathName(), true );
196  node = node->GetNewDaughter( id );
197  }
198  else {
199  skipCount++;
200  }
201  continue;
202  }
203 
204  std::cerr << "MiniConfig::ReadFile(): "
205  << "badly formatted line: \"" << line << "\", line number " << lineNumber << "\n";
206  success = false;
207  }
208 
209  return success;
210 }
211 
212 
213 std::string
215 GetStringAttribute( std::string objName, std::string attName ) const
216 {
217  if( m_tree == 0 ) {
218  std::cerr << "MiniConfig::GetStringAttribute(): "
219  << "not configured (no file has been read)\n";
220  return std::string("");
221  }
222 
223  const MiniConfigTreeNode* node = m_tree->GetNode( objName );
224  if( node == 0 ) {
225  std::cerr << "MiniConfig::GetStringAttribute(): "
226  << "\"" << objName << "\" does not exist\n";
227  return std::string("");
228  }
229  return node->GetAttribute( std::move(attName) );
230 }
231 
232 
233 int
235 GetIntAttribute( std::string objName, std::string attName ) const
236 {
237  if( m_tree == 0 ) {
238  std::cerr << "MiniConfig::GetIntAttribute(): "
239  << "not configured (no file has been read)\n";
240  return 0;
241  }
242 
243  const MiniConfigTreeNode* node = m_tree->GetNode( objName );
244  if( node == 0 ) {
245  std::cerr << "MiniConfig::GetIntAttribute(): "
246  << "\"" << objName << "\" does not exist\n";
247  return 0;
248  }
249 
250  int val;
251  std::string valstring = node->GetAttribute( attName );
252  std::istringstream valstream(valstring);
253  valstream >> val;
254  if( !valstream ) {
255  std::cerr << "MiniConfig::GetIntAttribute(): "
256  << "\"" << attName << "\" not an integer type\n";
257  return 0;
258  }
259 
260  return val;
261 }
262 
263 
264 float
266 GetFloatAttribute( std::string objName, std::string attName ) const
267 {
268  if( m_tree == 0 ) {
269  std::cerr << "MiniConfig::GetFloatAttribute(): "
270  << "not configured (no file has been read)\n";
271  return 0;
272  }
273 
274  const MiniConfigTreeNode* node = m_tree->GetNode( objName );
275  if( node == 0 ) {
276  std::cerr << "MiniConfig::GetFloatAttribute(): "
277  << "\"" << objName << "\" does not exist\n";
278  return 0;
279  }
280 
281  float val;
282  std::string valstring = node->GetAttribute( attName );
283  std::istringstream valstream(valstring);
284  valstream >> val;
285  if( !valstream ) {
286  std::cerr << "MiniConfig::GetFloatAttribute(): object \"" << objName << "\""
287  << ": \"" << attName << "\" not a floating-point type\n";
288  return 0;
289  }
290 
291  return val;
292 }
293 
294 
295 void
297 GetAttributeNames( std::string objName, std::set<std::string>& attSet ) const
298 {
299  attSet.clear();
300 
301  if( m_tree == 0 ) {
302  std::cerr << "MiniConfig::GetAttributeNames(): "
303  << "not configured (no file has been read)\n";
304  return;
305  }
306 
307  const MiniConfigTreeNode* node = m_tree->GetNode( objName );
308  if( node == 0 ) {
309  std::cerr << "MiniConfig::GetAttributeNames(): "
310  << "\"" << objName << "\" does not exist\n";
311  return;
312  }
313 
314  node->GetAttributeNames( attSet );
315 }
316 
317 
318 void
321 {
322  if( m_tree == 0 ) {
323  std::cerr << "MiniConfig::SendVisitor(): "
324  << "not configured (no file has been read)\n";
325  } else {
326  m_tree->Accept(visitor);
327  }
328 }
329 
330 void
333 {
334  if( m_tree == 0 ) {
335  std::cerr << "MiniConfig::SendWriter(): "
336  << "not configured (no file has been read)\n";
337  } else {
338  m_tree->Accept(writer);
339  }
340 }
341 
342 
343 } // namespace dqi
dqi::MiniConfigTreeNode
A node of a tree structure holding a configuration, where each node may be given attributes,...
Definition: MiniConfigTreeNode.h:25
checkFileSG.line
line
Definition: checkFileSG.py:75
dqi::MiniConfig::m_propagateDown
bool m_propagateDown
Definition: MiniConfig.h:61
dqi::MiniConfig::AddKeyword
virtual void AddKeyword(std::string keyword_)
Definition: MiniConfig.cxx:49
dqi::MiniConfig::m_keywords
KeySet_t m_keywords
Definition: MiniConfig.h:57
trim
std::string trim(const std::string &str, const std::string &whitespace=" \t")
Definition: BTaggingTruthTaggingTool.cxx:1149
dqi::MiniConfigTreeNode::SetAttribKeywordPropagateDown
virtual void SetAttribKeywordPropagateDown(bool propagateDown)
Definition: MiniConfigTreeNode.cxx:232
dqi::MiniConfig::GetAttributeNames
virtual void GetAttributeNames(std::string objName, std::set< std::string > &attSet) const
Definition: MiniConfig.cxx:297
dqi::MiniConfig::m_tree
MiniConfigTreeNode * m_tree
Definition: MiniConfig.h:59
dqi::MiniConfig::AddAttributeKeyword
virtual void AddAttributeKeyword(std::string keyword_)
Definition: MiniConfig.cxx:58
dqi::MiniConfig::GetStringAttribute
virtual std::string GetStringAttribute(std::string objName, std::string attName) const
Definition: MiniConfig.cxx:215
MiniConfig.h
dqi::MiniConfig::GetIntAttribute
virtual int GetIntAttribute(std::string objName, std::string attName) const
Definition: MiniConfig.cxx:235
dqi::MiniConfig::SetAttribKeywordPropagateDown
virtual void SetAttribKeywordPropagateDown(bool propagateDown)
Definition: MiniConfig.cxx:66
ClassImp
ClassImp(xAOD::TFileChecker) namespace xAOD
Definition: TFileChecker.cxx:28
dqi::MiniConfig::SendVisitor
virtual void SendVisitor(MiniConfigTreeNode::Visitor &visitor) const
Definition: MiniConfig.cxx:320
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
dqi::MiniConfig::~MiniConfig
virtual ~MiniConfig()
Definition: MiniConfig.cxx:41
dqi::MiniConfig::GetFloatAttribute
virtual float GetFloatAttribute(std::string objName, std::string attName) const
Definition: MiniConfig.cxx:266
file
TFile * file
Definition: tile_monitor.h:29
dqi::MiniConfigTreeNode::Visitor
Definition: MiniConfigTreeNode.h:28
dqi::MiniConfigTreeNode::Writer
Definition: MiniConfigTreeNode.h:34
dqi::MiniConfig
description
Definition: MiniConfig.h:25
dqi::MiniConfig::MiniConfig
MiniConfig()
Definition: MiniConfig.cxx:33
grepfile.sep
sep
Definition: grepfile.py:38
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:194
dqi::MiniConfig::ReadFile
virtual bool ReadFile(std::string fileName)
Definition: MiniConfig.cxx:73
dqi::MiniConfigTreeNode::GetNode
virtual const MiniConfigTreeNode * GetNode(std::string name_) const
This function takes the full path name of a subnode (in UNIX directory style) and returns the corresp...
Definition: MiniConfigTreeNode.cxx:108
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
dqi::MiniConfig::m_attKeywords
KeySet_t m_attKeywords
Definition: MiniConfig.h:58
dqi::MiniConfigTreeNode::Accept
virtual void Accept(Visitor &visitor) const
Definition: MiniConfigTreeNode.cxx:208
example.writer
writer
show summary of content
Definition: example.py:36
dqi
Definition: CompositeAlgorithm.h:16
python.compressB64.c
def c
Definition: compressB64.py:93
node
Definition: memory_hooks-stdcmalloc.h:74
dqi::MiniConfig::SendWriter
virtual void SendWriter(MiniConfigTreeNode::Writer &writer)
Definition: MiniConfig.cxx:332
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37