The Gaudi Framework  v32r2 (46d42edc)
AttribStringParser.h
Go to the documentation of this file.
1 #ifndef _ATTRIB_STRING_PARSER_H_
2 #define _ATTRIB_STRING_PARSER_H_
3 
4 #include "GaudiKernel/Kernel.h"
5 #include "GaudiKernel/System.h"
6 #include <iterator>
7 #ifdef __clang__
8 # pragma clang diagnostic push
9 // Hide warning message:
10 // boost/regex/v4/instances.hpp:128:17: warning: keyword is hidden by macro definition
11 # pragma clang diagnostic ignored "-Wkeyword-macro"
12 #endif
13 #include <boost/regex.hpp>
14 #ifdef __clang__
15 # pragma clang diagnostic pop
16 #endif
17 
18 namespace Gaudi {
19  namespace Utils {
31  public:
33  struct Attrib {
36  };
37 
39  // This class is essentially a wrapper around boost::sregex_iterator.
40  class Iterator : public std::iterator<std::input_iterator_tag, Attrib> {
41  public:
42  Iterator() = default;
43  Iterator( const boost::sregex_iterator& it, bool expand_vars ) : m_it( it ), m_expandVars( expand_vars ) {
44  // i_setAttrib();
45  }
46  Iterator( const Iterator& other ) : Iterator( other.m_it, other.m_expandVars ) {}
47  Iterator( Iterator&& other ) : m_it( std::move( other.m_it ) ), m_expandVars( other.m_expandVars ) {}
49  ++m_it;
50  return *this;
51  }
53  auto old = *this;
54  ++m_it;
55  return old;
56  }
57  reference operator*() {
58  i_setAttrib();
59  return m_attrib;
60  }
61  bool operator==( const Iterator& other ) { return m_it == other.m_it; }
62  bool operator!=( const Iterator& other ) { return m_it != other.m_it; }
63 
64  private:
66  boost::sregex_iterator m_it;
67  bool m_expandVars = false;
72  void i_setAttrib() {
73  static const boost::sregex_iterator endmark;
74  if ( m_it != endmark ) {
75  // if we have a match, we cache the values
76  m_attrib = Attrib{( *m_it )[1], ( *m_it )[2]};
77  if ( m_expandVars && m_attrib.value.find( "${" ) != std::string::npos ) {
78  static const boost::regex varexp{"\\$\\{([^}]+)\\}"};
79  auto i = 1;
80  while ( i ) {
81  i = 0;
82  m_attrib.value = boost::regex_replace(
83  m_attrib.value, varexp,
84  [&i]( const boost::smatch& m ) -> std::string {
85  const std::string name = m[1];
86  const char* cname = name.c_str();
87  if ( System::isEnvSet( cname ) ) {
88  ++i;
89  return System::getEnv( cname );
90  }
91  return m[0]; // do not expand unknown vars
92  },
93  boost::match_default | boost::format_all );
94  }
95  }
96  } else {
97  // otherwise we clean the cache
98  m_attrib = Attrib();
99  }
100  }
101  };
102 
108  AttribStringParser( std::string data, bool expand_vars = true ) : m_data( data ), m_expandVars( expand_vars ) {}
109 
110  private:
113 
114  boost::sregex_iterator parse() const {
115  static const boost::regex exp{"[[:space:]]*([^[:space:]]+)[[:space:]]*=[[:space:]]*'(.*?)'"};
116  return boost::sregex_iterator( begin( m_data ), end( m_data ), exp );
117  }
118  friend Iterator begin( const AttribStringParser& );
119  };
121  return AttribStringParser::Iterator( parser.parse(), parser.m_expandVars );
122  }
125  }
126  } // namespace Utils
127 } // namespace Gaudi
128 
129 #endif
Parse attribute strings allowing iteration over the various attributes.
AttribStringParser::Iterator end(const AttribStringParser &)
STL namespace.
Iterator to loop over the tag/value pairs in the attribute string.
STL class.
Iterator(const boost::sregex_iterator &it, bool expand_vars)
constexpr double m
Definition: SystemOfUnits.h:92
boost::sregex_iterator m_it
Wrapped boost::sregex_iterator instance.
Simple class to wrap tag/value pairs.
T find(T... args)
boost::sregex_iterator parse() const
boost::spirit::classic::position_iterator2< ForwardIterator > Iterator
Definition: Iterator.h:18
Attrib m_attrib
Cached Attrib instance.
AttribStringParser(std::string data, bool expand_vars=true)
Initialize the parsing of an attribute string.
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
void i_setAttrib()
Helper method used to update the cached Attrib instance when dereferencing the iterator.