bin/bitbake:
[vuplus_bitbake] / lib / bb / event.py
1 #!/usr/bin/env python
2 # ex:ts=4:sw=4:sts=4:et
3 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4 """
5 BitBake 'Event' implementation
6
7 Classes and functions for manipulating 'events' in the
8 BitBake build tools.
9
10 Copyright (C) 2003, 2004  Chris Larson
11
12 This program is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free Software
14 Foundation; either version 2 of the License, or (at your option) any later
15 version.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23 Place, Suite 330, Boston, MA 02111-1307 USA. 
24 """
25
26 import os, re
27 import bb.data
28 import bb.utils
29
30 class Event:
31     """Base class for events"""
32     type = "Event"
33
34     def __init__(self, d = bb.data.init()):
35         self._data = d
36
37     def getData(self):
38         return self._data
39
40     def setData(self, data):
41         self._data = data
42
43     data = property(getData, setData, None, "data property")
44
45 NotHandled = 0
46 Handled = 1
47 _handlers = []
48 _handlers_dict = {}
49
50 def tmpHandler(event):
51     """Default handler for code events"""
52     return NotHandled
53
54 def defaultTmpHandler():
55     tmp = "def tmpHandler(e):\n\t\"\"\"heh\"\"\"\n\treturn NotHandled"
56     comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event.defaultTmpHandler")
57     return comp
58
59 def fire(event):
60     """Fire off an Event"""
61     for h in _handlers:
62         if type(h).__name__ == "code":
63             exec(h)
64             if tmpHandler(event) == Handled:
65                 return Handled
66         else:
67             if h(event) == Handled:
68                 return Handled
69     return NotHandled
70
71 def register(name, handler):
72     """Register an Event handler"""
73
74     # already registered
75     if name in _handlers_dict:
76         return;
77
78     if handler is not None:
79 #       handle string containing python code
80         if type(handler).__name__ == "str":
81             _registerCode(handler)
82         else:
83             _handlers.append(handler)
84
85         _handlers_dict[name] = 1
86
87 def _registerCode(handlerStr):
88     """Register a 'code' Event.
89        Deprecated interface; call register instead.
90
91        Expects to be passed python code as a string, which will
92        be passed in turn to compile() and then exec().  Note that
93        the code will be within a function, so should have had
94        appropriate tabbing put in place."""
95     tmp = "def tmpHandler(e):\n%s" % handlerStr
96     comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event._registerCode")
97 #   prevent duplicate registration
98     _handlers.append(comp)
99
100 def remove(name, handler):
101     """Remove an Event handler"""
102
103     _handlers_dict.pop(name)
104     if type(handler).__name__ == "str":
105         return _removeCode(handler)
106     else:
107         _handlers.remove(handler)
108
109 def _removeCode(handlerStr):
110     """Remove a 'code' Event handler
111        Deprecated interface; call remove instead."""
112     tmp = "def tmpHandler(e):\n%s" % handlerStr
113     comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event._removeCode")
114     _handlers.remove(comp)
115
116 def getName(e):
117     """Returns the name of a class or class instance"""
118     if getattr(e, "__name__", None) == None:
119         return e.__class__.__name__
120     else:
121         return e.__name__
122
123
124 class PkgBase(Event):
125     """Base class for package events"""
126
127     def __init__(self, t, d = bb.data.init()):
128         self._pkg = t
129         Event.__init__(self, d)
130
131     def getPkg(self):
132         return self._pkg
133
134     def setPkg(self, pkg):
135         self._pkg = pkg
136
137     pkg = property(getPkg, setPkg, None, "pkg property")
138
139
140 class BuildBase(Event):
141     """Base class for bbmake run events"""
142
143     def __init__(self, n, p, c, failures = 0):
144         self._name = n
145         self._pkgs = p
146         Event.__init__(self, c)
147         self._failures = failures
148
149     def getPkgs(self):
150         return self._pkgs
151
152     def setPkgs(self, pkgs):
153         self._pkgs = pkgs
154
155     def getName(self):
156         return self._name
157
158     def setName(self, name):
159         self._name = name
160
161     def getCfg(self):
162         return self.data
163
164     def setCfg(self, cfg):
165         self.data = cfg
166
167     def getFailures(self):
168         """
169         Return the number of failed packages
170         """
171         return self._failures
172
173     pkgs = property(getPkgs, setPkgs, None, "pkgs property")
174     name = property(getName, setName, None, "name property")
175     cfg = property(getCfg, setCfg, None, "cfg property")
176
177
178 class DepBase(PkgBase):
179     """Base class for dependency events"""
180
181     def __init__(self, t, data, d):
182         self._dep = d
183         PkgBase.__init__(self, t, data)
184
185     def getDep(self):
186         return self._dep
187
188     def setDep(self, dep):
189         self._dep = dep
190
191     dep = property(getDep, setDep, None, "dep property")
192
193
194 class PkgStarted(PkgBase):
195     """Package build started"""
196
197
198 class PkgFailed(PkgBase):
199     """Package build failed"""
200
201
202 class PkgSucceeded(PkgBase):
203     """Package build completed"""
204
205
206 class BuildStarted(BuildBase):
207     """bbmake build run started"""
208
209
210 class BuildCompleted(BuildBase):
211     """bbmake build run completed"""
212
213
214 class UnsatisfiedDep(DepBase):
215     """Unsatisfied Dependency"""
216
217
218 class RecursiveDep(DepBase):
219     """Recursive Dependency"""
220
221 class NoProvider(Event):
222     """No Provider for an Event"""
223
224     def __init__(self, item, data,runtime=False):
225         Event.__init__(self, data)
226         self._item = item
227         self._runtime = runtime
228
229     def getItem(self):
230         return self._item
231
232     def isRuntime(self):
233         return self._runtime
234
235 class MultipleProviders(Event):
236     """Multiple Providers"""
237
238     def  __init__(self, item, candidates, data, runtime = False):
239         Event.__init__(self, data)
240         self._item = item
241         self._candidates = candidates
242         self._is_runtime = runtime
243
244     def isRuntime(self):
245         """
246         Is this a runtime issue?
247         """
248         return self._is_runtime
249
250     def getItem(self):
251         """
252         The name for the to be build item
253         """
254         return self._item
255
256     def getCandidates(self):
257         """
258         Get the possible Candidates for a PROVIDER.
259         """
260         return self._candidates