Release coccinelle-0.1
[bpt/coccinelle.git] / python / coccilib / output.py
1 import pygtk
2 import gtk, gobject
3 import coccilib.coccigui
4 import coccilib.coccigui.coccigui
5 from threading import Thread, Lock
6 import time
7 from copy import deepcopy
8
9 class Output:
10 """In order to implement an output class for use with Coccinelle,
11 one can inherit from this class and overload register_match with
12 the same number of arguments.
13
14 include_match will be overwritten by inheriting from your actual
15 class, and thus if your class is a.b.C then Coccinelle will create
16 a Python class "class Coccinelle(a.b.C)" that hooks include_match
17 into the O'Caml internals.
18 """
19 def include_match(self, b):
20 pass
21
22 def register_match(self, include, messages):
23 pass
24
25 def combine(self, meta_variable, locations):
26 nmv = deepcopy(meta_variable)
27 nloc = [deepcopy(loc) for loc in locations]
28 nmv.location = nloc[0]
29 nmv.locations = nloc
30
31 return nmv
32
33 def finalise(self):
34 pass
35
36 class Console(Output):
37 def __init__(self):
38 pass
39
40 def register_match(self, include, messages):
41 self.include_match(include)
42 if include:
43 for variable, message in messages:
44 print "%s:%s:%s: %s - %s" % (variable.location.file, variable.location.line, variable.location.column, message, variable)
45
46 class GtkRunner(Thread):
47 def __init__(self):
48 Thread.__init__(self)
49 self.lock = Lock()
50 self.rows = []
51
52 def add_row(self, cocci, l):
53 for i in xrange(0, len(l)):
54 l[i] = (l[i][1], l[i][0].location.file, l[i][0].location.line, l[i][0].location.column)
55
56 self.lock.acquire()
57 try:
58 self.rows.append((cocci, l))
59 finally:
60 self.lock.release()
61
62 def has_row(self):
63 self.lock.acquire()
64 try:
65 return len(self.rows) > 0
66 finally:
67 self.lock.release()
68
69 def get_row(self):
70 self.lock.acquire()
71 try:
72 return self.rows.pop(0)
73 finally:
74 self.lock.release()
75
76 def update(self):
77 while self.has_row():
78 cocci, l = self.get_row()
79 self.gui.add_result(cocci, l)
80 gobject.timeout_add(1000, self.update)
81
82 def run(self):
83 self.gui = coccilib.coccigui.coccigui.pycocci()
84 globals()['gtk_sock'] = self.gui
85 gobject.timeout_add(1000, self.update)
86
87 gtk.gdk.threads_init()
88 gtk.gdk.threads_enter()
89
90 gtk.main()
91
92 gtk.gdk.threads_leave()
93
94 globals().pop('gtk_thread')
95 globals().pop('gtk_sock')
96
97 class Gtk(Output):
98 def check_availability(self):
99 if not globals().has_key('gtk_sock'):
100 t = GtkRunner()
101 globals()['gtk_thread'] = t
102 globals()['gtk_thread'].start()
103 time.sleep(2)
104
105 def register_match(self, include, messages):
106 self.check_availability()
107
108 self.include_match(include)
109 if include:
110 globals()['gtk_thread'].add_row(self.cocci_file, messages)
111
112 def finalise(self):
113 self.check_availability()
114
115 globals()['gtk_thread'].join()