~patrickas/ensoft-sextant/no-caching

« back to all changes in this revision

Viewing changes to src/sextant/export.py

  • Committer: Tarmac
  • Author(s): patrickas at co, James Harkin, James Harkin, Phil Connell, Phil Connell, Phil Connell, Robert Wills
  • Date: 2014-08-15 16:01:06 UTC
  • mfrom: (1.2.177 sextant)
  • Revision ID: tarmac-20140815160106-1cxti0gzlrwks0np
setup.py no uploads config and web file to the correct location for the pypi installation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -----------------------------------------
 
2
# Sextant
 
3
# Copyright 2014, Ensoft Ltd.
 
4
# Author: Patrick Stevens,  James Harkin
 
5
# -----------------------------------------
 
6
# Convert a program from internal Python representation to various output formats
 
7
 
 
8
__all__ = "ProgramConverter"
 
9
 
 
10
 
 
11
class ProgramConverter:
 
12
    # Given our internal program representation, converts it to output formats.
 
13
    # Currently supported: GraphML
 
14
 
 
15
    @staticmethod
 
16
    def get_supported_outputs():
 
17
        return ['graphml', 'yed_graphml', 'dot']
 
18
 
 
19
    @staticmethod
 
20
    def get_display_name(function, suppress_common_nodes=False):
 
21
        """
 
22
        Given a Function object, retrieve the label we attach to it.
 
23
        For instance, function-pointers are labelled "(function pointer)",
 
24
        while the `main` function is usually labelled "main".
 
25
        """
 
26
        if function.type == "function_pointer":
 
27
            name = "(function pointer)"
 
28
        else:
 
29
            name = function.name
 
30
        
 
31
        if suppress_common_nodes and function.is_common:
 
32
            name += ' (common)'
 
33
        return name
 
34
 
 
35
    @staticmethod
 
36
    def to_dot(program, suppress_common_nodes=False):
 
37
        """
 
38
        Convert the program to DOT output format.
 
39
        """
 
40
        output_str = 'digraph "{}" {{\n '.format(program.program_name)
 
41
        output_str += 'overlap=false; \n'
 
42
 
 
43
        font_name = "helvetica"
 
44
 
 
45
        for func in program.get_functions():
 
46
            if func.type == "plt_stub":
 
47
                output_str += ' "{}" [fillcolor=pink, style=filled]\n'.format(func.name)
 
48
            elif func.type == "function_pointer":
 
49
                output_str += ' "{}" [fillcolor=yellow, style=filled]\n'.format(func.name)
 
50
 
 
51
            # in all cases, even if we've specified that we want a filled-in
 
52
            # node already, DOT lets us add more information about that node
 
53
            # so we can insist on turning that same node into a box-shape
 
54
            # and changing its font.
 
55
            output_str += ' "{}" [label="{}", fontname="{}", shape=box]\n'.format(func.name,
 
56
                                                                                  ProgramConverter.get_display_name(func, suppress_common_nodes),
 
57
                                                                                  font_name)
 
58
            if func.is_common:
 
59
                output_str += ' "{}" [fillcolor=lightgreen, style=filled]\n'.format(func.name)
 
60
 
 
61
            for func_called in func.functions_i_call:
 
62
                if not (suppress_common_nodes and func_called.is_common):
 
63
                    output_str += ' "{}" -> "{}"\n'.format(func.name, func_called.name)
 
64
 
 
65
        output_str += '}'
 
66
        return output_str
 
67
 
 
68
 
 
69
 
 
70
    @staticmethod
 
71
    def to_yed_graphml(program, suppress_common_nodes=False):
 
72
        commonly_called = []
 
73
        output_str = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 
74
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \
 
75
xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" \
 
76
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
 
77
"""
 
78
        output_str += """<key for="graphml" id="d0" yfiles.type="resources"/>
 
79
                        <key for="port" id="d1" yfiles.type="portgraphics"/>
 
80
                        <key for="port" id="d2" yfiles.type="portgeometry"/>
 
