[parser] Move evaluating into the ast class...
[bitbake.git] / lib / bb / parse / ast.py
1 # ex:ts=4:sw=4:sts=4:et
2 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3 """
4  AbstractSyntaxTree classes for the Bitbake language
5 """
6
7 # Copyright (C) 2003, 2004 Chris Larson
8 # Copyright (C) 2003, 2004 Phil Blundell
9 # Copyright (C) 2009 Holger Hans Peter Freyther
10 #
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License version 2 as
13 # published by the Free Software Foundation.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License along
21 # with this program; if not, write to the Free Software Foundation, Inc.,
22 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
24 import bb, re
25
26 __word__ = re.compile(r"\S+")
27 __parsed_methods__ = methodpool.get_parsed_dict()
28
29 def handleInclude(m, fn, lineno, data, force):
30     s = bb.data.expand(m.group(1), data)
31     bb.msg.debug(3, bb.msg.domain.Parsing, "CONF %s:%d: including %s" % (fn, lineno, s))
32     if force:
33         include(fn, s, data, "include required")
34     else:
35         include(fn, s, data, False)
36
37 def handleExport(m, data):
38     bb.data.setVarFlag(m.group(1), "export", 1, data)
39
40 def handleData(groupd, data):
41     key = groupd["var"]
42     if "exp" in groupd and groupd["exp"] != None:
43         bb.data.setVarFlag(key, "export", 1, data)
44     if "ques" in groupd and groupd["ques"] != None:
45         val = getFunc(groupd, key, data)
46         if val == None:
47             val = groupd["value"]
48     elif "colon" in groupd and groupd["colon"] != None:
49         e = data.createCopy()
50         bb.data.update_data(e)
51         val = bb.data.expand(groupd["value"], e)
52     elif "append" in groupd and groupd["append"] != None:
53         val = "%s %s" % ((getFunc(groupd, key, data) or ""), groupd["value"])
54     elif "prepend" in groupd and groupd["prepend"] != None:
55         val = "%s %s" % (groupd["value"], (getFunc(groupd, key, data) or ""))
56     elif "postdot" in groupd and groupd["postdot"] != None:
57         val = "%s%s" % ((getFunc(groupd, key, data) or ""), groupd["value"])
58     elif "predot" in groupd and groupd["predot"] != None:
59         val = "%s%s" % (groupd["value"], (getFunc(groupd, key, data) or ""))
60     else:
61         val = groupd["value"]
62     if 'flag' in groupd and groupd['flag'] != None:
63         bb.msg.debug(3, bb.msg.domain.Parsing, "setVarFlag(%s, %s, %s, data)" % (key, groupd['flag'], val))
64         bb.data.setVarFlag(key, groupd['flag'], val, data)
65     else:
66         bb.data.setVar(key, val, data)
67
68 def getFunc(groupd, key, data):
69     if 'flag' in groupd and groupd['flag'] != None:
70         return bb.data.getVarFlag(key, groupd['flag'], data)
71     else:
72         return bb.data.getVar(key, data)
73
74 def handleMethod(func_name, lineno, fn, body, d):
75     if func_name == "__anonymous":
76         funcname = ("__anon_%s_%s" % (lineno, fn.translate(string.maketrans('/.+-', '____'))))
77         if not funcname in methodpool._parsed_fns:
78             text = "def %s(d):\n" % (funcname) + '\n'.join(body)
79             methodpool.insert_method(funcname, text, fn)
80         anonfuncs = data.getVar('__BBANONFUNCS', d) or []
81         anonfuncs.append(funcname)
82         data.setVar('__BBANONFUNCS', anonfuncs, d)
83     else:
84         data.setVarFlag(func_name, "func", 1, d)
85         data.setVar(func_name, '\n'.join(body), d)
86
87
88
89 def handlePythonMethod(root, body, fn):
90     # Note we will add root to parsedmethods after having parse
91     # 'this' file. This means we will not parse methods from
92     # bb classes twice
93     if not root in __parsed_methods__:
94         text = '\n'.join(body)
95         methodpool.insert_method(root, text, fn)
96
97 def handleMethodFlags(key, m, d):
98     if data.getVar(key, d):
99         # Clean up old version of this piece of metadata, as its
100         # flags could cause problems
101         data.setVarFlag(key, 'python', None, d)
102         data.setVarFlag(key, 'fakeroot', None, d)
103     if m.group("py") is not None:
104         data.setVarFlag(key, "python", "1", d)
105     else:
106         data.delVarFlag(key, "python", d)
107     if m.group("fr") is not None:
108         data.setVarFlag(key, "fakeroot", "1", d)
109     else:
110         data.delVarFlag(key, "fakeroot", d)
111
112 def handleExportFuncs(m, d):
113     fns = m.group(1)
114     n = __word__.findall(fns)
115     for f in n:
116         allvars = []
117         allvars.append(f)
118         allvars.append(classes[-1] + "_" + f)
119
120         vars = [[ allvars[0], allvars[1] ]]
121         if len(classes) > 1 and classes[-2] is not None:
122             allvars.append(classes[-2] + "_" + f)
123             vars = []
124             vars.append([allvars[2], allvars[1]])
125             vars.append([allvars[0], allvars[2]])
126
127         for (var, calledvar) in vars:
128             if data.getVar(var, d) and not data.getVarFlag(var, 'export_func', d):
129                 continue
130
131             if data.getVar(var, d):
132                 data.setVarFlag(var, 'python', None, d)
133                 data.setVarFlag(var, 'func', None, d)
134
135             for flag in [ "func", "python" ]:
136                 if data.getVarFlag(calledvar, flag, d):
137                     data.setVarFlag(var, flag, data.getVarFlag(calledvar, flag, d), d)
138             for flag in [ "dirs" ]:
139                 if data.getVarFlag(var, flag, d):
140                     data.setVarFlag(calledvar, flag, data.getVarFlag(var, flag, d), d)
141
142             if data.getVarFlag(calledvar, "python", d):
143                 data.setVar(var, "\tbb.build.exec_func('" + calledvar + "', d)\n", d)
144             else:
145                 data.setVar(var, "\t" + calledvar + "\n", d)
146             data.setVarFlag(var, 'export_func', '1', d)
147
148 def handleAddTask(m, d):
149     func = m.group("func")
150     before = m.group("before")
151     after = m.group("after")
152     if func is None:
153         return
154     if func[:3] != "do_":
155         var = "do_" + func
156
157     data.setVarFlag(var, "task", 1, d)
158
159     bbtasks = data.getVar('__BBTASKS', d) or []
160     if not var in bbtasks:
161         bbtasks.append(var)
162     data.setVar('__BBTASKS', bbtasks, d)
163
164     existing = data.getVarFlag(var, "deps", d) or []
165     if after is not None:
166         # set up deps for function
167         for entry in after.split():
168             if entry not in existing:
169                 existing.append(entry)
170     data.setVarFlag(var, "deps", existing, d)
171     if before is not None:
172         # set up things that depend on this func
173         for entry in before.split():
174             existing = data.getVarFlag(entry, "deps", d) or []
175             if var not in existing:
176                 data.setVarFlag(entry, "deps", [var] + existing, d)
177
178 def handleBBHandlers(m, d):
179     fns = m.group(1)
180     hs = __word__.findall(fns)
181     bbhands = data.getVar('__BBHANDLERS', d) or []
182     for h in hs:
183         bbhands.append(h)
184         data.setVarFlag(h, "handler", 1, d)
185     data.setVar('__BBHANDLERS', bbhands, d)
186
187 def handleInherit(m, d):
188     files = m.group(1)
189     n = __word__.findall(files)
190     inherit(n, d)
191