mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-19 21:09:03 +02:00

Currently, bitbake will accept variables in the forms: X = 1 X = '1 \ X = "1" X = '1' which will all set X=1. This patch removes the first two possibilities and makes quoting mandatory. There is little metadata out there which doesn't quote properly and bitbake will exit with an error about the exact line number and file with any problem so users can easily identify and fix issues. OE-Core has already been checked/fixed. The motivation for this is being able to give sane errors if a user does something like: IMAGE_INSTALL += # tslib mtd-utils" which currently gives a really nasty failure. (Bitbake rev: a8ae80741fea5e0ec0fb9a52a963a4baa38d2564) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
140 lines
4.1 KiB
Python
140 lines
4.1 KiB
Python
#!/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 configuration data files
|
|
|
|
Reads a .conf 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 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, os
|
|
import logging
|
|
import bb.utils
|
|
from bb.parse import ParseError, resolve_file, ast, logger
|
|
|
|
__config_regexp__ = re.compile( r"(?P<exp>export\s*)?(?P<var>[a-zA-Z0-9\-_+.${}/]+)(\[(?P<flag>[a-zA-Z0-9\-_+.]+)\])?\s*((?P<colon>:=)|(?P<lazyques>\?\?=)|(?P<ques>\?=)|(?P<append>\+=)|(?P<prepend>=\+)|(?P<predot>=\.)|(?P<postdot>\.=)|=)\s*(?P<apo>['\"])(?P<value>.*)(?P=apo)$")
|
|
__include_regexp__ = re.compile( r"include\s+(.+)" )
|
|
__require_regexp__ = re.compile( r"require\s+(.+)" )
|
|
__export_regexp__ = re.compile( r"export\s+(.+)" )
|
|
|
|
def init(data):
|
|
topdir = data.getVar('TOPDIR')
|
|
if not topdir:
|
|
data.setVar('TOPDIR', os.getcwd())
|
|
|
|
|
|
def supports(fn, d):
|
|
return fn[-5:] == ".conf"
|
|
|
|
def include(oldfn, fn, lineno, data, error_out):
|
|
"""
|
|
error_out: A string indicating the verb (e.g. "include", "inherit") to be
|
|
used in a ParseError that will be raised if the file to be included could
|
|
not be included. Specify False to avoid raising an error in this case.
|
|
"""
|
|
if oldfn == fn: # prevent infinite recursion
|
|
return None
|
|
|
|
import bb
|
|
fn = data.expand(fn)
|
|
oldfn = data.expand(oldfn)
|
|
|
|
if not os.path.isabs(fn):
|
|
dname = os.path.dirname(oldfn)
|
|
bbpath = "%s:%s" % (dname, data.getVar("BBPATH", 1))
|
|
abs_fn = bb.utils.which(bbpath, fn)
|
|
if abs_fn:
|
|
fn = abs_fn
|
|
|
|
from bb.parse import handle
|
|
try:
|
|
ret = handle(fn, data, True)
|
|
except IOError:
|
|
if error_out:
|
|
raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), oldfn, lineno)
|
|
logger.debug(2, "CONF file '%s' not found", fn)
|
|
|
|
def handle(fn, data, include):
|
|
init(data)
|
|
|
|
if include == 0:
|
|
oldfile = None
|
|
else:
|
|
oldfile = data.getVar('FILE')
|
|
|
|
abs_fn = resolve_file(fn, data)
|
|
f = open(abs_fn, 'r')
|
|
|
|
if include:
|
|
bb.parse.mark_dependency(data, abs_fn)
|
|
|
|
statements = ast.StatementGroup()
|
|
lineno = 0
|
|
while True:
|
|
lineno = lineno + 1
|
|
s = f.readline()
|
|
if not s: break
|
|
w = s.strip()
|
|
if not w: continue # skip empty lines
|
|
s = s.rstrip()
|
|
if s[0] == '#': continue # skip comments
|
|
while s[-1] == '\\':
|
|
s2 = f.readline().strip()
|
|
lineno = lineno + 1
|
|
s = s[:-1] + s2
|
|
feeder(lineno, s, fn, statements)
|
|
|
|
# DONE WITH PARSING... time to evaluate
|
|
data.setVar('FILE', abs_fn)
|
|
statements.eval(data)
|
|
if oldfile:
|
|
data.setVar('FILE', oldfile)
|
|
|
|
return data
|
|
|
|
def feeder(lineno, s, fn, statements):
|
|
m = __config_regexp__.match(s)
|
|
if m:
|
|
groupd = m.groupdict()
|
|
ast.handleData(statements, fn, lineno, groupd)
|
|
return
|
|
|
|
m = __include_regexp__.match(s)
|
|
if m:
|
|
ast.handleInclude(statements, fn, lineno, m, False)
|
|
return
|
|
|
|
m = __require_regexp__.match(s)
|
|
if m:
|
|
ast.handleInclude(statements, fn, lineno, m, True)
|
|
return
|
|
|
|
m = __export_regexp__.match(s)
|
|
if m:
|
|
ast.handleExport(statements, fn, lineno, m)
|
|
return
|
|
|
|
raise ParseError("unparsed line: '%s'" % s, fn, lineno);
|
|
|
|
# Add us to the handlers list
|
|
from bb.parse import handlers
|
|
handlers.append({'supports': supports, 'handle': handle, 'init': init})
|
|
del handlers
|