build.py: revert setting LC_ALL=C due to IRC discussion
[vuplus_bitbake] / lib / bb / parse / parse_c / BBHandler.py
1 # ex:ts=4:sw=4:sts=4:et
2 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3 """class for handling .bb files (using a C++ parser)
4
5     Reads a .bb file and obtains its metadata (using a C++ parser)
6
7     Copyright (C) 2006 Tim Robert Ansell
8     Copyright (C) 2006 Holger Hans Peter Freyther
9
10     This program is free software; you can redistribute it and/or modify it under
11     the terms of the GNU General Public License as published by the Free Software
12     Foundation; either version 2 of the License, or (at your option) any later
13     version.
14
15     Permission is hereby granted, free of charge, to any person obtaining a copy
16     of this software and associated documentation files (the "Software"), to deal
17     in the Software without restriction, including without limitation the rights
18     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19     copies of the Software, and to permit persons to whom the Software is
20     furnished to do so, subject to the following conditions:
21
22     The above copyright notice and this permission notice shall be included in all
23     copies or substantial portions of the Software.
24
25     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
28     SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
29     DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
30     OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
31     THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 """
33
34 import os, sys
35
36 # The Module we will use here
37 import bb
38
39 from bitbakec import parsefile
40
41 #
42 # This is the Python Part of the Native Parser Implementation.
43 # We will only parse .bbclass, .inc and .bb files but no
44 # configuration files.
45 # supports, init and handle are the public methods used by
46 # parser module
47 #
48 # The rest of the methods are internal implementation details.
49
50 def _init(fn, d):
51     """
52     Initialize the data implementation with values of
53     the environment and data from the file.
54     """
55     pass
56
57 #
58 # public
59 #
60 def supports(fn, data):
61     return fn[-3:] == ".bb" or fn[-8:] == ".bbclass" or fn[-4:] == ".inc" or fn[-5:] == ".conf"
62
63 def init(fn, data):
64     if not bb.data.getVar('TOPDIR', data):
65         bb.data.setVar('TOPDIR', os.getcwd(), data)
66     if not bb.data.getVar('BBPATH', data):
67         bb.data.setVar('BBPATH', os.path.join(sys.prefix, 'share', 'bitbake'), data)
68
69 def handle_inherit(d):
70     """
71     Handle inheriting of classes. This will load all default classes.
72     It could be faster, it could detect infinite loops but this is todo
73     Also this delayed loading of bb.parse could impose a penalty
74     """
75     from bb.parse import handle
76
77     files = (data.getVar('INHERIT', d, True) or "").split()
78     if not "base" in i:
79         files[0:0] = ["base"]
80
81     __inherit_cache = data.getVar('__inherit_cache', d) or []
82     for f in files:
83         file = data.expand(f, d)
84         if file[0] != "/" and file[-8:] != ".bbclass":
85             file = os.path.join('classes', '%s.bbclass' % file)
86
87         if not file in __inherit_cache:
88             debug(2, "BB %s:%d: inheriting %s" % (fn, lineno, file))
89             __inherit_cache.append( file )
90
91             try:
92                 handle(file, d, True)
93             except IOError:
94                 print "Failed to inherit %s" % file
95     data.setVar('__inherit_cache', __inherit_cache, d)
96
97
98 def handle(fn, d, include):
99     from bb import data, parse
100
101     (root, ext) = os.path.splitext(os.path.basename(fn))
102     base_name = "%s%s" % (root,ext)
103
104     # initialize with some data
105     init(fn,d)
106
107     # check if we include or are the beginning
108     oldfile = None
109     if include:
110         oldfile = d.getVar('FILE', False)
111         is_conf = False
112     elif ext == ".conf":
113         is_conf = True
114         data.inheritFromOS(d)
115
116     # find the file
117     if not os.path.isabs(fn):
118         abs_fn = bb.which(d.getVar('BBPATH', True), fn)
119     else:
120         abs_fn = fn
121
122     # check if the file exists
123     if not os.path.exists(abs_fn):
124         raise IOError("file '%(fn)s' not found" % locals() )
125
126     # now we know the file is around mark it as dep
127     if include:
128         parse.mark_dependency(d, abs_fn)
129
130     # manipulate the bbpath
131     if ext != ".bbclass" and ext != ".conf":
132         old_bb_path = data.getVar('BBPATH', d)
133         data.setVar('BBPATH', os.path.dirname(abs_fn) + (":%s" %old_bb_path) , d)
134
135     # handle INHERITS and base inherit
136     if ext != ".bbclass" and ext != ".conf":
137         data.setVar('FILE', fn, d)
138         handle_interit(d)
139
140     # now parse this file - by defering it to C++
141     parsefile(abs_fn, d, is_conf)
142
143     # Finish it up
144     if include == 0:
145         data.expandKeys(d)
146         data.update_data(d)
147         #### !!! XXX Finish it up by executing the anonfunc
148
149
150     # restore the original FILE
151     if oldfile:
152         d.setVar('FILE', oldfile)
153
154     # restore bbpath
155     if ext != ".bbclass" and ext != ".conf":
156         data.setVar('BBPATH', old_bb_path, d )
157
158
159     return d
160
161
162 # Needed for BitBake files...
163 __pkgsplit_cache__={}
164 def vars_from_file(mypkg, d):
165     if not mypkg:
166         return (None, None, None)
167     if mypkg in __pkgsplit_cache__:
168         return __pkgsplit_cache__[mypkg]
169
170     myfile = os.path.splitext(os.path.basename(mypkg))
171     parts = myfile[0].split('_')
172     __pkgsplit_cache__[mypkg] = parts
173     exp = 3 - len(parts)
174     tmplist = []
175     while exp != 0:
176         exp -= 1
177         tmplist.append(None)
178     parts.extend(tmplist)
179     return parts
180
181
182
183
184 # Inform bitbake that we are a parser
185 # We need to define all three
186 from bb.parse import handlers
187 handlers.append( {'supports' : supports, 'handle': handle, 'init' : init})
188 del handlers