#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
-"""class for handling .bb files
+"""
+ class for handling .bb files
Reads a .bb file and obtains its metadata
- Copyright (C) 2003, 2004 Chris Larson
- Copyright (C) 2003, 2004 Phil Blundell
-
- This program is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free Software
- Foundation; either version 2 of the License, or (at your option) any later
- version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- Place, Suite 330, Boston, MA 02111-1307 USA."""
-
-import re, bb, os, sys
+"""
+
+
+# Copyright (C) 2003, 2004 Chris Larson
+# Copyright (C) 2003, 2004 Phil Blundell
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import re, bb, os, sys, time
import bb.fetch, bb.build, bb.utils
-from bb import debug, data, fetch, fatal
+from bb import data, fetch, methodpool
from ConfHandler import include, localpath, obtain, init
from bb.parse import ParseError
__infunc__ = ""
__inpython__ = False
__body__ = []
-__bbpath_found__ = 0
__classname__ = ""
classes = [ None, ]
+# We need to indicate EOF to the feeder. This code is so messy that
+# factoring it out to a close_parse_file method is out of question.
+# We will use the IN_PYTHON_EOF as an indicator to just close the method
+#
+# The two parts using it are tightly integrated anyway
+IN_PYTHON_EOF = -9999999999999
+
+__parsed_methods__ = methodpool.get_parsed_dict()
+
def supports(fn, d):
localfn = localpath(fn, d)
return localfn[-3:] == ".bb" or localfn[-8:] == ".bbclass" or localfn[-4:] == ".inc"
def inherit(files, d):
- __inherit_cache = data.getVar('__inherit_cache', d) or ""
+ __inherit_cache = data.getVar('__inherit_cache', d) or []
fn = ""
lineno = 0
- for f in files:
- file = data.expand(f, d)
+ files = data.expand(files, d)
+ for file in files:
if file[0] != "/" and file[-8:] != ".bbclass":
file = os.path.join('classes', '%s.bbclass' % file)
- if not file in __inherit_cache.split():
- debug(2, "BB %s:%d: inheriting %s" % (fn, lineno, file))
- __inherit_cache += " %s" % file
- include(fn, file, d)
- data.setVar('__inherit_cache', __inherit_cache, d)
-
+ if not file in __inherit_cache:
+ bb.msg.debug(2, bb.msg.domain.Parsing, "BB %s:%d: inheriting %s" % (fn, lineno, file))
+ __inherit_cache.append( file )
+ data.setVar('__inherit_cache', __inherit_cache, d)
+ include(fn, file, d, "inherit")
+ __inherit_cache = data.getVar('__inherit_cache', d) or []
def handle(fn, d, include = 0):
- global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __infunc__, __body__, __bbpath_found__, __residue__
+ global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __infunc__, __body__, __residue__
__body__ = []
- __bbpath_found__ = 0
__infunc__ = ""
__classname__ = ""
__residue__ = []
if include == 0:
- debug(2, "BB " + fn + ": handle(data)")
+ bb.msg.debug(2, bb.msg.domain.Parsing, "BB " + fn + ": handle(data)")
else:
- debug(2, "BB " + fn + ": handle(data, include)")
+ bb.msg.debug(2, bb.msg.domain.Parsing, "BB " + fn + ": handle(data, include)")
(root, ext) = os.path.splitext(os.path.basename(fn))
+ base_name = "%s%s" % (root,ext)
init(d)
if ext == ".bbclass":
__classname__ = root
classes.append(__classname__)
+ __inherit_cache = data.getVar('__inherit_cache', d) or []
+ if not fn in __inherit_cache:
+ __inherit_cache.append(fn)
+ data.setVar('__inherit_cache', __inherit_cache, d)
if include != 0:
oldfile = data.getVar('FILE', d)
if not os.path.isabs(fn):
f = None
for p in bbpath:
- p = data.expand(p, d)
j = os.path.join(p, fn)
if os.access(j, os.R_OK):
abs_fn = j
if ext != ".bbclass":
data.setVar('FILE', fn, d)
- i = (data.getVar("INHERIT", d, 1) or "").split()
- if not "base" in i and __classname__ != "base":
- i[0:0] = ["base"]
- inherit(i, d)
lineno = 0
while 1:
s = f.readline()
if not s: break
s = s.rstrip()
- feeder(lineno, s, fn, d)
+ feeder(lineno, s, fn, base_name, d)
if __inpython__:
# add a blank line to close out any python definition
- feeder(lineno + 1, "", fn, d)
+ feeder(IN_PYTHON_EOF, "", fn, base_name, d)
if ext == ".bbclass":
classes.remove(__classname__)
else:
data.expandKeys(d)
data.update_data(d)
anonqueue = data.getVar("__anonqueue", d, 1) or []
- for anon in anonqueue:
- data.setVar("__anonfunc", anon["content"], d)
- data.setVarFlags("__anonfunc", anon["flags"], d)
- from bb import build
- try:
- t = data.getVar('T', d)
- data.setVar('T', '${TMPDIR}/', d)
- build.exec_func("__anonfunc", d)
- data.delVar('T', d)
- if t:
- data.setVar('T', t, d)
- except Exception, e:
- bb.debug(1, "executing anonymous function: %s" % e)
- raise
+ body = [x['content'] for x in anonqueue]
+ flag = { 'python' : 1, 'func' : 1 }
+ data.setVar("__anonfunc", "\n".join(body), d)
+ data.setVarFlags("__anonfunc", flag, d)
+ from bb import build
+ try:
+ t = data.getVar('T', d)
+ data.setVar('T', '${TMPDIR}/', d)
+ build.exec_func("__anonfunc", d)
+ data.delVar('T', d)
+ if t:
+ data.setVar('T', t, d)
+ except Exception, e:
+ bb.msg.debug(1, bb.msg.domain.Parsing, "Exception when executing anonymous function: %s" % e)
+ raise
data.delVar("__anonqueue", d)
data.delVar("__anonfunc", d)
set_additional_vars(fn, d, include)
data.update_data(d)
- for var in data.keys(d):
- if data.getVarFlag(var, 'handler', d):
- bb.event.register(data.getVar(var, d))
- continue
+ all_handlers = {}
+ for var in data.getVar('__BBHANDLERS', d) or []:
+ # try to add the handler
+ handler = data.getVar(var,d)
+ bb.event.register(var, handler)
- if not data.getVarFlag(var, 'task', d):
- continue
+ tasklist = data.getVar('__BBTASKS', d) or []
+ bb.build.add_tasks(tasklist, d)
- deps = data.getVarFlag(var, 'deps', d) or []
- postdeps = data.getVarFlag(var, 'postdeps', d) or []
- bb.build.add_task(var, deps, d)
- for p in postdeps:
- pdeps = data.getVarFlag(p, 'deps', d) or []
- pdeps.append(var)
- data.setVarFlag(p, 'deps', pdeps, d)
- bb.build.add_task(p, pdeps, d)
bbpath.pop(0)
if oldfile:
bb.data.setVar("FILE", oldfile, d)
+
+ # we have parsed the bb class now
+ if ext == ".bbclass" or ext == ".inc":
+ __parsed_methods__[base_name] = 1
+
return d
-def feeder(lineno, s, fn, d):
- global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __def_regexp__, __python_func_regexp__, __inpython__,__infunc__, __body__, __bbpath_found__, classes, bb, __residue__
+def feeder(lineno, s, fn, root, d):
+ global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __def_regexp__, __python_func_regexp__, __inpython__,__infunc__, __body__, classes, bb, __residue__
if __infunc__:
if s == '}':
__body__.append('')
if __inpython__:
m = __python_func_regexp__.match(s)
- if m:
+ if m and lineno != IN_PYTHON_EOF:
__body__.append(s)
return
else:
- text = '\n'.join(__body__)
- comp = bb.utils.better_compile(text, "<bb>", fn )
- bb.utils.better_exec(comp, __builtins__, text, fn)
+ # Note we will add root to parsedmethods after having parse
+ # 'this' file. This means we will not parse methods from
+ # bb classes twice
+ if not root in __parsed_methods__:
+ text = '\n'.join(__body__)
+ methodpool.insert_method( root, text, fn )
+ funcs = data.getVar('__functions__', d) or {}
+ if not funcs.has_key( root ):
+ funcs[root] = text
+ else:
+ funcs[root] = "%s\n%s" % (funcs[root], text)
+
+ data.setVar('__functions__', funcs, d)
__body__ = []
__inpython__ = False
- funcs = data.getVar('__functions__', d) or ""
- data.setVar('__functions__', "%s\n%s" % (funcs, text), d)
+
+ if lineno == IN_PYTHON_EOF:
+ return
+
# fall through
if s == '' or s[0] == '#': return # skip comments and empty lines
data.setVarFlag(var, "task", 1, d)
+ bbtasks = data.getVar('__BBTASKS', d) or []
+ if not var in bbtasks:
+ bbtasks.append(var)
+ data.setVar('__BBTASKS', bbtasks, d)
+
+ existing = data.getVarFlag(var, "deps", d) or []
if after is not None:
-# set up deps for function
- data.setVarFlag(var, "deps", after.split(), d)
+ # set up deps for function
+ for entry in after.split():
+ if entry not in existing:
+ existing.append(entry)
+ data.setVarFlag(var, "deps", existing, d)
if before is not None:
-# set up things that depend on this func
- data.setVarFlag(var, "postdeps", before.split(), d)
+ # set up things that depend on this func
+ for entry in before.split():
+ existing = data.getVarFlag(entry, "deps", d) or []
+ if var not in existing:
+ data.setVarFlag(entry, "deps", [var] + existing, d)
return
m = __addhandler_regexp__.match(s)
if m:
fns = m.group(1)
hs = __word__.findall(fns)
+ bbhands = data.getVar('__BBHANDLERS', d) or []
for h in hs:
+ bbhands.append(h)
data.setVarFlag(h, "handler", 1, d)
+ data.setVar('__BBHANDLERS', bbhands, d)
return
m = __inherit_regexp__.match(s)
myfile = os.path.splitext(os.path.basename(mypkg))
parts = myfile[0].split('_')
__pkgsplit_cache__[mypkg] = parts
+ if len(parts) > 3:
+ raise ParseError("Unable to generate default variables from the filename: %s (too many underscores)" % mypkg)
exp = 3 - len(parts)
tmplist = []
while exp != 0:
def set_additional_vars(file, d, include):
"""Deduce rest of variables, e.g. ${A} out of ${SRC_URI}"""
- debug(2,"BB %s: set_additional_vars" % file)
+ return
+ # Nothing seems to use this variable
+ #bb.msg.debug(2, bb.msg.domain.Parsing, "BB %s: set_additional_vars" % file)
- src_uri = data.getVar('SRC_URI', d)
- if not src_uri:
- return
- src_uri = data.expand(src_uri, d)
+ #src_uri = data.getVar('SRC_URI', d, 1)
+ #if not src_uri:
+ # return
- a = data.getVar('A', d)
- if a:
- a = data.expand(a, d).split()
- else:
- a = []
-
- from bb import fetch
- try:
- fetch.init(src_uri.split(), d)
- except fetch.NoMethodError:
- pass
- except bb.MalformedUrl,e:
- raise ParseError("Unable to generate local paths for SRC_URI due to malformed uri: %s" % e)
-
- a += fetch.localpaths(d)
- del fetch
- data.setVar('A', " ".join(a), d)
+ #a = (data.getVar('A', d, 1) or '').split()
+
+ #from bb import fetch
+ #try:
+ # ud = fetch.init(src_uri.split(), d)
+ # a += fetch.localpaths(d, ud)
+ #except fetch.NoMethodError:
+ # pass
+ #except bb.MalformedUrl,e:
+ # raise ParseError("Unable to generate local paths for SRC_URI due to malformed uri: %s" % e)
+ #del fetch
+
+ #data.setVar('A', " ".join(a), d)
# Add us to the handlers list