EvtGen
2.2.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
Toggle main menu visibility
Loading...
Searching...
No Matches
src
EvtGenBase
EvtParserXml.cpp
Go to the documentation of this file.
1
2
/***********************************************************************
3
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4
* *
5
* This file is part of EvtGen. *
6
* *
7
* EvtGen is free software: you can redistribute it and/or modify *
8
* it under the terms of the GNU General Public License as published by *
9
* the Free Software Foundation, either version 3 of the License, or *
10
* (at your option) any later version. *
11
* *
12
* EvtGen is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
* GNU General Public License for more details. *
16
* *
17
* You should have received a copy of the GNU General Public License *
18
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19
***********************************************************************/
20
21
#include "
EvtGenBase/EvtParserXml.hh
"
22
23
#include "
EvtGenBase/EvtReport.hh
"
24
25
#include <fstream>
26
#include <sstream>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <vector>
30
using namespace
std;
31
32
bool
EvtParserXml::open
( std::string filename )
33
{
34
if
( !
expandEnvVars
( filename ) ) {
35
EvtGenReport
(
EVTGEN_ERROR
,
"EvtGen"
)
36
<<
"Error while expanding environment variables in file name '"
37
<< filename.c_str() <<
"'"
<< endl;
38
return
false
;
39
}
40
41
m_fin
.open( filename.c_str() );
42
if
( !
m_fin
) {
43
EvtGenReport
(
EVTGEN_ERROR
,
"EvtGen"
)
44
<<
"Could not open file '"
<< filename.c_str() <<
"'"
<< endl;
45
return
false
;
46
}
47
48
return
true
;
49
}
50
51
bool
EvtParserXml::close
()
52
{
53
m_fin
.close();
54
return
true
;
55
}
56
57
bool
EvtParserXml::readNextTag
()
58
{
59
if
( !
processTagTree
() ) {
60
EvtGenReport
(
EVTGEN_ERROR
,
"EvtGen"
)
61
<<
"Unexpected end tag "
<<
m_tagTitle
<<
" found near line "
62
<<
m_lineNo
<< endl;
63
EvtGenReport
(
EVTGEN_ERROR
,
"EvtGen"
)
64
<<
"Will terminate execution!"
<< endl;
65
return
false
;
66
}
//first process the previous tag to find out where we are in the tag tree
67
68
while
(
m_line
.find(
"<"
) ==
69
std::string::npos ) {
//add lines until we find start of a tag
70
std::string addLine;
71
if
( !std::getline(
m_fin
, addLine ) )
72
return
false
;
73
m_lineNo
++;
74
m_line
+=
" "
;
75
m_line
+= addLine;
76
}
77
78
unsigned
int
startTag;
79
unsigned
int
endTag;
80
unsigned
int
endTagTitle;
81
82
startTag =
m_line
.find(
"<"
);
83
84
if
(
m_line
[startTag + 1] ==
85
'?'
) {
//XML header tag - ignore then read the next tag
86
while
(
m_line
.find(
"?>"
, startTag ) == std::string::npos ) {
87
std::string addLine;
88
if
( !std::getline(
m_fin
, addLine ) )
89
return
false
;
90
m_lineNo
++;
91
m_line
+=
" "
;
92
m_line
+= addLine;
93
}
94
endTag =
m_line
.find(
"?>"
, startTag );
95
m_line
=
m_line
.substr( endTag + 2 );
96
return
readNextTag
();
97
}
else
if
(
m_line
[startTag + 1] ==
98
'!'
) {
//XML comment tag - ignore then read the next tag
99
while
(
m_line
.find(
"-->"
, startTag ) == std::string::npos ) {
100
std::string addLine;
101
if
( !std::getline(
m_fin
, addLine ) )
102
return
false
;
103
m_lineNo
++;
104
m_line
+=
" "
;
105
m_line
+= addLine;
106
}
107
endTag =
m_line
.find(
"-->"
, startTag );
108
m_line
=
m_line
.substr( endTag + 3 );
109
m_tagTitle
=
""
;
110
m_tag
=
""
;
111
return
readNextTag
();
112
}
else
{
//parsable
113
114
while
(
m_line
.find(
">"
, startTag ) ==
115
std::string::npos ) {
//find end of a tag
116
std::string addLine;
117
if
( !std::getline(
m_fin
, addLine ) )
118
return
false
;
119
m_lineNo
++;
120
m_line
+=
" "
;
121
m_line
+= addLine;
122
}
123
endTag =
m_line
.find(
">"
, startTag );
124
m_inLineTag
=
false
;
125
if
(
m_line
.find(
"/>"
, startTag ) < endTag ) {
126
endTag--;
127
m_inLineTag
=
true
;
128
}
129
130
if
(
m_line
.find(
" "
, startTag ) != std::string::npos &&
131
m_line
.find(
" "
, startTag ) <
132
endTag ) {
//find end of the first word in the tag
133
endTagTitle =
m_line
.find(
" "
, startTag );
134
}
else
{
135
endTagTitle = endTag;
136
}
137
138
m_tagTitle
=
m_line
.substr( startTag + 1, endTagTitle - startTag - 1 );
139
m_tag
=
m_line
.substr( startTag + 1, endTag - startTag - 1 );
140
141
//now we have the tag lets remove it from the line
142
if
(
m_inLineTag
) {
143
m_line
=
m_line
.substr( endTag + 2 );
144
}
else
{
145
m_line
=
m_line
.substr( endTag + 1 );
146
}
147
return
true
;
148
}
149
}
150
151
std::string
EvtParserXml::getParentTagTitle
()
152
{
153
if
(
m_tagTree
.empty() )
154
return
""
;
155
else
156
return
m_tagTree
.back();
157
}
158
159
std::string
EvtParserXml::readAttribute
( std::string attribute,
160
std::string defaultValue )
161
{
162
std::string whitespace =
" \t\n\v\f\r"
;
163
for
(
unsigned
int
i = 0; i < whitespace.size(); i++ ) {
164
//find any whitespace followed by the attribute name followed by an '='
165
std::string attName = whitespace[i] + attribute +
"="
;
166
if
(
m_tag
.find( attName ) != std::string::npos ) {
167
int
startAttri =
m_tag
.find( attName );
168
int
startQuote =
m_tag
.find(
"\""
, startAttri + 1 );
169
int
endQuote =
m_tag
.find(
"\""
, startQuote + 1 );
170
return
m_tag
.substr( startQuote + 1, endQuote - startQuote - 1 );
171
}
172
}
173
return
defaultValue;
174
}
175
176
bool
EvtParserXml::readAttributeBool
( std::string attribute,
bool
defaultValue )
177
{
178
std::string valStr =
readAttribute
( attribute );
179
if
( !defaultValue )
180
return
( valStr ==
"true"
|| valStr ==
"1"
|| valStr ==
"on"
||
181
valStr ==
"yes"
);
182
else
183
return
( valStr !=
"false"
&& valStr !=
"0"
&& valStr !=
"off"
&&
184
valStr !=
"no"
);
185
}
186
187
int
EvtParserXml::readAttributeInt
( std::string attribute,
int
defaultValue )
188
{
189
std::string valStr =
readAttribute
( attribute );
190
if
( valStr ==
""
)
191
return
defaultValue;
192
std::istringstream valStream( valStr );
193
int
retVal;
194
valStream >> retVal;
195
return
retVal;
196
}
197
198
double
EvtParserXml::readAttributeDouble
( std::string attribute,
199
double
defaultValue )
200
{
201
std::string valStr =
readAttribute
( attribute );
202
if
( valStr ==
""
)
203
return
defaultValue;
204
std::istringstream valStream( valStr );
205
double
retVal;
206
valStream >> retVal;
207
return
retVal;
208
}
209
210
bool
EvtParserXml::processTagTree
()
211
{
212
if
(
m_tagTitle
==
""
)
213
return
true
;
214
if
(
m_tagTitle
[0] ==
'/'
) {
215
if
(
m_tagTitle
.substr( 1 ) ==
m_tagTree
.back() ) {
216
m_tagTree
.pop_back();
217
}
else
{
218
return
false
;
219
}
220
}
else
if
( !
m_inLineTag
) {
221
m_tagTree
.push_back(
m_tagTitle
);
222
}
223
return
true
;
224
}
225
226
bool
EvtParserXml::expandEnvVars
( std::string& str )
227
{
228
while
( str.find(
'$'
) != std::string::npos ) {
229
size_t
varStart = str.find(
'$'
);
230
size_t
varNameLength;
231
std::string varName;
232
233
//if this is the last character then just remove the $
234
if
( varStart == str.length() - 1 ) {
235
str.erase( varStart );
236
return
true
;
237
}
238
239
if
( str[varStart + 1] ==
'{'
) {
240
//deal with environment variables in {}s
241
size_t
braceStart = varStart + 1;
242
size_t
braceEnd = str.find(
'}'
, braceStart );
243
244
if
( braceEnd == std::string::npos ) {
245
EvtGenReport
(
EVTGEN_ERROR
,
"EvtGen"
)
246
<<
"Incomplete environment variable found in text: "
<< str
247
<< endl;
248
EvtGenReport
(
EVTGEN_ERROR
,
"EvtGen"
)
249
<<
"Will terminate execution!"
<< endl;
250
return
false
;
251
}
252
253
varName = str.substr( braceStart + 1, braceEnd - braceStart - 1 );
254
varNameLength = braceEnd - varStart;
255
256
}
else
{
257
//deal with everything else
258
varNameLength = 0;
259
260
while
( varNameLength + varStart + 1 < str.length() &&
261
isAlphaNum
( str[varStart + varNameLength + 1] ) ) {
262
++varNameLength;
263
}
264
265
varName = str.substr( varStart + 1, varNameLength );
266
}
267
268
char
* envVar = getenv( varName.c_str() );
269
270
if
( envVar )
271
str.replace( varStart, varNameLength + 1, envVar );
272
else
{
273
EvtGenReport
(
EVTGEN_WARNING
,
"EvtGen"
)
274
<<
"Undefined environment variable found in text: "
<< varName
275
<< endl;
276
str.replace( varStart, varNameLength + 1,
""
);
277
}
278
}
279
return
true
;
280
}
281
282
bool
EvtParserXml::isAlphaNum
(
char
c )
283
{
284
if
( c >=
'0'
&& c <=
'9'
)
285
return
true
;
286
if
( c >=
'A'
&& c <=
'Z'
)
287
return
true
;
288
if
( c >=
'a'
&& c <=
'z'
)
289
return
true
;
290
if
( c ==
'_'
)
291
return
true
;
292
return
false
;
293
}
EvtParserXml.hh
EvtReport.hh
EvtGenReport
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=nullptr)
Definition
EvtReport.cpp:32
EVTGEN_WARNING
@ EVTGEN_WARNING
Definition
EvtReport.hh:50
EVTGEN_ERROR
@ EVTGEN_ERROR
Definition
EvtReport.hh:49
EvtParserXml::readAttribute
std::string readAttribute(std::string attribute, std::string defaultValue="")
Definition
EvtParserXml.cpp:159
EvtParserXml::processTagTree
bool processTagTree()
Definition
EvtParserXml.cpp:210
EvtParserXml::m_lineNo
int m_lineNo
Definition
EvtParserXml.hh:49
EvtParserXml::open
bool open(std::string filename)
Definition
EvtParserXml.cpp:32
EvtParserXml::close
bool close()
Definition
EvtParserXml.cpp:51
EvtParserXml::m_inLineTag
bool m_inLineTag
Definition
EvtParserXml.hh:53
EvtParserXml::isAlphaNum
bool isAlphaNum(char c)
Definition
EvtParserXml.cpp:282
EvtParserXml::readAttributeDouble
double readAttributeDouble(std::string attribute, double defaultValue=-1.)
Definition
EvtParserXml.cpp:198
EvtParserXml::readAttributeBool
bool readAttributeBool(std::string attribute, bool defaultValue=false)
Definition
EvtParserXml.cpp:176
EvtParserXml::m_line
std::string m_line
Definition
EvtParserXml.hh:48
EvtParserXml::m_tag
std::string m_tag
Definition
EvtParserXml.hh:51
EvtParserXml::getParentTagTitle
std::string getParentTagTitle()
Definition
EvtParserXml.cpp:151
EvtParserXml::m_tagTitle
std::string m_tagTitle
Definition
EvtParserXml.hh:52
EvtParserXml::m_tagTree
std::vector< std::string > m_tagTree
Definition
EvtParserXml.hh:54
EvtParserXml::readAttributeInt
int readAttributeInt(std::string attribute, int defaultValue=-1)
Definition
EvtParserXml.cpp:187
EvtParserXml::expandEnvVars
bool expandEnvVars(std::string &str)
Definition
EvtParserXml.cpp:226
EvtParserXml::readNextTag
bool readNextTag()
Definition
EvtParserXml.cpp:57
EvtParserXml::m_fin
std::ifstream m_fin
Definition
EvtParserXml.hh:47
Generated by
1.17.0