Files
codeql-sample-polkit/dgml2dot
Michael Hohn 1e8971afab Add a two-color CFG to illustrate the branches following the first for-loop
This includes the scripts, dgml, and pdf output
2022-03-05 18:07:10 -08:00

52 lines
1.6 KiB
Python
Executable File

#!/usr/bin/env python3
#
# Read dgml from stdin, write dot to stdout
#
import re
import sys
import xml.etree.ElementTree as ET
import argparse
parser = argparse.ArgumentParser(description='Read a dgml file and produce dot output.')
parser.add_argument('-m', '--merge-with', metavar='mergefile', type=str,
help='Color nodes found in main and mergefile to distinguish them')
args = parser.parse_args()
mergenodes = set()
if args.merge_with:
# Form a set of Node Ids to check Node presence later
mergetree = ET.fromstring(open(args.merge_with, 'rb').read())
for node in mergetree.find("{http://schemas.microsoft.com/vs/2009/dgml}Nodes"):
mergenodes.add(node.attrib['Id'])
# Read source
xml = sys.stdin.read()
root = ET.fromstring(xml)
# Form dot element sequence
body_l = ["digraph qlast {",
"node [shape=box];",
]
for node in root.find("{http://schemas.microsoft.com/vs/2009/dgml}Nodes"):
att = node.attrib
keys = set(att.keys()) - set(['Id', 'Label'])
prop_l = ['{}="{}"'.format(key, att[key]) for key in keys]
prop_l.append('{}="{}"'.format("label", att["Label"]))
node_id = att['Id']
if node_id in mergenodes:
prop_l.append('color=green')
node_s = "nd_{} [{}];".format(node_id, ", ".join(prop_l))
body_l.append(node_s)
for edge in root.find("{http://schemas.microsoft.com/vs/2009/dgml}Links"):
att = edge.attrib
edge_s = 'nd_{} -> nd_{} [label="{}"];'.format(
att["Source"], att["Target"], att.get("Label", ""))
body_l.append(edge_s)
body_l.append("}")
# Write dot
sys.stdout.write("\n".join(body_l))