81
                        <key for="port" id="d3" yfiles.type="portuserdata"/>
 
82
                        <key attr.name="url" attr.type="string" for="node" id="d4"/>
 
83
                        <key attr.name="description" attr.type="string" for="node" id="d5"/>
 
84
                        <key for="node" id="d6" yfiles.type="nodegraphics"/>
 
85
                        <key attr.name="url" attr.type="string" for="edge" id="d7"/>
 
86
                        <key attr.name="description" attr.type="string" for="edge" id="d8"/>
 
87
                        <key for="edge" id="d9" yfiles.type="edgegraphics"/>\n"""
 
88
 
 
89
        output_str += """<graph id="{}" edgedefault="directed">\n""".format(program.program_name)
 
90
 
 
91
        for func in program.get_functions():
 
92
            display_func = ProgramConverter.get_display_name(func)
 
93
            if func.type == "plt_stub":
 
94
                colour = "#ff00ff"
 
95
            elif func.type == "function_pointer":
 
96
                colour = "#99ffff"
 
97
            elif func.is_common:
 
98
                colour = "#00FF00"
 
99
            else:
 
100
                colour = "#ffcc00"
 
101
            output_str += """<node id="{}">
 
102
                                <data key="d6">
 
103
                                    <y:ShapeNode>
 
104
                                        <y:Geometry height="{}" width="{}" x="60.0" y="0.0"/>
 
105
                                      <y:Fill color="{}" transparent="false"/>
 
106
                                      <y:BorderStyle color="#000000" type="line" width="1.0"/>
 
107
                                      <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog"
 
108
                                      fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false"
 
109
                                      height="18.701171875" modelName="custom" textColor="#000000" visible="true"
 
110
                                      width="36.6953125" x="-3.34765625" y="5.6494140625">{}<y:LabelModel>
 
111
                                          <y:SmartNodeLabelModel distance="4.0"/>
 
112
                                        </y:LabelModel>
 
113
                                        <y:ModelParameter>
 
114
                                          <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0"
 
115
                                          nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0"
 
116
                                          upY="-1.0"/>
 
117
                                        </y:ModelParameter>
 
118
                                      </y:NodeLabel>
 
119
                                      <y:Shape type="rectangle"/>
 
120
                                    </y:ShapeNode>
 
121
                                </data> 
 
122
                                </node>\n""".format(func.name, 20, len(display_func)*8, colour, display_func)
 
123
            for callee in func.functions_i_call:
 
124
                if callee not in commonly_called:
 
125
                    if not(suppress_common_nodes and callee.is_common):
 
126
                            output_str += """<edge source="{}" target="{}"> <data key="d9">
 
127
                                        <y:PolyLineEdge>
 
128
                                        <y:LineStyle color="#000000" type="line" width="1.0"/>
 
129
                                        <y:Arrows source="none" target="standard"/>
 
130
                                        <y:BendStyle smoothed="false"/>
 
131
                                        </y:PolyLineEdge>
 
132
                                        </data>
 
133
                                     </edge>\n""".format(func.name, callee.name)
 
134
 
 
135
        output_str += '</graph>\n<data key="d0">    <y:Resources/>  </data>\n</graphml>'
 
136
        return output_str
 
137
 
 
138
    @staticmethod
 
139
    def to_graphml(program):
 
140
        output_str = """<?xml version="1.0" encoding="UTF-8"?>
 
141
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \
 
142
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
 
143
"""
 
144
        output_str += '<graph id="{}" edgedefault="directed">\n'.format(program.program_name)
 
145
 
 
146
        for func in program.get_functions():
 
147
            output_str += '<node id="{}"> <data key="name">{}</data> </node>\n'.format(func.name, ProgramConverter.get_display_name(func))
 
148
            for callee in func.functions_i_call:
 
149
                output_str += '<edge source="{}" target="{}"> <data key="calls">1</data> </edge>\n'.format(func.name, callee.name)
 
150
 
 
151
        output_str += '</graph>\n</graphml>'
 
152
        return output_str
 
 
b'\\ No newline at end of file'