Import patch tmpfile
[vuplus_bitbake] / bin / oe / parse / OEHandler.py
1 """class for handling .oe files
2
3    Reads the file and obtains its metadata"""
4
5 import re, oe, os, sys
6 import oe.fetch
7 from oe import debug, data, fetch, fatal
8
9 from oe.parse.ConfHandler import include, localpath, obtain, init
10
11 __func_start_regexp__    = re.compile( r"(((?P<py>python)|(?P<fr>fakeroot))\s*)*(?P<func>\w+)?\s*\(\s*\)\s*{$" )
12 __inherit_regexp__       = re.compile( r"inherit\s+(.+)" )
13 __export_func_regexp__   = re.compile( r"EXPORT_FUNCTIONS\s+(.+)" )
14 __addtask_regexp__       = re.compile("addtask\s+(?P<func>\w+)\s*((before\s*(?P<before>((.*(?=after))|(.*))))|(after\s*(?P<after>((.*(?=before))|(.*)))))*")
15 __addhandler_regexp__    = re.compile( r"addhandler\s+(.+)" )
16 __def_regexp__           = re.compile( r"def\s+.*:" )
17 __python_func_regexp__   = re.compile( r"\s+.*" )
18 __word__ = re.compile(r"\S+")
19
20 __infunc__ = ""
21 __inpython__ = False
22 __body__   = []
23 __oepath_found__ = 0
24 __classname__ = ""
25 classes = [ None, ]
26
27 def supports(fn, d):
28         localfn = localpath(fn, d)
29         return localfn[-3:] == ".oe" or localfn[-8:] == ".oeclass"
30
31 def inherit(files, d):
32         __inherit_cache = data.getVar('__inherit_cache', d) or ""
33         fn = ""
34         lineno = 0
35         for f in files:
36                 file = data.expand(f, d)
37                 if file[0] != "/" and file[-8:] != ".oeclass":
38                         file = "classes/%s.oeclass" % file
39
40                 if not file in __inherit_cache.split():
41                         debug(2, "OE %s:%d: inheriting %s" % (fn, lineno, file))
42                         __inherit_cache += " %s" % file
43                         include(fn, file, d)
44         data.setVar('__inherit_cache', __inherit_cache, d)
45
46
47 def handle(fn, d = {}, include = 0):
48         global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __infunc__, __body__, __oepath_found__
49         __body__ = []
50         __oepath_found__ = 0
51         __infunc__ = ""
52         __classname__ = ""
53
54         if include == 0:
55                 debug(2, "OE " + fn + ": handle(data)")
56         else:
57                 debug(2, "OE " + fn + ": handle(data, include)")
58
59         (root, ext) = os.path.splitext(os.path.basename(fn))
60         init(d)
61
62         if ext == ".oeclass":
63                 __classname__ = root
64                 classes.append(__classname__)
65
66         if include != 0:
67                 oldfile = data.getVar('FILE', d)
68         else:
69                 oldfile = None
70
71         fn = obtain(fn, d)
72         oepath = ['.']
73         if not os.path.isabs(fn):
74                 f = None
75                 voepath = data.getVar("OEPATH", d)
76                 if voepath:
77                         oepath += voepath.split(":")
78                 for p in oepath:
79                         p = data.expand(p, d)
80                         j = os.path.join(p, fn)
81                         if os.access(j, os.R_OK):
82                                 f = open(j, 'r')
83                                 break
84                 if f is None:
85                         raise IOError("file not found")
86         else:
87                 f = open(fn,'r')
88
89         if ext != ".oeclass":
90                 data.setVar('FILE', fn, d)
91                 i = (data.getVar("INHERIT", d, 1) or "").split()
92                 if not "base" in i and __classname__ != "base":
93                         i[0:0] = ["base"]
94                 inherit(i, d)
95
96         lineno = 0
97         while 1:
98                 lineno = lineno + 1
99                 s = f.readline()
100                 if not s: break
101                 w = s.strip()
102                 if not w: continue              # skip empty lines
103                 s = s.rstrip()
104                 while s[-1] == '\\':
105                         s2 = f.readline()[:-1].strip()
106                         s = s[:-1] + s2
107                 feeder(lineno, s, fn, d)
108         if ext == ".oeclass":
109                 classes.remove(__classname__)
110         else:
111                 if include == 0:
112                         data.expandKeys(d)
113                         data.update_data(d)
114                         set_additional_vars(fn, d, include)
115                         anonqueue = data.getVar("__anonqueue", d, 1) or []
116                         for anon in anonqueue:
117                                 data.setVar("__anonfunc", anon["content"], d)
118                                 data.setVarFlags("__anonfunc", anon["flags"], d)
119                                 from oe import build
120                                 try:
121                                         t = data.getVar('T', d)
122                                         data.setVar('T', '${TMPDIR}/', d)
123                                         build.exec_func("__anonfunc", d)
124                                         data.delVar('T', d)
125                                         if t:
126                                                 data.setVar('T', t, d)
127                                 except Exception, e:
128                                         oe.debug(1, "executing anonymous function: %s" % e)
129                                         raise
130                         data.delVar("__anonqueue", d)
131                         data.delVar("__anonfunc", d)
132
133                         for var in d.keys():
134                                 if data.getVarFlag(var, 'handler', d):
135                                         oe.event.register(data.getVar(var, d))
136                                         continue
137
138                                 if not data.getVarFlag(var, 'task', d):
139                                         continue
140
141                                 deps = data.getVarFlag(var, 'deps', d) or []
142                                 postdeps = data.getVarFlag(var, 'postdeps', d) or []
143                                 oe.build.add_task(var, deps, d)
144                                 for p in postdeps:
145                                         pdeps = data.getVarFlag(p, 'deps', d) or []
146                                         pdeps.append(var)
147                                         data.setVarFlag(p, 'deps', pdeps, d)
148                                         oe.build.add_task(p, pdeps, d)
149         if oldfile:
150                 oe.data.setVar("FILE", oldfile, d)
151         return d
152
153 def feeder(lineno, s, fn, d):
154         global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __def_regexp__, __python_func_regexp__, __inpython__,__infunc__, __body__, __oepath_found__, classes, oe
155         if __infunc__:
156                 if s == '}':
157                         __body__.append('')
158                         data.setVar(__infunc__, '\n'.join(__body__), d)
159                         data.setVarFlag(__infunc__, "func", 1, d)
160                         if __infunc__ == "__anonymous":
161                                 anonqueue = oe.data.getVar("__anonqueue", d) or []
162                                 anonitem = {}
163                                 anonitem["content"] = oe.data.getVar("__anonymous", d)
164                                 anonitem["flags"] = oe.data.getVarFlags("__anonymous", d)
165                                 anonqueue.append(anonitem)
166                                 oe.data.setVar("__anonqueue", anonqueue, d)
167                                 oe.data.delVarFlags("__anonymous", d)
168                                 oe.data.delVar("__anonymous", d)
169                         __infunc__ = ""
170                         __body__ = []
171                 else:
172                         __body__.append(s)
173                 return
174
175         if __inpython__:
176                 m = __python_func_regexp__.match(s)
177                 if m:
178                         __body__.append(s)
179                         return
180                 else:
181                         text = '\n'.join(__body__)
182                         comp = compile(text, "<oe>", "exec")
183                         exec comp in __builtins__
184                         __body__ = []
185                         __inpython__ = False
186                         # fall through
187
188         if s[0] == '#': return          # skip comments
189
190         m = __func_start_regexp__.match(s)
191         if m:
192                 __infunc__ = m.group("func") or "__anonymous"
193                 key = __infunc__
194                 if data.getVar(key, d):
195                         # clean up old version of this piece of metadata, as its
196                         # flags could cause problems
197                         data.setVarFlag(key, 'python', None, d)
198                         data.setVarFlag(key, 'fakeroot', None, d)
199                 if m.group("py") is not None:
200                         data.setVarFlag(key, "python", "1", d)
201                 else:
202                         data.delVarFlag(key, "python", d)
203                 if m.group("fr") is not None:
204                         data.setVarFlag(key, "fakeroot", "1", d)
205                 else:
206                         data.delVarFlag(key, "fakeroot", d)
207                 return
208
209         m = __def_regexp__.match(s)
210         if m:
211                 __body__.append(s)
212                 __inpython__ = True
213                 return
214
215         m = __export_func_regexp__.match(s)
216         if m:
217                 fns = m.group(1)
218                 n = __word__.findall(fns)
219                 for f in n:
220                         allvars = []
221                         allvars.append(f)
222                         allvars.append(classes[-1] + "_" + f)
223
224                         vars = [[ allvars[0], allvars[1] ]]
225                         if len(classes) > 1 and classes[-2] is not None:
226                                 allvars.append(classes[-2] + "_" + f)
227                                 vars = []
228                                 vars.append([allvars[2], allvars[1]])
229                                 vars.append([allvars[0], allvars[2]])
230
231                         for (var, calledvar) in vars:
232                                 if data.getVar(var, d) and not data.getVarFlag(var, 'export_func', d):
233                                         continue
234
235                                 if data.getVar(var, d):
236                                         data.setVarFlag(var, 'python', None, d)
237                                         data.setVarFlag(var, 'func', None, d)
238
239                                 for flag in [ "func", "python" ]:
240                                         if data.getVarFlag(calledvar, flag, d):
241                                                 data.setVarFlag(var, flag, data.getVarFlag(calledvar, flag, d), d)
242                                 for flag in [ "dirs" ]:
243                                         if data.getVarFlag(var, flag, d):
244                                                 data.setVarFlag(calledvar, flag, data.getVarFlag(var, flag, d), d)
245
246                                 if data.getVarFlag(calledvar, "python", d):
247                                         data.setVar(var, "\treturn oe.build.exec_func('" + calledvar + "', d)\n", d)
248                                 else:
249                                         data.setVar(var, "\t" + calledvar + "\n", d)
250                                 data.setVarFlag(var, 'export_func', '1', d)
251
252                 return
253
254         m = __addtask_regexp__.match(s)
255         if m:
256                 func = m.group("func")
257                 before = m.group("before")
258                 after = m.group("after")
259                 if func is None:
260                         return
261                 var = "do_" + func
262
263                 data.setVarFlag(var, "task", 1, d)
264
265                 if after is not None:
266                         # set up deps for function
267                         data.setVarFlag(var, "deps", after.split(), d)
268                 if before is not None:
269                         # set up things that depend on this func
270                         data.setVarFlag(var, "postdeps", before.split(), d)
271                 return
272
273         m = __addhandler_regexp__.match(s)
274         if m:
275                 fns = m.group(1)
276                 hs = __word__.findall(fns)
277                 for h in hs:
278                         data.setVarFlag(h, "handler", 1, d)
279                 return
280
281         m = __inherit_regexp__.match(s)
282         if m:
283
284                 files = m.group(1)
285                 n = __word__.findall(files)
286                 inherit(n, d)
287                 return
288
289         from oe.parse import ConfHandler
290         return ConfHandler.feeder(lineno, s, fn, d)
291
292 __pkgsplit_cache__={}
293 def vars_from_file(mypkg, d):
294         if not mypkg:
295                 return (None, None, None)
296         if mypkg in __pkgsplit_cache__:
297                 return __pkgsplit_cache__[mypkg]
298
299         myfile = os.path.splitext(os.path.basename(mypkg))
300         parts = myfile[0].split('_')
301         __pkgsplit_cache__[mypkg] = parts
302         exp = 3 - len(parts)
303         tmplist = []
304         while exp != 0:
305                 exp -= 1
306                 tmplist.append(None)
307         parts.extend(tmplist)
308         return parts
309
310 def set_additional_vars(file, d, include):
311         """Deduce rest of variables, e.g. ${A} out of ${SRC_URI}"""
312
313         debug(2,"OE %s: set_additional_vars" % file)
314
315         src_uri = data.getVar('SRC_URI', d)
316         if not src_uri:
317                 return
318         src_uri = data.expand(src_uri, d)
319
320         a = data.getVar('A', d)
321         if a:
322                 a = data.expand(a, d).split()
323         else:
324                 a = []
325
326         from oe import fetch
327         try:
328                 fetch.init(src_uri.split())
329         except fetch.NoMethodError:
330                 pass
331
332         a += fetch.localpaths(d)
333         del fetch
334         data.setVar('A', "".join(a), d)
335
336
337 # Add us to the handlers list
338 from oe.parse import handlers
339 handlers.append({'supports': supports, 'handle': handle, 'init': init})
340 del handlers