File indexing completed on 2025-02-21 10:00:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef _ATTRIB_STRING_PARSER_H_
0012 #define _ATTRIB_STRING_PARSER_H_
0013
0014 #include "GaudiKernel/Kernel.h"
0015 #include "GaudiKernel/System.h"
0016 #include <iterator>
0017 #ifdef __clang__
0018 # pragma clang diagnostic push
0019
0020
0021 # pragma clang diagnostic ignored "-Wkeyword-macro"
0022 #endif
0023 #include <boost/regex.hpp>
0024 #ifdef __clang__
0025 # pragma clang diagnostic pop
0026 #endif
0027
0028 namespace Gaudi {
0029 namespace Utils {
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 class AttribStringParser {
0041 public:
0042
0043 struct Attrib {
0044 std::string tag;
0045 std::string value;
0046 };
0047
0048
0049
0050 class Iterator {
0051 public:
0052 using iterator_category = std::input_iterator_tag;
0053 using value_type = Attrib;
0054 using difference_type = std::ptrdiff_t;
0055 using pointer = value_type*;
0056 using reference = value_type&;
0057
0058 Iterator() = default;
0059 Iterator( const boost::sregex_iterator& it, bool expand_vars ) : m_it( it ), m_expandVars( expand_vars ) {
0060
0061 }
0062 Iterator( const Iterator& other ) : Iterator( other.m_it, other.m_expandVars ) {}
0063 Iterator( Iterator&& other ) : m_it( std::move( other.m_it ) ), m_expandVars( other.m_expandVars ) {}
0064 Iterator operator++( int ) {
0065 ++m_it;
0066 return *this;
0067 }
0068 Iterator operator++() {
0069 auto old = *this;
0070 ++m_it;
0071 return old;
0072 }
0073 reference operator*() {
0074 i_setAttrib();
0075 return m_attrib;
0076 }
0077 bool operator==( const Iterator& other ) { return m_it == other.m_it; }
0078 bool operator!=( const Iterator& other ) { return m_it != other.m_it; }
0079
0080 private:
0081
0082 boost::sregex_iterator m_it;
0083 bool m_expandVars = false;
0084
0085 Attrib m_attrib;
0086
0087
0088 void i_setAttrib() {
0089 static const boost::sregex_iterator endmark;
0090 if ( m_it != endmark ) {
0091
0092 m_attrib = Attrib{ ( *m_it )[1], ( *m_it )[2] };
0093 if ( m_expandVars && m_attrib.value.find( "${" ) != std::string::npos ) {
0094 static const boost::regex varexp{ "\\$\\{([^}]+)\\}" };
0095 auto i = 1;
0096 while ( i ) {
0097 i = 0;
0098 m_attrib.value = boost::regex_replace(
0099 m_attrib.value, varexp,
0100 [&i]( const boost::smatch& m ) -> std::string {
0101 const std::string name = m[1];
0102 const char* cname = name.c_str();
0103 if ( System::isEnvSet( cname ) ) {
0104 ++i;
0105 return System::getEnv( cname );
0106 }
0107 return m[0];
0108 },
0109 boost::match_default | boost::format_all );
0110 }
0111 }
0112 } else {
0113
0114 m_attrib = Attrib();
0115 }
0116 }
0117 };
0118
0119
0120
0121
0122
0123
0124 AttribStringParser( std::string data, bool expand_vars = true ) : m_data( data ), m_expandVars( expand_vars ) {}
0125
0126 private:
0127 std::string m_data;
0128 bool m_expandVars;
0129
0130 boost::sregex_iterator parse() const {
0131 static const boost::regex exp{ "[[:space:]]*([^[:space:]]+)[[:space:]]*=[[:space:]]*'(.*?)'" };
0132 return boost::sregex_iterator( begin( m_data ), end( m_data ), exp );
0133 }
0134 friend Iterator begin( const AttribStringParser& );
0135 };
0136 inline AttribStringParser::Iterator begin( const AttribStringParser& parser ) {
0137 return AttribStringParser::Iterator( parser.parse(), parser.m_expandVars );
0138 }
0139 inline AttribStringParser::Iterator end( const AttribStringParser& ) {
0140 return AttribStringParser::Iterator();
0141 }
0142 }
0143 }
0144
0145 #endif