summaryrefslogtreecommitdiffstats
path: root/source-builder/sb/config.py
diff options
context:
space:
mode:
Diffstat (limited to 'source-builder/sb/config.py')
-rw-r--r--source-builder/sb/config.py218
1 files changed, 118 insertions, 100 deletions
diff --git a/source-builder/sb/config.py b/source-builder/sb/config.py
index a40147d..24590eb 100644
--- a/source-builder/sb/config.py
+++ b/source-builder/sb/config.py
@@ -45,8 +45,7 @@ except KeyboardInterrupt:
print('user terminated', file = sys.stderr)
sys.exit(1)
except:
- print('error: unknown application load error', file = sys.stderr)
- sys.exit(1)
+ raise
def _check_bool(value):
istrue = None
@@ -69,6 +68,13 @@ def _check_nil(value):
istrue = False
return istrue
+def _check_number(value):
+ try:
+ float(value)
+ return True
+ except ValueError:
+ return False
+
class package:
def __init__(self, name, arch, config):
@@ -252,7 +258,7 @@ class file:
re.compile('%select'),
re.compile('%disable') ]
- def __init__(self, name, opts, macros = None):
+ def __init__(self, name, opts, macros = None, load = True):
log.trace('config: %s: initialising' % (name))
self.opts = opts
self.init_name = name
@@ -261,7 +267,8 @@ class file:
self.sf = re.compile(r'%\([^\)]+\)')
self.set_macros(macros)
self._reset(name)
- self.load(name)
+ if load:
+ self.load(name)
def __str__(self):
@@ -283,6 +290,7 @@ class file:
return s
def _reset(self, name):
+ self.parent = 'root'
self.name = name
self.load_depth = 0
self.configpath = []
@@ -430,7 +438,8 @@ class file:
if len(shell_macro) > 3:
e = execute.capture_execution()
if options.host_windows:
- shell_cmd = ''.join([c if c != '"' else '\\' + c for c in shell_macro[2:-1]])
+ shell_cmd = \
+ ''.join([c if c != '"' else '\\' + c for c in shell_macro[2:-1]])
cmd = '%s -c "%s"' % (self.macros.expand('%{__sh}'), shell_cmd)
else:
cmd = shell_macro[2:-1]
@@ -458,7 +467,8 @@ class file:
if braces > 0:
braces -= 1
else:
- shell_cmd = '%(' + self._shell(line[pos + 2:p], nesting + 1) + ')'
+ shell_cmd = '%(' + \
+ self._shell(line[pos + 2:p], nesting + 1) + ')'
line = line[:pos] + _exec(shell_cmd) + line[p + 1:]
updating = True
break
@@ -472,9 +482,10 @@ class file:
('with_download' in self.macros and self.macros['with_download'] == '1'):
return '0'
ok = False
- log.trace('pkgconfig: check: crossc=%d pkg_crossc=%d prefix=%s' % ( self._cross_compile(),
- self.pkgconfig_crosscompile,
- self.pkgconfig_prefix))
+ log.trace('pkgconfig: check: crossc=%d pkg_crossc=%d prefix=%s'
+ % ( self._cross_compile(),
+ self.pkgconfig_crosscompile,
+ self.pkgconfig_prefix))
log.trace('pkgconfig: check: test=%s' % (test))
if type(test) == str:
test = test.split()
@@ -496,6 +507,7 @@ class file:
except pkgconfig.error as pe:
self._error('pkgconfig: check: %s' % (pe))
except:
+ raise
raise error.internal('pkgconfig failure')
if ok:
return '1'
@@ -520,6 +532,7 @@ class file:
except pkgconfig.error as pe:
self._error('pkgconfig: %s: %s' % (flags, pe))
except:
+ raise
raise error.internal('pkgconfig failure')
if pkg_flags is None:
pkg_flags = ''
@@ -594,7 +607,8 @@ class file:
elif m.startswith('%{expand'):
colon = m.find(':')
if colon < 8:
- log.warning(self._name_line_msg('malformed expand macro, no colon found'))
+ log.warning(self._name_line_msg('malformed expand macro, ' \
+ 'no colon found'))
else:
e = self._expand(m[colon + 1:-1].strip())
s = s.replace(m, self._label(e))
@@ -772,7 +786,16 @@ class file:
mn = '%{nil}'
if mn:
if mn.lower() in self.macros:
- s = s.replace(m, self.macros[mn.lower()])
+ em = self.macros[mn.lower()]
+ if self.macros.get_type(mn) == 'dir' and ':' in em:
+ ss = []
+ for sp in s.split():
+ if m in sp:
+ sp = ':'.join([sp.replace(mn, ps) for ps in em.split(':')])
+ ss += [sp]
+ s = ' '.join(ss)
+ else:
+ s = s.replace(m, self.macros[mn.lower()])
expanded = True
elif show_warning:
self._error("macro '%s' not found" % (mn))
@@ -861,7 +884,8 @@ class file:
dir, info, data = self._process_directive(r, dir, info, data)
else:
if in_dir != dir:
- self._error('directives cannot change scope across if statements')
+ self._error('directives cannot change' \
+ ' scope across if statements')
return data
if r[1] == '%else':
@@ -904,34 +928,42 @@ class file:
elif cls[0] == '&&':
join_op = 'and'
cls = cls[1:]
- log.trace('config: %s: %3d: _if[%i]: joining: %s' % (self.name, self.lc,
- self.if_depth,
- join_op))
+ log.trace('config: %s: %3d: _if[%i]: joining: %s' % \
+ (self.name, self.lc,
+ self.if_depth,
+ join_op))
+ # If OR and the previous check was true short circuit the evaluation
+ if join_op == 'or' and cistrue:
+ log.trace('config: %s: %3d: _if[%i]: OR true, short circuit eval' % \
+ (self.name, self.lc,
+ self.if_depth))
+ break
ori = 0
andi = 0
i = len(cls)
if '||' in cls:
ori = cls.index('||')
- log.trace('config: %s: %3d: _if[%i}: OR found at %i' % (self.name, self.lc,
- self.if_depth,
- ori))
+ log.trace('config: %s: %3d: _if[%i}: OR found at %i' % \
+ (self.name, self.lc,
+ self.if_depth,
+ ori))
if '&&' in cls:
andi = cls.index('&&')
- log.trace('config: %s: %3d: _if[%i]: AND found at %i' % (self.name, self.lc,
- self.if_depth,
- andi))
+ log.trace('config: %s: %3d: _if[%i]: AND found at %i' % \
+ (self.name, self.lc,
+ self.if_depth,
+ andi))
if ori > 0 or andi > 0:
if ori == 0:
i = andi
elif andi == 0:
i = ori
- elif ori < andi:
- i = andi
else:
- i = andi
- log.trace('config: %s: %3d: _if[%i]: next OP found at %i' % (self.name, self.lc,
- self.if_depth,
- i))
+ i = min(ori, andi)
+ log.trace('config: %s: %3d: _if[%i]: next OP found at %i' % \
+ (self.name, self.lc,
+ self.if_depth,
+ i))
ls = cls[:i]
if len(ls) == 0:
self._error('invalid if expression: ' + reduce(add, sls, ''))
@@ -985,37 +1017,27 @@ class file:
ifls = (' '.join(ifls[:op_pos]), op, ' '.join(ifls[op_pos + 1:]))
break
if len(ifls) != 3:
- self._error('malformed if: ' + reduce(add, ls, ''))
- if ifls[1] == '==':
- if ifls[0] == ifls[2]:
- istrue = True
- else:
- istrue = False
- elif ifls[1] == '!=' or ifls[1] == '=!':
- if ifls[0] != ifls[2]:
- istrue = True
- else:
- istrue = False
- elif ifls[1] == '>':
- if ifls[0] > ifls[2]:
- istrue = True
- else:
- istrue = False
- elif ifls[1] == '>=' or ifls[1] == '=>':
- if ifls[0] >= ifls[2]:
- istrue = True
- else:
- istrue = False
- elif ifls[1] == '<=' or ifls[1] == '=<':
- if ifls[0] <= ifls[2]:
- istrue = True
- else:
- istrue = False
- elif ifls[1] == '<':
- if ifls[0] < ifls[2]:
- istrue = True
- else:
- istrue = False
+ self._error('malformed if: ' + reduce(add, ls, ''))
+ lhs = ifls[0]
+ operator = ifls[1]
+ rhs = ifls[2]
+ if _check_number(lhs) and _check_number(rhs):
+ log.trace('config: %s: %3d: _if: numeric value check' % \
+ (self.name, self.lc))
+ lhs = float(lhs)
+ rhs = float(rhs)
+ if operator == '==':
+ istrue = lhs == rhs
+ elif operator == '!=' or operator == '=!':
+ istrue = lhs != rhs
+ elif operator == '>':
+ istrue = lhs > rhs
+ elif operator == '>=' or operator == '=>':
+ istrue = lhs >= rhs
+ elif operator == '<=' or operator == '=<':
+ istrue = lhs <= rhs
+ elif operator == '<':
+ istrue = lhs < rhs
else:
self._error('invalid %if operator: ' + reduce(add, ls, ''))
@@ -1226,7 +1248,8 @@ class file:
log.trace('config: %s: %3d: _parse: directive: %s' % \
(self.name, self.lc, ls[0].strip()))
return ('directive', ls[0].strip(), ls[1:])
- log.warning(self._name_line_msg("unknown directive: '" + ls[0] + "'"))
+ log.warning(self._name_line_msg("unknown directive: '" + \
+ ls[0] + "'"))
return ('data', [lo])
else:
return ('data', [lo])
@@ -1247,7 +1270,8 @@ class file:
_package = results[2][0]
else:
if results[2][0].strip() != '-n':
- log.warning(self._name_line_msg("unknown directive option: '%s'" % (' '.join(results[2]))))
+ log.warning(self._name_line_msg("unknown directive option: '%s'" % \
+ (' '.join(results[2]))))
_package = results[2][1].strip()
self._set_package(_package)
if directive and directive != results[1]:
@@ -1257,7 +1281,8 @@ class file:
return (directive, info, data)
def _process_data(self, results, directive, info, data):
- log.trace('config: %s: %3d: _process_data: result=#%r# directive=#%s# info=#%r# data=#%r#' % \
+ log.trace('config: %s: %3d: _process_data: result=#%r# ' \
+ 'directive=#%s# info=#%r# data=#%r#' % \
(self.name, self.lc, results, directive, info, data))
new_data = []
for l in results[1]:
@@ -1284,10 +1309,12 @@ class file:
if info is not None:
self._info_append(info, info_data)
else:
- log.warning(self._name_line_msg("invalid format: '%s'" % (info_data[:-1])))
+ log.warning(self._name_line_msg("invalid format: '%s'" % \
+ (info_data[:-1])))
else:
l = self._expand(l)
- log.trace('config: %s: %3d: _data: %s %s' % (self.name, self.lc, l, new_data))
+ log.trace('config: %s: %3d: _data: %s %s' % \
+ (self.name, self.lc, l, new_data))
new_data.append(l)
return (directive, info, data + new_data)
@@ -1303,7 +1330,8 @@ class file:
self.package = _package
def _directive_extend(self, dir, data):
- log.trace('config: %s: %3d: _directive_extend: %s: %r' % (self.name, self.lc, dir, data))
+ log.trace('config: %s: %3d: _directive_extend: %s: %r' % \
+ (self.name, self.lc, dir, data))
self._packages[self.package].directive_extend(dir, data)
def _info_append(self, info, data):
@@ -1327,8 +1355,15 @@ class file:
right = right[:-1]
return end
+ def search_path(confignames):
+ for configname in confignames.split(':'):
+ if not configname.endswith('.cfg'):
+ configname = '%s.cfg' % (configname)
+ if path.exists(configname):
+ return configname
+ return None
+
if self.load_depth == 0:
- self._reset(name)
self._packages[self.package] = package(self.package,
self.define('%{_arch}'),
self)
@@ -1336,11 +1371,12 @@ class file:
self.load_depth += 1
save_name = self.name
+ save_parent = self.parent
save_lc = self.lc
#
# Locate the config file. Expand any macros then add the
- # extension. Check if the file exists, therefore directly
+ # extension. Check if the file exists then it is directly
# referenced. If not see if the file contains ':' or the path
# separator. If it does split the path else use the standard config dir
# path in the defaults.
@@ -1348,32 +1384,13 @@ class file:
exname = self.expand(name)
- #
- # Macro could add an extension.
- #
- if exname.endswith('.cfg'):
- configname = exname
- else:
- configname = '%s.cfg' % (exname)
- name = '%s.cfg' % (name)
-
- if ':' in configname:
- cfgname = path.basename(configname)
- else:
- cfgname = common_end(configname, name)
+ configname = search_path(exname)
+ if configname is None:
+ configname = search_path(self.expand(path.join('%{_configdir}', exname)))
+ if configname is None:
+ raise error.general('no config file found: %s' % (','.join(exname.split(':'))))
- if not path.exists(configname):
- if ':' in configname:
- configdirs = path.dirname(configname).split(':')
- else:
- configdirs = self.define('_configdir').split(':')
- for cp in configdirs:
- configname = path.join(path.abspath(cp), cfgname)
- if path.exists(configname):
- break
- configname = None
- if configname is None:
- raise error.general('no config file found: %s' % (cfgname))
+ name = path.basename(configname)
try:
log.trace('config: %s: _open: %s' % (self.name, path.host(configname)))
@@ -1382,7 +1399,9 @@ class file:
raise error.general('error opening config file: %s' % (path.host(configname)))
self.configpath += [configname]
- self._includes += [configname]
+
+ self._includes += [configname + ':' + self.parent]
+ self.parent = configname
self.name = self._relative_path(configname)
self.lc = 0
@@ -1413,13 +1432,12 @@ class file:
except:
config.close()
raise
-
- config.close()
-
- self.name = save_name
- self.lc = save_lc
-
- self.load_depth -= 1
+ finally:
+ config.close()
+ self.name = save_name
+ self.parent = save_parent
+ self.lc = save_lc
+ self.load_depth -= 1
def defined(self, name):
return name in self.macros
@@ -1456,7 +1474,7 @@ class file:
raise error.general('package "' + _package + '" not found')
if name not in self._packages[_package].directives:
raise error.general('directive "' + name + \
- '" not found in package "' + _package + '"')
+ '" not found in package "' + _package + '"')
return self._packages[_package].directives[name]
def abspath(self, rpath):