1/*******************************************************************\
3Module: Read/write graphs as GraphML
5Author: Michael Tautschnig, mt@eecs.qmul.ac.uk
7\*******************************************************************/
14// include last to make sure #define stack(x) of parser.h does not
15// collide with std::stack included by graph.h
18 typedef std::map<std::string, graphmlt::node_indext>
name_mapt;
21 const std::string &name,
25 std::pair<name_mapt::iterator, bool> entry=
28 entry.first->second=graph.
add_node();
30 return entry.first->second;
36 std::map<std::string, std::map<std::string, std::string> > &
defaults,
52 for(xmlt::elementst::const_iterator
59 if(
e_it->get_attribute(
"key")==
"violation" &&
62 else if(
e_it->get_attribute(
"key")==
"entry" &&
75 // add edge and annotate
79 for(std::map<std::string, std::string>::const_iterator
85 for(xmlt::elementst::const_iterator
89 found=
e_it->get_attribute(
"key")==it->first;
105 for(xmlt::elementst::const_iterator
120 for(xmlt::elementst::const_iterator
124 if(
e_it->name==
"default")
149 std::map<std::string, std::map<std::string, std::string> >
defaults;
161 for(std::size_t i=0; !
err && i<dest.
size(); ++i)
165 INVARIANT(!
n.node_name.empty(),
"node should be named");
190 const std::string &filename,
205 xmlt graphml(
"graphml");
208 "http://www.w3.org/2001/XMLSchema-instance");
211 "http://graphml.graphdrawing.org/xmlns");
213 // <key attr.name="originFileName" attr.type="string" for="edge"
215 // <default>"<command-line>"</default>
219 key.set_attribute(
"attr.name",
"originFileName");
220 key.set_attribute(
"attr.type",
"string");
221 key.set_attribute(
"for",
"edge");
222 key.set_attribute(
"id",
"originfile");
225 key.new_element(
"default").data=src.
key_values.at(
"programfile");
227 key.new_element(
"default").data=
"<command-line>";
230 // <key attr.name="invariant" attr.type="string" for="node" id="invariant"/>
233 key.set_attribute(
"attr.name",
"invariant");
234 key.set_attribute(
"attr.type",
"string");
235 key.set_attribute(
"for",
"node");
236 key.set_attribute(
"id",
"invariant");
239 // <key attr.name="invariant.scope" attr.type="string" for="node"
240 // id="invariant.scope"/>
243 key.set_attribute(
"attr.name",
"invariant.scope");
244 key.set_attribute(
"attr.type",
"string");
245 key.set_attribute(
"for",
"node");
246 key.set_attribute(
"id",
"invariant.scope");
249 // <key attr.name="isViolationNode" attr.type="boolean" for="node"
251 // <default>false</default>
255 key.set_attribute(
"attr.name",
"isViolationNode");
256 key.set_attribute(
"attr.type",
"boolean");
257 key.set_attribute(
"for",
"node");
258 key.set_attribute(
"id",
"violation");
260 key.new_element(
"default").data=
"false";
263 // <key attr.name="isEntryNode" attr.type="boolean" for="node" id="entry">
264 // <default>false</default>
268 key.set_attribute(
"attr.name",
"isEntryNode");
269 key.set_attribute(
"attr.type",
"boolean");
270 key.set_attribute(
"for",
"node");
271 key.set_attribute(
"id",
"entry");
273 key.new_element(
"default").data=
"false";
276 // <key attr.name="isSinkNode" attr.type="boolean" for="node" id="sink">
277 // <default>false</default>
281 key.set_attribute(
"attr.name",
"isSinkNode");
282 key.set_attribute(
"attr.type",
"boolean");
283 key.set_attribute(
"for",
"node");
284 key.set_attribute(
"id",
"sink");
286 key.new_element(
"default").data=
"false";
289 // <key attr.name="enterLoopHead" attr.type="boolean" for="edge"
290 // id="enterLoopHead">
291 // <default>false</default>
295 key.set_attribute(
"attr.name",
"enterLoopHead");
296 key.set_attribute(
"attr.type",
"boolean");
297 key.set_attribute(
"for",
"edge");
298 key.set_attribute(
"id",
"enterLoopHead");
300 key.new_element(
"default").data=
"false";
303 // <key attr.name="cyclehead" attr.type="boolean" for="node"
305 // <default>false</default>
309 key.set_attribute(
"attr.name",
"cyclehead");
310 key.set_attribute(
"attr.type",
"boolean");
311 key.set_attribute(
"for",
"node");
312 key.set_attribute(
"id",
"cyclehead");
314 key.new_element(
"default").data =
"false";
317 // <key attr.name="threadId" attr.type="string" for="edge" id="threadId"/>
320 key.set_attribute(
"attr.name",
"threadId");
321 key.set_attribute(
"attr.type",
"int");
322 key.set_attribute(
"for",
"edge");
323 key.set_attribute(
"id",
"threadId");
325 key.new_element(
"default").data =
"0";
328 // <key attr.name="createThread" attr.type="string"
329 // for="edge" id="createThread"/>
332 key.set_attribute(
"attr.name",
"createThread");
333 key.set_attribute(
"attr.type",
"int");
334 key.set_attribute(
"for",
"edge");
335 key.set_attribute(
"id",
"createThread");
337 key.new_element(
"default").data=
"0";
340 // <key attr.name="sourcecodeLanguage" attr.type="string" for="graph"
341 // id="sourcecodelang"/>
344 key.set_attribute(
"attr.name",
"sourcecodeLanguage");
345 key.set_attribute(
"attr.type",
"string");
346 key.set_attribute(
"for",
"graph");
347 key.set_attribute(
"id",
"sourcecodelang");
350 // <key attr.name="programFile" attr.type="string" for="graph"
351 // id="programfile"/>
354 key.set_attribute(
"attr.name",
"programFile");
355 key.set_attribute(
"attr.type",
"string");
356 key.set_attribute(
"for",
"graph");
357 key.set_attribute(
"id",
"programfile");
360 // <key attr.name="programHash" attr.type="string" for="graph"
361 // id="programhash"/>
364 key.set_attribute(
"attr.name",
"programHash");
365 key.set_attribute(
"attr.type",
"string");
366 key.set_attribute(
"for",
"graph");
367 key.set_attribute(
"id",
"programhash");
370 // <key attr.name="specification" attr.type="string" for="graph"
371 // id="specification"/>
374 key.set_attribute(
"attr.name",
"specification");
375 key.set_attribute(
"attr.type",
"string");
376 key.set_attribute(
"for",
"graph");
377 key.set_attribute(
"id",
"specification");
380 // <key attr.name="architecture" attr.type="string" for="graph"
381 // id="architecture"/>
384 key.set_attribute(
"attr.name",
"architecture");
385 key.set_attribute(
"attr.type",
"string");
386 key.set_attribute(
"for",
"graph");
387 key.set_attribute(
"id",
"architecture");
390 // <key attr.name="producer" attr.type="string" for="graph"
394 key.set_attribute(
"attr.name",
"producer");
395 key.set_attribute(
"attr.type",
"string");
396 key.set_attribute(
"for",
"graph");
397 key.set_attribute(
"id",
"producer");
400 // <key attr.name="creationtime" attr.type="string" for="graph"
401 // id="creationtime"/>
404 key.set_attribute(
"attr.name",
"creationtime");
405 key.set_attribute(
"attr.type",
"string");
406 key.set_attribute(
"for",
"graph");
407 key.set_attribute(
"id",
"creationtime");
410 // <key attr.name="startline" attr.type="int" for="edge" id="startline"/>
413 key.set_attribute(
"attr.name",
"startline");
414 key.set_attribute(
"attr.type",
"int");
415 key.set_attribute(
"for",
"edge");
416 key.set_attribute(
"id",
"startline");
419 // <key attr.name="control" attr.type="string" for="edge" id="control"/>
422 key.set_attribute(
"attr.name",
"control");
423 key.set_attribute(
"attr.type",
"string");
424 key.set_attribute(
"for",
"edge");
425 key.set_attribute(
"id",
"control");
428 // <key attr.name="assumption" attr.type="string" for="edge" id="assumption"/>
431 key.set_attribute(
"attr.name",
"assumption");
432 key.set_attribute(
"attr.type",
"string");
433 key.set_attribute(
"for",
"edge");
434 key.set_attribute(
"id",
"assumption");
437 // <key attr.name="assumption.resultfunction" attr.type="string" for="edge"
438 // id="assumption.resultfunction"/>
441 key.set_attribute(
"attr.name",
"assumption.resultfunction");
442 key.set_attribute(
"attr.type",
"string");
443 key.set_attribute(
"for",
"edge");
444 key.set_attribute(
"id",
"assumption.resultfunction");
447 // <key attr.name="assumption.scope" attr.type="string" for="edge"
448 // id="assumption.scope"/>
451 key.set_attribute(
"attr.name",
"assumption.scope");
452 key.set_attribute(
"attr.type",
"string");
453 key.set_attribute(
"for",
"edge");
454 key.set_attribute(
"id",
"assumption.scope");
457 // <key attr.name="enterFunction" attr.type="string" for="edge"
458 // id="enterFunction"/>
461 key.set_attribute(
"attr.name",
"enterFunction");
462 key.set_attribute(
"attr.type",
"string");
463 key.set_attribute(
"for",
"edge");
464 key.set_attribute(
"id",
"enterFunction");
467 // <key attr.name="returnFromFunction" attr.type="string" for="edge"
471 key.set_attribute(
"attr.name",
"returnFromFunction");
472 key.set_attribute(
"attr.type",
"string");
473 key.set_attribute(
"for",
"edge");
474 key.set_attribute(
"id",
"returnFrom");
477 // <key attr.name="witness-type" attr.type="string" for="graph"
478 // id="witness-type"/>
481 key.set_attribute(
"attr.name",
"witness-type");
482 key.set_attribute(
"attr.type",
"string");
483 key.set_attribute(
"for",
"graph");
484 key.set_attribute(
"id",
"witness-type");
507 // <data key="entry">true</data>
519 // <data key="violation">true</data>
531 val.set_attribute(
"key",
"invariant");
532 val.data=
n.invariant;
534 // Only add invariant.scope if it's not empty
535 if(!
n.invariant_scope.empty())
538 val_s.set_attribute(
"key",
"invariant.scope");
539 val_s.data =
n.invariant_scope;
543 for(graphmlt::edgest::const_iterator
550 os <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
nodet::node_indext node_indext
const edgest & out(node_indext n) const
node_indext add_node(arguments &&... values)
const edgest & in(node_indext n) const
std::string get_attribute(const std::string &attribute) const
xmlt & new_element(const std::string &key)
void set_attribute(const std::string &attribute, unsigned value)
void err(int eval, const char *fmt,...)
bool read_graphml(std::istream &is, graphmlt &dest, graphmlt::node_indext &entry, message_handlert &message_handler)
static graphmlt::node_indext add_node(const std::string &name, name_mapt &name_to_node, graphmlt &graph)
bool write_graphml(const graphmlt &src, std::ostream &os)
std::map< std::string, graphmlt::node_indext > name_mapt
static bool build_graph(const xmlt &xml, graphmlt &dest, graphmlt::node_indext &entry)
static bool build_graph_rec(const xmlt &xml, name_mapt &name_to_node, std::map< std::string, std::map< std::string, std::string > > &defaults, graphmlt &dest, std::string &entrynode)
Read/write graphs as GraphML.
xmlt xml(const irep_idt &property_id, const property_infot &property_info)
#define CHECK_RETURN(CONDITION)
#define UNREACHABLE
This should be used to mark dead code.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
bool parse_xml(std::istream &in, const std::string &filename, message_handlert &message_handler, xmlt &dest)