Loading [MathJax]/jax/output/SVG/config.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ExpatCoreParser.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "ExpatCoreParser.h"
8 
9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <expat.h>
13 
14 #include <string>
15 #include <vector>
16 #include <iostream>
17 #include <map>
18 
19 
20 
22 ExpatCoreParser::ExternalEntityMap ExpatCoreParser::s_entities;
23 ExpatCoreParser::ExternalEntityMap ExpatCoreParser::s_text_entities;
24 
26 public:
27  static bool get_debug_state() {
28  return ::getenv ("XMLDEBUG") != 0;
29  }
30  static bool debug () {
31  static const bool debug_state = get_debug_state();
32  return debug_state;
33  }
34 };
35 
36 
37 
38 #define BUFFSIZE 1000
39 
40 void
41 ExpatCoreParser::start (void* user_data, const char* el, const char** attr){
42  ExpatCoreParser& me = *reinterpret_cast<ExpatCoreParser*> (user_data);
43  me.do_start (el, attr);
44 }
45 
46 void
47 ExpatCoreParser::end (void* user_data, const char* el){
48  ExpatCoreParser& me = *reinterpret_cast<ExpatCoreParser*> (user_data);
49  me.do_end (el);
50 }
51 
52 void
53 ExpatCoreParser::char_data (void* user_data, const XML_Char* s, int len){
54  ExpatCoreParser& me = *reinterpret_cast<ExpatCoreParser*> (user_data);
55  me.do_char_data (s, len);
56 }
57 
58 void
59 ExpatCoreParser::default_handler (void* user_data, const XML_Char* s, int len){
60  ExpatCoreParser& me = *reinterpret_cast<ExpatCoreParser*> (user_data);
61  me.do_default_handler (s, len);
62 }
63 
64 void
65 ExpatCoreParser::comment (void* user_data, const XML_Char* s){
66  ExpatCoreParser& me = *reinterpret_cast<ExpatCoreParser*> (user_data);
67  me.do_comment (s);
68 }
69 
70 int
72  const XML_Char* context,
73  const XML_Char* /*base*/,
74  const XML_Char* systemId,
75  const XML_Char* /*publicId*/){
76  void* user_data = XML_GetUserData (parser);
77  ExpatCoreParser& me = *reinterpret_cast<ExpatCoreParser*> (user_data);
78  return (me.do_external_entity (parser, context, systemId));
79 }
80 
81 void
82 ExpatCoreParser::register_external_entity (const std::string& name, const std::string& file_name) {
84  std::cout << "ExpatCoreParser::register_external_entity> name=" << name
85  << " file_name=" << file_name << std::endl;
86  }
87  lock_t lock (s_mutex);
88  s_entities[name] = file_name;
89 }
90 
91 void
92 ExpatCoreParser::register_text_entity (const std::string& name, const std::string& text) {
94  std::cout << "ExpatCoreParser::register_text_entity> name=" << name
95  << std::endl;
96  }
97  lock_t lock (s_mutex);
98  s_text_entities[name] = text;
99 }
100 
101 void
102 ExpatCoreParser::entity (void* /*userData*/,
103  const XML_Char* entityName,
104  int is_parameter_entity,
105  const XML_Char* value,
106  int value_length,
107  const XML_Char* base,
108  const XML_Char* systemId,
109  const XML_Char* publicId,
110  const XML_Char* /*notationName*/){
111  if (!base) base = "none";
112  if (!systemId) systemId = "none";
113  if (!publicId) publicId = "none";
114  std::string temp = "none";
115  if (value) {
116  temp.assign (value, strnlen(value, value_length));
117  }
118 
120  std::cout << "ExpatCoreParser::entity[" << 0 << "]> " << entityName;
121  std::cout << " is_parameter=" << is_parameter_entity;
122  std::cout << " value=[" << temp << "]";
123  std::cout << " base=[" << base << "]";
124  std::cout << " systemId=[" << systemId << "]";
125  std::cout << " publicId=[" << publicId << "]";
126  std::cout << std::endl;
127  }
128 }
129 
130 std::unique_ptr<CoreParser::DOMNode>
132  return std::move(m_top);
133 }
134 
136  : m_top (nullptr),
137  m_last (nullptr),
138  m_prefix (prefix){
139 }
140 
141 void
142 ExpatCoreParser::do_start (const char* el, const char** attr){
143  int i;
144  std::map <std::string, std::string> a;
145  if (!m_top){
146  m_top = std::make_unique<CoreParser::DOMNode> ();
147  m_last = m_top.get();
148  }
151  std::cout << "ExpatCoreParser::do_start> el=" << el << " top=" << m_top.get() << " last=" << m_last << " node=" << node << std::endl;
152  }
153  m_last = node;
154  for (i = 0; attr[i]; i += 2) {
155  const char* name = attr[i];
156  const char* value = attr[i+1];
157  node->m_attributes[name] = value;
158  }
159 }
160 
161 void
164  std::cout << "ExpatCoreParser::do_end> el=" << el << std::endl;
165  }
167 }
168 
169 void
170 ExpatCoreParser::do_char_data (const XML_Char* s, int len){
171  if (len == 0) return;
172  while ((len > 0) && (s[len-1] == '\n')) len--;
173  if (len == 0) return;
174  std::string temp (s, len);
176  std::cout << "ExpatCoreParser::do_char_data> [" << temp << "]" << std::endl;
177  }
178 }
179 
180 void
181 ExpatCoreParser::do_default_handler (const XML_Char* s, int len){
182  if (len == 0) return;
183  while ((len > 0) && (s[len-1] == '\n')) len--;
184  if (len == 0) return;
185  std::string temp (s, len);
187  std::cout << "ExpatCoreParser::do_default_handler> [" << temp << "]" << std::endl;
188  }
189 }
190 
191 void
192 ExpatCoreParser::do_comment (const XML_Char* s){
193  if (!m_top) {
194  m_top = std::make_unique<CoreParser::DOMNode> ();
195  m_last = m_top.get();
196  }
199  std::cout << "ExpatCoreParser::do_comment> s=" << s << " top=" << m_top.get() << " last=" << m_last << " node=" << node << std::endl;
200  }
201  // Node is owned by m_last.
202  // cppcheck-suppress memleak
203  node = nullptr;
204 }
205 
206 int
207 ExpatCoreParser::generic_parse (XML_Parser p, const std::string& file_name){
208  FILE* docfd;
210  std::cout << "ExpatCoreParser::generic_parse> file_name=" << file_name << " prefix=" << m_prefix << std::endl;
211  }
212 
213  std::string temp_name = file_name;
214  docfd = fopen (temp_name.c_str (), "r");
215  if (!docfd){
216  temp_name = m_prefix + "/" + file_name;
217  docfd = fopen (temp_name.c_str (), "r");
218  }
219 
220  if (docfd == 0){
221  const char* xmlpathenv = ::getenv ("XMLPATH");
222  if (xmlpathenv == 0) return (0);
223  std::string xmlpath = xmlpathenv;
224  std::string::size_type pos = 0;
225  while (pos != std::string::npos){
226  std::string::size_type sep = xmlpath.find (":", pos);
227  if (sep == std::string::npos){
228  temp_name = xmlpath.substr (pos);
229  pos = std::string::npos;
230  } else {
231  temp_name = xmlpath.substr (pos, sep - pos);
232  pos = sep + 1;
233  }
234  if (temp_name.empty()) continue;
235  std::string last_temp_name = temp_name;
236  temp_name += "/";
237  temp_name += file_name;
239  std::cout << "ExpatCoreParser::generic_parse> file_name=" << file_name
240  << " xmlpath=" << xmlpath
241  << " temp_name=" << temp_name
242  << std::endl;
243  }
244 
245  docfd = fopen (temp_name.c_str (), "r");
246  if (docfd != 0) break;
247  // Test whether prefix is a relative path and if so use it
248  if (m_prefix != "" && '/' != m_prefix[0]) {
249  temp_name = last_temp_name;
250  temp_name += "/";
251  temp_name += m_prefix;
252  temp_name += "/";
253  temp_name += file_name;
255  std::cout << "ExpatCoreParser::generic_parse> file_name=" << file_name
256  << " xmlpath=" << xmlpath
257  << " temp_name=" << temp_name
258  << std::endl;
259  }
260  docfd = fopen (temp_name.c_str (), "r");
261  if (docfd != 0) break;
262  }
263  }
264  }
265 
266  if (docfd == 0){
267  return (0);
268  }
269  int result = 1;
270  XML_SetParamEntityParsing (p, XML_PARAM_ENTITY_PARSING_ALWAYS);
271  XML_SetElementHandler (p, start, end);
272  XML_SetCharacterDataHandler (p, char_data);
273  XML_SetExternalEntityRefHandler (p, external_entity);
274  XML_SetCommentHandler (p, comment);
275  XML_SetUserData (p, this);
277  std::cout << "ExpatCoreParser::generic_parse> starting" << std::endl;
278  }
279  for (;;) {
280  int items;
281  char* buff = (char*) XML_GetBuffer (p, BUFFSIZE + 1);
282  items = fread (buff, 1, BUFFSIZE, docfd);
283  if (ferror (docfd)){
284  std::cout << "Read error" << std::endl;
285  result = 0;
286  break;
287  }
288  int done = feof (docfd);
289  buff[items] = 0;
290  if (XML_ParseBuffer (p, BUFFSIZE, done) == XML_STATUS_ERROR) {
291  if (!done) {
292  std::cout << "ExpatCoreParser::Parse error at line " << XML_GetCurrentLineNumber(p)
293  << " of file " << file_name
294  << ":" << std::endl
295  << XML_ErrorString (XML_GetErrorCode(p)) << std::endl;
296  result = 0;
297  }
298  /* handle parse error */
299  }
300  if (done) break;
301  }
302  fclose (docfd);
303  return (result);
304 }
305 
306 int
307 ExpatCoreParser::generic_text_parse (XML_Parser p, const std::string& text){
309  std::cout << "ExpatCoreParser::generic_text_parse> " << std::endl;
310  }
311  int result = 1;
312  XML_SetParamEntityParsing (p, XML_PARAM_ENTITY_PARSING_ALWAYS);
313  XML_SetElementHandler (p, start, end);
314  XML_SetCharacterDataHandler (p, char_data);
315  XML_SetExternalEntityRefHandler (p, external_entity);
316  XML_SetCommentHandler (p, comment);
317  XML_SetUserData (p, this);
319  std::cout << "ExpatCoreParser::generic_text_parse> starting" << std::endl;
320  }
321  {
322  char* buff = (char*) XML_GetBuffer (p, text.size() + 1);
323  strcpy (buff, text.c_str ());
324  int done = 1;
325  if (XML_ParseBuffer (p, text.size(), done) == XML_STATUS_ERROR) {
326  std::cout << "ExpatCoreParser::Parse error at line " << XML_GetCurrentLineNumber(p)
327  << ":" << std::endl
328  << XML_ErrorString (XML_GetErrorCode(p)) << std::endl;
329  result = 0;
330  /* handle parse error */
331  }
332  }
333  return (result);
334 }
335 
336 int
338  const XML_Char* context, const XML_Char* systemId){
339  std::string context_str;
340  if (context == 0) context_str = "none";
341  else context_str = context;
342  bool done = false;
343  int status = 0;
344  if (context != 0) {
345  std::string replacement = find_text_entity (context_str);
346  if (replacement != "") {
348  std::cout << "ExpatCoreParser::do_external_entity> "
349  << " context=[" << context_str << "]"
350  << " replacement=[" << replacement << "]"
351  << std::endl;
352  }
353  XML_Parser p = XML_ExternalEntityParserCreate (parser, context, NULL);
354  status = generic_text_parse (p, replacement);
355  XML_ParserFree (p);
356  done = true;
357  }
358  }
359  if (!done) {
360  std::string replacement = find_external_entity (context_str);
361  if (replacement == "NULL") {
362  return (1);
363  }
364  if (replacement != "") {
365  systemId = replacement.c_str ();
366  }
367 
369  std::cout << "ExpatCoreParser::do_external_entity> "
370  << " context=[" << context_str << "]"
371  << " systemId=[" << systemId << "]"
372  << " replacement=[" << replacement << "]"
373  << std::endl;
374  }
375  XML_Parser p = XML_ExternalEntityParserCreate (parser, context, NULL);
377  XML_ParserFree (p);
378  }
379  return (status);
380 }
381 
382 const std::string&
384  lock_t lock (s_mutex);
385  ExternalEntityMap::const_iterator it = s_entities.find (name);
386  if (it == s_entities.end ()) {
387  static const std::string empty;
388  return (empty);
389  } else {
390  return ((*it).second);
391  }
392 }
393 
394 const std::string&
396  lock_t lock (s_mutex);
397  ExternalEntityMap::const_iterator it = s_text_entities.find (name);
398  if (it == s_text_entities.end ()) {
399  static const std::string empty;
400  return (empty);
401  } else {
402  return ((*it).second);
403  }
404 }
405 
406 std::unique_ptr<CoreParser::DOMNode>
407 ExpatCoreParser::parse (const std::string& file_name){
408  std::string name = file_name;
409  std::string::size_type pos = file_name.rfind ('/');
410  std::string prefix;
411  if (pos != std::string::npos){
412  prefix = file_name.substr (0, pos);
413  name = file_name.substr (pos + 1);
414  }
415  ExpatCoreParser me (prefix);
416  XML_Parser p = XML_ParserCreate (NULL);
417  if (!p) {
418  std::cout << "ExpatCoreParser::Couldn't allocate memory for parser" << std::endl;
419  std::abort();
420  }
421  int result = me.generic_parse (p, name);
422  XML_ParserFree (p);
423  if (result == 0) return nullptr;
424  return me.get_document ();
425 }
426 
ExpatCoreParser::external_entity
static int external_entity(XML_Parser parser, const XML_Char *context, const XML_Char *, const XML_Char *systemId, const XML_Char *)
Definition: ExpatCoreParser.cxx:71
base
std::string base
Definition: hcg.cxx:78
get_hdefs.buff
buff
Definition: get_hdefs.py:61
ExpatCoreParser::find_external_entity
static const std::string & find_external_entity(const std::string &name)
Definition: ExpatCoreParser.cxx:383
get_generator_info.result
result
Definition: get_generator_info.py:21
BUFFSIZE
#define BUFFSIZE
Definition: ExpatCoreParser.cxx:38
ExpatCoreParser::do_end
void do_end(const char *el)
Definition: ExpatCoreParser.cxx:162
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
ExpatCoreParser::do_external_entity
int do_external_entity(XML_Parser parser, const XML_Char *context, const XML_Char *systemId)
Definition: ExpatCoreParser.cxx:337
ExpatCoreParser::find_text_entity
static const std::string & find_text_entity(const std::string &name)
Definition: ExpatCoreParser.cxx:395
skel.it
it
Definition: skel.GENtoEVGEN.py:407
ExpatCoreParser::lock_t
std::lock_guard< std::mutex > lock_t
Definition: ExpatCoreParser.h:71
ExpatCoreParser::entity
static void entity(void *userData, const XML_Char *entityName, int is_parameter_entity, const XML_Char *value, int value_length, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *)
Definition: ExpatCoreParser.cxx:102
athena.value
value
Definition: athena.py:124
CoreParser::DOMNode
Definition: DOMNode.h:21
ExpatCoreParser::ExternalEntityMap
std::map< std::string, std::string > ExternalEntityMap
Definition: ExpatCoreParser.h:19
ExpatCoreParser::do_char_data
void do_char_data(const XML_Char *s, int len)
Definition: ExpatCoreParser.cxx:170
ExpatCoreParser::m_prefix
std::string m_prefix
Definition: ExpatCoreParser.h:68
ExpatCoreParserDebugger
Definition: ExpatCoreParser.cxx:25
XMLCoreParser.h
ExpatCoreParser::end
static void end(void *, const char *el)
Definition: ExpatCoreParser.cxx:47
ExpatCoreParser.h
ExpatCoreParser::ExpatCoreParser
ExpatCoreParser(const std::string &prefix)
Definition: ExpatCoreParser.cxx:135
ExpatCoreParser
Definition: ExpatCoreParser.h:16
python.CaloAddPedShiftConfig.parser
parser
Definition: CaloAddPedShiftConfig.py:41
physics_parameters.file_name
string file_name
Definition: physics_parameters.py:32
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ExpatCoreParserDebugger::get_debug_state
static bool get_debug_state()
Definition: ExpatCoreParser.cxx:27
CoreParser::DOMNode::COMMENT_NODE
@ COMMENT_NODE
Definition: DOMNode.h:27
lumiFormat.i
int i
Definition: lumiFormat.py:85
ExpatCoreParser::register_text_entity
static void register_text_entity(const std::string &name, const std::string &text)
Definition: ExpatCoreParser.cxx:92
CoreParser::DOMNode::ELEMENT_NODE
@ ELEMENT_NODE
Definition: DOMNode.h:26
ExpatCoreParser::do_comment
void do_comment(const XML_Char *s)
Definition: ExpatCoreParser.cxx:192
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
ExpatCoreParser::m_last
CoreParser::DOMNode * m_last
Definition: ExpatCoreParser.h:67
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
CaloCondBlobAlgs_fillNoiseFromASCII.systemId
systemId
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:108
ExpatCoreParser::do_default_handler
void do_default_handler(const XML_Char *s, int len)
Definition: ExpatCoreParser.cxx:181
ExpatCoreParser::generic_parse
int generic_parse(XML_Parser p, const std::string &file_name)
Definition: ExpatCoreParser.cxx:207
PyPoolBrowser.node
node
Definition: PyPoolBrowser.py:131
ExpatCoreParserDebugger::debug
static bool debug()
Definition: ExpatCoreParser.cxx:30
ExpatCoreParser::get_document
std::unique_ptr< CoreParser::DOMNode > get_document()
Definition: ExpatCoreParser.cxx:131
ExpatCoreParser::start
static void start(void *, const char *el, const char **attr)
Definition: ExpatCoreParser.cxx:41
grepfile.sep
sep
Definition: grepfile.py:38
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ExpatCoreParser::char_data
static void char_data(void *, const XML_Char *s, int len)
Definition: ExpatCoreParser.cxx:53
ExpatCoreParser::default_handler
static void default_handler(void *, const XML_Char *s, int len)
Definition: ExpatCoreParser.cxx:59
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:71
ExpatCoreParser::do_start
void do_start(const char *el, const char **attr)
Definition: ExpatCoreParser.cxx:142
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
a
TList * a
Definition: liststreamerinfos.cxx:10
SCT_ConditionsAlgorithms::CoveritySafe::getenv
std::string getenv(const std::string &variableName)
get an environment variable
Definition: SCT_ConditionsUtilities.cxx:17
ExpatCoreParser::parse
static std::unique_ptr< CoreParser::DOMNode > parse(const std::string &file_name)
Definition: ExpatCoreParser.cxx:407
ExpatCoreParser::generic_text_parse
int generic_text_parse(XML_Parser p, const std::string &text)
Definition: ExpatCoreParser.cxx:307
ExpatCoreParser::s_mutex
static std::mutex s_mutex
Definition: ExpatCoreParser.h:70
ExpatCoreParser::comment
static void comment(void *, const XML_Char *s)
Definition: ExpatCoreParser.cxx:65
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:146
makeTransCanvas.text
text
Definition: makeTransCanvas.py:11
ExpatCoreParser::register_external_entity
static void register_external_entity(const std::string &name, const std::string &file_name)
Definition: ExpatCoreParser.cxx:82
merge.status
status
Definition: merge.py:17
CoreParser::DOMNode::m_parent
DOMNode * m_parent
Definition: DOMNode.h:52
ExpatCoreParser::m_top
std::unique_ptr< CoreParser::DOMNode > m_top
Definition: ExpatCoreParser.h:66
node
Definition: node.h:21