summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/parse/parse_py/ConfHandler.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/parse/parse_py/ConfHandler.py')
-rw-r--r--bitbake/lib/bb/parse/parse_py/ConfHandler.py182
1 files changed, 182 insertions, 0 deletions
diff --git a/bitbake/lib/bb/parse/parse_py/ConfHandler.py b/bitbake/lib/bb/parse/parse_py/ConfHandler.py
new file mode 100644
index 0000000000..7b30c8acb3
--- /dev/null
+++ b/bitbake/lib/bb/parse/parse_py/ConfHandler.py
@@ -0,0 +1,182 @@
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 class for handling configuration data files
6
7 Reads a .conf file and obtains its metadata
8
9"""
10
11# Copyright (C) 2003, 2004 Chris Larson
12# Copyright (C) 2003, 2004 Phil Blundell
13#
14# This program is free software; you can redistribute it and/or modify
15# it under the terms of the GNU General Public License version 2 as
16# published by the Free Software Foundation.
17#
18# This program is distributed in the hope that it will be useful,
19# but WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21# GNU General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License along
24# with this program; if not, write to the Free Software Foundation, Inc.,
25# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26
27import re, os
28import logging
29import bb.utils
30from bb.parse import ParseError, resolve_file, ast, logger
31
32__config_regexp__ = re.compile( r"""
33 ^
34 (?P<exp>export\s*)?
35 (?P<var>[a-zA-Z0-9\-~_+.${}/]+?)
36 (\[(?P<flag>[a-zA-Z0-9\-_+.]+)\])?
37
38 \s* (
39 (?P<colon>:=) |
40 (?P<lazyques>\?\?=) |
41 (?P<ques>\?=) |
42 (?P<append>\+=) |
43 (?P<prepend>=\+) |
44 (?P<predot>=\.) |
45 (?P<postdot>\.=) |
46 =
47 ) \s*
48
49 (?!'[^']*'[^']*'$)
50 (?!\"[^\"]*\"[^\"]*\"$)
51 (?P<apo>['\"])
52 (?P<value>.*)
53 (?P=apo)
54 $
55 """, re.X)
56__include_regexp__ = re.compile( r"include\s+(.+)" )
57__require_regexp__ = re.compile( r"require\s+(.+)" )
58__export_regexp__ = re.compile( r"export\s+([a-zA-Z0-9\-_+.${}/]+)$" )
59
60def init(data):
61 topdir = data.getVar('TOPDIR')
62 if not topdir:
63 data.setVar('TOPDIR', os.getcwd())
64
65
66def supports(fn, d):
67 return fn[-5:] == ".conf"
68
69def include(oldfn, fn, lineno, data, error_out):
70 """
71 error_out: A string indicating the verb (e.g. "include", "inherit") to be
72 used in a ParseError that will be raised if the file to be included could
73 not be included. Specify False to avoid raising an error in this case.
74 """
75 if oldfn == fn: # prevent infinite recursion
76 return None
77
78 import bb
79 fn = data.expand(fn)
80 oldfn = data.expand(oldfn)
81
82 if not os.path.isabs(fn):
83 dname = os.path.dirname(oldfn)
84 bbpath = "%s:%s" % (dname, data.getVar("BBPATH", True))
85 abs_fn = bb.utils.which(bbpath, fn)
86 if abs_fn:
87 fn = abs_fn
88
89 from bb.parse import handle
90 try:
91 ret = handle(fn, data, True)
92 except (IOError, OSError):
93 if error_out:
94 raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), oldfn, lineno)
95 logger.debug(2, "CONF file '%s' not found", fn)
96
97# We have an issue where a UI might want to enforce particular settings such as
98# an empty DISTRO variable. If configuration files do something like assigning
99# a weak default, it turns out to be very difficult to filter out these changes,
100# particularly when the weak default might appear half way though parsing a chain
101# of configuration files. We therefore let the UIs hook into configuration file
102# parsing. This turns out to be a hard problem to solve any other way.
103confFilters = []
104
105def handle(fn, data, include):
106 init(data)
107
108 if include == 0:
109 oldfile = None
110 else:
111 oldfile = data.getVar('FILE')
112
113 abs_fn = resolve_file(fn, data)
114 f = open(abs_fn, 'r')
115
116 if include:
117 bb.parse.mark_dependency(data, abs_fn)
118
119 statements = ast.StatementGroup()
120 lineno = 0
121 while True:
122 lineno = lineno + 1
123 s = f.readline()
124 if not s:
125 break
126 w = s.strip()
127 # skip empty lines
128 if not w:
129 continue
130 s = s.rstrip()
131 while s[-1] == '\\':
132 s2 = f.readline().strip()
133 lineno = lineno + 1
134 if (not s2 or s2 and s2[0] != "#") and s[0] == "#" :
135 bb.fatal("There is a confusing multiline, partially commented expression on line %s of file %s (%s).\nPlease clarify whether this is all a comment or should be parsed." % (lineno, fn, s))
136 s = s[:-1] + s2
137 # skip comments
138 if s[0] == '#':
139 continue
140 feeder(lineno, s, fn, statements)
141
142 # DONE WITH PARSING... time to evaluate
143 data.setVar('FILE', abs_fn)
144 statements.eval(data)
145 if oldfile:
146 data.setVar('FILE', oldfile)
147
148 f.close()
149
150 for f in confFilters:
151 f(fn, data)
152
153 return data
154
155def feeder(lineno, s, fn, statements):
156 m = __config_regexp__.match(s)
157 if m:
158 groupd = m.groupdict()
159 ast.handleData(statements, fn, lineno, groupd)
160 return
161
162 m = __include_regexp__.match(s)
163 if m:
164 ast.handleInclude(statements, fn, lineno, m, False)
165 return
166
167 m = __require_regexp__.match(s)
168 if m:
169 ast.handleInclude(statements, fn, lineno, m, True)
170 return
171
172 m = __export_regexp__.match(s)
173 if m:
174 ast.handleExport(statements, fn, lineno, m)
175 return
176
177 raise ParseError("unparsed line: '%s'" % s, fn, lineno);
178
179# Add us to the handlers list
180from bb.parse import handlers
181handlers.append({'supports': supports, 'handle': handle, 'init': init})
182del handlers