efl

Форк
0
/
widget_hierarchy.py 
176 строк · 5.2 Кб
1
#!/usr/bin/env python
2

3
import re
4
import os
5
import sys
6
import pickle
7
from optparse import OptionParser
8

9
def print_node(a, b, on_tree=False):
10
    if on_tree:
11
        rank = "source"
12
    else:
13
        rank = "same"
14

15
    i_list = ifaces.get(a)
16
    if i_list:
17
        for iface in i_list:
18
            if_instance = a + iface
19
            if_node_tuple = (if_instance, a) if on_tree else (a, if_instance)
20

21
            print '"%s" [label="",shape=circle,width=0.2]' % if_instance
22
            print '"%s" -> "%s" [label="%s", color=transparent]' \
23
                % (if_instance, if_instance, iface)
24
            print '{rank="%s" "%s" -> "%s" [arrowhead="none"];}' \
25
                % ((rank,) + if_node_tuple)
26

27
    i_list = ifaces.get(b)
28
    if i_list:
29
        for iface in i_list:
30
            if_instance = b + iface
31
            if_node_tuple = (if_instance, b) if on_tree else (b, if_instance)
32

33
            print '"%s" [label="",shape=circle,width=0.2]' % if_instance
34
            print '"%s" -> "%s" [label="%s", color=transparent]' \
35
                % (if_instance, if_instance, iface)
36
            print '{rank="%s" "%s" -> "%s" [arrowhead="none"];}' \
37
                % ((rank,) + if_node_tuple)
38

39
    print '"%s" -> "%s"' % (a, b), '[arrowhead="empty"];' \
40
        if on_tree else '[arrowtail="empty",dir=back];'
41

42
def topological_sort(dep_map, value):
43
    hierarchy = []
44

45
    def sort_do(dep_map, value):
46
        if value is None:
47
            return
48

49
        hierarchy.insert(0, value)
50
        sort_do(dep_map, dep_map.get(value, None))
51

52
    sort_do(dep_map, value)
53

54
    return hierarchy
55

56
def hierachy_build(files_list):
57
    cls_map = {"Elm_Widget_Smart_Class": "widget"}
58

59
    for path in files_list:
60
        contents = ''.join(l[:-1] for l in open(path))
61
        m = re.search(class_re, contents)
62
        iface_m = re.search(class_iface_re, contents)
63
        if m is not None:
64
            items.setdefault(m.group(3), []).append(m.group(1))
65
            if m.group(2) != m.group(3):
66
                cls_map[m.group(2)] = m.group(1)
67
        if iface_m is not None:
68
            items.setdefault(iface_m.group(3), []).append(iface_m.group(1))
69
            if iface_m.group(2) != iface_m.group(3):
70
                cls_map[iface_m.group(2)] = iface_m.group(1)
71
            #hardcoding scrollable now, for brevity -- it may change in future
72
            ifaces.setdefault(iface_m.group(1), []).append('scrollable')
73

74
    for k, v in items.iteritems():
75
        clsname = cls_map.get(k, k)
76
        for c in v:
77
            hierarchy[c] = clsname
78

79
def files_list_build(d):
80
    files_list = []
81
    for f in os.listdir(d):
82
        if f.endswith('.c'):
83
            files_list.append(d + '/' + f)
84

85
    return files_list
86

87
#widget name, widget class, parent class
88
class_re = 'EVAS_SMART_SUBCLASS_NEW.*?,.*?_elm_(\w+).*?,.*?(\w+).*?,.*?(\w+)'
89

90
#widget name, widget class, parent class
91
class_iface_re = \
92
    'EVAS_SMART_SUBCLASS_IFACE_NEW.*?,.*?_elm_(\w+).*?,.*?(\w+).*?,.*?(\w+)'
93

94
usage = "usage: %prog -s <DIRECTORY> -o <OUTPUT_FILE>\n" \
95
    "       %prog -w <WIDGET_NAME> -i <INPUT_FILE>\n" \
96
    "       %prog -t -i <INPUT_FILE>\n"
97
parser = OptionParser(usage=usage)
98
parser.add_option(
99
    "-s", "--scan", dest="scan_dir", default=None, type="str",
100
    help="scan for .h/.c files, at the given path, and build the whole" +
101
    " widget tree")
102
parser.add_option(
103
    "-o", "--output", dest="output_file", default=None, type="str",
104
    help="path of the output scanning file (widget tree)")
105

106
parser.add_option(
107
    "-w", "--widget", dest="widget", default=None, type="str",
108
    help="name of an specific widget to generate a hierarchy tree for")
109
parser.add_option(
110
    "-i", "--input", dest="input_file", default=None, type="str",
111
    help="path of the input (widget tree) where to get data from")
112

113
parser.add_option(
114
    "-t", "--tree", action="store_true", dest="tree",
115
    help="generate the whole hierarchy tree")
116

117
opts, args = parser.parse_args()
118

119
if (not opts.scan_dir and not opts.widget and not opts.tree) \
120
      or (opts.scan_dir and opts.widget) \
121
      or (opts.scan_dir and opts.tree) or \
122
      (opts.tree and opts.widget):
123
    sys.exit(parser.print_usage())
124

125
if opts.scan_dir and not opts.output_file:
126
    sys.exit(parser.print_usage())
127

128
if opts.widget and not opts.input_file:
129
    sys.exit(parser.print_usage())
130

131
if opts.tree and not opts.input_file:
132
    sys.exit(parser.print_usage())
133

134
items = {}
135
hierarchy = {}
136
ifaces = {}
137

138
if opts.scan_dir:
139
    files = files_list_build(opts.scan_dir)
140
    hierachy_build(files)
141
    pickle.dump([hierarchy, ifaces], open(opts.output_file, "wb" ))
142
    sys.exit()
143

144
if opts.tree:
145
    print "digraph elm { node [shape=box];"
146
    print "rankdir=RL;"
147

148
    f = open(opts.input_file)
149
    if not f:
150
        sys.exit("Bad input file path")
151

152
    hierarchy, ifaces = pickle.load(f)
153

154
    for cls, parent in hierarchy.items():
155
        print_node(cls, parent, True);
156

157
    print "}"
158

159
if opts.widget:
160
    print "digraph elm { node [shape=box];"
161

162
    f = open(opts.input_file)
163
    if not f:
164
        sys.exit("Bad input file path")
165

166
    hierarchy, ifaces = pickle.load(f)
167
    l = topological_sort(hierarchy, opts.widget)
168

169
    def pairs(lst):
170
        for i in range(1, len(lst)):
171
            yield lst[i-1], lst[i]
172

173
    for i1, i2 in pairs(l):
174
        print_node(i1, i2);
175

176
    print "}"
177

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.